C++ OpenGL缓冲区更新

C++ OpenGL缓冲区更新,c++,opengl,C++,Opengl,目前我正在编写一个模拟水的程序。以下是我执行的步骤: 创建水面-平面 创建VAO 创建顶点缓冲区对象,在其中存储法线和顶点 将指针绑定到此VBO 创建索引缓冲区对象 然后,我使用GLDraweElements渲染这个平面,然后调用update()函数来更改水面顶点的位置。之后,我调用glBufferSubData函数来更新顶点位置 当我这样做时,缓冲区没有改变,什么也不会发生 下面是代码片段: glGenBuffers(1, &vertexBuffer); glBindBuffer(GL

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

  • 创建水面-平面
  • 创建VAO
  • 创建顶点缓冲区对象,在其中存储法线和顶点
  • 将指针绑定到此VBO
  • 创建索引缓冲区对象
  • 然后,我使用GLDraweElements渲染这个平面,然后调用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(法线),上升速度,newY

    振荡器-这是一组振荡器结构


    我做错了什么?

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

    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()。

    在调用update之前,水渲染是否正确?是否清除颜色缓冲区/深度缓冲区/。。。再次调用draw之前?是的,水渲染正确,我清除颜色和深度缓冲区。在调用
    glBufferSubData
    之前,您是否绑定了正确的缓冲区?是的,您可以。绑定第一个缓冲区并更新它,然后绑定第二个缓冲区并更新它。绑定GL_数组_缓冲区不会影响VAO中设置的属性指针。但请注意,更新不是同步的,因为
    glBufferSubData()
    调用是同步的。在修改缓冲区内容之前,无需执行
    glFlush