OpenGL基本框架 画基本图形 纹理和光照
OpenGl 基本框架 画基本图形 纹理 光照

Code
1
//Link:OpenGL32.lib GLu32.lib GLaux.lib
2
#include <stdio.h>
3
#include <windows.h> // Windows的头文件
4
//#include <glew.h> // 包含最新的gl.h,glu.h库
5
#include <gl\gl.h>
6
#include <gl\glu.h>
7
#include <gl/glaux.h>
8
9
HGLRC hRC=NULL; // 窗口着色描述表句柄
10
HDC hDC=NULL; // OpenGL渲染描述表句柄
11
HWND hWnd=NULL; // 保存我们的窗口句柄
12
HINSTANCE hInstance; // 保存程序的实例
13
bool keys[256]; // 保存键盘按键的数组
14
bool active=TRUE; // 窗口的活动标志,缺省为TRUE
15
bool fullscreen=TRUE; // 全屏标志缺省,缺省设定成全屏模式
16
GLfloat rtri; // 用于三角形的角度
17
GLfloat rquad; // 用于四边形的角度
18
//GLfloat xrot; // X 旋转量
19
//GLfloat yrot; // Y 旋转量
20
GLfloat zrot; // Z 旋转量
21
//GLuint texture[1]; // 存储一个纹理
22
BOOL light; // 光源的开/关
23
BOOL lp; // L键按下了么?
24
BOOL fp; // F键按下了么?
25
26
GLfloat xrot; // X 旋转
27
GLfloat yrot; // Y 旋转
28
GLfloat xspeed; // X 旋转速度
29
GLfloat yspeed; // Y 旋转速度
30
GLfloat z=-5.0f; // 深入屏幕的距离
31
32
GLuint filter; // 滤波类型
33
GLuint texture[3]; // 3种纹理的储存空间
34
35
GLfloat LightAmbient[]=
{ 0.1f, 0.1f, 0.5f, 1.0f }; // 环境光参数
36
GLfloat LightDiffuse[]=
{ 1.0f, 1.0f, 1.0f, 1.0f }; // 漫射光参数
37
GLfloat LightPosition[]=
{ 0.0f, 0.0f, 2.0f, 1.0f }; // 光源位置
38
39
40
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定义
41
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象
42

{
43
FILE *File=NULL; // 文件句柄
44
if (!Filename) // 确保文件名已提供
45
{
46
return NULL; // 如果没提供,返回 NULL
47
}
48
File=fopen(Filename,"r");
49
if (File) // 文件存在么?
50
{
51
fclose(File); // 关闭句柄
52
return auxDIBImageLoad(Filename); // 载入位图并返回指针
53
}
54
return NULL; // 如果载入失败,返回 NULL
55
}
56
57
int LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理
58

{
59
int Status=FALSE; // 状态指示器
60
AUX_RGBImageRec *TextureImage[1]; // 创建纹理的存储空间
61
memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULL
62
63
// 载入位图,检查有无错误,如果位图没找到则退出
64
if (TextureImage[0]=LoadBMP("Images\\1.bmp"))
65
{
66
Status=TRUE; // 将 Status 设为 TRUE
67
glGenTextures(1, &texture[0]); // 创建纹理
68
// 使用来自位图数据生成 的典型纹理
69
glBindTexture(GL_TEXTURE_2D, texture[0]);
70
// 生成纹理
71
/**///////////////////////////////////MyDraw3//////////////////////////////////////
72
//glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,
73
// TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
74
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波
75
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线形滤波
76
77
78
/**////////////////////////////////////MyDraw4////////////////////////////////////
79
// 创建 Nearest 滤波贴图
80
glBindTexture(GL_TEXTURE_2D, texture[0]);
81
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
82
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
83
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,
84
TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
85
86
// 创建线性滤波纹理
87
glBindTexture(GL_TEXTURE_2D, texture[1]);
88
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
89
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
90
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX,
91
TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
92
93
// 创建 MipMapped 纹理
94
glBindTexture(GL_TEXTURE_2D, texture[2]);
95
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
96
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
97
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX,
98
TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
99
}
100
if (TextureImage[0]) // 纹理是否存在
101
{
102
if (TextureImage[0]->data) // 纹理图像是否存在
103
{
104
free(TextureImage[0]->data); // 释放纹理图像占用的内存
105
}
106
107
free(TextureImage[0]); // 释放图像结构
108
}
109
return Status; // 返回 Status
110
}
111
112
113
114
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小
115

{
116
if (height==0) // 防止被零除
117
{
118
height=1; // 将Height设为1
119
}
120
121
glViewport(0, 0, width, height); // 重置当前的视口
122
glMatrixMode(GL_PROJECTION); // 选择投影矩阵
123
glLoadIdentity(); // 重置投影矩阵
124
125
// 设置视口的大小
126
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
127
128
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵
129
glLoadIdentity(); // 重置模型观察矩阵
130
}
131
132
int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置
133

{
134
135
if (!LoadGLTextures()) // 调用纹理载入子例程
136
{
137
return FALSE; // 如果未能载入,返回FALSE
138
}
139
glEnable(GL_TEXTURE_2D); //启用2D纹理映射
140
glShadeModel(GL_SMOOTH); // 启用阴影平滑
141
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景
142
glClearDepth(1.0f); // 设置深度缓存
143
glEnable(GL_DEPTH_TEST); // 启用深度测试
144
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型
145
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正
146
147
//MyDraw4/////////////////////////////////
148
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光
149
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光
150
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 设置光源位置
151
glEnable(GL_LIGHT1); // 启用一号光源
152
153
154
155
return TRUE; // 初始化 OK
156
}
157
void MyDraw1()
158

{
159
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
160
161
glLoadIdentity(); // 重置当前的模型观察矩阵
162
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0
163
164
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转三角形
165
glBegin(GL_TRIANGLES); // 绘制三角形
166
glColor3f(1.0f,0.0f,0.0f); // 设置当前色为红色
167
glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点
168
glColor3f(0.0f,1.0f,0.0f); // 设置当前色为绿色
169
glVertex3f(-1.0f,-1.0f, 0.0f); // 左下
170
glColor3f(0.0f,0.0f,1.0f); // 设置当前色为蓝色
171
glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
172
glEnd();
173
174
glLoadIdentity(); // 重置模型观察矩阵 避免上面的旋转影响下面
175
//glTranslatef(3.0f,0.0f,0.0f); // 右移3单位 也就是把(3.0f,0.0f,0.0f)当作原点
176
177
glTranslatef(1.5f,0.0f,-6.0f); // 右移1.5单位,并移入屏幕 6.0
178
179
glRotatef(rquad,1.0f,0.0f,0.0f); // 绕X轴旋转四边形
180
glBegin(GL_QUADS); // 绘制正方形
181
glColor3f(0.0f,1.0f,0.0f); // 设置当前色为绿色
182
glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
183
glColor3f(0.0f,0.5f,1.0f); // 设置当前色为蓝色
184
glVertex3f( 1.0f, 1.0f, 0.0f); // 右上
185
glColor3f(1.0f,0.0f,1.0f); // 设置当前色为蓝色
186
glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
187
glColor3f(0.0f,0.0f,1.0f); // 设置当前色为蓝色
188
glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
189
glEnd(); // 正方形绘制结束
190
191
192
rtri+=0.2f; // 增加三角形的旋转变量
193
rquad-=0.15f; // 减少四边形的旋转变量
194
}
195
void MyDraw2()
196

