[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

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81


82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

程序执行的结果为一个自动旋转的立方体,截图如下:
我没有什么雄心壮志,我只想给自己和关心自己的家人和朋友一个交代,仅此而已。