在动态场景中,当一个纹理对象迅速地远离观察点时,纹理图像必须随着背投影的图像一起缩小,为了实现这个效果,OPENGL必须对纹理图像进行过渡,适当地对它进行缩小,使他不会产生令人不舒服的视觉感受。
OpenGL mipmap 预先设置好不同分辨率的纹理图像,根据被贴图的物体的大小确定采用哪种分辨率的纹理图像,达到平滑过渡的效果
使用mipmap必须提供全系列的大小为2的整数次方的纹理图像,其范围从最大值直到1*1,例如最大值为64*16的纹理单元还必须提供32*8,16*4,8*2,4*1,2*1,1*1的纹理单元。他们的分辨率为,0,1,2,3,4,5,6
另外使用mipmap还需要选择一种适当的过滤模式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32);//黄 glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 16, 16, 0,GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage16);//紫 glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage8);//红 glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 0,GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage4);//绿 glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage2);//蓝 glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage1);//白
mipmap层控制
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);//最高分辨率层
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4);//最低分辨率层
mipmap细节层参数控制
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
对于32*32的纹理图像来说,包含16*16,8*8,4*4,2*2,1*1. min可以简单的认为是起始分辨率(最大值) max是结束分别率(最大值)
上面方法如果要创建一个64*16的纹理,必须创建7个纹理图形,并进行分别绑定,很繁琐,当然OpenGL提供了一些方法,让这一切变得简单
方法1:OPENGL 1.4 以后
glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32);
方法2: OPENGL1.1
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 32, 32, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32);
方法3:OPENGL3.0
glGenerateMipmap(GL_TEXTURE_2D)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32);
#include "header.h" GLubyte mipmapImage32[32][32][4]; GLubyte mipmapImage16[16][16][4]; GLubyte mipmapImage8[8][8][4]; GLubyte mipmapImage4[4][4][4]; GLubyte mipmapImage2[2][2][4]; GLubyte mipmapImage1[1][1][4]; #ifdef GL_VERSION_1_1 static GLuint texName; #endif void makeImages(void) { int i, j; for (i = 0; i < 32; i++) { for (j = 0; j < 32; j++) { mipmapImage32[i][j][0] = 255; mipmapImage32[i][j][1] = 255; mipmapImage32[i][j][2] = 0; mipmapImage32[i][j][3] = 255; } } for (i = 0; i < 16; i++) { for (j = 0; j < 16; j++) { mipmapImage16[i][j][0] = 255; mipmapImage16[i][j][1] = 0; mipmapImage16[i][j][2] = 255; mipmapImage16[i][j][3] = 255; } } for (i = 0; i < 8; i++) { for (j = 0; j < 8; j++) { mipmapImage8[i][j][0] = 255; mipmapImage8[i][j][1] = 0; mipmapImage8[i][j][2] = 0; mipmapImage8[i][j][3] = 255; } } for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { mipmapImage4[i][j][0] = 0; mipmapImage4[i][j][1] = 255; mipmapImage4[i][j][2] = 0; mipmapImage4[i][j][3] = 255; } } for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { mipmapImage2[i][j][0] = 0; mipmapImage2[i][j][1] = 0; mipmapImage2[i][j][2] = 255; mipmapImage2[i][j][3] = 255; } } mipmapImage1[0][0][0] = 255; mipmapImage1[0][0][1] = 255; mipmapImage1[0][0][2] = 255; mipmapImage1[0][0][3] = 255; } int a; GLboolean b=0; void init(void) { glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); glTranslatef(0.0, 0.0, -3.6); makeImages(); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); #ifdef GL_VERSION_1_1 glGenTextures(1, &texName); glBindTexture(GL_TEXTURE_2D, texName); #endif 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_MIPMAP_NEAREST); //方法3: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32); glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage16); glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA, 8, 8, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage8); glTexImage2D(GL_TEXTURE_2D, 3, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage4); glTexImage2D(GL_TEXTURE_2D, 4, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage2); glTexImage2D(GL_TEXTURE_2D, 5, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage1); // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); // 方法1:OPENGL 1.4 以后 /*glTexParameteri(GL_TEXTURE_2D,GL_GENERATE_MIPMAP,GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32);*/ // 方法2: OPENGL1.1 //gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, 32, 32, GL_RGBA, GL_UNSIGNED_BYTE, mipmapImage32); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glEnable(GL_TEXTURE_2D); //glGetTexLevelParameteriv(GL_TEXTURE_RESIDENT,0,texName,&a); glAreTexturesResident(1,&texName,&b); glEnable(GL_TEXTURE_2D); } void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #ifdef GL_VERSION_1_1 glBindTexture(GL_TEXTURE_2D, texName); #endif glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0); glTexCoord2f(0.0, 8.0); glVertex3f(-2.0, 1.0, 0.0); glTexCoord2f(8.0, 8.0); glVertex3f(2000.0, 1.0, -6000.0); glTexCoord2f(8.0, 0.0); glVertex3f(2000.0, -1.0, -6000.0); glEnd(); glFlush(); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 1.0, 30000.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard (unsigned char key, int x, int y) { switch (key) { case 27: exit(0); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (50, 50); glutCreateWindow (argv[0]); glewInit(); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutKeyboardFunc(keyboard); glutMainLoop(); return 0; }
相关推荐
NEHE的OPENGL教程 第42课 多视窗口… NEHE的OPENGL教程 第42课 多视窗口… NeHe的OPENGL中文教程:第41课 体… NeHe的OPENGL中文教程:第40课 绳… NeHe的OPENGL中文教程:第39课 物… ...怎样开始学习OpenGL
Includes Complete Coverage of the OpenGL® Shading Language! Today’s OpenGL software interface enables programmers to produce extraordinarily high-quality computer-generated images and interactive ...
The OpenGL®Programming Guide, Seventh Edition, provides definitive and comprehensive information on OpenGL and the OpenGL Utility Library. The previous edition covered OpenGL through Version 2.1. ...
OpenGL源代码:oglwrapperclass_demo
毕业设计!模拟音乐喷泉,随着音频文件的起伏,OpenGL所绘制的音乐喷泉大小和水量缓急出现相应变化!
现代OpenGL+Qt:smooth和flat着色模式,在Qt,通过现代OpenGL实现的flat着色模式的示例程序。详见博文:现代OpenGL+Qt学习笔记之九:smooth和flat着色模式
The OPenGL Graphics System:Specification(Version 1.2)
对应的OpenGL学习博客:...此代码仅用于OpenGL入门学习。PS:可能会有点卡主要是因为:①使用的地面模型是高模(几十万个顶点)②使用的天空盒贴图是2040x2048的超大贴图6张;没办法只找到这些资源,所以只能将就着用了
OpenGL游戏编程:3D三连棋源码..rar
Android OpenGL入门示例:绘制三角形和正方形,详见博文: http://blog.csdn.net/yanzi1225627/article/details/30096181
OpenGL源代码:oglwrapperclass_src
一个VC OpenGL API实例:旋转的彩色3D立方体,在窗口缩放的过程中,3D立方体会自动旋转,改变角度,虽然很简单,但可学习一下OpenGL API在VC 中的用法。
现代OpenGL+Qt:使用halfway向量提高光照计算效率,使用halfway向量提高OpenGL光照计算的效率,详见博文:现代OpenGL+Qt学习笔记之十一:使用halfway向量提高光照计算效率...
手动实现OpenGL部分功能:放缩、旋转、视角变换、操纵BMP文件、颜色缓冲区等等,写到这个程度就再没时间继续写下去了,总之给大家作为参考吧。
现代OpenGL+Qt:绘制可旋转、带光照效果的三维物体。使用现代OpenGL和Qt,绘制一个可以用鼠标控制旋转缩放,带光照效果的三维物体,其中演示了最简单的光照,即漫射光的计算过程。
OpenGL游戏编程:Delphi星空闪电图源代码..rar
在Qt框架下,用现代OpenGL实现的双面渲染,渲染对象是常见的茶壶模型,详见CSDN博客现代OpenGL+Qt学习笔记之八:GLSL双面渲染。
Computer Graphics: Using OpenGL cppComputer Graphics: Using OpenGL cppComputer Graphics: Using OpenGL cppComputer Graphics: Using OpenGL cppComputer Graphics: Using OpenGL cppComputer Graphics: Using ...
OpenGL 学习库 相关资料 教程地址: 原教程地址: 中文教程地址: 参考网址: OpenGL API doc: GLFW: GLEW: stb: assimp: OpenGL tutorial video: Xcode GLFW & GLEW 环境配置: 目录 注:以下各部分并非...
Opengl 开发库, 动态链接库文件,opengl辅助库: 31个函数,以aux 开头。