#include "math3d.h" static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; static void ChangeSize(int w, int h) { GLfloat fAspect = (GLfloat) w / (GLfloat) h; if (h == 0) h = 1; glViewport(0, 0, w, h); /* reset coordinate system */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* produce the perspective projection */ gluPerspective(35.0f, fAspect, 1.0, 40.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } static void SetupRC() { GLbyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; /* light values and coordinates */ GLfloat whiteLight[] = { 0.05f, 0.05f, 0.05f, 1.0f }; GLfloat sourceLight[] = { 0.75f, 0.75f, 0.75f, 1.0f }; GLfloat lightPos[] = { -10.f, 5.0f, 5.0f, 1.0f }; glEnable(GL_DEPTH_TEST); /* hidden surface removal */ glFrontFace(GL_CCW); /* counter clock-wise polygons face out */ glEnable(GL_CULL_FACE); /* do not calculate inside of a pyramid */ /* enable lighting */ glEnable(GL_LIGHTING); /* setup and enable light 0 */ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, whiteLight); glLightfv(GL_LIGHT0, GL_AMBIENT, sourceLight); glLightfv(GL_LIGHT0, GL_DIFFUSE, sourceLight); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glEnable(GL_LIGHT0); /* enable color tracking */ glEnable(GL_COLOR_MATERIAL); /* set Material properties to follow glColor values */ glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); /* black blue background */ glClearColor(0.0f, 0.0f, 0.5f, 1.0f); /* load texture */ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); pBytes = gltLoadTGA("stone.tga", &iWidth, &iHeight, &iComponents, &eFormat); if (!pBytes) fprintf(stderr, "gltLoadTGA: failed to load texture!\n"); /* load texture image */ glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes); free(pBytes); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); } static void SpecialKeys(int key, int x, int y) { if (key == GLUT_KEY_UP) xRot-= 5.0f; if (key == GLUT_KEY_DOWN) xRot += 5.0f; if (key == GLUT_KEY_LEFT) yRot -= 5.0f; if (key == GLUT_KEY_RIGHT) yRot += 5.0f; xRot = (GLfloat) ((const int) xRot % 360); yRot = (GLfloat) ((const int) yRot % 360); glutPostRedisplay(); } static void RenderScene(void) { M3DVector3f vNormal; M3DVector3f vCorners[5] = { { 0.0f, .80f, 0.0f }, /* top 0 */ { -0.5f, 0.0f, -.5f }, /* back left 1 */ { 0.5f, 0.0f, -0.5f }, /* back right 2 */ { 0.5f, 0.0f, 0.5f }, /* front right 3 */ { -0.5f, 0.0f, 0.5f } /* front left 4 */ }; /* clear the window with current clearing color */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* save the matrix state and do the rotations */ glPushMatrix(); /* move object back and do in place rotation */ glTranslatef(0.0f, -0.25f, -4.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); /* draw the pyramid */ glColor3f(1.0f, 1.0f, 1.0f); glBegin(GL_TRIANGLES); /* bottom section - two triangles */ glNormal3f(0.0f, -1.0f, 0.0f); /* map texture to geometry */ glTexCoord2f(1.0f, 1.0f); glVertex3fv(vCorners[2]); glTexCoord2f(0.0f, 1.0f); glVertex3fv(vCorners[4]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[1]); glTexCoord2f(1.0f, 1.0f); glVertex3fv(vCorners[2]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(vCorners[3]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[4]); /* front face */ m3dFindNormal(vNormal, vCorners[0], vCorners[4], vCorners[3]); glNormal3fv(vNormal); glTexCoord2f(0.5f, 1.0f); glVertex3fv(vCorners[0]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[4]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(vCorners[3]); /* left face */ m3dFindNormal(vNormal, vCorners[0], vCorners[1], vCorners[4]); glNormal3fv(vNormal); glTexCoord2f(0.5f, 1.0f); glVertex3fv(vCorners[0]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[1]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(vCorners[4]); /* back face */ m3dFindNormal(vNormal, vCorners[0], vCorners[2], vCorners[1]); glNormal3fv(vNormal); glTexCoord2f(0.5f, 1.0f); glVertex3fv(vCorners[0]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[2]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(vCorners[1]); /* right face */ m3dFindNormal(vNormal, vCorners[0], vCorners[3], vCorners[2]); glNormal3fv(vNormal); glTexCoord2f(0.5f, 1.0f); glVertex3fv(vCorners[0]); glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[3]); glTexCoord2f(1.0f, 0.0f); glVertex3fv(vCorners[2]); glEnd(); /* restore the matrix state */ glPopMatrix(); /* buffer swap */ glutSwapBuffers(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(640, 480); glutCreateWindow("Textured Pyramid"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutDisplayFunc(RenderScene); /* initalize glew */ GLenum glewerr = glewInit(); if (GLEW_OK != glewerr) { fprintf(stderr, "Error: %s\n", glewGetErrorString(glewerr)); return 1; } else fprintf(stdout, "status: using GLEW %s\n", glewGetString(GLEW_VERSION)); SetupRC(); glutMainLoop(); return 0; }