{
197
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
198
glLoadIdentity(); // 重置模型观察矩阵
199
glTranslatef(-1.5f,0.0f,-7.0f); // 左移 1.5 单位,并移入屏幕 6.0
200
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔
201
202
glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面
203
glColor3f(1.0f,0.0f,0.0f); // 红色
204
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (前侧面)
205
glColor3f(0.0f,1.0f,0.0f); // 绿色
206
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (前侧面)
207
glColor3f(0.0f,0.0f,1.0f); // 蓝色
208
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (前侧面)
209
210
glColor3f(1.0f,0.0f,0.0f); // 红色
211
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (右侧面)
212
glColor3f(0.0f,0.0f,1.0f); // 蓝色
213
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (右侧面)
214
glColor3f(0.0f,1.0f,0.0f); // 绿色
215
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (右侧面)
216
217
glColor3f(1.0f,0.0f,0.0f); // 红色
218
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (后侧面)
219
glColor3f(0.0f,1.0f,0.0f); // 绿色
220
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的左下顶点 (后侧面)
221
glColor3f(0.0f,0.0f,1.0f); // 蓝色
222
glVertex3f(-1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (后侧面)
223
224
glColor3f(1.0f,0.0f,0.0f); // 红色
225
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (左侧面)
226
glColor3f(0.0f,0.0f,1.0f); // 蓝色
227
glVertex3f(-1.0f,-1.0f,-1.0f); // 三角形的左下顶点 (左侧面)
228
glColor3f(0.0f,1.0f,0.0f); // 绿色
229
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (左侧面)
230
glEnd(); // 金字塔绘制结束
231
232
233
glLoadIdentity();
234
glTranslatef(1.5f,0.0f,-7.0f); // 先右移再移入屏幕
235
236
glRotatef(rquad,1.0f,1.0f,1.0f); // 在XYZ轴上旋转立方体
237
238
glBegin(GL_QUADS); // 开始绘制立方体
239
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
240
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)
241
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
242
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)
243
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)
244
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)
245
246
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色
247
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)
248
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
249
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)
250
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
251
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)
252
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)
253
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色
254
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)
255
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
256
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)
257
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
258
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)
259
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)
260
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色
261
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)
262
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
263
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)
264
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)
265
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色
266
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)
267
268
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色
269
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)
270
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
271
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)
272
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)
273
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
274
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)
275
276
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
277
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)
278
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
279
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)
280
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)
281
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
282
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)
283
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色
284
glEnd(); // 立方体绘制结束
285
286
rtri+=0.2f; // 增加三角形的旋转变量
287
rquad-=0.15f; // 减少四边形的旋转变量
288
289
}
290
void MyDraw3()
291

{
292
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
293
glLoadIdentity(); // 重置当前的模型观察矩阵
294
glTranslatef(0.0f,0.0f,-5.0f); // 移入屏幕 5 个单位
295
296
297
glRotatef(xrot,1.0f,0.0f,0.0f); // 绕X轴旋转
298
glRotatef(yrot,0.0f,1.0f,0.0f); // 绕Y轴旋转
299
glRotatef(zrot,0.0f,0.0f,1.0f); // 绕Z轴旋转
300
301
glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择纹理
302
303
glBegin(GL_QUADS);
304
// 前面
305
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
306
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
307
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
308
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
309
// 后面
310
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
311
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
312
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
313
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
314
// 顶面
315
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
316
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下
317
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下
318
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
319
// 底面
320
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上
321
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上
322
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
323
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
324
// 右面
325
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下
326
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上
327
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上
328
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下
329
// 左面
330
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下
331
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下
332
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上
333
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上
334
glEnd();
335
336
xrot+=0.3f; // X 轴旋转
337
yrot+=0.2f; // Y 轴旋转
338
zrot+=0.4f; // Z 轴旋转
339
}
340
void MyDraw4()
341

{
342
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存
343
glLoadIdentity(); // 重置当前的模型观察矩阵
344
glTranslatef(0.0f,0.0f,z); // 移入/移出屏幕 z 个单位
345
346
glRotatef(xrot,1.0f,0.0f,0.0f); // 绕X轴旋转
347
glRotatef(yrot,0.0f,1.0f,0.0f); // 绕Y轴旋转
348
349
glBindTexture(GL_TEXTURE_2D, texture[filter]); // 选择由filter决定的纹理
350
351
glBegin(GL_QUADS); // 开始绘制四边形
352
// 前侧面
353
glNormal3f( 0.0f, 0.0f, 1.0f); // 法线指向观察者
354
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
355
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
356
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
357
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
358
// 后侧面
359
glNormal3f( 0.0f, 0.0f,-1.0f); // 法线背向观察者
360
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
361
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
362
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
363
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
364
// 顶面
365
glNormal3f( 0.0f, 1.0f, 0.0f); // 法线向上
366
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
367
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
368
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
369
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
370
// 底面
371
glNormal3f( 0.0f,-1.0f, 0.0f); // 法线朝下
372
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
373
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
374
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
375
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
376
// 右侧面
377
glNormal3f( 1.0f, 0.0f, 0.0f); // 法线朝右
378
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
379
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
380
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
381
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
382
// 左侧面
383
glNormal3f(-1.0f, 0.0f, 0.0f); // 法线朝左
384
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
385
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
386
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
387
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
388
glEnd(); // 四边形绘制结束
389
xrot+=xspeed; // xrot 增加 xspeed 单位
390
yrot+=yspeed; // yrot 增加 yspeed 单位
391
}
392
393
int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制
394

{
395
MyDraw4();
396
return TRUE; // 一切 OK
397
}
398
GLvoid KillGLWindow(GLvoid) // 正常销毁窗口
399

{
400
401
if (fullscreen) // 我们处于全屏模式吗?
402
{
403
ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面
404
ShowCursor(TRUE); // 显示鼠标指针
405
}
406
if (hRC) // 我们拥有OpenGL渲染描述表吗?
407
{
408
if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表?
409
{
410
MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
411
}
412
if (!wglDeleteContext(hRC)) // 我们能否删除RC?
413
{
414
MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
415
}
416
hRC=NULL; // 将RC设为 NULL
417
}
418
if (hDC && !ReleaseDC(hWnd,hDC)) // 我们能否释放 DC?
419
{
420
MessageBox(NULL,"释放DC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
421
hDC=NULL; // 将 DC 设为 NULL
422
}
423
if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口?
424
{
425
MessageBox(NULL,"释放窗口句柄失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
426
hWnd=NULL; // 将 hWnd 设为 NULL
427
}
428
if (!UnregisterClass("OpenG",hInstance)) // 能否注销类?
429
{
430
MessageBox(NULL,"不能注销窗口类。","关闭错误",MB_OK | MB_ICONINFORMATION);
431
hInstance=NULL; // 将 hInstance 设为 NULL
432
}
433
}
434
435
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
436

{
437
GLuint PixelFormat; // 保存查找匹配的结果
438
WNDCLASS wc; // 窗口类结构
439
DWORD dwExStyle; // 扩展窗口风格
440
DWORD dwStyle; // 窗口风格
441
RECT WindowRect; // 取得矩形的左上角和右下角的坐标值
442
WindowRect.left=(long)100; // 将Left 设为 0
443
WindowRect.right=(long)width+WindowRect.left; // 将Right 设为要求的宽度
444
WindowRect.top=(long)200; // 将Top 设为 0
445
WindowRect.bottom=(long)height+WindowRect.top; // 将Bottom 设为要求的高度
446
fullscreen=fullscreenflag; // 设置全局全屏标志
447
hInstance = GetModuleHandle(NULL); // 取得我们窗口的实例
448
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 移动时重画,并为窗口取得DC
449
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc处理消息
450
wc.cbClsExtra = 0; // 无额外窗口数据
451
wc.cbWndExtra = 0; // 无额外窗口数据
452
wc.hInstance = hInstance; // 设置实例
453
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // 装入缺省图标
454
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 装入鼠标指针
455
wc.hbrBackground = NULL; // GL不需要背景
456
wc.lpszMenuName = NULL; // 不需要菜单
457
wc.lpszClassName = "OpenG"; // 设定类名字
458
if (!RegisterClass(&wc)) // 尝试注册窗口类
459
{
460
MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION);
461
return FALSE; // 退出并返回FALSE
462
}
463
if (fullscreen) // 要尝试全屏模式吗?
464
{
465
DEVMODE dmScreenSettings; // 设备模式
466
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 确保内存清空为零
467
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 结构的大小
468
dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度
469
dmScreenSettings.dmPelsHeight = height; // 所选屏幕高度
470
dmScreenSettings.dmBitsPerPel = bits; // 每象素所选的色彩深度
471
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
472
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
473
{
474
// 若模式失败,提供两个选项:退出或在窗口内运行。
475
if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
476
{
477
fullscreen=FALSE; // 选择窗口模式(Fullscreen=FALSE)
478
}
479
else
480
{
481
// 弹出一个对话框,告诉用户程序结束
482
MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP);
483
return FALSE; // 退出并返回 FALSE
484
}
485
}
486
}
487
if (fullscreen) // 仍处于全屏模式吗?
488
{
489
dwExStyle=WS_EX_APPWINDOW; // 扩展窗体风格
490
dwStyle=WS_POPUP; // 窗体风格
491
ShowCursor(FALSE); // 隐藏鼠标指针
492
}
493
else
494
{
495
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // 扩展窗体风格
496
dwStyle=WS_OVERLAPPEDWINDOW; // 窗体风格
497
}
498
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // 调整窗口达到真正要求的大小
499
if (!(hWnd=CreateWindowEx( dwExStyle, // 扩展窗体风格
500
"OpenG", // 类名字
501
title, // 窗口标题
502
WS_CLIPSIBLINGS | // 必须的窗体风格属性
503
WS_CLIPCHILDREN | // 必须的窗体风格属性
504
dwStyle, // 选择的窗体属性
505
0, 0, // 窗口位置
506
WindowRect.right-WindowRect.left, // 计算调整好的窗口宽度
507
WindowRect.bottom-WindowRect.top, // 计算调整好的窗口高度
508
NULL, // 无父窗口
509
NULL, // 无菜单
510
hInstance, // 实例
511
NULL))) // 不向WM_CREATE传递任何东东
512
{
513
KillGLWindow(); // 重置显示区
514
MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION);
515
return FALSE; // 返回 FALSE
516
}
517
518
static PIXELFORMATDESCRIPTOR pfd= // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式
519
{
520
sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小
521
1, // 版本号
522
PFD_DRAW_TO_WINDOW | // 格式支持窗口
523
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL
524
PFD_DOUBLEBUFFER, // 必须支持双缓冲
525
PFD_TYPE_RGBA, // 申请 RGBA 格式
526
bits, // 选定色彩深度
527
0, 0, 0, 0, 0, 0, // 忽略的色彩位
528
0, // 无Alpha缓存
529
0, // 忽略Shift Bit
530
0, // 无累加缓存
531
0, 0, 0, 0, // 忽略聚集位
532
16, // 16位 Z-缓存 (深度缓存)
533
0, // 无蒙板缓存
534
0, // 无辅助缓存
535
PFD_MAIN_PLANE, // 主绘图层
536
0, // Reserved
537
0, 0, 0 // 忽略层遮罩
538
};
539
if (!(hDC=GetDC(hWnd))) // 取得设备描述表了么?
540
{
541
KillGLWindow(); // 重置显示区
542
MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
543
return FALSE; // 返回 FALSE
544
}
545
546
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Windows 找到相应的象素格式了吗?
547
{
548
KillGLWindow(); // 重置显示区
549
MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
550
return FALSE; // 返回 FALSE
551
}
552
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // 能够设置象素格式么?
553
{
554
KillGLWindow(); // 重置显示区
555
MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);
556
return FALSE; // 返回 FALSE
557
}
558
if (!(hRC=wglCreateContext(hDC))) // 能否取得着色描述表?
559
{
560
KillGLWindow(); // 重置显示区
561
MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);
562
return FALSE; // 返回 FALSE
563
}
564
if(!wglMakeCurrent(hDC,hRC)) // 尝试激活着色描述表
565
{
566
KillGLWindow(); // 重置显示区
567
MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION);
568
return FALSE; // 返回 FALSE
569
}
570
571
ShowWindow(hWnd,SW_SHOW); // 显示窗口
572
SetForegroundWindow(hWnd); // 略略提高优先级
573
SetFocus(hWnd); // 设置键盘的焦点至此窗口
574
ReSizeGLScene(width, height); // 设置透视 GL 屏幕
575
576
if (!InitGL()) // 初始化新建的GL窗口
577
{
578
KillGLWindow(); // 重置显示区
579
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
580
return FALSE; // 返回 FALSE
581
}
582
return TRUE; // 成功
583
}
584
585
586
LRESULT CALLBACK WndProc(
587
HWND hWnd, // 窗口的句柄
588
UINT uMsg, // 窗口的消息
589
WPARAM wParam, // 附加的消息内容
590
LPARAM lParam) // 附加的消息内容
591

