如何在OpenGL Es 2.0中正确更新顶点数组? [英] How do I properly update a vertex array in OpenGL Es 2.0?

查看:183
本文介绍了如何在OpenGL Es 2.0中正确更新顶点数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在OpenGL 2.0中更新iOS上的顶点数组时,原始顶点数据停留在屏幕上 - 即第一次刷新是持久的(我向下发送到GPU的初始点集每帧渲染一次),但是第2次,第3次,第4次,第n次冲洗似乎都覆盖了相同的记忆。

When I update my vertex array on iOS in OpenGL 2.0, the original vertex data is staying on the screen -- ie the 1st flush is persistent (the initial set of points I sent down to the GPU gets rendered every frame), but the 2nd, 3rd, 4th, .. nth flushes all seem to overwrite the same memory.

所以我在做:

vector<VertexType> rawDynamicData ;

glGenVertexArraysOES( 1, &va ) ;        CHECK_GL ;
glBindVertexArrayOES( va ) ;            CHECK_GL ;
glGenBuffers( 1, &vb ) ;                CHECK_GL ;
glBindBuffer( GL_ARRAY_BUFFER, vb ) ;   CHECK_GL ;

glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType ),
  &rawDynamicData[0],
  GL_DYNAMIC_DRAW  // I plan to update the data every frame
) ;  CHECK_GL ; 

在后续帧中,我只是再次呼叫:

On subsequent frames, I'm just calling again:

// update the data
glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType ),
  &rawDynamicData[0],
  GL_DYNAMIC_DRAW  // I plan to update the data every frame
) ;  CHECK_GL ; 

我也试过

//update the data
GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 
memcpy(vbo_buffer, &rawDynamicData[0], rawDynamicData.size()*sizeof(VertexType) );
glUnmapBufferOES(GL_ARRAY_BUFFER); 

但是从这两方面来看,我得到了这个:

But with both ways, I get this:

白点是初始数据,红点是后续调用 glBufferData的结果

The white points were the initial data, and the red points are the result of subsequent calls to glBufferData

所以这个问题有几个关于OpenGL ES 2.0中动态vbos的部分:

So this question has a couple of parts regarding dynamic vbos in OpenGL ES 2.0:


  1. 创建动态顶点缓冲区的正确命令顺序是什么,其元素将完全在每一帧上更新

  1. What is the correct command order for creating a dynamic vertex buffer whose elements will be completely updated on every frame?

顶点缓冲区可以在帧之间增长吗?或者我是否必须刷新完全相同的大小?

Can the vertex buffer grow between frames? Or do I have to flush exactly the same size?

我知道使用客户端内存指针,你能在OpenGL ES 2.0中做到这一点(以避免使用memcpy)还是不赞成使用顶点缓冲区?

I know about using "client memory" pointers, can you do this in OpenGL ES 2.0 (to avoid the memcpy) or is that deprecated, should use vertex buffers exclusively?


推荐答案

Misfire#1



I找到这里的答案指向我使用 glSubBufferData 用于停放数组中的数据,并仅对初始分配使用 glBufferData 。最终这不起作用(如果vb太大,只会更新前3个元素),

Misfire #1

I found an answer here which pointed me to using glSubBufferData for parking data in the array, and to use glBufferData only for the initial allocation. Ultimately this did not work (if the vb was too big, only the first 3 elements would be updated),

所以,

glBufferData( glBufferData(
  GL_ARRAY_BUFFER, //Specifies the target buffer object.
  rawDynamicData.size() * sizeof( VertexType ),
  0, // NO INITIAL DATA
  GL_DYNAMIC_DRAW  // I plan to update the data every frame
) ;  CHECK_GL ; 

然后是第一个后续更新:

Then for the first and subsequent updates:

// Update the whole buffer
glBufferSubData(GL_ARRAY_BUFFER, 0,
  rawDynamicData.size()*sizeof(VertexType), &rawDynamicData[0]) ;

这似乎有效。

我唯一可以做的就是使用顶点缓冲区退出并使用客户端内存顶点数组

The only thing I could do to make it work was quit using vertex buffers and use client memory vertex arrays.

这看起来如下:

// do all your vertex attrib/glVertexAttrib enable commands:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPC), &debugPoints->data[0].pos.x) ;
CHECK_GL ;
glEnableVertexAttribArray(0);  CHECK_GL ;

// ..do glVertexAttrib* for all attributes you have..

// then just flush your draw command
glDrawArrays(GL_POINTS, 0, debugPoints->data.size());  

所以简而言之,我发现使用顶点缓冲区来动态数据要么挑战不受支持。

So in short, I have found that using vertex buffers for dynamic data is either challenging or not supported.

这篇关于如何在OpenGL Es 2.0中正确更新顶点数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