OpenGL学习十八:多重细节层

来源:互联网 发布:众意好医师软件 编辑:程序博客网 时间:2024/05/22 15:18

在动态场景中,当一个纹理对象迅速地远离观察点时,纹理图像必须随着背投影的图像一起缩小,为了实现这个效果,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_1static GLuint texName;#endifvoid 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;     }


 

 

0 0