{
592
switch (uMsg) // 检查Windows消息
593
{
594
case WM_ACTIVATE: // 监视窗口激活消息
595
{
596
if (!HIWORD(wParam)) // 检查最小化状态
597
{
598
active=TRUE; // 程序处于激活状态
599
}
600
else
601
{
602
active=FALSE; // 程序不再激活
603
}
604
605
return 0; // 返回消息循环
606
}
607
608
case WM_SYSCOMMAND: // 系统中断命令
609
{
610
switch (wParam) // 检查系统调用
611
{
612
case SC_SCREENSAVE: // 屏保要运行?
613
case SC_MONITORPOWER: // 显示器要进入节电模式?
614
return 0; // 阻止发生
615
}
616
break; // 退出
617
}
618
619
case WM_CLOSE: // 收到Close消息?
620
{
621
PostQuitMessage(0); // 发出退出消息
622
return 0; // 返回
623
}
624
625
case WM_KEYDOWN: // 有键按下么?
626
{
627
keys[wParam] = TRUE; // 如果是,设为TRUE
628
return 0; // 返回
629
}
630
631
case WM_KEYUP: // 有键放开么?
632
{
633
keys[wParam] = FALSE; // 如果是,设为FALSE
634
return 0; // 返回
635
}
636
637
case WM_SIZE: // 调整OpenGL窗口大小
638
{
639
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width,HiWord=Height
640
return 0; // 返回
641
}
642
}
643
// 向 DefWindowProc传递所有未处理的消息。
644
return DefWindowProc(hWnd,uMsg,wParam,lParam);
645
}
646
647
648
649
int WINAPI WinMain( HINSTANCE hInstance, // 当前窗口实例
650
HINSTANCE hPrevInstance, // 前一个窗口实例
651
LPSTR lpCmdLine, // 命令行参数
652
int nCmdShow) // 窗口显示状态
653

{
654
MSG msg; // Windowsx消息结构
655
BOOL done=FALSE; // 用来退出循环的Bool 变量
656
rtri = 0;
657
rquad= 0;
658
// 提示用户选择运行模式
659
//if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO)
660
{
661
fullscreen=FALSE; // FALSE为窗口模式
662
}
663
// 创建OpenGL窗口
664
if (!CreateGLWindow("My OpenGL程序框架",640,480,16,fullscreen))
665
{
666
return 0; // 失败退出
667
}
668
while(!done) // 保持循环直到 done=TRUE
669
{
670
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // 有消息在等待吗?异步查获
671
{
672
if (msg.message==WM_QUIT) // 收到退出消息?
673
{
674
done=TRUE; // 是,则done=TRUE
675
}
676
else // 不是,处理窗口消息
677
{
678
TranslateMessage(&msg); // 翻译消息
679
DispatchMessage(&msg); // 发送消息
680
}
681
}
682
else // 如果没有消息
683
{
684
// 绘制场景。监视ESC键和来自DrawGLScene()的退出消息
685
if (active) // 程序激活的么?
686
{
687
if (keys[VK_ESCAPE]) // ESC 按下了么?
688
{
689
done=TRUE; // ESC 发出退出信号
690
}
691
else // 不是退出的时候,刷新屏幕
692
{
693
DrawGLScene(); // 绘制场景
694
SwapBuffers(hDC); // 交换缓存 (双缓存)
695
if (keys['L'] && !lp) // L 键已按下并且松开了?
696
{
697
lp=TRUE; // lp 设为 TRUE
698
light=!light; // 切换光源的 TRUE/FALSE
699
lp=TRUE; // lp 设为 TRUE
700
light=!light; // 切换光源的 TRUE/FALSE
701
}
702
if (!keys['L']) // L键松开了么?
703
{
704
lp=FALSE; // 若是,则将lp设为FALSE
705
}
706
707
if (keys['F'] && !fp) // F键按下了么?
708
{
709
fp=TRUE; // fp 设为 TRUE
710
filter+=1; // filter的值加一
711
if (filter>2) // 大于2了么?
712
{
713
filter=0; // 若是重置为0
714
}
715
}
716
if (!keys['F']) // F键放开了么?
717
{
718
fp=FALSE; // 若是fp设为FALSE
719
}
720
721
722
if (keys[VK_PRIOR]) // PageUp按下了?
723
{
724
z-=0.2f; // 若按下,将木箱移向屏幕内部
725
}
726
if (keys[VK_NEXT]) // PageDown按下了么
727
{
728
z+=0.2f; // 若按下的话,将木箱移向观察者
729
}
730
731
if (keys[VK_UP]) // Up方向键按下了么?
732
{
733
xspeed-=0.01f; // 若是,减少xspeed
734
}
735
if (keys[VK_DOWN]) // Down方向键按下了么?
736
{
737
xspeed+=0.01f; // 若是,增加xspeed
738
}
739
if (keys[VK_RIGHT]) // Right方向键按下了么?
740
{
741
yspeed+=0.01f; // 若是,增加yspeed
742
}
743
if (keys[VK_LEFT]) // Left方向键按下了么?
744
{
745
yspeed-=0.01f; // 若是, 减少yspeed
746
}
747
}
748
}
749
750
if (keys[VK_F1]) // F1键按下了么?
751
{
752
keys[VK_F1]=FALSE; // 若是,使对应的Key数组中的值为 FALSE
753
KillGLWindow(); // 销毁当前的窗口
754
fullscreen=!fullscreen; // 切换 全屏 / 窗口 模式
755
// 重建 OpenGL 窗口
756
if (!CreateGLWindow("My OpenGL 程序框架",640,480,16,fullscreen))
757
{
758
return 0; // 如果窗口未能创建,程序退出
759
}
760
}
761
}
762
}
763
// 关闭程序
764
KillGLWindow(); // 销毁窗口
765
return (msg.wParam); // 退出程序
766
}
767
1
//Link:OpenGL32.lib GLu32.lib GLaux.lib2
#include <stdio.h>3
#include <windows.h> // Windows的头文件4
//#include <glew.h> // 包含最新的gl.h,glu.h库5
#include <gl\gl.h> 6
#include <gl\glu.h> 7
#include <gl/glaux.h>8

9
HGLRC hRC=NULL; // 窗口着色描述表句柄10
HDC hDC=NULL; // OpenGL渲染描述表句柄11
HWND hWnd=NULL; // 保存我们的窗口句柄12
HINSTANCE hInstance; // 保存程序的实例13
bool keys[256]; // 保存键盘按键的数组14
bool active=TRUE; // 窗口的活动标志,缺省为TRUE15
bool fullscreen=TRUE; // 全屏标志缺省,缺省设定成全屏模式16
GLfloat rtri; // 用于三角形的角度17
GLfloat rquad; // 用于四边形的角度18
//GLfloat xrot; // X 旋转量19
//GLfloat yrot; // Y 旋转量20
GLfloat zrot; // Z 旋转量21
//GLuint texture[1]; // 存储一个纹理22
BOOL light; // 光源的开/关23
BOOL lp; // L键按下了么?24
BOOL fp; // F键按下了么?25

26
GLfloat xrot; // X 旋转27
GLfloat yrot; // Y 旋转28
GLfloat xspeed; // X 旋转速度29
GLfloat yspeed; // Y 旋转速度30
GLfloat z=-5.0f; // 深入屏幕的距离31

