OpenGL(七)-纹理(下)

绘制一个隧道

定义绘制批次类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
GLShaderManager		shaderManager;			//着色器管理器
GLMatrixStack modelViewMatrix; //模型视图矩阵
GLMatrixStack projectionMatrix; //投影矩阵
GLFrustum viewFrustum; //视景体
GLGeometryTransform transformPipeline; //几何变换管线

//4个批次容器类
GLBatch floorBatch;//地面
GLBatch ceilingBatch;//天花板
GLBatch leftWallBatch;//左墙面
GLBatch rightWallBatch;//右墙面

//深度初始值,-65。
GLfloat viewZ = -65.0f;

// 纹理标识符号
#define TEXTURE_BRICK 0 //墙面
#define TEXTURE_FLOOR 1 //地板
#define TEXTURE_CEILING 2 //纹理天花板
#define TEXTURE_COUNT 3 //纹理个数
GLuint textures[TEXTURE_COUNT];//纹理标记数组

//文件tag名字数组
const char *szTextureFiles[TEXTURE_COUNT] = { "brick.tga", "floor.tga", "ceiling.tga" };
初始化

floor.png
ceiling.png
leftWall.png
rightWall.png

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
//在这个函数里能够在渲染环境中进行任何需要的初始化,它这里的设置并初始化纹理对象
void SetupRC()
{
GLbyte *pBytes;
GLint iWidth,iHeight,iComponents;
GLenum eFormat;
GLint iLoop;

//背景
glClearColor(0.0f, 0.0f, 0.0f,1.0f);

shaderManager.InitializeStockShaders();

//1.加载纹理
/*
glGenTextures (GLsizei n, GLuint *textures)
参数1:n,纹理数量
参数2:textures,纹理对象标识数组
*/
glGenTextures(TEXTURE_COUNT, textures);

for (iLoop =0; iLoop < TEXTURE_COUNT; iLoop++) {

//2.绑定纹理
/*
glBindTexture (GLenum target, GLuint texture);
参数1:target,使用的纹理类型GL_TEXTURE_1D\GL_TEXTURE_2D\GL_TEXTURE_3D
参数2:texture,纹理的标记
*/

glBindTexture(GL_TEXTURE_2D, textures[iLoop]);


//3.加载tga文件
/*
GLbyte *gltReadTGABits(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat, GLbyte *pData);
参数1:szFileName 纹理文件的名称
参数2:iWidth 获取纹理文件的宽度
参数3:iHeight获取纹理文件的高度
参数4:iComponents获取纹理文件的组件
参数5:eFormat获取纹理文件的格式

返回值:指向图像数据的指针
*/
pBytes = gltReadTGABits(szTextureFiles[iLoop], &iWidth, &iHeight, &iComponents, &eFormat);

//放大过滤器
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//缩小过滤器
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//环绕方式--S
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
//环绕方式--T
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


//载入纹理
/*
glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
参数1:target,使用的纹理类型GL_TEXTURE_1D\GL_TEXTURE_2D\GL_TEXTURE_3D
参数2:level ,Mip贴图的层次
参数3:internalformat,纹理单元的颜色组成方式(从读取像素图中获得)
参数4:width
参数5:height
参数6:border
参数7:format
参数8:type,像素数据的数据类型-GL_UNSIGNED_BYTE
参数9:pixels,指向纹理图像数据的指针
*/
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);

//生成MIP图层
/*
参数1:GL_TEXTURE_1D\GL_TEXTURE_2D\GL_TEXTURE_3D
*/
glGenerateMipmap(GL_TEXTURE_2D);

free(pBytes);

}


//建立立体图像!!!
GLfloat z;

/*
void Begin(GLenum primitive, GLuint nVerts, GLuint nTextureUnits = 0);
参数1:绘图模式
参数2:顶点个数
参数3:纹理,默认等于0
*/
floorBatch.Begin(GL_TRIANGLE_STRIP, 28,1);//共绘制了7个四边形, 共28个顶点

//参考图 - floor.png
for (z = 60.0f; z >= 0.0f; z -= 10.0f) {

//指定顶点对应纹理的坐标
floorBatch.MultiTexCoord2f(0, 0, 0);
//指定左下角顶点
floorBatch.Vertex3f(-10.0f, -10.0f, z);


//指定右下角顶点以及纹理坐标
floorBatch.MultiTexCoord2f(0, 1, 0);
floorBatch.Vertex3f(10.0f, -10.0f, z);


//指定顶点对应纹理的坐标
floorBatch.MultiTexCoord2f(0, 0, 1.0f);
floorBatch.Vertex3f(-10.0f, -10.0f, z-10.0f);


//指定顶点对应纹理的坐标
floorBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
floorBatch.Vertex3f(10.0f, -10.0f, z-10.0f);


}

floorBatch.End();

//参考图- ceiling.png
ceilingBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
ceilingBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);

ceilingBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);

ceilingBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
ceilingBatch.Vertex3f(-10.0f, 10.0f, z);

ceilingBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
ceilingBatch.Vertex3f(10.0f, 10.0f, z);
}
ceilingBatch.End();

//参考图 - leftWall.png
leftWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
leftWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z);

leftWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z);

leftWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
leftWallBatch.Vertex3f(-10.0f, -10.0f, z - 10.0f);

leftWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
leftWallBatch.Vertex3f(-10.0f, 10.0f, z - 10.0f);
}
leftWallBatch.End();

//参考图 - rightWall.png
rightWallBatch.Begin(GL_TRIANGLE_STRIP, 28, 1);
for(z = 60.0f; z >= 0.0f; z -=10.0f)
{
rightWallBatch.MultiTexCoord2f(0, 0.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z);

rightWallBatch.MultiTexCoord2f(0, 0.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z);

rightWallBatch.MultiTexCoord2f(0, 1.0f, 0.0f);
rightWallBatch.Vertex3f(10.0f, -10.0f, z - 10.0f);

rightWallBatch.MultiTexCoord2f(0, 1.0f, 1.0f);
rightWallBatch.Vertex3f(10.0f, 10.0f, z - 10.0f);
}
rightWallBatch.End();

}
窗口设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//改变视景体和视口,在改变窗口大小或初始化窗口调用
void ChangeSize(int w, int h)
{
if (h == 0) {

h = 1;
}

glViewport(0, 0, w, h);

//透视投影纵横比
GLfloat fAspect;
fAspect = (GLfloat)w / (GLfloat)h;

//设置透视投影
viewFrustum.SetPerspective(80.0f, fAspect, 1.0, 120.0);

//获取到投影矩阵
projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());

//通过变换管线来管理投影矩阵堆栈
transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);

}
调用,绘制场景
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
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);

modelViewMatrix.PushMatrix();

modelViewMatrix.Translate(0.0f, 0.0f, viewZ);

//纹理替换矩阵着色器
/*
参数1:GLT_SHADER_TEXTURE_REPLACE
参数2:模型视图矩阵 & 投影矩阵
参数3:纹理层次
*/
shaderManager.UseStockShader(GLT_SHADER_TEXTURE_REPLACE,transformPipeline.GetModelViewProjectionMatrix(),0);

//地板
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_FLOOR]);
floorBatch.Draw();

//天花板
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_CEILING]);
ceilingBatch.Draw();

//左右墙壁
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BRICK]);
leftWallBatch.Draw();
rightWallBatch.Draw();

modelViewMatrix.PopMatrix();

glutSwapBuffers();



}
效果图

image.png

谢谢你赏我糖果吃