openGL绘制一个带有纹理、光照效果的金字塔
openglsb.h:
//////////////////////////////////////////////// // Here, we will try to isolate as many platform // dependencies here as possible so that all sample // programs contain as few headers and are as self // contained as possible. // Windows... Visual C++ #ifdef _WIN32 // Standard Windows includes #include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include "glut.h" #include "glext.h" #include "wglext.h" // Mac OS X #elif defined __APPLE__ #include <Carbon/Carbon.h> #include <GLUT/glut.h> #include <OpenGL/glext.h> #define APIENTRY #define INT_PTR int* #define Sleep(x) // Assume Linux #else #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <GL/glext.h> #include <sys/time.h> #endif
pyramid.c:
// Pyramid.c // Demonstrates Simple Texture Mapping // OpenGL SuperBible // Richard S. Wright Jr. #include "../../common/openglsb.h" // System and OpenGL Stuff #include "../../common/gltools.h" // OpenGL toolkit // Rotation amounts static GLfloat xRot = 0.0f; static GLfloat yRot = 0.0f; // Change viewing volume and viewport. Called when window is resized void ChangeSize(int w, int h) { GLfloat fAspect; // Prevent a divide by zero if(h == 0) h = 1; // Set Viewport to window dimensions glViewport(0, 0, w, h); fAspect = (GLfloat)w/(GLfloat)h; // 指定当前操作矩阵为投影矩阵。 glMatrixMode(GL_PROJECTION); //重置坐标系统 glLoadIdentity(); // Produce the perspective projection 产生透视投影 gluPerspective(35.0f, fAspect, 1.0, 40.0); //指定当前操作矩阵为模型视图矩阵。 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } // This function does any needed initialization on the rendering // context. Here it sets up and initializes the lighting for // the scene. void SetupRC() { GLubyte *pBytes; GLint iWidth, iHeight, iComponents; GLenum eFormat; // Light values and coordinates GLfloat whiteLight[] = { 0.05f, 0.05f, 0.05f, 1.0f }; GLfloat sourceLight[] = { 0.25f, 0.25f, 0.25f, 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 jet // 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); //启用颜色追踪 glEnable(GL_COLOR_MATERIAL); //多边形正面材料环境和散射颜色 追踪glcolor glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Black blue background glClearColor(0.0f, 0.0f, 0.0f, 1.0f ); // Load texture //设置像素提取方式 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //加载到内存 pBytes = gltLoadTGA("stone.tga", &iWidth, &iHeight, &iComponents, &eFormat); //iComponents 为颜色成分 //从内存中载入纹理 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); } // Respond to arrow keys 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); // Refresh the Window glutPostRedisplay(); } // Called to draw scene void RenderScene(void) { GLTVector3 vNormal; GLTVector3 vCorners[5] = { { 0.0f, .80f, 0.0f }, // Top 0 { -0.5f, 0.0f, -.50f }, // Back left 1 { 0.5f, 0.0f, -0.50f }, // 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); //因为十点在(0,0,0)点,所以要稍作调整 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); //法线向下 glTexCoord2f(1.0f, 1.0f); glVertex3fv(vCorners[2]); //后右 glTexCoord2f(0.0f, 0.0f); glVertex3fv(vCorners[4]); //前左 glTexCoord2f(0.0f, 1.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 gltGetNormalVector(vCorners[0], vCorners[4], vCorners[3], vNormal); 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 gltGetNormalVector(vCorners[0], vCorners[1], vCorners[4], vNormal);//计算法线 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 gltGetNormalVector(vCorners[0], vCorners[2], vCorners[1], vNormal); 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 gltGetNormalVector(vCorners[0], vCorners[3], vCorners[2], vNormal); 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(800, 600); glutCreateWindow("Textured Pyramid"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutDisplayFunc(RenderScene); SetupRC(); glutMainLoop(); return 0; }
运行效果:
.