32
GLuint filter; // 滤波类型33
GLuint texture[3]; // 3种纹理的储存空间34

35

GLfloat LightAmbient[]=
{ 0.1f, 0.1f, 0.5f, 1.0f }; // 环境光参数36

GLfloat LightDiffuse[]=
{ 1.0f, 1.0f, 1.0f, 1.0f }; // 漫射光参数37

GLfloat LightPosition[]=
{ 0.0f, 0.0f, 2.0f, 1.0f }; // 光源位置38

39

40
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // WndProc的定义41
AUX_RGBImageRec *LoadBMP(char *Filename) // 载入位图图象42


{43
FILE *File=NULL; // 文件句柄44
if (!Filename) // 确保文件名已提供45

{46
return NULL; // 如果没提供,返回 NULL47
}48
File=fopen(Filename,"r"); 49
if (File) // 文件存在么?50

{51
fclose(File); // 关闭句柄52
return auxDIBImageLoad(Filename); // 载入位图并返回指针53
}54
return NULL; // 如果载入失败,返回 NULL55
}56

57
int LoadGLTextures() // 载入位图(调用上面的代码)并转换成纹理58


{59
int Status=FALSE; // 状态指示器60
AUX_RGBImageRec *TextureImage[1]; // 创建纹理的存储空间61
memset(TextureImage,0,sizeof(void *)*1); // 将指针设为 NULL62

63
// 载入位图,检查有无错误,如果位图没找到则退出64
if (TextureImage[0]=LoadBMP("Images\\1.bmp"))65

{66
Status=TRUE; // 将 Status 设为 TRUE67
glGenTextures(1, &texture[0]); // 创建纹理68
// 使用来自位图数据生成 的典型纹理69
glBindTexture(GL_TEXTURE_2D, texture[0]);70
// 生成纹理71

/**///////////////////////////////////MyDraw3//////////////////////////////////////72
//glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, 73
// TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);74
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); // 线形滤波75
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); // 线形滤波76

77

78

/**////////////////////////////////////MyDraw4////////////////////////////////////79
// 创建 Nearest 滤波贴图80
glBindTexture(GL_TEXTURE_2D, texture[0]);81
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); 82
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); 83
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, 84
TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);85

86
// 创建线性滤波纹理87
glBindTexture(GL_TEXTURE_2D, texture[1]);88
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);89
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);90
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, 91
TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);92

93
// 创建 MipMapped 纹理94
glBindTexture(GL_TEXTURE_2D, texture[2]);95
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);96
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);97
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, 98
TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); 99
}100
if (TextureImage[0]) // 纹理是否存在101

{102
if (TextureImage[0]->data) // 纹理图像是否存在103

{104
free(TextureImage[0]->data); // 释放纹理图像占用的内存105
}106

107
free(TextureImage[0]); // 释放图像结构108
}109
return Status; // 返回 Status110
}111

112

113

114
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // 重置OpenGL窗口大小115


{116
if (height==0) // 防止被零除117

{118
height=1; // 将Height设为1119
}120

121
glViewport(0, 0, width, height); // 重置当前的视口122
glMatrixMode(GL_PROJECTION); // 选择投影矩阵123
glLoadIdentity(); // 重置投影矩阵124

125
// 设置视口的大小126
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);127

128
glMatrixMode(GL_MODELVIEW); // 选择模型观察矩阵129
glLoadIdentity(); // 重置模型观察矩阵130
}131

132
int InitGL(GLvoid) // 此处开始对OpenGL进行所有设置133


{134
135
if (!LoadGLTextures()) // 调用纹理载入子例程136

{137
return FALSE; // 如果未能载入,返回FALSE138
}139
glEnable(GL_TEXTURE_2D); //启用2D纹理映射140
glShadeModel(GL_SMOOTH); // 启用阴影平滑141
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // 黑色背景142
glClearDepth(1.0f); // 设置深度缓存143
glEnable(GL_DEPTH_TEST); // 启用深度测试144
glDepthFunc(GL_LEQUAL); // 所作深度测试的类型145
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // 告诉系统对透视进行修正146

147
//MyDraw4/////////////////////////////////148
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // 设置环境光149
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // 设置漫射光150
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // 设置光源位置151
glEnable(GL_LIGHT1); // 启用一号光源152

153

154

155
return TRUE; // 初始化 OK156
}157
void MyDraw1()158


{159
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存 160
161
glLoadIdentity(); // 重置当前的模型观察矩阵162
glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0 163
164
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转三角形165
glBegin(GL_TRIANGLES); // 绘制三角形166
glColor3f(1.0f,0.0f,0.0f); // 设置当前色为红色167
glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点168
glColor3f(0.0f,1.0f,0.0f); // 设置当前色为绿色169
glVertex3f(-1.0f,-1.0f, 0.0f); // 左下170
glColor3f(0.0f,0.0f,1.0f); // 设置当前色为蓝色171
glVertex3f( 1.0f,-1.0f, 0.0f); // 右下172
glEnd(); 173
174
glLoadIdentity(); // 重置模型观察矩阵 避免上面的旋转影响下面175
//glTranslatef(3.0f,0.0f,0.0f); // 右移3单位 也就是把(3.0f,0.0f,0.0f)当作原点176

177
glTranslatef(1.5f,0.0f,-6.0f); // 右移1.5单位,并移入屏幕 6.0178

179
glRotatef(rquad,1.0f,0.0f,0.0f); // 绕X轴旋转四边形180
glBegin(GL_QUADS); // 绘制正方形181
glColor3f(0.0f,1.0f,0.0f); // 设置当前色为绿色182
glVertex3f(-1.0f, 1.0f, 0.0f); // 左上183
glColor3f(0.0f,0.5f,1.0f); // 设置当前色为蓝色184
glVertex3f( 1.0f, 1.0f, 0.0f); // 右上185
glColor3f(1.0f,0.0f,1.0f); // 设置当前色为蓝色186
glVertex3f( 1.0f,-1.0f, 0.0f); // 左下187
glColor3f(0.0f,0.0f,1.0f); // 设置当前色为蓝色188
glVertex3f(-1.0f,-1.0f, 0.0f); // 右下189
glEnd(); // 正方形绘制结束 190

191

192
rtri+=0.2f; // 增加三角形的旋转变量193
rquad-=0.15f; // 减少四边形的旋转变量194
}195
void MyDraw2()196


{197
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存198
glLoadIdentity(); // 重置模型观察矩阵199
glTranslatef(-1.5f,0.0f,-7.0f); // 左移 1.5 单位,并移入屏幕 6.0200
glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转金字塔201

202
glBegin(GL_TRIANGLES); // 开始绘制金字塔的各个面203
glColor3f(1.0f,0.0f,0.0f); // 红色204
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (前侧面)205
glColor3f(0.0f,1.0f,0.0f); // 绿色206
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (前侧面)207
glColor3f(0.0f,0.0f,1.0f); // 蓝色208
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (前侧面)209

210
glColor3f(1.0f,0.0f,0.0f); // 红色211
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (右侧面)212
glColor3f(0.0f,0.0f,1.0f); // 蓝色213
glVertex3f( 1.0f,-1.0f, 1.0f); // 三角形的左下顶点 (右侧面)214
glColor3f(0.0f,1.0f,0.0f); // 绿色215
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (右侧面)216

217
glColor3f(1.0f,0.0f,0.0f); // 红色218
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (后侧面)219
glColor3f(0.0f,1.0f,0.0f); // 绿色220
glVertex3f( 1.0f,-1.0f, -1.0f); // 三角形的左下顶点 (后侧面)221
glColor3f(0.0f,0.0f,1.0f); // 蓝色222
glVertex3f(-1.0f,-1.0f, -1.0f); // 三角形的右下顶点 (后侧面)223

224
glColor3f(1.0f,0.0f,0.0f); // 红色225
glVertex3f( 0.0f, 1.0f, 0.0f); // 三角形的上顶点 (左侧面)226
glColor3f(0.0f,0.0f,1.0f); // 蓝色227
glVertex3f(-1.0f,-1.0f,-1.0f); // 三角形的左下顶点 (左侧面)228
glColor3f(0.0f,1.0f,0.0f); // 绿色229
glVertex3f(-1.0f,-1.0f, 1.0f); // 三角形的右下顶点 (左侧面)230
glEnd(); // 金字塔绘制结束231

232

233
glLoadIdentity();234
glTranslatef(1.5f,0.0f,-7.0f); // 先右移再移入屏幕235

236
glRotatef(rquad,1.0f,1.0f,1.0f); // 在XYZ轴上旋转立方体237

238
glBegin(GL_QUADS); // 开始绘制立方体239
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色240
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点 (顶面)241
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色242
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点 (顶面)243
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左下顶点 (顶面)244
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右下顶点 (顶面)245

246
glColor3f(1.0f,0.5f,0.0f); // 颜色改成橙色247
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右上顶点(底面)248
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色249
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左上顶点(底面)250
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色251
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(底面)252
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(底面)253
glColor3f(1.0f,0.0f,0.0f); // 颜色改成红色254
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的右上顶点(前面)255
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色256
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的左上顶点(前面)257
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色258
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的左下顶点(前面)259
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的右下顶点(前面)260
glColor3f(1.0f,1.0f,0.0f); // 颜色改成黄色261
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右上顶点(后面)262
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色263
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左上顶点(后面)264
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左下顶点(后面)265
glColor3f(0.0f,1.0f,0.0f); // 颜色改为蓝色266
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右下顶点(后面)267
268
glColor3f(0.0f,0.0f,1.0f); // 颜色改成蓝色269
glVertex3f(-1.0f, 1.0f, 1.0f); // 四边形的右上顶点(左面)270
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色271
glVertex3f(-1.0f, 1.0f,-1.0f); // 四边形的左上顶点(左面)272
glVertex3f(-1.0f,-1.0f,-1.0f); // 四边形的左下顶点(左面)273
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色274
glVertex3f(-1.0f,-1.0f, 1.0f); // 四边形的右下顶点(左面)275
276
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色277
glVertex3f( 1.0f, 1.0f,-1.0f); // 四边形的右上顶点(右面)278
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色279
glVertex3f( 1.0f, 1.0f, 1.0f); // 四边形的左上顶点(右面)280
glVertex3f( 1.0f,-1.0f, 1.0f); // 四边形的左下顶点(右面)281
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色282
glVertex3f( 1.0f,-1.0f,-1.0f); // 四边形的右下顶点(右面)283
glColor3f(1.0f,0.0f,1.0f); // 颜色改成紫罗兰色284
glEnd(); // 立方体绘制结束285

286
rtri+=0.2f; // 增加三角形的旋转变量287
rquad-=0.15f; // 减少四边形的旋转变量 288

289
}290
void MyDraw3()291


{292
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存293
glLoadIdentity(); // 重置当前的模型观察矩阵294
glTranslatef(0.0f,0.0f,-5.0f); // 移入屏幕 5 个单位295

296

297
glRotatef(xrot,1.0f,0.0f,0.0f); // 绕X轴旋转298
glRotatef(yrot,0.0f,1.0f,0.0f); // 绕Y轴旋转299
glRotatef(zrot,0.0f,0.0f,1.0f); // 绕Z轴旋转300

301
glBindTexture(GL_TEXTURE_2D, texture[0]); // 选择纹理302

303
glBegin(GL_QUADS);304
// 前面305
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的左下306
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的右下307
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右上308
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左上309
// 后面310
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右下311
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的右上312
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的左上313
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左下314
// 顶面315
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上316
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的左下317
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的右下318
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上319
// 底面320
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的右上321
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的左上322
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下323
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下324
// 右面325
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); // 纹理和四边形的右下326
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); // 纹理和四边形的右上327
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); // 纹理和四边形的左上328
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); // 纹理和四边形的左下329
// 左面330
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); // 纹理和四边形的左下331
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); // 纹理和四边形的右下332
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); // 纹理和四边形的右上333
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // 纹理和四边形的左上334
glEnd();335

336
xrot+=0.3f; // X 轴旋转337
yrot+=0.2f; // Y 轴旋转338
zrot+=0.4f; // Z 轴旋转339
} 340
void MyDraw4()341


{342
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕和深度缓存343
glLoadIdentity(); // 重置当前的模型观察矩阵344
glTranslatef(0.0f,0.0f,z); // 移入/移出屏幕 z 个单位345

346
glRotatef(xrot,1.0f,0.0f,0.0f); // 绕X轴旋转347
glRotatef(yrot,0.0f,1.0f,0.0f); // 绕Y轴旋转348

349
glBindTexture(GL_TEXTURE_2D, texture[filter]); // 选择由filter决定的纹理350

351
glBegin(GL_QUADS); // 开始绘制四边形352
// 前侧面353
glNormal3f( 0.0f, 0.0f, 1.0f); // 法线指向观察者354
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); 355
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); 356
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); 357
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 358
// 后侧面359
glNormal3f( 0.0f, 0.0f,-1.0f); // 法线背向观察者360
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 361
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 362
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); 363
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 364
// 顶面365
glNormal3f( 0.0f, 1.0f, 0.0f); // 法线向上366
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 367
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 368
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f); 369
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); 370
// 底面371
glNormal3f( 0.0f,-1.0f, 0.0f); // 法线朝下372
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 373
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 374
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); 375
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); 376
// 右侧面377
glNormal3f( 1.0f, 0.0f, 0.0f); // 法线朝右378
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f); 379
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f); 380
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); 381
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); 382
// 左侧面383
glNormal3f(-1.0f, 0.0f, 0.0f); // 法线朝左384
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f); 385
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); 386
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 387
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); 388
glEnd(); // 四边形绘制结束389
xrot+=xspeed; // xrot 增加 xspeed 单位390
yrot+=yspeed; // yrot 增加 yspeed 单位 391
}392

393
int DrawGLScene(GLvoid) // 从这里开始进行所有的绘制394


