-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCube.cpp
More file actions
240 lines (215 loc) · 6.88 KB
/
Cube.cpp
File metadata and controls
240 lines (215 loc) · 6.88 KB
1
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
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
#include "Cube.h"
#include <stdio.h>
#include <Windows.h>
Cube::Cube(float x, float y, float z, float size, GLuint top, GLuint bot, GLuint side)
:_x(x), _y(y), _z(z), _size(size), _top(top), _bot(bot), _side(side)
{
}
Cube::~Cube()
{
}
// 检查一个整数是否为2的整数次方,如果是,返回1,否则返回0
int Cube::power_of_two(int n)
{
if (n <= 0)
return 0;
return ((n & (n - 1)) == 0);
}
// 读取一个BMP文件作为纹理
GLuint Cube::load_texture(const char* file_name)
{
GLint width, height, total_bytes; //图片高宽和图片要分配的字节数
GLubyte *pixels = 0; // 指向图片数据的指针
GLuint last_texture_ID = 0, texture_ID = 0;
// 打开文件,如果失败,返回
FILE *pFile = fopen(file_name, "rb"); // rb表示读写
if (pFile == 0)
return 0;
// 读取文件中的图像高宽
fseek(pFile, 0x0012, SEEK_SET);
fread(&width, 4, 1, pFile);
fread(&height, 4, 1, pFile);
fseek(pFile, BMP_Header_Length, SEEK_SET);
// 计算每行像素所占的字节数,并根据此计算总像素字节数
{
GLint line_bytes = width * 3; // 为什么*3?
while (line_bytes % 4 != 0) // 使得字节总数为4的倍数,方便存储
++line_bytes;
total_bytes = line_bytes * height;
}
//根据总像素字节分配内存
pixels = (GLubyte*)malloc(total_bytes);
if (pixels == 0)
{
fclose(pFile);
return 0;
}
//读取像素数据
if (fread(pixels, total_bytes, 1, pFile) <= 0)
{
free(pixels);
fclose(pFile);
return 0;
}
// 在旧版本的OpenGL中
// 如果图象的宽度和高度不是的整数次方,则需要进行缩放
// 这里并没有检查OpenGL版本,出于对版本兼容性的考虑,按旧版本处理
// 另外,无论是旧版本还是新版本,
// 当图象的宽度和高度超过当前OpenGL实现所支持的最大值时,也要进行缩放
{
GLint max;
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max); // 得到最大纹理支持存储在max中
if (!power_of_two(width)
|| !power_of_two(height)
|| width > max
|| height > max)
{
const GLint new_width = 256;
const GLint new_height = 256; // 缩放后的正方形边长
GLint new_line_bytes, new_total_bytes;
GLubyte *new_pixels = 0;
//计算每行需要的字节数和总字节数
new_line_bytes = new_width * 3;
while (new_line_bytes % 4 != 0)
++new_line_bytes;
new_total_bytes = new_line_bytes * new_height;
// 分配内存
new_pixels = (GLubyte*)malloc(new_total_bytes);
if (new_pixels == 0)
{
free(pixels);
fclose(pFile);
return 0;
}
// 进行像素缩放
gluScaleImage(GL_RGB,
width, height, GL_UNSIGNED_BYTE, pixels,
new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);
// 释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height
free(pixels);
pixels = new_pixels;
width = new_width;
height = new_height;
}
}
// 分配一个新的纹理号
glGenTextures(1, &texture_ID);
if (texture_ID == 0)
{
free(pixels);
fclose(pFile);
return 0;
}
// 绑定新纹理,载入纹理并设置参数纹理
// 在绑定前,先获得原来绑定的纹理号,以便在最后进行恢复
GLint lid = last_texture_ID;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &lid);
glBindTexture(GL_TEXTURE_2D, texture_ID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);
glBindTexture(GL_TEXTURE_2D, last_texture_ID);
// 之前为pixels分配的内存可在使用glTexImage2D以后释放
// 因为此时像素数据已经被OpenGL另行保存了一份(可能被保存到专门的图形硬件中)
free(pixels);
return texture_ID;
}
void Cube::createCube()
{
float x = _x;
float y = _y;
float z = _z;
float size = _size;
//底面
glBindTexture(GL_TEXTURE_2D, _bot);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + size, y, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + size, y, z + size);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y, z + size);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z);
glEnd();
//侧面西
glBindTexture(GL_TEXTURE_2D, _side);
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + size, y, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + size, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + size, y + size, z);
glEnd();
//侧面东
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z + size);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + size, y, z + size);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + size, y + size, z + size);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + size, z + size);
glEnd();
//侧面南
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + size, y, z + size);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x + size, y, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x + size, y + size, z);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + size, y + size, z + size);
glEnd();
//侧面北
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x, y, z);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y, z + size);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + size, z + size);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x, y + size, z);
glEnd();
//顶面
glBindTexture(GL_TEXTURE_2D, _top);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f); glVertex3f(x, y + size, z);
glTexCoord2f(0.0f, 1.0f); glVertex3f(x, y + size, z + size);
glTexCoord2f(1.0f, 1.0f); glVertex3f(x + size, y + size, z + size);
glTexCoord2f(1.0f, 0.0f); glVertex3f(x + size, y + size, z);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}
//初始化材质
void Cube::initCubeTexture()
{
texRedStone = Cube::load_texture("img/redStone.bmp");
texGrass = Cube::load_texture("img/grass.bmp");
texSoil = Cube::load_texture("img/soil.bmp");
texStone = Cube::load_texture("img/stone.bmp");
texWater = Cube::load_texture("img/water.bmp");
texWood = Cube::load_texture("img/wood.bmp");
texDirt = Cube::load_texture("img/dirt.bmp");;
texBrick = Cube::load_texture("img/brick.bmp");
texTabletop = Cube::load_texture("img/tabletop.bmp");
texTableside = Cube::load_texture("img/tableside1.bmp");
texDiamond = Cube::load_texture("img/diamond.bmp");
texTnttop = Cube::load_texture("img/tnttop.bmp");
texTntside = Cube::load_texture("img/tntside.bmp");
texTreetop = Cube::load_texture("img/treetop.bmp");
texTreeside = Cube::load_texture("img/treeside.bmp");
texLeaf = Cube::load_texture("img/leaf.bmp");
texBookshelf = Cube::load_texture("img/bookshelf.bmp");
texRedSand = Cube::load_texture("img/redsand.bmp");
texSand = Cube::load_texture("img/sand.bmp");
}
GLuint Cube::texRedStone = 0;
GLuint Cube::texGrass = 0;
GLuint Cube::texSoil = 0;
GLuint Cube::texStone = 0;
GLuint Cube::texWater = 0;
GLuint Cube::texWood = 0;
GLuint Cube::texDirt = 0;
GLuint Cube::texBrick = 0;
GLuint Cube::texTabletop = 0;
GLuint Cube::texTableside = 0;
GLuint Cube::texDiamond = 0;
GLuint Cube::texTnttop = 0;
GLuint Cube::texTntside = 0;
GLuint Cube::texTreetop = 0;
GLuint Cube::texTreeside = 0;
GLuint Cube::texLeaf = 0;
GLuint Cube::texBookshelf = 0;
GLuint Cube::texRedSand = 0;
GLuint Cube::texSand = 0;