OpenGL缓冲区更新

4

目前我正在编写一个模拟水的程序,以下是我的步骤:

  1. 创建水面-平面。
  2. 创建VAO。
  3. 创建顶点缓冲对象,用于存储法线和顶点。
  4. 将指针绑定到该VBO。
  5. 创建索引缓冲对象。

然后我使用glDrawElements渲染这个平面,并调用update()函数来改变水面的顶点位置。之后我调用glBufferSubData函数来更新顶点位置。

当我这样做时 - 没有任何反应,好像缓冲区没有被改变。

下面是代码片段:

glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Oscillator) * nOscillators, oscillators, GL_DYNAMIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Oscillator), 0);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Oscillator), (const GLvoid*)12);
glEnableVertexAttribArray(0);  // Vertex position
glEnableVertexAttribArray(2);  // normals position

glGenBuffers(1, &indicesBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * nIndices, indices, GL_DYNAMIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indicesBuffer);
glBindVertexArray(0);

然后进行渲染:

glBindVertexArray(vaoHandle);
glDrawElements(GL_TRIANGLES, nIndices, GL_UNSIGNED_INT, 0); 
update(time);

更新功能:

//some calculations
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Oscillator) * nOscillators, oscillators);

振荡器 - 这是一种具有以下8个浮点数的结构:x、y、z(顶点位置)、nx、ny、nz(法线)、upSpeed、newY。

振荡器 - 这是一个振荡器结构的数组。

我做错了什么?


在调用更新之前,水是否正确呈现? - Andreas Brinck
您在再次调用绘制之前是否清除了颜色缓冲区/深度缓冲区/...? - Mircea Ispas
是的,水正确地渲染了,并且我清除了颜色和深度缓冲区。 - Shot
2
在调用 glBufferSubData 之前,您是否绑定了正确的缓冲区? - Andreas Brinck
谢谢 - 现在它可以工作了 :) :D 我能同时更新多个缓冲区吗?我的意思是 - 首先我更新水面顶点位置缓冲区,然后我更新粒子位置缓冲区。 - Shot
1
可以的。首先绑定第一个缓冲区并更新它,然后绑定第二个缓冲区并更新它。绑定GL_ARRAY_BUFFER不会影响在VAO中设置的属性指针。但请注意,由于glBufferSubData()调用是同步的,因此更新不是同时进行的。 - Oleg Titov
1个回答

1

在更新数据之前,您需要绑定正确的缓冲区。例如:

glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

由于您一次性更新整个缓冲区,我建议使用glMapBuffer来进行更新。

void* data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
//[...] update the buffer with new values
bool done = glUnmapBuffer(GL_ARRAY_BUFFER);

请记得在修改要复制到gl缓冲区的数据之前等待(或强制执行)glFlush()。


在修改缓冲区内容之前,不需要执行glFlush - Nicol Bolas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接