[NEHE Couse] 06.Texture Map

      趁着寒假还没过完,还是本着良心的原则把这课给做了吧,从今天上午就开始看这课,一直对texture map不太敢接近,原因有多方面,感觉它有点小深奥。但还是结合红宝书把有关texture map的基本知识算是重温了下,因为之前为了应付老板的检查也做过相关的Demo,感觉这部分的知识自己是相当的生疏,虽然今天把简单的程序给写了出来,但关于texture map自己还有很多东西要看,这个就看自己回校后自己安排时间了,先把程序贴出来吧。
     这个程序只是简单的texture map入门级的程序,如果想了解一些深入的东东还要再努力.在code中,我用前面那个24位BMP文件读取的程序为基础,把BMP文件作为纹理对象的内容(PS:在这个程序中也只能读取24位BMP图像的信息),然后把纹理简单的应用到四方形上,就是这么简单,呵呵~
程序如下:

  1/*
  2Introduction:Written by krisdy,finished at 2009.2.11
  3Apply to:NEHE Couse 06
  4*/

  5#include <gl/glut.h>
  6#include <stdio.h>
  7#include <stdlib.h>
  8
  9#define WinWidth 500        //the width of the window
 10#define WinHeight 500        //the height of the window
 11
 12#define FileName "krisdy.bmp"
 13static const char *str = FileName;
 14
 15static GLint    ImageWidth;
 16static GLint    ImageHeight;
 17static GLint    PixelLength;
 18static GLubyte* PixelData;
 19
 20static GLint t;
 21static GLuint texName;
 22static GLfloat xrot,yrot,zrot;
 23//把指定BMP图像读入PixelData数据结构中
 24void LoadBMP()
 25{
 26    // 打开文件
 27    FILE* pFile = fopen(str, "rb");
 28    if( pFile == 0 )
 29        exit(0);
 30
 31    // 读取图象的大小信息
 32    fseek(pFile, 0x0012, SEEK_SET);
 33    fread(&ImageWidth, sizeof(ImageWidth), 1, pFile);
 34    fread(&ImageHeight, sizeof(ImageHeight), 1, pFile);
 35
 36    // 计算像素数据长度
 37    PixelLength = ImageWidth * 3;
 38    while( PixelLength % 4 != 0 )
 39        ++PixelLength;
 40    PixelLength *= ImageHeight;
 41
 42    // 读取像素数据
 43    PixelData = (GLubyte*)malloc(PixelLength);
 44    if( PixelData == 0 )
 45        exit(0);
 46
 47    fseek(pFile, 54, SEEK_SET);
 48    fread(PixelData, PixelLength, 1, pFile);
 49
 50    // 关闭文件
 51    fclose(pFile);
 52}

 53void init(void)
 54{
 55    glShadeModel(GL_SMOOTH);
 56    glClearColor(0.0f,0.0f,0.0f,0.0f);
 57    glClearDepth(1.0f);
 58    //开启深度测试,凡是在程序中要涉及三维物体的基本都要开启深度测试
 59    glEnable(GL_DEPTH_TEST);
 60    LoadBMP();
 61    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
 62    glPixelStorei(GL_UNPACK_ALIGNMENT,1);
 63    //命名纹理对象
 64    glGenTextures(1,&texName);
 65    //创建纹理对象,属性为初始默认值
 66    glBindTexture(GL_TEXTURE_2D,texName);
 67    //以下几行均为相关参数赋值
 68    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
 69    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
 70    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
 71    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
 72    glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,ImageWidth,ImageHeight,0,GL_BGR_EXT,GL_UNSIGNED_BYTE,PixelData);
 73}

 74void display(void)
 75{
 76    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
 77    glEnable(GL_TEXTURE_2D);//开启二维纹理贴图功能
 78    glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
 79    //第二次出现glBindTexture表示使用纹理对象
 80    glBindTexture(GL_TEXTURE_2D,texName);
 81    //这句话偶开始又因为粗心没写,导致立方体转起来飞快的不像样子
 82    glLoadIdentity();
 83    //绕三个轴以一定量旋转
 84    glRotatef(xrot,1.0f,0.0f,0.0f);
 85    glRotatef(yrot,0.0f,1.0f,0.0f);
 86    glRotatef(zrot,0.0f,0.0f,1.0f);
 87    glBegin(GL_QUADS);
 88    //以下的坐标都遵从先是纹理坐标后是几何坐标的格式,分六个面画出了一个立方体
 89    //且都是用同一个纹理对象,如果为了美观,可以在每个面上分别使用不同的纹理对象,而你
 90    //需要做的仅仅是开始多创建几个纹理对象而已
 91    // 前面
 92    glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // 纹理和四边形的左下
 93    glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // 纹理和四边形的右下
 94    glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // 纹理和四边形的右上
 95    glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // 纹理和四边形的左上
 96    // 后面
 97    glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);    // 纹理和四边形的右下
 98    glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // 纹理和四边形的右上
 99    glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // 纹理和四边形的左上
