// main.cpp // OpenGL_HelloWorld // Created by pgAgent on 13/06/2015. // Copyright (c) 2015 RJM Programming. All rights reserved. // Can draw a cube and hexagonal prism #include #include #include #include #include #ifdef __APPLE__ # include #else # include #endif // Thanks to https://www.opengl.org/archives/resources/code/samples/glut_examples/examples/examples.html //GLfloat light_diffuse[] = {1.0, 0.0, 0.0, 1.0}; /* Red diffuse light. */ GLfloat light_diffuse[] = {0.0, 1.0, 0.0, 1.0}; /* Green ambient light. */ //GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0}; /* Infinite light location. */ GLfloat light_position[] = {1.0, 1.0, 1.0, 100.0}; /* Not Infinite light location. */ GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */ {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} }; GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */ {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4}, {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} }; GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */ GLfloat n6[8][3] = { /* Normals for the 8 faces of a hexagonal prism. */ {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} }; GLint faces6[8][6] = { /* Vertex indices for the 8 faces of a hexagonal prism. */ {0, 1, 2, 3, 4, 5}, {0, 0, 11, 5, 6, 6}, {0, 0, 11, 1, 10, 10}, {11, 10, 9, 8, 7, 6}, {1, 1, 10, 2, 9, 9}, {2, 2, 9, 3, 8, 8}, {4, 4, 7, 3, 8, 8}, {5, 5, 6, 4, 7, 7} }; GLfloat v6[12][3]; /* Will be filled in with X,Y,Z vertexes. */ GLfloat sqrt3 = 1.73205080757f; GLfloat sidelen = 0.0; struct pointXZ { GLfloat x; GLfloat z; } pointXZ; void drawHexagonalPrism(void) { int i; for (i = 0; i < 8; i++) { glBegin(GL_POLYGON); glNormal3fv(&n6[i][0]); glVertex3fv(&v6[faces6[i][0]][0]); glVertex3fv(&v6[faces6[i][1]][0]); glVertex3fv(&v6[faces6[i][2]][0]); glVertex3fv(&v6[faces6[i][3]][0]); glVertex3fv(&v6[faces6[i][4]][0]); glVertex3fv(&v6[faces6[i][5]][0]); glEnd(); } } // macro to use to set a = b X c void crossProduct(GLfloat a[], GLfloat b[], GLfloat c[]) { // thanks to http://cs.indstate.edu a[0] = b[1] * c[2] - c[1] * b[2]; a[1] = b[2] * c[0] - c[2] * b[0]; a[2] = b[0] * c[1] - c[0] * b[1]; } void drawHexPrism(GLfloat s, GLfloat h) { // thanks to http://cs.indstate.edu GLfloat a = s/2.0f*sqrt3; // apothem GLfloat halfs = s/2.0f; // half side length struct pointXZ hex[] = {{-halfs, a}, {halfs, a}, {a, 0.0f}, {halfs, -a}, {-halfs, -a}, {-a, 0.0f}, {-halfs, a}}; // base. glNormal3f(0.0f,-1.0f,0.0f); glBegin(GL_POLYGON); for(int i=0;i<6;i++) glVertex3f(hex[i].x, 0.0f, hex[i].z); glEnd(); // top glPushMatrix(); glTranslatef(0.0f,h,0.0f); glNormal3f(0.0f,1.0f,0.0f); glBegin(GL_POLYGON); for(int i=0;i<6;i++) glVertex3f(hex[i].x, 0.0f, hex[i].z); glEnd(); glPopMatrix(); // for use in computing normal vectors GLfloat v[3], p1[3], p2[3]; // 6 sides for(int i=0;i<6;i++) { // compute normal vector for this polygon // p1 points up p1[0] = 0.0f; p1[1] = 1.0f; p1[2] = 0.0f; // p2 points along the base of the rectangle p2[0] = hex[i].x-hex[i+1].x; p2[1] = 0.0f; p2[3] = hex[i].z-hex[i+1].z; crossProduct(v, p1, p2); // now v points out from rectangle glNormal3f(v[0],v[1],v[2]); //cout << v[0] << " " << v[1] << " " << v[2] << endl; glBegin(GL_QUADS); glVertex3f(hex[i].x, 0.0f, hex[i].z); glVertex3f(hex[i].x, h, hex[i].z); glVertex3f(hex[i+1].x, h, hex[i+1].z); glVertex3f(hex[i+1].x, 0.0f, hex[i+1].z); glEnd(); } } void drawBox(void) { int i; for (i = 0; i < 6; i++) { glBegin(GL_QUADS); glNormal3fv(&n[i][0]); glVertex3fv(&v[faces[i][0]][0]); glVertex3fv(&v[faces[i][1]][0]); glVertex3fv(&v[faces[i][2]][0]); glVertex3fv(&v[faces[i][3]][0]); glEnd(); } } void displaynew(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawBox(); glutSwapBuffers(); } void displayhexagonalprism(void) { int cnum_sides = 6; int clength_of_side = 2; double capothem = (double)clength_of_side * sqrt(3.0)/2.0; // = R sqrt(3)/2 if (7 == 7) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (sidelen > 0.0) { drawHexPrism(sidelen, (GLfloat)1); //drawHexagonalPrism(); } else { drawHexPrism((GLfloat)clength_of_side, (GLfloat)1); //drawHexagonalPrism(); } } else { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glBegin(GL_POLYGON); for(int i = 0; i < cnum_sides; i++) { glBegin(GL_POLYGON); glVertex3f(0 - (clength_of_side / 2), -capothem, 0.0); glRotatef(360.0 / cnum_sides, 0.0, 0.0, 1.0); //I'm not sure if this statement will work inside a glBegin/glEnd pair glEnd(); } glEnd(); glPopMatrix(); } glutSwapBuffers(); } void init(void) { /* Setup cube vertex data. */ v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1; v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1; v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1; v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1; v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1; v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1; /* Enable a single OpenGL light. */ //glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_AMBIENT, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.0); /* up is in positive Y direction */ /* Adjust cube position to be asthetic angle. */ glTranslatef(0.0, 0.0, -1.0); glRotatef(60, 1.0, 0.0, 0.0); glRotatef(-20, 0.0, 0.0, 1.0); } void init6(char *cl_o_s) { if (strstr(cl_o_s, ",")) { /* Setup hexagonal prism vertex data. */ sscanf(cl_o_s, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &v6[0][0], &v6[0][1], &v6[1][0], &v6[1][1], &v6[2][0], &v6[2][1], &v6[3][0], &v6[3][1], &v6[4][0], &v6[4][1], &v6[5][0], &v6[5][1]); sscanf(cl_o_s, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &v6[11][0], &v6[11][1], &v6[10][0], &v6[10][1], &v6[9][0], &v6[9][1], &v6[8][0], &v6[8][1], &v6[7][0], &v6[7][1], &v6[6][0], &v6[6][1]); } else { /* Setup hexagonal prism vertex data. */ v6[0][0] = v6[1][0] = v6[2][0] = v6[3][0] = -1; v6[4][0] = v6[5][0] = v6[6][0] = v6[7][0] = 1; v6[0][1] = v6[1][1] = v6[4][1] = v6[5][1] = -1; v6[2][1] = v6[3][1] = v6[6][1] = v6[7][1] = 1; } v6[0][2] = v6[3][2] = v6[4][2] = v6[7][2] = v6[8][2] = v6[11][2] = 1; v6[1][2] = v6[2][2] = v6[5][2] = v6[6][2] = v6[9][2] = v6[10][2] = -1; /* Enable a single OpenGL light. */ glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); //glLightfv(GL_LIGHT0, GL_AMBIENT, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.0); /* up is in positive Y direction */ /* Adjust cube position to be asthetic angle. */ glTranslatef(0.0, 0.0, -1.0); glRotatef(60, 1.0, 0.0, 0.0); glRotatef(-20, 0.0, 0.0, 1.0); } void init6(int l_o_s) { /* Setup hexagonal prism vertex data. */ v6[0][2] = v6[3][2] = v6[4][2] = v6[7][2] = v6[8][2] = v6[11][2] = l_o_s; v6[1][2] = v6[2][2] = v6[5][2] = v6[6][2] = v6[9][2] = v6[10][2] = -l_o_s; /* Enable a single OpenGL light. */ //glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_AMBIENT, light_diffuse); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHT0); glEnable(GL_LIGHTING); /* Use depth buffering for hidden surface elimination. */ glEnable(GL_DEPTH_TEST); /* Setup the view of the cube. */ glMatrixMode(GL_PROJECTION); gluPerspective( /* field of view in degree */ 40.0, /* aspect ratio */ 1.0, /* Z near */ 1.0, /* Z far */ 10.0); glMatrixMode(GL_MODELVIEW); gluLookAt(0.0, 0.0, 5.0, /* eye is at (0,0,5) */ 0.0, 0.0, 0.0, /* center is at (0,0,0) */ 0.0, 1.0, 0.0); /* up is in positive Y direction */ /* Adjust cube position to be asthetic angle. */ glTranslatef(0.0, 0.0, -1.0); glRotatef(60, 1.0, 0.0, 0.0); glRotatef(-20, 0.0, 0.0, 1.0); } void display (void) { if (1 == 1) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); drawBox(); glutSwapBuffers(); } else { glClearColor(1.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glFlush(); } } static int make_resources(void) { return 1; } static void update_fade_factor(void) { } static void render(void) { glClearColor(0.5f, 0.5f, 0.5f, 0.5f); glClear(GL_COLOR_BUFFER_BIT); glutSwapBuffers(); } int main (int argc, char **argv) { if (6 == 6) { // thanks to http://www.experts-exchange.com/Programming/Game/Q_21374680.html and http://mathforum.org/dr.math/faq/formulas/faq.regpoly.html int num_sides = 6; int length_of_side = 2; double apothem = (double)length_of_side * sqrt(3.0)/2.0; // = R sqrt(3)/2 char creal[100]; sprintf(creal, "Hexagonal prism %lf", apothem); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); if (argc > 1) { sscanf(argv[1], "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &v6[0][0], &v6[0][1], &v6[1][0], &v6[1][1], &v6[2][0], &v6[2][1], &v6[3][0], &v6[3][1], &v6[4][0], &v6[4][1], &v6[5][0], &v6[5][1]); sidelen = fmod(sqrt((v6[0][0] - v6[1][0]) * (v6[0][0] - v6[1][0]) + (v6[0][1] - v6[1][1]) * (v6[0][1] - v6[1][1])), 2.1); sprintf(creal, "Hexagonal Prism %f", sidelen); sscanf(argv[1], "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &v6[11][0], &v6[11][1], &v6[10][0], &v6[10][1], &v6[9][0], &v6[9][1], &v6[8][0], &v6[8][1], &v6[7][0], &v6[7][1], &v6[6][0], &v6[6][1]); glutCreateWindow(creal); glutDisplayFunc(displayhexagonalprism); init6(argv[1]); } else { glutCreateWindow(creal); //"Hexagonal prism"); //creal); glutDisplayFunc(displayhexagonalprism); init6(length_of_side); } glutMainLoop(); } else if (1 == 1) { // thanks to https://www.opengl.org/archives/resources/code/samples/glut_examples/examples/examples.html glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow("Green 3D lighted cube"); glutDisplayFunc(displaynew); init(); glutMainLoop(); } else if (1 == 1) { // thanks to http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-2:-Hello-World:-The-Slideshow.html glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowSize(400, 300); glutCreateWindow("Hello World"); glutDisplayFunc(&render); glutIdleFunc(&update_fade_factor); glutMainLoop(); } else { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow ("Your first OpenGL Window ... Hello World"); glutDisplayFunc(display); glutMainLoop(); } }