如何在OpenGL Es 2.0中正确更新顶点数组?

bob*_*obo 11 vertex-buffer ios opengl-es-2.0

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

所以我在做:

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 ; 
Run Code Online (Sandbox Code Playgroud)

在随后的帧中,我只是再次打电话:

// 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 ; 
Run Code Online (Sandbox Code Playgroud)

我也试过了

//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); 
Run Code Online (Sandbox Code Playgroud)

但是通过这两种方式,我得到了这个:

在此输入图像描述

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

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

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

  2. 顶点缓冲区可以在帧之间增长吗? 或者我必须冲洗完全相同的尺寸?

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

bob*_*obo 6

失火#1

我在这里找到了一个答案,它指出我glSubBufferData用于数组中的停车数据,并glBufferData仅用于初始分配.最终这不起作用(如果vb太大,只会更新前3个元素),

所以,

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 ; 
Run Code Online (Sandbox Code Playgroud)

然后是第一次后续更新:

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

这似乎有效.

看起来.但事实并非如此.

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

这看起来如下:

// 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());  
Run Code Online (Sandbox Code Playgroud)

简而言之,我发现对动态数据使用顶点缓冲区要么具有挑战性,要么不受支持.

  • 你有没有想过这个?我遇到了同样的问题似乎工作,但事实并非如此. (2认同)
  • 我现在唯一使用VB的地方是模型__that加载一次___然后永远不会改变.它们在转换下很好,你只是不能改变_actual顶点data_而不会有什么奇怪的东西.对于可变形几何体,我使用顶点数组_only_.在绘制顶点数组之前,__确保用以下行禁用顶点缓冲区:__`glBindBuffer(GL_ARRAY_BUFFER,0); //禁用愚蠢的VERTEX BUFFER RAT POISON`.我之前也被绊倒了. (2认同)