下面的方式windows和安卓下都可以使用
纹理的渲染
有了纹理对象且存储了图像数据后, 就可以拿来进行纹理渲染了.
使用时, 直接再次绑定GL_TEXTURE_2D即可, 表示接下来读取GL_TEXTURE_2D时要使用的是_textureID纹理对象中的数据:
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, _textureID);
glUniform1i(_textureSlot, 5);
纹理数据可以跟纹理坐标一一对应, 在OpenGL坐标中呈现出来.
GLfloat texCoords[] = {
0, 0,
1, 0,
0, 1,
1, 1,
};
glVertexAttribPointer(_textureCoordsSlot, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
glEnableVertexAttribArray(_textureCoordsSlot);
纹理坐标也同样存储于一个数组中, 使用glVertexAttribPointer方法将其传递给对应的插槽_textureCoordsSlot, 继而传递给Shader中的TextureCoords变量.
注意, 纹理坐标的坐标系与OpenGL不同, 左下角是原点.
有了纹理数据和纹理坐标, 接下来只需要我们已经很熟悉的顶点绘制方式将OpenGL画布绘制出来即可.
这里, 顶点坐标与纹理坐标的位置要一一对应, 即将图像的某个点绘制到OpenGL画布的对应点.
如果我们只是普通的渲染图片, 则将左下, 右下, 左上, 右上这四个点一一对应起来就好了.
GLfloat vertices[] = {
-1, -1, 0,
1, -1, 0,
-1, 1, 0,
1, 1, 0 };
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(_positionSlot);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindTexture(GL_TEXTURE_2D, 0);
[_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
这样, 使用OpenGLES来渲染一张图片的过程就结束了.
实际上, 准备好了纹理数据, 并且将纹理坐标传递给了Shader之后, 就不再需要对其进行操作了.
因此, 至于要不要使用VBO来优化顶点绘制的效率, 就是另外一回事了.
使用索引和VBO来绘制
那么, 既然如此, 再来回顾一下索引数组和VBO的使用吧.
const GLfloat vertices[] = {
-1, -1, 0,
1, -1, 0,
-1, 1, 0,
1, 1, 0 };
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(_positionSlot);
const GLubyte indices[] = {
0,1,2,
1,2,3
};
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glDrawElements(GL_TRIANGLE_STRIP, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_BYTE, 0);
说明:
安卓下,生成buffer方法如下:
package
com.android.gallery3d.glrenderer;
import
android.opengl.GLES20;
import
javax.microedition.khronos.opengles.GL11;
import
javax.microedition.khronos.opengles.GL11ExtensionPack;
public
class
GLES20IdImpl
implements
GLId {
private
final
int
[] mTempIntArray =
new
int
[
1
];
@Override
public
int
generateTexture() {
GLES20.glGenTextures(
1
, mTempIntArray,
0
);
GLES20Canvas.checkError();
return
mTempIntArray[
0
];
}