【OpenGL】(NeHe教程学习)纹理映射及代码实现

本文将要实现的功能是绘制一个立方体,并且在六个面贴上不同的纹理(由外部导入图片)。按下x、y、z按键可以分别围绕x、y、z轴旋转。

在这里我使用的是GLUT库。


【1】读入bmp图片的信息采用了auxDIBImageLoad函数,它被包含在头文件glaux.h中。

实际上是一个宏,返回类型是AUX_RGBImageRec *。可以在头文件glaux.h中找到它的定义:

  1. #ifdef UNICODE  
  2. #define auxDIBImageLoad auxDIBImageLoadW  
  3. #else  
  4. #define auxDIBImageLoad auxDIBImageLoadA  
  5. #endif  
  6. AUX_RGBImageRec * APIENTRY auxDIBImageLoadA(LPCSTR);  
  7. AUX_RGBImageRec * APIENTRY auxDIBImageLoadW(LPCWSTR);  

AUX_RGBImageRec 是一个结构体类型,这是它在头文件glaux.h中的定义:

  1. typedef struct _AUX_RGBImageRec {  
  2.     GLint sizeX, sizeY;  
  3.     unsigned char *data;  
  4. } AUX_RGBImageRec;  

需要注意的是:导入作为纹理的bmp图像的高度和宽度必须为2的整数次幂,而且至少是64个像素。为了保持兼容性,也不应该超过256个像素。


【2】我们需要创建六个纹理,以给六个面以不同的效果。

为了使用纹理,需要执行下列步骤:

1、创建纹理对象,并为它指定一个纹理;

2、确定纹理如何应用到每个像素上;

3、启用纹理贴图功能;
4、绘制场景,提供纹理坐标和几何图形坐标。

注意:纹理坐标必须在RGBA模式下才可以使用。在颜色索引模式下使用纹理贴图的结果是难以预料的。

创建纹理的核心代码:

  1. glGenTextures(1,&texture[i]);//命名纹理对象  
  2. glBindTexture(GL_TEXTURE_2D,texture[i]);//绑定纹理  
  3. glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TextureImage[i]->sizeX,  
  4.                 TextureImage[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,  
  5.                 TextureImage[i]->data);//指定纹理  
  6. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//指定过滤模式  
  7. glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);  
接下来需要绘制正方体,并且指定纹理坐标。对于立方体的每个面,我们指定不同的纹理。

注意:我们需要再次绑定纹理,以确定需要使用的纹理。


【3】使用SOIL库代替glaux加载纹理

由于glaux在很长时间内受到反对,我们可以使用SOIL(Simple OpenGL Image Library)库来实现加载图像作为纹理。SOIL库可以在这里下载:SOIL库

在程序中需要包含头文件SOIL.h,并且连接SOIL.lib库文件。

而且SOIL库比glaux更方便,直接加载磁盘上的图像成为纹理。

我们所需要对代码做的修改就是修改LoadGLTextures函数:

  1. //load the bitmap and convert it into a texture  
  2. int LoadGLTextures()  
  3. {  
  4.     int Status = 1;  
  5.     char *bmpFile[6] = {"BmpFile/Ferrary.bmp","BmpFile/Honda.bmp","BmpFile/Hust.bmp",  
  6.         "BmpFile/Lamborghini.bmp","BmpFile/NeHe.bmp","BmpFile/Porsche.bmp"};  
  7.     for (int i = 0;i < 6;++i)  
  8.     {  
  9.         texture[i] = SOIL_load_OGL_texture(  
  10.             bmpFile[i],  
  11.             SOIL_LOAD_AUTO,  
  12.             SOIL_CREATE_NEW_ID,  
  13.             SOIL_FLAG_INVERT_Y);  
  14.         printf("texture[%d]: %d\n",i,texture[i]);  
  15.         if(texture[i] == 0)  
  16.             Status = 0;  
  17.         glBindTexture(GL_TEXTURE_2D,texture[i]);  
  18.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);  
  19.         glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);  
  20.     }  
  21.     return Status;  
  22. }  


【4】详细代码实现(使用glaux):

  1. #include <GL/glut.h>  
  2. #include <GL/glaux.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5.   
  6. GLuint texture[6];//6 textures for 6 faces of the cube  
  7.   
  8. GLfloat xRot,yRot,zRot;//control cube's rotation  
  9.   
  10. //read bmp image file  
  11. AUX_RGBImageRec *LoadBMP(char *FileName)  
  12. {  
  13.     FILE *File = NULL;  
  14.     if(!FileName)  
  15.         return NULL;  
  16.     File = fopen(FileName,"r");  
  17.     if (File)  
  18.     {  
  19.         fclose(File);  
  20.         return auxDIBImageLoad(FileName);  
  21.     }  
  22.     return NULL;  
  23. }  
  24.   
  25. //load the bitmap and convert it into a texture  
  26. int LoadGLTextures()  
  27. {  
  28.     int Status = FALSE;  
  29.     char *bmpFile[6] = {"BmpFile/Ferrary.bmp","BmpFile/Honda.bmp","BmpFile/Hust.bmp",  
  30.         "BmpFile/Lamborghini.bmp","BmpFile/NeHe.bmp","BmpFile/Porsche.bmp"};  
  31.     //AUX_RGBImageRec *TextureImage[6] = new AUX_RGBImageRec[6];//create storage for the texture  
  32.     AUX_RGBImageRec *TextureImage[6] = {NULL,NULL,NULL,NULL,NULL,NULL};  
  33.     for(int i = 0;i < 6;++i)  
  34.     {  
  35.         //memset(TextureImage[i],0,sizeof(void*) * 1);//set the point to NULL  
  36.         if (TextureImage[i] = LoadBMP(bmpFile[i]))  
  37.         {  
  38.             Status = TRUE;  
  39.             glGenTextures(1,&texture[i]);//命名纹理对象  
  40.             glBindTexture(GL_TEXTURE_2D,texture[i]);//绑定纹理  
  41.             glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,TextureImage[i]->sizeX,  
  42.                 TextureImage[i]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,  
  43.                 TextureImage[i]->data);//指定纹理  
  44.             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);//指定过滤模式  
  45.             glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);  
  46.         }  
  47.   
  48.         if (TextureImage[i])  
  49.         {  
  50.             if (TextureImage[i]->data)  
  51.                 free(TextureImage[i]->data);  
  52.             free(TextureImage[i]);  
  53.         }  
  54.     }  
  55.   
  56.     return Status;  
  57. }  
  58.   
  59. int init()  
  60. {  
  61.     if(!LoadGLTextures())  
  62.         return FALSE;  
  63.     glEnable(GL_TEXTURE_2D);  
  64.     glShadeModel(GL_SMOOTH);  
  65.     glClearColor(0.0f,0.0f,0.0f,0.5f);  
  66.     glClearDepth(1.0f);  
  67.     glEnable(GL_DEPTH_TEST);  
  68.     glDepthFunc(GL_LEQUAL);  
  69.     glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);  
  70.     return TRUE;  
  71. }  
  72.   
  73. void display()  
  74. {  
  75.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  76.     glLoadIdentity();  
  77.     glTranslatef(0.0f,0.0f,-5.0f);  
  78.     glRotatef(xRot,1.0f,0.0f,0.0f);  
  79.     glRotatef(yRot,0.0f,1.0f,0.0f);  
  80.     glRotatef(zRot,0.0f,0.0f,1.0f);  
  81.   
  82.     //glRotatef(45,1.0f,0.0f,0.0f);  
  83.     //glRotatef(45,0.0f,1.0f,0.0f);  
  84.   
  85.     glBindTexture(GL_TEXTURE_2D,texture[0]);  
  86.   
  87.     glBegin(GL_QUADS);   
  88.     // Front Face   
  89.     // Bottom Left Of The Texture and Quad   
  90.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   
  91.     // Bottom Right Of The Texture and Quad   
  92.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   
  93.     // Top Right Of The Texture and Quad   
  94.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   
  95.     // Top Left Of The Texture and Quad   
  96.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   
  97.     glEnd();   
  98.   
  99.     glBindTexture(GL_TEXTURE_2D,texture[1]);  
  100.     glBegin(GL_QUADS);   
  101.     // Back Face   
  102.     // Bottom Right Of The Texture and Quad   
  103.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   
  104.     // Top Right Of The Texture and Quad   
  105.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   
  106.     // Top Left Of The Texture and Quad   
  107.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   
  108.     // Bottom Left Of The Texture and Quad   
  109.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   
  110.     glEnd();   
  111.   
  112.     glBindTexture(GL_TEXTURE_2D,texture[2]);  
  113.     glBegin(GL_QUADS);   
  114.     // Top Face   
  115.     // Top Left Of The Texture and Quad   
  116.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   
  117.     // Bottom Left Of The Texture and Quad   
  118.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   
  119.     // Bottom Right Of The Texture and Quad   
  120.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   
  121.     // Top Right Of The Texture and Quad   
  122.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   
  123.     glEnd();   
  124.   
  125.     glBindTexture(GL_TEXTURE_2D,texture[3]);  
  126.     glBegin(GL_QUADS);   
  127.     // Bottom Face   
  128.     // Top Right Of The Texture and Quad   
  129.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   
  130.     // Top Left Of The Texture and Quad   
  131.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   
  132.     // Bottom Left Of The Texture and Quad   
  133.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   
  134.     // Bottom Right Of The Texture and Quad   
  135.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   
  136.     glEnd();   
  137.   
  138.     glBindTexture(GL_TEXTURE_2D,texture[4]);  
  139.     glBegin(GL_QUADS);   
  140.     // Right face   
  141.     // Bottom Right Of The Texture and Quad   
  142.     glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);   
  143.     // Top Right Of The Texture and Quad   
  144.     glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);   
  145.     // Top Left Of The Texture and Quad   
  146.     glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);   
  147.     // Bottom Left Of The Texture and Quad   
  148.     glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);   
  149.     glEnd();   
  150.   
  151.     glBindTexture(GL_TEXTURE_2D,texture[5]);  
  152.     glBegin(GL_QUADS);   
  153.     // Left Face   
  154.     // Bottom Left Of The Texture and Quad   
  155.     glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);   
  156.     // Bottom Right Of The Texture and Quad   
  157.     glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);   
  158.     // Top Right Of The Texture and Quad   
  159.     glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);   
  160.     // Top Left Of The Texture and Quad   
  161.     glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);   
  162.     glEnd();   
  163.   
  164.     /*xRot += 0.3f; 
  165.     yRot += 0.4f; 
  166.     zRot += 0.5f;*/  
  167.   
  168.     glutSwapBuffers();  
  169. }  
  170.   
  171. void reshape(int w,int h)  
  172. {  
  173.     if (0 == h)  
  174.         h = 1;  
  175.       
  176.     glViewport(0,0,(GLsizei)w,(GLsizei)h);  
  177.     glMatrixMode(GL_PROJECTION);  
  178.     glLoadIdentity();  
  179.     gluPerspective(60.0f,(GLfloat)w / (GLfloat)h,1,100);  
  180.     glMatrixMode(GL_MODELVIEW);  
  181.     glLoadIdentity();  
  182. }  
  183.   
  184. void keyboard(unsigned char key,int x,int y)  
  185. {  
  186.     switch(key){  
  187.         case 'x':  
  188.             xRot += 1.0f;  
  189.             glutPostRedisplay();  
  190.             break;  
  191.         case 'y':  
  192.             yRot += 1.0f;  
  193.             glutPostRedisplay();  
  194.             break;  
  195.         case 'z':  
  196.             zRot += 1.0f;  
  197.             glutPostRedisplay();  
  198.             break;  
  199.         default:  
  200.             break;  
  201.     }  
  202. }  
  203.   
  204. int main(int argc,char** argv)  
  205. {  
  206.     glutInit(&argc,argv);  
  207.     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);  
  208.     glutInitWindowSize(400,400);  
  209.     glutInitWindowPosition(100,100);  
  210.     glutCreateWindow("Texture Map");  
  211.     init();  
  212.     glutDisplayFunc(display);  
  213.     glutReshapeFunc(reshape);  
  214.     glutKeyboardFunc(keyboard);  
  215.     glutMainLoop();  
  216.     return 0;  
  217. }  
运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值