{395
MyDraw4();396
return TRUE; // 一切 OK397
}398
GLvoid KillGLWindow(GLvoid) // 正常销毁窗口399


{400

401
if (fullscreen) // 我们处于全屏模式吗?402

{403
ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面404
ShowCursor(TRUE); // 显示鼠标指针405
}406
if (hRC) // 我们拥有OpenGL渲染描述表吗?407

{408
if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表?409

{410
MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);411
}412
if (!wglDeleteContext(hRC)) // 我们能否删除RC?413

{414
MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);415
}416
hRC=NULL; // 将RC设为 NULL417
}418
if (hDC && !ReleaseDC(hWnd,hDC)) // 我们能否释放 DC?419

{420
MessageBox(NULL,"释放DC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);421
hDC=NULL; // 将 DC 设为 NULL422
}423
if (hWnd && !DestroyWindow(hWnd)) // 能否销毁窗口?424

{425
MessageBox(NULL,"释放窗口句柄失败。","关闭错误",MB_OK | MB_ICONINFORMATION);426
hWnd=NULL; // 将 hWnd 设为 NULL427
}428
if (!UnregisterClass("OpenG",hInstance)) // 能否注销类?429

{430
MessageBox(NULL,"不能注销窗口类。","关闭错误",MB_OK | MB_ICONINFORMATION);431
hInstance=NULL; // 将 hInstance 设为 NULL432
}433
}434

435
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)436


{437
GLuint PixelFormat; // 保存查找匹配的结果438
WNDCLASS wc; // 窗口类结构439
DWORD dwExStyle; // 扩展窗口风格440
DWORD dwStyle; // 窗口风格441
RECT WindowRect; // 取得矩形的左上角和右下角的坐标值442
WindowRect.left=(long)100; // 将Left 设为 0443
WindowRect.right=(long)width+WindowRect.left; // 将Right 设为要求的宽度444
WindowRect.top=(long)200; // 将Top 设为 0445
WindowRect.bottom=(long)height+WindowRect.top; // 将Bottom 设为要求的高度446
fullscreen=fullscreenflag; // 设置全局全屏标志447
hInstance = GetModuleHandle(NULL); // 取得我们窗口的实例448
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // 移动时重画,并为窗口取得DC449
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc处理消息450
wc.cbClsExtra = 0; // 无额外窗口数据451
wc.cbWndExtra = 0; // 无额外窗口数据452
wc.hInstance = hInstance; // 设置实例453
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // 装入缺省图标454
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // 装入鼠标指针455
wc.hbrBackground = NULL; // GL不需要背景456
wc.lpszMenuName = NULL; // 不需要菜单457
wc.lpszClassName = "OpenG"; // 设定类名字458
if (!RegisterClass(&wc)) // 尝试注册窗口类459

{460
MessageBox(NULL,"注册窗口失败","错误",MB_OK|MB_ICONEXCLAMATION);461
return FALSE; // 退出并返回FALSE462
}463
if (fullscreen) // 要尝试全屏模式吗?464

{465
DEVMODE dmScreenSettings; // 设备模式466
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 确保内存清空为零467
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 结构的大小468
dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度469
dmScreenSettings.dmPelsHeight = height; // 所选屏幕高度470
dmScreenSettings.dmBitsPerPel = bits; // 每象素所选的色彩深度471
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;472
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)473

{474
// 若模式失败,提供两个选项:退出或在窗口内运行。475
if (MessageBox(NULL,"全屏模式在当前显卡上设置失败!\n使用窗口模式?","NeHe G",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)476

{477
fullscreen=FALSE; // 选择窗口模式(Fullscreen=FALSE)478
}479
else480

{481
// 弹出一个对话框,告诉用户程序结束482
MessageBox(NULL,"程序将被关闭","错误",MB_OK|MB_ICONSTOP);483
return FALSE; // 退出并返回 FALSE484
}485
}486
}487
if (fullscreen) // 仍处于全屏模式吗?488

{489
dwExStyle=WS_EX_APPWINDOW; // 扩展窗体风格490
dwStyle=WS_POPUP; // 窗体风格491
ShowCursor(FALSE); // 隐藏鼠标指针492
}493
else494

{495
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // 扩展窗体风格496
dwStyle=WS_OVERLAPPEDWINDOW; // 窗体风格497
}498
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // 调整窗口达到真正要求的大小499
if (!(hWnd=CreateWindowEx( dwExStyle, // 扩展窗体风格500
"OpenG", // 类名字501
title, // 窗口标题502
WS_CLIPSIBLINGS | // 必须的窗体风格属性503
WS_CLIPCHILDREN | // 必须的窗体风格属性504
dwStyle, // 选择的窗体属性505
0, 0, // 窗口位置506
WindowRect.right-WindowRect.left, // 计算调整好的窗口宽度507
WindowRect.bottom-WindowRect.top, // 计算调整好的窗口高度508
NULL, // 无父窗口509
NULL, // 无菜单510
hInstance, // 实例511
NULL))) // 不向WM_CREATE传递任何东东512

{513
KillGLWindow(); // 重置显示区514
MessageBox(NULL,"不能创建一个窗口设备描述表","错误",MB_OK|MB_ICONEXCLAMATION);515
return FALSE; // 返回 FALSE516
}517

518
static PIXELFORMATDESCRIPTOR pfd= // /pfd 告诉窗口我们所希望的东东,即窗口使用的像素格式519

{520
sizeof(PIXELFORMATDESCRIPTOR), // 上述格式描述符的大小521
1, // 版本号522
PFD_DRAW_TO_WINDOW | // 格式支持窗口523
PFD_SUPPORT_OPENGL | // 格式必须支持OpenGL524
PFD_DOUBLEBUFFER, // 必须支持双缓冲525
PFD_TYPE_RGBA, // 申请 RGBA 格式526
bits, // 选定色彩深度527
0, 0, 0, 0, 0, 0, // 忽略的色彩位528
0, // 无Alpha缓存529
0, // 忽略Shift Bit530
0, // 无累加缓存531
0, 0, 0, 0, // 忽略聚集位532
16, // 16位 Z-缓存 (深度缓存)533
0, // 无蒙板缓存534
0, // 无辅助缓存535
PFD_MAIN_PLANE, // 主绘图层536
0, // Reserved537
0, 0, 0 // 忽略层遮罩538
};539
if (!(hDC=GetDC(hWnd))) // 取得设备描述表了么?540

{541
KillGLWindow(); // 重置显示区542
MessageBox(NULL,"不能创建一种相匹配的像素格式","错误",MB_OK|MB_ICONEXCLAMATION);543
return FALSE; // 返回 FALSE544
}545

546
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Windows 找到相应的象素格式了吗?547

{548
KillGLWindow(); // 重置显示区549
MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);550
return FALSE; // 返回 FALSE551
}552
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // 能够设置象素格式么?553

{554
KillGLWindow(); // 重置显示区555
MessageBox(NULL,"不能设置像素格式","错误",MB_OK|MB_ICONEXCLAMATION);556
return FALSE; // 返回 FALSE557
}558
if (!(hRC=wglCreateContext(hDC))) // 能否取得着色描述表?559

{560
KillGLWindow(); // 重置显示区561
MessageBox(NULL,"不能创建OpenGL渲染描述表","错误",MB_OK|MB_ICONEXCLAMATION);562
return FALSE; // 返回 FALSE563
}564
if(!wglMakeCurrent(hDC,hRC)) // 尝试激活着色描述表565

{566
KillGLWindow(); // 重置显示区567
MessageBox(NULL,"不能激活当前的OpenGL渲然描述表","错误",MB_OK|MB_ICONEXCLAMATION);568
return FALSE; // 返回 FALSE569
}570

571
ShowWindow(hWnd,SW_SHOW); // 显示窗口572
SetForegroundWindow(hWnd); // 略略提高优先级573
SetFocus(hWnd); // 设置键盘的焦点至此窗口574
ReSizeGLScene(width, height); // 设置透视 GL 屏幕575

576
if (!InitGL()) // 初始化新建的GL窗口577

{578
KillGLWindow(); // 重置显示区579
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);580
return FALSE; // 返回 FALSE581
}582
return TRUE; // 成功583
}584

585

586
LRESULT CALLBACK WndProc(587
HWND hWnd, // 窗口的句柄588
UINT uMsg, // 窗口的消息589
WPARAM wParam, // 附加的消息内容590
LPARAM lParam) // 附加的消息内容591


{592
switch (uMsg) // 检查Windows消息593

{594
case WM_ACTIVATE: // 监视窗口激活消息595

{596
if (!HIWORD(wParam)) // 检查最小化状态597

{598
active=TRUE; // 程序处于激活状态599
}600
else601

{602
active=FALSE; // 程序不再激活603
}604

605
return 0; // 返回消息循环606
}607

608
case WM_SYSCOMMAND: // 系统中断命令609

{610
switch (wParam) // 检查系统调用611

{612
case SC_SCREENSAVE: // 屏保要运行?613
case SC_MONITORPOWER: // 显示器要进入节电模式?614
return 0; // 阻止发生615
}616
break; // 退出617
}618

619
case WM_CLOSE: // 收到Close消息?620

{621
PostQuitMessage(0); // 发出退出消息622
return 0; // 返回623
}624

625
case WM_KEYDOWN: // 有键按下么?626

{627
keys[wParam] = TRUE; // 如果是,设为TRUE628
return 0; // 返回629
}630

631
case WM_KEYUP: // 有键放开么?632

{633
keys[wParam] = FALSE; // 如果是,设为FALSE634
return 0; // 返回635
}636

637
case WM_SIZE: // 调整OpenGL窗口大小638

{639
ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width,HiWord=Height640
return 0; // 返回641
}642
}643
// 向 DefWindowProc传递所有未处理的消息。644
return DefWindowProc(hWnd,uMsg,wParam,lParam);645
}646

647

648

649
int WINAPI WinMain( HINSTANCE hInstance, // 当前窗口实例650
HINSTANCE hPrevInstance, // 前一个窗口实例651
LPSTR lpCmdLine, // 命令行参数652
int nCmdShow) // 窗口显示状态653


{654
MSG msg; // Windowsx消息结构655
BOOL done=FALSE; // 用来退出循环的Bool 变量656
rtri = 0;657
rquad= 0;658
// 提示用户选择运行模式659
//if (MessageBox(NULL,"你想在全屏模式下运行么?", "设置全屏模式",MB_YESNO|MB_ICONQUESTION)==IDNO)660

{661
fullscreen=FALSE; // FALSE为窗口模式662
}663
// 创建OpenGL窗口664
if (!CreateGLWindow("My OpenGL程序框架",640,480,16,fullscreen))665

{666
return 0; // 失败退出667
}668
while(!done) // 保持循环直到 done=TRUE669

{670
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // 有消息在等待吗?异步查获671

{672
if (msg.message==WM_QUIT) // 收到退出消息?673

{674
done=TRUE; // 是,则done=TRUE675
}676
else // 不是,处理窗口消息677

{678
TranslateMessage(&msg); // 翻译消息679
DispatchMessage(&msg); // 发送消息680
}681
}682
else // 如果没有消息683

{684
// 绘制场景。监视ESC键和来自DrawGLScene()的退出消息685
if (active) // 程序激活的么?686

{687
if (keys[VK_ESCAPE]) // ESC 按下了么?688

{689
done=TRUE; // ESC 发出退出信号690
}691
else // 不是退出的时候,刷新屏幕692

{693
DrawGLScene(); // 绘制场景694
SwapBuffers(hDC); // 交换缓存 (双缓存)695
if (keys['L'] && !lp) // L 键已按下并且松开了?696

{697
lp=TRUE; // lp 设为 TRUE698
light=!light; // 切换光源的 TRUE/FALSE699
lp=TRUE; // lp 设为 TRUE700
light=!light; // 切换光源的 TRUE/FALSE701
}702
if (!keys['L']) // L键松开了么?703

{704
lp=FALSE; // 若是,则将lp设为FALSE705
}706

707
if (keys['F'] && !fp) // F键按下了么?708

{709
fp=TRUE; // fp 设为 TRUE710
filter+=1; // filter的值加一711
if (filter>2) // 大于2了么?712

{713
filter=0; // 若是重置为0714
}715
}716
if (!keys['F']) // F键放开了么?717

{718
fp=FALSE; // 若是fp设为FALSE719
}720

721

722
if (keys[VK_PRIOR]) // PageUp按下了?723

{724
z-=0.2f; // 若按下,将木箱移向屏幕内部725
}726
if (keys[VK_NEXT]) // PageDown按下了么727

{728
z+=0.2f; // 若按下的话,将木箱移向观察者729
}730

731
if (keys[VK_UP]) // Up方向键按下了么?732

{733
xspeed-=0.01f; // 若是,减少xspeed734
}735
if (keys[VK_DOWN]) // Down方向键按下了么?736

{737
xspeed+=0.01f; // 若是,增加xspeed738
}739
if (keys[VK_RIGHT]) // Right方向键按下了么?740

{741
yspeed+=0.01f; // 若是,增加yspeed742
}743
if (keys[VK_LEFT]) // Left方向键按下了么?744

{745
yspeed-=0.01f; // 若是, 减少yspeed746
}747
}748
}749
750
if (keys[VK_F1]) // F1键按下了么?751

{752
keys[VK_F1]=FALSE; // 若是,使对应的Key数组中的值为 FALSE753
KillGLWindow(); // 销毁当前的窗口754
fullscreen=!fullscreen; // 切换 全屏 / 窗口 模式755
// 重建 OpenGL 窗口756
if (!CreateGLWindow("My OpenGL 程序框架",640,480,16,fullscreen))757

{758
return 0; // 如果窗口未能创建,程序退出759
}760
}761
}762
}763
// 关闭程序764
KillGLWindow(); // 销毁窗口765
return (msg.wParam); // 退出程序766
}767


浙公网安备 33010602011771号