Android/windows 顶点对应方法(shader)

来源:互联网 发布:淘宝助理 csv excel 编辑:程序博客网 时间:2024/05/16 08:21

下面的方式windows和安卓下都可以使用

纹理的渲染

有了纹理对象且存储了图像数据后, 就可以拿来进行纹理渲染了. 
使用时, 直接再次绑定GL_TEXTURE_2D即可, 表示接下来读取GL_TEXTURE_2D时要使用的是_textureID纹理对象中的数据:

// 第一行和第三行不是严格必须的,默认使用GL_TEXTURE0作为当前激活的纹理单元glActiveTexture(GL_TEXTURE5); // 指定纹理单元GL_TEXTURE5glBindTexture(GL_TEXTURE_2D, _textureID); // 绑定,即可从_textureID中取出图像数据。glUniform1i(_textureSlot, 5); // 与纹理单元的序号对应
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

纹理数据可以跟纹理坐标一一对应, 在OpenGL坐标中呈现出来.

GLfloat texCoords[] = {    0, 0,//左下    1, 0,//右下    0, 1,//左上    1, 1,//右上};glVertexAttribPointer(_textureCoordsSlot, 2, GL_FLOAT, GL_FALSE, 0, texCoords);glEnableVertexAttribArray(_textureCoordsSlot);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

纹理坐标也同样存储于一个数组中, 使用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); // 使用完之后解绑GL_TEXTURE_2D[_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

这样, 使用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];
     
}

原创粉丝点击