在 OpenGL ES 2 中更新 VBO 的顶点
Posted
技术标签:
【中文标题】在 OpenGL ES 2 中更新 VBO 的顶点【英文标题】:Updating the vertices of a VBO in OpenGL ES 2 【发布时间】:2018-02-08 00:01:21 【问题描述】:如果我想更改 VBO 的顶点,是否必须重复以下代码中显示的过程,但使用新的顶点数组?
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vbo);
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
vertexBuffer.capacity() * BYTES_PER_FLOAT,
vertexBuffer, GLES20.GL_STATIC_DRAW);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
或者有没有更好、更有效的方法?我相信每次我想更改顶点时调用上面的代码都不会太理想。我感谢任何答案,谢谢。
【问题讨论】:
【参考方案1】:如果要更改现有缓冲区对象的数据,则应使用glBufferSubData
。 glBufferData
为缓冲区对象创建新的数据存储,glBufferSubData
更新缓冲区对象的数据存储。这避免了重新分配数据存储的成本。
见OpenGL ES 2.0 Full Specification, 2.9. BUFFER OBJECTS, page 24:
BufferData
删除任何现有的数据存储,并设置缓冲区的值 对象的状态变量如表........
要修改缓冲区对象的数据存储中包含的部分或全部数据,客户端可以使用命令
void BufferSubData( enum target, intptr offset, sizeiptr size, const void *data );
此外,您应该根据需要设置glBufferData
的usage
参数。
见OpenGL ES 2.0 Full Specification, 2.9. BUFFER OBJECTS, page 23:
void BufferData( enum target, sizeiptr size, const void *data, enum usage );
....
usage
被指定为三个枚举值之一,表示数据存储的预期应用程序使用模式。值是:
STATIC_DRAW
数据存储内容将由应用程序指定一次, 并多次用作GL绘图命令的来源。
DYNAMIC_DRAW
数据存储内容会被应用反复重新指定,多次作为GL绘图命令的来源。
STREAM_DRAW
数据存储内容将由应用程序指定一次,最多使用几次作为 GL 绘图命令的来源。
【讨论】:
...但要注意更新仍在使用的东西,否则您将获得大多数驱动程序的全部复制成本,即使使用glBufferSubData
。见community.arm.com/graphics/b/blog/posts/…
@Rabbid76 再次感谢您的帮助。如果顶点要经常更改,您认为是否值得创建 VBO?有没有比使用 VBO 更好的方法?
@LAD 常见且现代的方法是使用 VBO。但是你必须关注glBufferData
的最后一个参数,它可以是GL_STREAM_DRAW
、GL_STATIC_DRAW
或GL_DYNAMIC_DRAW
.以上是关于在 OpenGL ES 2 中更新 VBO 的顶点的主要内容,如果未能解决你的问题,请参考以下文章
Android OpenGL ES 2. 0 VBO 不渲染
iPhone Cheetah 3D OpenGL ES 顶点缓冲对象 (VBO) 示例