GLES中VA、VAO、VBO、EBO数据关系及绑定使用

1. OpenGL ES 2.+ 流程中,每次绘制时数据操作都有如下流程:

sharder代码中已定义顶点坐标和纹理坐标变量,并在GLES代码获取其变量location:posLoc、texLoc;

顶点着色器代码:

   "attribute vec4 aPosition;\n" +                // 顶点坐标
   "attribute vec4 aTextureCoord;\n" +       // 纹理坐标

GLES代码:

int positionLoc = GLES20.glGetAttribLocation(wrapper.cameraProgramId, "aPosition");
int textureCoordLoc = GLES20.glGetAttribLocation(wrapper.cameraProgramId, "aTextureCoord");

绘制时:

  1. 设置顶点坐标VA location: glVertexAttribPointer(positionLoc, size, type, normalized, stride, data);
  2. 设置纹理坐标VA location: glVertexAttribPointer(textureCoordLoc, size, type, normalized, stride,data);
    GLES20.glEnableVertexAttribArray(positionLoc);
    GLES20.glEnableVertexAttribArray(textureCoordLoc);
  3. 设置shader location参数
  4. 设置绘制索引数据(indices)引并绘制图像: glDrawElements(mode, indicesSize, type, indicesBuffer)
2.使用VAO优化绘制流程

  VBO将顶点信息放到GPU中,GPU在渲染时去缓存中取数据,二者中间的桥梁是GL-Context。GL-Context整个程序一般只有一个,所以如果一个渲染流程里有两份不同的绘制代码,GL-context就负责在他们之间进行切换。这也是为什么要在渲染过程中,在每份绘制代码之中会有glBindbuffer、glEnableVertexAttribArray、glVertexAttribPointer。那么优化的方法来了,把这些都放到初始化时候完成吧!VAO记录该次绘制所需要的所有VBO所需信息,把它保存到VBO特定位置,绘制的时候直接在这个位置取信息绘制。
  VAO的全名是Vertex Array Object,首先,它不是Buffer-Object,所以不用作存储数据;其次,它针对“顶点”而言,也就是说它跟“顶点的绘制”息息相关。(VAO和VA没有任何关系)
  VAO记录的是一次绘制中所需要的信息,这包括“数据在哪里glBindBuffer”、“数据的格式是怎么样的glVertexAttribPointer”、shader-attribute的location的启用glEnableVertexAttribArray。


OpenGL ES 3.+ 中, 使用VAO (VertexArrayObject)绑定VBO(VertexBufferObject)、EBO(ElementBufferObject,另作IBO,IndexBufferObject)的绘制流程:

sharder代码中,定义顶点坐标和纹理坐标变量及其变量location序号,并在GLES代码中通过location序号绑定到VAO内的VBO上

顶点着色器代码:

layout (location = 0) in vec3 aPos;      //opengl世界点坐标
layout (location = 1) in vec2 aTexCoord; //opengl纹理坐标

GLES代码
初始化 :

// 1.创建VAO(顶点数组对象)、VBO(顶点数据对象)、EBO(索引数据对象)
GLES32.glGenVertexArrays(,vao,);
GLES32.glGenBuffers(,vbo,);
GLES32.glGenBuffers(,ebo,);

// 绑定VAO并设置VBO、EBO数据,绑定VBO到顶点坐标location和纹理坐标location
GLES32.glBindVertexArray(vao);
// 绑定顶点VBO,类型为GL_ARRAY_BUFFER
GLES32.glBindBuffer(GLES32.GL_ARRAY_BUFFER, vbo);
GLES32.glBufferData(GLES32.GL_ARRAY_BUFFER, vertices.length * Float.BYTES, BufferUtils.floatToBuffer(vertices), GLES32.GL_STATIC_DRAW);
// 绑定索引EBO,类型为GL_ELEMENT_ARRAY_BUFFER
GLES32.glBindBuffer(GLES32.GL_ELEMENT_ARRAY_BUFFER, ebo);
GLES32.glBufferData(GLES32.GL_ELEMENT_ARRAY_BUFFER, index.length * Integer.BYTES, BufferUtils.intToBuffer(index), GLES32.GL_STATIC_DRAW);

// 按location序号绑定并启用VBO到顶点坐标VA location和纹理坐标VA location
GLES32.glVertexAttribPointer(0, 3, GLES32.GL_FLOAT, false, 5 * Float.BYTES, 0);
GLES32.glEnableVertexAttribArray(0);
GLES32.glVertexAttribPointer(1, 2, GLES32.GL_FLOAT, false, 5 * Float.BYTES, 3 * Float.BYTES);
GLES32.glEnableVertexAttribArray(1);

// 解除VAO绑定
GLES32.glBindVertexArray(0);
// 重置VBO,EBO
GLES32.glBindBuffer(GLES32.GL_ARRAY_BUFFER, 0);
GLES32.glBindBuffer(GLES32.GL_ELEMENT_ARRAY_BUFFER, 0);

绘制时 :

  1. 绑定VAO(VAO包含了当前绘制所需的信息):
    glBindVertexArray
  2. 设置 sharder location参数
  3. 绘制图像:
    glDrawElements(mode, indicesSize, type, offset)
  4. 解绑VAO:
    glBindVertexArray(0)

参考: https://www.cnblogs.com/BigFeng/p/5117311.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值