#include "stdafx.h" #define checkImageWidth 256 #define checkImageHeight 256 #define subImageWidth 64 #define subImageHeight 64 #define YGROUND 0.0f #define EX 0.0f #define EY 1.0f #define EZ 8.0f #define CX 0.0f #define CY YGROUND #define CZ 0.0f #define DELTA 0.01f #define DELTA_R 0.01f static GLubyte checkImage[checkImageHeight][checkImageWidth][4]; static GLubyte otherImage[checkImageHeight][checkImageWidth][4]; static GLubyte subImage[subImageHeight][subImageWidth][4]; static GLuint texName[2]; GLfloat ctrlpoints[4][4][3] = { { {-1.5, -1.5, 4.0}, {-0.5, -1.5, 2.0}, {0.5, -1.5, -1.0}, {1.5, -1.5, 2.0}}, { {-1.5, -0.5, 1.0}, {-0.5, -0.5, 3.0}, {0.5, -0.5, 0.0}, {1.5, -0.5, -1.0}}, { {-1.5, 0.5, 4.0}, {-0.5, 0.5, 0.0}, {0.5, 0.5, 3.0}, {1.5, 0.5, 4.0}}, { {-1.5, 1.5, -2.0}, {-0.5, 1.5, -2.0}, {0.5, 1.5, 0.0}, {1.5, 1.5, -1.0}} }; 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 }, mat_shininess[] = {50.0}, ex=EX, ey=EY, ez=EZ, cx=CX, cy=CY, cz=CZ, yground = YGROUND, delta= DELTA, deltaR= DELTA_R, // The light is positioned by this code, located in the ChangeSize function: lightPos[] = { -75.0f, 150.0f, -50.0f, 1.0f }; //{ -30.f, 4.0f, 15.0f, 1.0f }; void makeCheckImages(void) { int i, j, c; for (i = 0; i < checkImageHeight; i++) { for (j = 0; j < checkImageWidth; j++) { c = ((((i&0x8)==0)^((j&0x8))==0))*255; checkImage[i][j][0] = (GLubyte) c; checkImage[i][j][1] = (GLubyte) c; checkImage[i][j][2] = (GLubyte) c; checkImage[i][j][3] = (GLubyte) 255; c = ((((i&0x10)==0)^((j&0x10))==0))*255; otherImage[i][j][0] = (GLubyte) 0; otherImage[i][j][1] = (GLubyte) 0; otherImage[i][j][2] = (GLubyte) c; otherImage[i][j][3] = (GLubyte) 255; } } for (i = 0; i < subImageHeight; i++) { for (j = 0; j < subImageWidth; j++) { c = ((((i&0x4)==0)^((j&0x4))==0))*255; subImage[i][j][0] = (GLubyte) c; subImage[i][j][1] = (GLubyte) 0; subImage[i][j][2] = (GLubyte) 0; subImage[i][j][3] = (GLubyte) 255; } } } void SetupRC() { // Set color shading model to flat glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); makeCheckImages(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(2, texName); glBindTexture(GL_TEXTURE_2D, texName[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, checkImage); glTexSubImage2D(GL_TEXTURE_2D, 0, 48, 170, subImageWidth, subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, subImage); glTexSubImage2D(GL_TEXTURE_2D, 0, 48, 48, subImageWidth, subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, subImage); glTexSubImage2D(GL_TEXTURE_2D, 0, 170, 48, subImageWidth, subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, subImage); glTexSubImage2D(GL_TEXTURE_2D, 0, 170, 170, subImageWidth, subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, subImage); glBindTexture(GL_TEXTURE_2D, texName[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, otherImage); glEnable(GL_TEXTURE_2D); // 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); glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseLight); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); // Light blue background glClearColor(0.0f, 0.0f, 1.0f, 1.0f ); //setup evaluator glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, &ctrlpoints[0][0][0]); glEnable(GL_MAP2_VERTEX_3); glEnable(GL_AUTO_NORMAL); glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0); } void DrawSurface(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glBindTexture(GL_TEXTURE_2D, texName[0]); /* void glMapGrid2{fd}(GLint nu, TYPEu1, TYPEu2, GLint nv, TYPEv1, TYPEv2); void glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); (It's nearly equivalent because when i is equal to nu or j to nv, the parameter is exactly equal to u2 or v2, not to u1+nu*(u2-u1)/nu, which might be slightly different due to round-off error.) glEvalMesh2(GL_FILL, 0, 20, 0, 20); for (i = nu1; i < nu2; i++) { // mode == GL_FILL glBegin(GL_QUAD_STRIP); for (j = nv1; j <= nv2; j++) { glEvalCoord2(u1 + i*(u2-u1)/nu, v1+j*(v2-v1)/nv); glEvalCoord2(u1 + (i+1)*(u2-u1)/nu, v1+j*(v2-v1)/nv); glEnd(); }*/ glEvalMesh2(GL_FILL, 0, 20, 0, 20); glMapGrid2f(20, 0.0f, 1.0f, 20, 0.0f, 1.0f); glBegin(GL_QUADS); for (int i = 0; i < 20; i++) { // mode == GL_FILL for (int j = 0; j <= 20; j++) { glTexCoord2f((GLfloat) i /20.0f, (GLfloat) j/20.); glEvalCoord2f( (GLfloat) i /20.0f, (GLfloat) j/20.0); glTexCoord2f((GLfloat) i /20.0f, (GLfloat) (j+1)/20.); glEvalCoord2f( (GLfloat) i /20.0f, (GLfloat) (j+1)/20.0); glTexCoord2f((GLfloat)(i+1)/20.0f, (GLfloat) (j+1)/20.0f); glEvalCoord2f( (GLfloat)(i+1)/20.0f, (GLfloat) (j+1)/20.0f); glTexCoord2f((GLfloat)(i+1)/20.0f, (GLfloat) j/20.0f); glEvalCoord2f( (GLfloat)(i+1)/20.0f, (GLfloat) j/20.0f); } } glEnd(); // //for (int i = 0; i < 20; i++) { // mode == GL_FILL //glBegin(GL_QUAD_STRIP); //for (int j = 0; j <= 20; j++) { //glTexCoord2f((GLfloat) i /20.0f, (GLfloat) j/20.); // glEvalCoord2f( (GLfloat) i /20.0f, (GLfloat) j/20.0); //glTexCoord2f((GLfloat)(i+1)/20.0f, (GLfloat) j/20.0f); // glEvalCoord2f( (GLfloat)(i+1)/20.0f, (GLfloat) j/20.0f); //glEnd(); //} //} //glTexCoord2f(0.0, 0.0); glEvalCoord2f(0.0f, 0.0f);//glVertex3f( 400.0f, -150.0f, -700.0f); //glTexCoord2f(0.0, 1.0); glEvalCoord2f(0.0f, 1.0f);// glVertex3f(-400.0f, -150.0f, -700.0f); //glTexCoord2f(1.0, 1.0); glEvalCoord2f(1.0f, 1.0f);// glVertex3f(-400.0f, -150.0f, 200.0f); //glTexCoord2f(1.0, 0.0); glEvalCoord2f(1.0f, 0.0f);// glVertex3f(400.0f, -150.0f, 200.0f); //glEnd(); // glFlush(); glDisable(GL_TEXTURE_2D); } void RenderScene(void) { // Clear the window and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Reset coordinate system glLoadIdentity(); gluLookAt (ex, ey, ez, cx, cy, cz, 0.0, 1.0, 0.0); //gluLookAt (ex, ey, ez, 0.0, -50.0, 0.0, 0.0, 1.0, 0.0); glPushMatrix(); glRotatef(85.0, 1.0, 1.0, 1.0); DrawSurface(); glPopMatrix(); // Flush drawing commands glutSwapBuffers(); } void ChangeSize(GLsizei w, GLsizei h) { // Set Viewport to window dimensions glViewport(0, 0, (GLsizei)w, (GLsizei)h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, 1.0, 1.5, 700.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_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; } } void keyboard(unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; } } 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); glutKeyboardFunc(keyboard); SetupRC(); glutMainLoop(); return 0; }