纹理对象的使用:纹理图像数据的类型,图像数据的导入导出方式,纹理的使用过程:图像数据的加载,纹理参数的设置,纹理的绑定。
一、图像数据的分类:位图图像和像素图像
十、综合运用的例子:可以旋转带光照纹理的金字塔
// Pyramid.cpp // OpenGL SuperBible, Chapter 5 // Demonstrates Texture mapping a pyramid // Program by Richard S. Wright Jr. #include <GLTools.h> // OpenGL toolkit #include <GLMatrixStack.h> #include <GLFrame.h> #include <GLFrustum.h> #include <GLBatch.h> #include <GLGeometryTransform.h> #include <math.h> #ifdef __APPLE__ #include <glut/glut.h> #else #define FREEGLUT_STATIC #include <GL/glut.h> #endif ///////////////////////////////////////////////////////////////////////////////// // An assortment of needed classes GLShaderManager shaderManager; GLMatrixStack modelViewMatrix; GLMatrixStack projectionMatrix; GLFrame cameraFrame; GLFrame objectFrame; GLFrustum viewFrustum; GLBatch pyramidBatch; GLuint textureID; GLGeometryTransform transformPipeline; M3DMatrix44f shadowMatrix; void MakePyramid(GLBatch& pyramidBatch) { pyramidBatch.Begin(GL_TRIANGLES, 18, 1); <span style="white-space:pre"> </span>//手动设置金字塔的顶点数据,包括位置,纹理坐标和光照法线向量 // Bottom of pyramid pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f); pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f); pyramidBatch.Vertex3f(1.0f, -1.0f, -1.0f); pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f); pyramidBatch.Vertex3f(1.0f, -1.0f, 1.0f); pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 0.0f, 1.0f); pyramidBatch.Vertex3f(-1.0f, -1.0f, 1.0f); pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3f(-1.0f, -1.0f, -1.0f); pyramidBatch.Normal3f(0.0f, -1.0f, 0.0f); pyramidBatch.MultiTexCoord2f(0, 1.0f, 1.0f); pyramidBatch.Vertex3f(1.0f, -1.0f, 1.0f); M3DVector3f vApex = { 0.0f, 1.0f, 0.0f }; M3DVector3f vFrontLeft = { -1.0f, -1.0f, 1.0f }; M3DVector3f vFrontRight = { 1.0f, -1.0f, 1.0f }; M3DVector3f vBackLeft = { -1.0f, -1.0f, -1.0f }; M3DVector3f vBackRight = { 1.0f, -1.0f, -1.0f }; M3DVector3f n; // 根据三个点计算法线向量 m3dFindNormal(n, vApex, vFrontLeft, vFrontRight); pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f); pyramidBatch.Vertex3fv(vApex); // Apex pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3fv(vFrontLeft); // Front left corner pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f); pyramidBatch.Vertex3fv(vFrontRight); // Front right corner m3dFindNormal(n, vApex, vBackLeft, vFrontLeft); pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f); pyramidBatch.Vertex3fv(vApex); // Apex pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f); pyramidBatch.Vertex3fv(vBackLeft); // Back left corner pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3fv(vFrontLeft); // Front left corner m3dFindNormal(n, vApex, vFrontRight, vBackRight); pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f); pyramidBatch.Vertex3fv(vApex); // Apex pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f); pyramidBatch.Vertex3fv(vFrontRight); // Front right corner pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3fv(vBackRight); // Back right cornder m3dFindNormal(n, vApex, vBackRight, vBackLeft); pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f); pyramidBatch.Vertex3fv(vApex); // Apex pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f); pyramidBatch.Vertex3fv(vBackRight); // Back right cornder pyramidBatch.Normal3fv(n); pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f); pyramidBatch.Vertex3fv(vBackLeft); // Back left corner pyramidBatch.End(); } //获取纹理图像数据,并且设置纹理参数并得到一个纹理状态放入纹理对象中 bool loadTGATexture(const char *szFileName, GLenum minFilter, GLenum magFilter, GLenum wrapMode) { GLbyte *pBits; int nWidth,nHeight,nComponents; GLenum eFormat; pBits = gltReadTGABits(szFileName, &nWidth, &nHeight, &nComponents, &eFormat); if(pBits == NULL) return false; <span style="white-space:pre"> </span>//S,T轴上的纹理环绕模式 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); <span style="white-space:pre"> </span>//放大和缩小的过滤 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,minFilter); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,magFilter); glPixelStorei(GL_UNPACK_ALIGNMENT,1); //图像数据解包,从内存区到缓存区 glTexImage2D(GL_TEXTURE_2D,0,nComponents,nWidth,nHeight,0,eFormat,GL_UNSIGNED_BYTE,pBits); free(pBits); if(minFilter == GL_LINEAR_MIPMAP_LINEAR || minFilter == GL_LINEAR_MIPMAP_NEAREST || minFilter == GL_NEAREST_MIPMAP_LINEAR || minFilter == GL_NEAREST_MIPMAP_NEAREST) glGenerateMipmap(GL_TEXTURE_2D); return true; } void SetupRC(){ glClearColor(0.7f,0.7f,0.7f,1.0f); shaderManager.InitializeStockShaders(); glEnable(GL_DEPTH_TEST); glGenTextures(1,&textureID); glBindTexture(GL_TEXTURE_2D,textureID); loadTGATexture("stone.tga",GL_LINEAR,GL_LINEAR,GL_CLAMP_TO_EDGE); MakePyramid(pyramidBatch); <span style="white-space:pre"> </span>//场景的照相机 cameraFrame.MoveForward(-7.0f); } void ShutdownRC(){ glDeleteTextures(1,&textureID); } void RenderScene(){ static GLfloat vLightPos[] = {1.0f,1.0f,0.0f}; static GLfloat vWhite[] = {1.0f,1.0f,1.0f,1.0f}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); modelViewMatrix.PushMatrix(); M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); modelViewMatrix.MultMatrix(mCamera); M3DMatrix44f mObjectFrame; objectFrame.GetCameraMatrix(mObjectFrame); modelViewMatrix.MultMatrix(mObjectFrame); <span style="white-space:pre"> </span>//在提交批绘制的时候,绑定我们需要使用的纹理 glBindTexture(GL_TEXTURE_2D,textureID); shaderManager.UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF,transformPipeline.GetModelViewMatrix(), transformPipeline.GetProjectionMatrix(),vLightPos,vWhite,0); pyramidBatch.Draw(); modelViewMatrix.PopMatrix(); glutSwapBuffers(); } void SpecialKeys(int key,int x,int y){ if(key == GLUT_KEY_UP) objectFrame.RotateWorld(m3dDegToRad(-5.0f),1.0f,0.0f,0.0f); if(key == GLUT_KEY_DOWN) objectFrame.RotateWorld(m3dDegToRad(5.0f),1.0f,0.0f,0.0f); if(key == GLUT_KEY_LEFT) objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f); if(key == GLUT_KEY_RIGHT) objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f); glutPostRedisplay(); } void ChangeSize(int w,int h){ glViewport(0,0,w,h); viewFrustum.SetPerspective(35.0f,float(w)/float(h),1.0f,500.0f); projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); transformPipeline.SetMatrixStacks(modelViewMatrix,projectionMatrix); } int main(int argc, char* argv[]) { gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(800, 600); glutCreateWindow("Pyramid"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutDisplayFunc(RenderScene); GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC(); glutMainLoop(); ShutdownRC(); return 0; }
原文:http://blog.csdn.net/zh13544539220/article/details/45562083