Android OpenGL ES VBO VAO应用

VBO即Vertex Buffer Object顶点缓冲区对象,OpenGL ES 3.0总是建议使用VBO,VBO的使用也比较简单,下面是VBO的基本用法:

        mVertexId = new int[2];
        GLES30.glGenBuffers(2, mVertexId, 0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVertexId[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, triangleCoords.length * 4, mVertexBuffer, GLES30.GL_STATIC_DRAW);
glGenBuffers分配n个缓冲区对象名称,并在mVBOId中返回它们。glGenBuffers返回的缓冲区对象名称是0以外的无符号整数。0值由OpenGL ES保留,不表示缓冲区对象。企图修改或者查询缓冲区对象0的缓冲区对象状态将产生一个错误。


glBindBuffer命令用于指定当前缓冲区对象。第一次通过调用glBindBuffer绑定缓冲区对象名称时,缓冲区对象以默认状态分配;如果分配成功,则分配的对象绑定为目标的当前缓冲区对象。


顶点数组数据或者元素数组数据存储用glBufferData命令创建和初始化。
glBufferData将根据size的值保留相应的数据存储。data参数可以NULL值,表示保留的数据存储不进行初始化。如果data是一个有效的指针,则其内容被复制到分配的数据存储。缓冲区对象数据存储的内容可以用glBufferSubData命令初始化或者更新


下面的效果是使用VBO绘制的三角形


下面的效果图是用glBufferSubData更新VBO的数据:


应用程序也可以将缓冲区对象数据存储映射到应用程序的地址空间。应用程序映射缓冲区而不使用glBufferData或者glBufferSubData加载数据有几个理由:
1.映射缓冲区可以减少应用程序的内存占用,因为可能只需要存储数据的一个副本。
2.在使用共享内存的架构上,映射缓冲区返回GPU存储缓冲区的地址空间的直接指针。通过映射缓冲区,应用程序可以避免复制步骤,从而实现更好的更新性能。


glMapBufferRange命令返回指向所有或者一部分(范围)缓冲区对象数据存储的指针。这个指针可以供应用程序使用,以读取或者更新缓冲区对象的内容。glUmmapBuffer命令用于指示更新已经完成和释放映射的指针。

下图为用glMapBufferRange更新数据:


另外还可以glFlushMappedBufferRange更新映射范围的一部分数据。


OpenGL ES 3.0还可以从一个缓冲区对象将数据完全复制到设备,这可用glCopyBufferSubData函数完成


这两个函数这里就不举例了。


顶点缓冲区对象优于客户顶点数组,因为它们能够减少CPU和GPU之间复制的数据量,从而获得更好的性能。在OpenGL ES 3.0中引入了一个新特性,使顶点数组的使用更加高效:顶点数组对象(VAO)。使用顶点缓冲区对象设置绘图操作可能需要多次调用glBindBuffer、glVertexAttribPointer和glEnableVertexAttribArray。为了更快地在顶点数组配置之间切换,OpenGL ES 3.0推出了顶点数组对象。VAO提供包含在顶点数组/顶点缓冲区对象配置之间切换所需要的所有状态的单一对象。


实际上,OpenGL ES 3.0中总是有一个活动的顶点数组对象。默认的顶点数组对象ID为0.

下面的代码为创建一个VAO

        mVAOId = new int[1];
        GLES30.glGenVertexArrays(1, mVAOId, 0);
        GLES30.glBindVertexArray(mVAOId[0]);


        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVertexId[0]);
        GLES30.glVertexAttribPointer(0, 3, GLES30.GL_FLOAT, false, 0, 0);
        GLES30.glEnableVertexAttribArray(0);

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, mVertexId[1]);
        GLES30.glVertexAttribPointer(1, 4, GLES30.GL_FLOAT, false, 0, 0);
        GLES30.glEnableVertexAttribArray(1);

        GLES30.glBindVertexArray(0);
然后就可以在onDrawFrame使用这个VAO:

        GLES30.glClear(GLES30.GL_COLOR_BUFFER_BIT);
        GLES30.glUseProgram(mProgram);

        GLES30.glUniformMatrix4fv(muMVPMatrixHandler, 1, false, MatrixUtil.getFinalMatrix(), 0);

        GLES30.glBindVertexArray(mVAOId[0]);
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, 3);
        GLES30.glBindVertexArray(0);
最后附上本篇文章例子的下载链接:

点击打开链接


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值