[NEHE Couse] 06.Texture Map
趁着寒假还没过完,还是本着良心的原则把这课给做了吧,从今天上午就开始看这课,一直对texture map不太敢接近,原因有多方面,感觉它有点小深奥。但还是结合红宝书把有关texture map的基本知识算是重温了下,因为之前为了应付老板的检查也做过相关的Demo,感觉这部分的知识自己是相当的生疏,虽然今天把简单的程序给写了出来,但关于texture map自己还有很多东西要看,这个就看自己回校后自己安排时间了,先把程序贴出来吧。
这个程序只是简单的texture map入门级的程序,如果想了解一些深入的东东还要再努力.在code中,我用前面那个24位BMP文件读取的程序为基础,把BMP文件作为纹理对象的内容(PS:在这个程序中也只能读取24位BMP图像的信息),然后把纹理简单的应用到四方形上,就是这么简单,呵呵~
程序如下:
1
/*
2
Introduction:Written by krisdy,finished at 2009.2.11
3
Apply 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"
13
static const char *str = FileName;
14
15
static GLint ImageWidth;
16
static GLint ImageHeight;
17
static GLint PixelLength;
18
static GLubyte* PixelData;
19
20
static GLint t;
21
static GLuint texName;
22
static GLfloat xrot,yrot,zrot;
23
//把指定BMP图像读入PixelData数据结构中
24
void 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
}
53
void 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
}
74
void 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
//改变绕各个轴的旋转角度
127
void 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
}
140
void 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
}
155
void 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
}
177
int 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
}
/*2
Introduction:Written by krisdy,finished at 2009.2.113
Apply to:NEHE Couse 064
*/5
#include <gl/glut.h>6
#include <stdio.h>7
#include <stdlib.h>8

9
#define WinWidth 500 //the width of the window10
#define WinHeight 500 //the height of the window11

12
#define FileName "krisdy.bmp"13
static const char *str = FileName;14

15
static GLint ImageWidth;16
static GLint ImageHeight;17
static GLint PixelLength;18
static GLubyte* PixelData;19

20
static GLint t;21
static GLuint texName;22
static GLfloat xrot,yrot,zrot;23
//把指定BMP图像读入PixelData数据结构中24
void 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
}53
void 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
}74
void 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
//改变绕各个轴的旋转角度127
void 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
}140
void 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
else151
glOrtho(-(range * w)/h,(range * w)/h,-range,range,-range,range);152
glMatrixMode(GL_MODELVIEW);153
glLoadIdentity();154
}155
void 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 screen163
glutFullScreen(); 164
else165
//requests a change to the size of the current window166
glutReshapeWindow(WinWidth,WinHeight); 167
t++;168
break;169
//use the Esc key to quit the application170
case 27:171
exit(0);172
break;173
default:174
break;175
}176
}177
int 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
}程序执行的结果为一个自动旋转的立方体,截图如下:
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。

浙公网安备 33010602011771号