[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.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
93 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
94 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
95 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
96 // 后面
97 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
98 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
99 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
100 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
101 // 顶面
102 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
103 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下
104 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下
105 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
106 // 底面
107 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上
108 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上
109 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
110 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
111 // 右面
112 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
113 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
114 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
115 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
116 // 左面
117 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
118 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
119 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
120 glTexCoord2f(0.0f, 1.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}
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.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
93 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
94 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
95 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
96 // 后面
97 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
98 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
99 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
100 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
101 // 顶面
102 glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
103 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下
104 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下
105 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
106 // 底面
107 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上
108 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上
109 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
110 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
111 // 右面
112 glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
113 glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
114 glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
115 glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
116 // 左面
117 glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
118 glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
119 glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
120 glTexCoord2f(0.0f, 1.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}
程序执行的结果为一个自动旋转的立方体,截图如下:
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。