100    glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);    // 纹理和四边形的左下
101    // 顶面
102    glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // 纹理和四边形的左上
103    glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // 纹理和四边形的左下
104    glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // 纹理和四边形的右下
105    glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // 纹理和四边形的右上
106    // 底面
107    glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f-1.0f-1.0f);    // 纹理和四边形的右上
108    glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f-1.0f-1.0f);    // 纹理和四边形的左上
109    glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // 纹理和四边形的左下
110    glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // 纹理和四边形的右下
111    // 右面
112    glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);    // 纹理和四边形的右下
113    glTexCoord2f(1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);    // 纹理和四边形的右上
114    glTexCoord2f(0.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);    // 纹理和四边形的左上
115    glTexCoord2f(0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);    // 纹理和四边形的左下
116    // 左面
117    glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);    // 纹理和四边形的左下
118    glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);    // 纹理和四边形的右下
119    glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);    // 纹理和四边形的右上
120    glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);    // 纹理和四边形的左上
121    glEnd();
122
123    glutSwapBuffers();
124    glDisable(GL_TEXTURE_2D);//关闭纹理贴图功能
125}

126//改变绕各个轴的旋转角度
127void spin()
128{
129    xrot += 0.3f;
130    yrot += 0.3f;
131    zrot += 0.3f;
132    if(xrot > 360.0)
133        xrot -= 360.0;
134    if(yrot > 360.0)
135        yrot -= 360.0;
136    if(zrot > 360.0)
137        zrot -= 360.0;
138    glutPostRedisplay();
139}

140void reshape(int w,int h)
141{
142    GLfloat range = 2.0f;
143    if(h == 0)
144        h = 1;
145    glViewport(0,0,w,h);
146    glMatrixMode(GL_PROJECTION);
147    glLoadIdentity();
148    if(w < h)
149        glOrtho(-range,range,-(range * h)/w,(range * h)/w,-range,range);
150    else
151        glOrtho(-(range * w)/h,(range * w)/h,-range,range,-range,range);
152    glMatrixMode(GL_MODELVIEW);
153    glLoadIdentity();
154}

155void keyboard(unsigned char key,int x,int y)
156{
157    switch(key)
158    {
159    //use the space key to decide whether the window will be full-screen displayed.
160    case 32:                                            
161        if(t%2 == 0)
162            //requests that the current window be made full screen
163            glutFullScreen();                            
164        else
165            //requests a change to the size of the current window
166            glutReshapeWindow(WinWidth,WinHeight);        
167        t++;
168        break;
169    //use the Esc key to quit the application
170    case 27:
171        exit(0);
172        break;
173    default:
174        break;
175    }

176}

177int main(int argc,char *argv[])
178{
179    glutInit(&argc,argv);
180    glutInitDisplayMode(GLUT_DEPTH|GLUT_RGB|GLUT_DOUBLE);
181    glutInitWindowSize(WinWidth,WinHeight);
182    glutInitWindowPosition(100,100);
183    glutCreateWindow("Lesson 06");
184
185    init();
186    glutDisplayFunc(display);
187    glutReshapeFunc(reshape);
188    glutIdleFunc(spin);
189    glutKeyboardFunc(keyboard);
190    glutMainLoop();
191    return 0;
192}

程序执行的结果为一个自动旋转的立方体,截图如下:

posted on 2009-02-11 01:42  笔记  阅读(543)  评论(0编辑  收藏  举报

导航