// OPEN_GL_test.cpp : Defines the entry point for the console application. // // OPEN_GL_test.cpp : Defines the entry point for the console application. // #include "stdafx.h" #define GL_PI 3.1415f GLfloat xRot = 0.45f, yRot = 0.35f; GLboolean bCull = (GLboolean)true, bDepth= (GLboolean)true, bOutline=(GLboolean)true, bShade= (GLboolean)true; GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f }, diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f }, specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}, specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }, // The light is positioned by this code, located in the ChangeSize function: lightPos[] = { -75.0f, 150.0f, -50.0f, 0.0f }, //{ -30.f, 4.0f, 15.0f, 1.0f }; //jet vertices vdata[13][3] = { {0.0f, 0.0f, 25.0f}, //Pinnacle of cone is shared vertex for fan, moved up z-axis {5.0f, 0.0f, 0.0f}, {0.0f, 3.0f, 0.0f}, {-5.0f, 0.0f, 0.0f}, //to close the fan use {5.0f, 0.0f, 0.0f} twice {0.0f, 0.0f, -6.0f}, //Pinnacle of new cone with the same base verteces as above // horiz tail {-8.0f, 0.0f, 30.0}, {8.0f, 0.0f, 30.0}, {0.0f, 0.0f, 23.0}, //vertical tail {0.0f, 0.0f, 30.0}, //far point {0.0f, 8.0f, 30.0}, //up point // {0.0f, 0.0f, 23.0} //close point the same as for horiz. tail //wing {-20.0f, 1.0f, 10.0}, { 20.0f, 1.0f, 10.0}, {0.0f, 1.0f, 5.0} }; GLfloat ex=0.0f, ey=30.0f, ez=-30.0f, delta= 0.01f, deltaR= 0.01f, trans[] = {0.0f, 0.0f, -1.0f}, ktrans = 0.0f, deltatrans = 0.1f, jetrot = 0.0f, deljetrot = 0.1f, // Transformation matrix to project shadow shadowMat[16], // Any three points on the ground (counterclockwise order) vGroundPlane[4] = {0.0f, 0.0f, 1.0f, -20.0f}; void gltMakeShadowMatrix(GLfloat vPlaneEquation[], GLfloat vLightPos[], GLfloat destMat[]) { GLfloat dot; // gltGetPlaneEquation(vPoints[0], vPoints[1], vPoints[2], vPlaneEquation); // Dot product of plane and light position dot = vPlaneEquation[0]*vLightPos[0] + vPlaneEquation[1]*vLightPos[1] + vPlaneEquation[2]*vLightPos[2] + vPlaneEquation[3]*vLightPos[3]; // Now do the projection // First column destMat[0] = dot - vLightPos[0] * vPlaneEquation[0]; destMat[4] = 0.0f - vLightPos[0] * vPlaneEquation[1]; destMat[8] = 0.0f - vLightPos[0] * vPlaneEquation[2]; destMat[12] = 0.0f - vLightPos[0] * vPlaneEquation[3]; // Second column destMat[1] = 0.0f - vLightPos[1] * vPlaneEquation[0]; destMat[5] = dot - vLightPos[1] * vPlaneEquation[1]; destMat[9] = 0.0f - vLightPos[1] * vPlaneEquation[2]; destMat[13] = 0.0f - vLightPos[1] * vPlaneEquation[3]; // Third Column destMat[2] = 0.0f - vLightPos[2] * vPlaneEquation[0]; destMat[6] = 0.0f - vLightPos[2] * vPlaneEquation[1]; destMat[10] = dot - vLightPos[2] * vPlaneEquation[2]; destMat[14] = 0.0f - vLightPos[2] * vPlaneEquation[3]; // Fourth Column destMat[3] = 0.0f - vLightPos[3] * vPlaneEquation[0]; destMat[7] = 0.0f - vLightPos[3] * vPlaneEquation[1]; destMat[11] = 0.0f - vLightPos[3] * vPlaneEquation[2]; destMat[15] = dot - vLightPos[3] * vPlaneEquation[3]; } void normalize(GLfloat v[3]) { GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); if (d == 0.0) {exit(100); return;} // wrong input exit v[0] /= d; v[1] /= d; v[2] /= d; } void normcrossprod(GLfloat v1[3], GLfloat v2[3], GLfloat out[3]) { out[0] = v1[1]*v2[2] - v1[2]*v2[1]; out[1] = v1[2]*v2[0] - v1[0]*v2[2]; out[2] = v1[0]*v2[1] - v1[1]*v2[0]; normalize(out); } void gltGetNormalVector( GLfloat v0[3], GLfloat //build normal 'norm' v1[3], GLfloat v2[3], GLfloat norm[3]) // by the triangle vrtices { GLfloat d1[3], d2[3]; for (int j = 0; j < 3; j++) { d1[j] = v0[j] - v1[j]; d2[j] = v1[j] - v2[j]; } normcrossprod(d1, d2, norm); } void SetupRC() { // Set color shading model to flat glShadeModel(GL_FLAT); // Clockwise-wound polygons are front facing; this is reversed // because we are using triangle fans glFrontFace(GL_CCW); // Enable lighting glEnable(GL_LIGHTING); glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST); glPolygonMode(GL_BACK,GL_FILL); // the light source GL_LIGHT0 is enabled: // Set up and enable light 0 glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); glLightfv(GL_LIGHT0,GL_SPECULAR,specular); glEnable(GL_LIGHT0); //glLightfv(GL_LIGHT0,GL_POSITION,lightPos); // Enable color tracking glEnable(GL_COLOR_MATERIAL); // Front material ambient and diffuse colors track glColor glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); // All materials hereafter have full specular reflectivity // with a high shine glMaterialfv(GL_FRONT, GL_SPECULAR,specref); glMateriali(GL_FRONT,GL_SHININESS,128); // Light blue background glClearColor(0.0f, 0.0f, 1.0f, 1.0f ); // Calculate projection matrix to draw shadow on the ground gltMakeShadowMatrix(vGroundPlane, lightPos, shadowMat); } // Called to draw scene void RenderScene(void) { // Reset coordinate system glLoadIdentity(); gluLookAt (ex, ey, ez, 0.0, -50.0, 0.0, 0.0, 1.0, 0.0); // Clear the window and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_QUADS); glColor3ub(32,0,0); glVertex3f(400.0f, -150.0f, -400.0f); glVertex3f(-400.0f, -150.0f, -400.0f); glColor3ub(255,0,0); glVertex3f(-400.0f, -150.0f, 400.0f); glVertex3f(400.0f, -150.0f, 400.0f); glEnd(); GLfloat norm[3], wtrans[3]; // Save matrix state and do the rotation glPushMatrix(); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_POSITION,lightPos); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); /* begin 1st jet drawing (for shadow) */ // Draw jet at new orientation; put light in correct position // before rotating the jet wtrans[0]= ktrans* trans[0]; wtrans[1]= ktrans* trans[1]; wtrans[2]= ktrans* trans[2]; glTranslatef(wtrans[0], wtrans[1], wtrans[2]); glRotatef(jetrot, 0.0f, 1.0f, 0.0f); // Begin a triangle fan (far part of plane body) glBegin(GL_TRIANGLE_FAN); // Pinnacle of cone is shared vertex for fan, moved up z-axis // to produce a cone instead of a circle glVertex3fv(&vdata[0][0] /* 0.0f, 0.0f, 25.0f*/); //glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(&vdata[1][0] /*5.0f, 0.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[1][0], &vdata[2][0], norm);/* color information here */ glNormal3fv(norm);/* color information here */ glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(&vdata[2][0] /*0.0f, 3.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[2][0], &vdata[3][0], norm); glNormal3fv(norm); // glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv( &vdata[3][0] /*-5.0f, 0.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[3][0], &vdata[1][0], norm); glNormal3fv(norm); //glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(& vdata[1][0] /*5.0f, 0.0f*/); glEnd(); glBegin(GL_TRIANGLE_FAN); // Begin a new triangle fan (close part of plane body) glVertex3fv(&vdata[4][0] /* {0.0f, 0.0f, -6.0f} */); glVertex3fv(&vdata[1][0] ); gltGetNormalVector( &vdata[1][0], &vdata[4][0], &vdata[2][0], norm);/* color information here */ glNormal3fv(norm);/* color information here */ glVertex3fv(&vdata[2][0] ); gltGetNormalVector( &vdata[4][0], &vdata[3][0], &vdata[2][0], norm); glNormal3fv(norm); //glColor3f(0.0f, 1.0f, 1.0f); glVertex3fv( &vdata[3][0] ); gltGetNormalVector( &vdata[4][0], &vdata[1][0], &vdata[3][0], norm); glNormal3fv(norm); //glColor3f(1.0f, 1.0f, 0.0f); glVertex3fv(& vdata[1][0] ); glEnd(); // Done drawing the fan (close part of plane body) glBegin(GL_TRIANGLES); // horiz tail gltGetNormalVector( &vdata[5][0], &vdata[6][0], &vdata[7][0], norm); glNormal3fv(norm); glVertex3fv( & vdata[5][0] /*-8.0f, 0.0f, 30.0*/); // V0 glVertex3fv( & vdata[6][0] /*8.0f, 0.0f, 30.0*/); // V1 glVertex3fv( & vdata[7][0] /*0.0f, 0.0f, 23.0*/); // V2 // vertic tail gltGetNormalVector( &vdata[8][0], &vdata[9][0], &vdata[7][0], norm); glNormal3fv(norm); glVertex3fv( & vdata[8][0] /*{0.0f, 0.0f, 30.0}*/); // V0 glVertex3fv( & vdata[9][0] /*{0.0f, 8.0f, 30.0}*/); // V1 glVertex3fv( & vdata[7][0] /*0.0f, 0.0f, 23.0*/); // V2 //wing gltGetNormalVector( &vdata[11][0], &vdata[12][0], &vdata[10][0], norm); glNormal3fv(norm); glVertex3fv( & vdata[10][0] /*{-20.0f, 1.0f, 10.0}*/); // V0 glVertex3fv( & vdata[11][0] /*{ 20.0f, 1.0f, 10.0}*/); // V1 glVertex3fv( & vdata[12][0] /*0.0f, 1.0f, 5.0*/); // V2 glEnd(); /* end 1st jet drawing (for shadow) */ // Restore transformations glPopMatrix(); // Get ready to draw the shadow and the ground // First disable lighting and save the projection state glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glPushMatrix(); // Multiply by shadow projection matrix glMultMatrixf((GLfloat *)shadowMat); // Now rotate the jet around in the new flattened space glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); /* begin 2nd jet drawing (for jet) */ wtrans[0]= ktrans* trans[0]; wtrans[1]= ktrans* trans[1]; wtrans[2]= ktrans* trans[2]; glTranslatef(wtrans[0], wtrans[1], wtrans[2]); glRotatef(jetrot, 0.0f, 1.0f, 0.0f); // Begin a triangle fan (far part of plane body) glBegin(GL_TRIANGLE_FAN); // Pinnacle of cone is shared vertex for fan, moved up z-axis // to produce a cone instead of a circle glVertex3fv(&vdata[0][0] /* 0.0f, 0.0f, 25.0f*/); //glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(&vdata[1][0] /*5.0f, 0.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[1][0], &vdata[2][0], norm);/* color information here */ glNormal3fv(norm);/* color information here */ glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(&vdata[2][0] /*0.0f, 3.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[2][0], &vdata[3][0], norm); glNormal3fv(norm); // glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv( &vdata[3][0] /*-5.0f, 0.0f*/); gltGetNormalVector( &vdata[0][0], &vdata[3][0], &vdata[1][0], norm); glNormal3fv(norm); //glColor3f(0.0f, 1.0f, 0.0f); glVertex3fv(& vdata[1][0] /*5.0f, 0.0f*/); glEnd(); glBegin(GL_TRIANGLE_FAN); // Begin a new triangle fan (close part of plane body) glVertex3fv(&vdata[4][0] /* {0.0f, 0.0f, -6.0f} */); //glColor3f(1.0f, 1.0f, 0.0f); glVertex3fv(&vdata[1][0] ); gltGetNormalVector( &vdata[1][0], &vdata[4][0], &vdata[2][0], norm);/* color information here */ glNormal3fv(norm);/* color information here */ //glColor3f(1.0f, 0.0f, 1.0f); glVertex3fv(&vdata[2][0] ); gltGetNormalVector( &vdata[4][0], &vdata[3][0], &vdata[2][0], norm); glNormal3fv(norm); //glColor3f(0.0f, 1.0f, 1.0f); glVertex3fv( &vdata[3][0] ); gltGetNormalVector( &vdata[4][0], &vdata[1][0], &vdata[3][0], norm); glNormal3fv(norm); //glColor3f(1.0f, 1.0f, 0.0f); glVertex3fv(& vdata[1][0] ); glEnd(); // Done drawing the fan (close part of plane body) glBegin(GL_TRIANGLES); // horiz tail gltGetNormalVector( &vdata[5][0], &vdata[6][0], &vdata[7][0], norm); glNormal3fv(norm); //glColor3f(0.5f, 1.0f, 1.0f); glVertex3fv( & vdata[5][0] /*-8.0f, 0.0f, 30.0*/); // V0 glVertex3fv( & vdata[6][0] /*8.0f, 0.0f, 30.0*/); // V1 glVertex3fv( & vdata[7][0] /*0.0f, 0.0f, 23.0*/); // V2 // vertic tail gltGetNormalVector( &vdata[8][0], &vdata[9][0], &vdata[7][0], norm); glNormal3fv(norm); //glColor3f(1.0f, 0.5f, 1.0f); glVertex3fv( & vdata[8][0] /*{0.0f, 0.0f, 30.0}*/); // V0 glVertex3fv( & vdata[9][0] /*{0.0f, 8.0f, 30.0}*/); // V1 glVertex3fv( & vdata[7][0] /*0.0f, 0.0f, 23.0*/); // V2 //wing gltGetNormalVector( &vdata[11][0], &vdata[12][0], &vdata[10][0], norm); glNormal3fv(norm); //glColor3f(0.5f, 1.0f, 1.0f); glVertex3fv( & vdata[10][0] /*{-20.0f, 1.0f, 10.0}*/); // V0 glVertex3fv( & vdata[11][0] /*{ 20.0f, 1.0f, 10.0}*/); // V1 glVertex3fv( & vdata[12][0] /*0.0f, 1.0f, 5.0*/); // V2 glEnd(); /* end 2nd jet drawing (for shadow) */ // Restore the projection to normal glPopMatrix(); // Draw the light source glPushMatrix(); glTranslatef(lightPos[0],lightPos[1], lightPos[2]); glColor3ub(255,255,0); glutSolidSphere(5.0f,10,10); glPopMatrix(); // Restore lighting state variables glEnable(GL_DEPTH_TEST); // Flush drawing commands glutSwapBuffers(); } // Called by GLUT library when the window has changed size void ChangeSize(GLsizei w, GLsizei h) { // Set Viewport to window dimensions glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glOrtho (-100.0, 100.0, -100, 100, -270.0, 270.0); //glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); gluPerspective(60.0, 1.0, 1.5, 600.0); glMatrixMode (GL_MODELVIEW); } void SpecialKeys(int key, int x, int y) {GLfloat dx, dy, dz; if(key == GLUT_KEY_UP) {//increase distance from camera to origin ex*=(1.0f+deltaR); ey*=(1.0f+deltaR); ez*=(1.0f+deltaR); // Refresh the Window glutPostRedisplay(); return; } if(key == GLUT_KEY_DOWN) {//reduce distance from camera to origin (close up) ex*=(1.0f-deltaR); ey*=(1.0f-deltaR); ez*=(1.0f-deltaR); // Refresh the Window glutPostRedisplay(); return;} if(key == GLUT_KEY_LEFT) //Rotate camera around origin in Oxz plane {dx=-ez; dz= ex; GLfloat s=sqrtf(ex*ex+ey*ey+ez*ez); ex+=delta*dx; ez+=delta*dz; GLfloat s1=sqrtf(ex*ex+ey*ey+ez*ez)/s; ex/=s1; ey/=s1; ey/=s1; // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_RIGHT) //Rotate camera around origin in Oxz plane {dx=-ez; dz= ex; GLfloat s=sqrtf(ex*ex+ey*ey+ez*ez); ex-=delta*dx; ez-=delta*dz; GLfloat s1=sqrtf(ex*ex+ey*ey+ez*ez)/s; ex/=s1; ey/=s1; ey/=s1; // Refresh the Window glutPostRedisplay();return;} if(key == GLUT_KEY_F5)//Rotate camera around origin in Oyz plane {dy=-ez; dz= ey; GLfloat s=sqrtf(ex*ex+ey*ey+ez*ez); ey-=delta*dy; ez-=delta*dz; GLfloat s1=sqrtf(ex*ex+ey*ey+ez*ez)/s; ex/=s1; ey/=s1; ey/=s1; // Refresh the Window glutPostRedisplay();return;} if(key == GLUT_KEY_F6)//Rotate camera around origin in Oyz plane {dy=-ez; dz= ey; GLfloat s=sqrtf(ex*ex+ey*ey+ez*ez); ey+=delta*dy; ez+=delta*dz; GLfloat s1=sqrtf(ex*ex+ey*ey+ez*ez)/s; ex/=s1; ey/=s1; ey/=s1; // Refresh the Window glutPostRedisplay();return;} if(key == GLUT_KEY_F7)//Move jet forward { ktrans += deltatrans; // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_F8)//Rote jet around origin in Oyz plane { ktrans += deltatrans; jetrot += deljetrot; // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_F9)//Rote jet around origin in Oyz plane { ktrans += deltatrans; jetrot -= deljetrot; // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_F1){ bCull=!bCull; // Turn on/off culling on if flag is set if(bCull) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_F2){bDepth=!bDepth; if(bDepth) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); // Refresh the Window glutPostRedisplay();return; } if(key == GLUT_KEY_F3){bOutline=!bOutline; // Draw the back side as a wireframe only, if flag is set if(bOutline)glPolygonMode(GL_BACK,GL_LINE); else glPolygonMode(GL_BACK,GL_FILL); // Refresh the Window glutPostRedisplay(); return; } if(key == GLUT_KEY_F4) {bShade=!bShade; if(bShade){glShadeModel(GL_FLAT);} else {glShadeModel(GL_SMOOTH);} // Refresh the Window glutPostRedisplay(); return; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutSpecialFunc (SpecialKeys); SetupRC(); glutMainLoop(); return 0; }