学习之路系列
上篇文章在最后提了一下, 给立方体添加纹理, 下面就来实现下那个效果。
本篇主要内容
立方体纹理贴图
效果图
实现过程
这里把上篇文章的效果拷贝过来,直接在上面进行添加纹理
static const float Texture[] = {
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
};
上期的顶点坐标为8个, 前面和后面各4个, 纹理坐标我们也对应的设置为前面和后面各4个
在compileShaders
方法中新增下面代码
//获取着色器中的纹理变量
_textureSlot = glGetAttribLocation(_program, "TexCoordIn");
glEnableVertexAttribArray(_textureSlot);
//获取纹理单元
_textureUniform = glGetUniformLocation(_program, "ourTexture");
//获取纹理对象
_texture = [TextureManager getTextureImageName:@"Texture3_1.png"];
在render:
中新增下面代码
//使用纹理单元
glActiveTexture(GL_TEXTURE0);
//绑定纹理对象
glBindTexture(GL_TEXTURE_2D, _texture);
//这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
glUniform1i(_textureUniform, 0);
当然着色器也需要修改一下
Texture3Vertex.glsl
如下
attribute vec4 Position;
attribute vec4 InColor;
varying vec4 OutColor;
uniform mat4 ModelView;
attribute vec2 TexCoordIn; //new
varying vec2 TexCoordOut; //new
void main(void){
OutColor = InColor;
gl_Position = ModelView * Position;
TexCoordOut = vec2(TexCoordIn.x, 1. - TexCoordIn.y); //new
}
Texture3Fragment.glsl
如下
varying lowp vec4 OutColor;
uniform sampler2D ourTexture; //new
varying lowp vec2 TexCoordOut; //new
void main(void){
// gl_FragColor = OutColor;
gl_FragColor = texture2D(ourTexture, TexCoordOut); //modify
}
如果设置纹理这一块还有小伙伴不明白的话,可以看下前面的这篇文章
运行看下效果
发现一个问题,就只有两面有图案 前面
和后面
.
我在前面的文章中提到过纹理坐标是(0,0)
到(1,1)
看了下刚才设置的纹理坐标,只有前面
和后面
满足这个要求
为了让大家更直观更容易的理解,每个面弄4
个坐标,4 x 6 == 24
个坐标
将下面顶点数据
//4个顶点(分别表示xyz轴)
static const float Vertices[] = {
//前面4个坐标
-0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
-0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
//后面4个坐标
-0.5, -0.5, -0.5,
0.5, -0.5, -0.5,
-0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
};
static const float Texture[] = {
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
};
修改为
//4个顶点(分别表示xyz轴)
static const float Vertices[] = {
//前面4个坐标
-0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
-0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
//后面4个坐标
-0.5, -0.5, -0.5,
0.5, -0.5, -0.5,
-0.5, 0.5, -0.5,
0.5, 0.5, -0.5,
//左边4个坐标
-0.5, -0.5, -0.5,
-0.5, -0.5, 0.5,
-0.5, 0.5, -0.5,
-0.5, 0.5, 0.5,
//右边4个坐标
0.5, -0.5, -0.5,
0.5, -0.5, 0.5,
0.5, 0.5, -0.5,
0.5, 0.5, 0.5,
//上边4个坐标
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
0.5, 0.5, 0.5,
-0.5, 0.5, 0.5,
//下边4个坐标
0.5, -0.5, -0.5,
-0.5, -0.5, -0.5,
0.5, -0.5, 0.5,
-0.5, -0.5, 0.5,
};
static const float Texture[] = {
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
0, 0,
1, 0,
0, 1,
1, 1,
};
绘制的索引数组也需要修改一下
static const GLubyte Indices[] = {
0, 1, 2,
2, 3, 1,
4, 5, 6,
6, 7, 5,
2, 3, 6,
6, 7, 3,
0, 1, 4,
4, 5, 1,
0, 4, 2,
2, 6, 4,
1, 5, 3,
3, 7, 5
};
修改为
static const GLubyte Indices[] = {
//前面
0, 1, 2,
2, 3, 1,
//后面
4, 5, 6,
6, 7, 5,
//左面
8, 9, 10,
10, 11, 9,
//右面
12, 13, 14,
14, 15, 13,
//上面
16, 17, 18,
18, 19, 17,
//下面
20, 21, 22,
22, 23, 21
};
运行看下效果
这样子6个面的渲染就出来了,就是如此的简单O(∩_∩)O哈哈~
接下来将6个面渲染成不同的画面
将compileShaders
中的单个纹理对象修改下
//获取纹理对象
_texture = [TextureManager getTextureImageName:@"Texture3_1.png"];
改成
//获取纹理对象
for(int i = 0; i < 6; i++) {
NSString *imageName = [NSString stringWithFormat:@"Texture3_%d.png", i + 1];
_texture[i] = [TextureManager getTextureImageName:imageName];
}
渲染里面的代码也需要修改下
//使用纹理单元
glActiveTexture(GL_TEXTURE0);
//绑定纹理对象
glBindTexture(GL_TEXTURE_2D, _texture);
//这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
glUniform1i(_textureUniform, 0);
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, Indices);
改成
for(int i = 0; i < 6; i++) {
//使用纹理单元
glActiveTexture(GL_TEXTURE0 + i);
//绑定纹理对象
glBindTexture(GL_TEXTURE_2D, _texture[i]);
//这里的参数要对应纹理单元(如果纹理单元为0,这里也要给0)
glUniform1i(_textureUniform, i);
GLubyte *p = (GLubyte *)&Indices[6*i];
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, p);
}