纹理贴图:
// 列出所有不同顶点,根据索引读取
GLfloat verticesIndex[] = {
0.5, -0.5, 0.0f, 1.0f, 0.0f, //右下(x,y,z坐标 + s,t纹理)
-0.5, 0.5, 0.0f, 0.0f, 1.0f, //左上
-0.5, -0.5, 0.0f, 0.0f, 0.0f, //左下
0.5, 0.5, 0.0f, 1.0f, 1.0f, //右上
};
GLfloat textureVertices[] = {
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
};
GLuint indices[] = { // 注意索引从0开始!
0,1,2, // 第一个三角形
1,3,0 // 第二个三角形
};
- (void)configVBOs
{
//顶点数据缓存
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticesIndex), verticesIndex, GL_STATIC_DRAW);
GLuint indicesBuffer; //索引数组
glGenBuffers(1, &indicesBuffer); //申请一个标识符(索引数组buffer)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
//GL_STATIC_DRAW表示此缓冲区内容只能被修改一次,但可以无限次读取。
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
//开启对应的顶点属性
glEnableVertexAttribArray(GLKVertexAttribPosition); //顶点数组缓存
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 0);
//为vertex shader的Position和TexCoord0配置合适的值
glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 5, (GLfloat *)NULL + 3);
// 纹理顶点数据单独缓存
// GLuint bufferTexture;
// glGenBuffers(1, &bufferTexture);
// glBindBuffer(GL_ARRAY_BUFFER, bufferTexture);
// glBufferData(GL_ARRAY_BUFFER, sizeof(textureVertices), textureVertices, GL_STATIC_DRAW);
//
// //为vertex shader的Position和TexCoord0配置合适的值
// glEnableVertexAttribArray(GLKVertexAttribTexCoord0); //纹理
// glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, (GLfloat *)NULL);
}
对于定点位置的读取之后,设置纹理的顶点坐标,既可以进行组合读取,也可以进行单独缓存读取,建议组合读取。
//创建着色器效果
- (void)setupBaseEffect{
// GLKTextureLoader读取图片,创建纹理GLKTextureInfo
UIImage *imageTexture = [UIImage imageNamed:@"chunyu"];
//GLKTextureLoaderOriginBottomLeft 参数是避免纹理上下颠倒,原因是纹理坐标系和世界坐标系的原点不同。
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], GLKTextureLoaderOriginBottomLeft, nil];
//加载图片
GLKTextureInfo* textureInfo = [GLKTextureLoader textureWithCGImage:imageTexture.CGImage options:options error:nil];
// 创建着色器GLKBaseEffect,把纹理赋值给着色器
self.mEffect = [[GLKBaseEffect alloc] init];
self.mEffect.texture2d0.enabled = GL_TRUE;
self.mEffect.texture2d0.name = textureInfo.name;
}
着色器对纹理素材进行读取,既可以读取资源路径,也可以直接读取CGImage对象。
效果如下: