OpenGL超级宝典笔记三

纹理对象的使用:纹理图像数据的类型,图像数据的导入导出方式,纹理的使用过程:图像数据的加载,纹理参数的设置,纹理的绑定。

一、图像数据的分类:位图图像和像素图像

二、像素图像数据的包装:在OpenGL中:使用4字节的行对齐方式,每一行补全到4的倍数,使用glPixelStorei(pname,param)可以改变或者恢复像素的存储方式介绍常用的两组:内存<->缓冲区的压缩和解包glPixcelStorei(GL_UNPACK_ALIGNMENT) —-图像数据从内存到缓冲区的解包设置glPixcelStorei(GL_PACK_ALIGNMENT) —- 图像数据从缓冲区到内存的封包设置三、像素图的存储过程(从颜色缓冲区中获取图像保存为图片)1、从颜色缓冲区读取像素数据到内存中:glReadPixcels(x,y,width,height,format,type,*pixcels)pixcels:必须有足够的存储空间format:指定颜色布局,类似GL_RGB,GL_RBGA之类type:颜色分量的数据类型,类似GL_UNSIGHED_BYTE,GL_BYTE之类2、从内存到硬盘的图像文件保存四、像素图数据的获取过程(从硬盘到内存)gltReadTGABits(szFileName,iWidth,iHeight,iComponents,eFormat)获取:图片位图数据,宽高,iComponents:颜色成分的存储大小和压缩状况,eFormat:颜色布局这些数据是位图数据从内存加载到缓冲区的时候,,OpenGL需要的数据五、纹理载入方式一(图像数据从内存到纹理缓冲区):glTexImage1D/glTexImage2D/glTexImage3DglTexImage2D(target,level,internalformat,width,height,border,format,type,*data)target:GL_TEXTURE_1D,GL_TEXTURE_2D,GL_TEXTURE_3Dlevel:指定mip贴图的层次internalformat:就是上述获取到的iComponents的数据border:为纹理贴图指定一个边界宽度format,type,data:和用于把图像数据放入颜色缓冲区的glDrawPixcels函数对应的参数一致六、纹理载入方式二(图像数据从颜色缓冲区读取到纹理缓冲区):glCopyTexImage2D(target,level,internalformat,x,y,width,height,border)源缓冲区是通过glReadBuffer(mode)函数设置的。 mode为GL_FRONT,GL_LEFT 等参数七、纹理更新操纵:更新替换原纹理的一部分数据glTexSubImage2D(target,level,xOffset,yOffset,width,height,format,type,*data)从颜色缓冲区中提取纹理作为数据去更新:glCopyTexSubImage2D(target,level,xOffset,yOffset,width,height)八、纹理对象的使用:由于使用glTexImage和glTexSubImage这样的函数加载和更新纹理太耗费内存,所以引用纹理对象特点:纹理对象是允许我们一次加载一个以上的纹理状态(包括纹理图像)以及可以在它们之间快速切换的。纹理对象的创建:glGenTextures(GLsizei n,GLuint* textures)n:纹理对象数量textures:不同纹理状态的句柄数组纹理状态的绑定:glBindTexture(GLenum target,Gluint texture)target:GL_TEXTURE_2D…..texture:需要绑定的特定纹理状态纹理对象的销毁:glDeleteTextures(n,textures)纹理状态的确认:glIsTexure(GLuint texture)九、纹理应用:1、加载纹理数据2、提供纹理坐标s,t,r相当于x,y,z3、设置纹理坐标的环绕模式(相对每个纹理坐标轴的)glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT)glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT)环绕模式:GL_REPEAT:超出1.0的对纹理进行重复GL_CLAMP:使用纹理边界或者既定设置的边界颜色GL_CLAMP_EDGE:使用纹理单元的最后一行或者一列数据GL_CLAMP_BORDER:使用边界纹理单元4、设置纹理的过滤(相对于拉伸和缩小的)glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);过滤模式:GL_NEAREST:最邻近过滤,快速,但是如果纹理被拉伸过大会出现大片的斑驳像素GL_LINEAR:线性过滤,开销大,但是效果比较好

十、综合运用的例子:可以旋转带光照纹理的金字塔

// 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 classesGLShaderManagershaderManager;GLMatrixStackmodelViewMatrix;GLMatrixStackprojectionMatrix;GLFramecameraFrame;GLFrameobjectFrame;GLFrustumviewFrustum;GLBatchpyramidBatch;GLuinttextureID;GLGeometryTransformtransformPipeline;M3DMatrix44fshadowMatrix;void MakePyramid(GLBatch& pyramidBatch){pyramidBatch.Begin(GL_TRIANGLES, 18, 1);<span style="white-space:pre"></span>//手动设置金字塔的顶点数据,包括位置,纹理坐标和光照法线向量// Bottom of pyramidpyramidBatch.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);// ApexpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);pyramidBatch.Vertex3fv(vFrontLeft);// Front left cornerpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);pyramidBatch.Vertex3fv(vFrontRight);// Front right cornerm3dFindNormal(n, vApex, vBackLeft, vFrontLeft);pyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);pyramidBatch.Vertex3fv(vApex);// ApexpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);pyramidBatch.Vertex3fv(vBackLeft);// Back left cornerpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);pyramidBatch.Vertex3fv(vFrontLeft);// Front left cornerm3dFindNormal(n, vApex, vFrontRight, vBackRight);pyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);pyramidBatch.Vertex3fv(vApex);// ApexpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);pyramidBatch.Vertex3fv(vFrontRight);// Front right cornerpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);pyramidBatch.Vertex3fv(vBackRight);// Back right cornderm3dFindNormal(n, vApex, vBackRight, vBackLeft);pyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.5f, 1.0f);pyramidBatch.Vertex3fv(vApex);// ApexpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 0.0f, 0.0f);pyramidBatch.Vertex3fv(vBackRight);// Back right cornderpyramidBatch.Normal3fv(n);pyramidBatch.MultiTexCoord2f(0, 1.0f, 0.0f);pyramidBatch.Vertex3fv(vBackLeft);// Back left cornerpyramidBatch.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;}

没有预兆目的地在哪,前进的脚步不能停下,

OpenGL超级宝典笔记三

相关文章:

你感兴趣的文章:

标签云: