PDA

View Full Version : Updating opengl buffers after changing attributes of a mesh



qqtolene
06-04-2017, 08:14 AM
I am using opengl in order to visualize geometric deformations on 3d meshes. I am using a vao to draw the mesh. This is the code I use to setup the buffers and the vao

void setupDrawingBuffers()
{

glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(MyVertex),
&vertices[0], GL_DYNAMIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint),
&indices[0], GL_DYNAMIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex),
(GLvoid*)0);
glEnableVertexAttribArray(0);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex),
(GLvoid*)offsetof(MyVertex, Normal));
glEnableVertexAttribArray(1);

glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(MyVertex),
(GLvoid*)offsetof(MyVertex, Color));
glEnableVertexAttribArray(2);

glBindVertexArray(0);
}

After I do a transformation of the mesh data (deforming some vertices lets say) I want to update the buffers so the changes I did can be rendered. How do I correctly do that? Should I use glBufferSubData (https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glBufferSubData.xml) ?


What I tried:
1)After the deformation I called setupDrawingBuffers() but nothing was rendered on screen.
2)Instead of calling setupDrawingBuffers() after the deformation I called it in my rendering loop. That worked but it is obviously wrong since my setupDrawingBuffers function generates new buffers each time it is called which results in a memory leak on every rendering cycle.

Silence
06-04-2017, 10:17 AM
Yes you have the options to use glBufferSubData or to use glMapBuffer (https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/glMapBuffer.xml). Depending on various things (ie how often and how much of your buffer will change), one or the other method might be more suitable (fast enough).

Why your first attempt did not work is, I guess, because you create new buffers and the rendering part is still using the old buffer ?

GClements
06-04-2017, 04:13 PM
You can use glBufferData() if you want to replace the contents of the entire buffer. This may be faster than glBufferSubData() or glMapBuffer(), as it can use double-buffering (a new block of memory will be allocated and associated with the buffer ID, the old block will be freed once any pending commands have finished using it). Also, glMapBufferRange() provides more options than glMapBuffer(), many of which allow for performance improvements.

qqtolene
06-07-2017, 06:02 AM
If the rendering part is using the old buffers shouldn't I see the undeformed model?
My draw function is simply:


void Draw()
{
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
}

GClements
06-07-2017, 10:02 AM
If the rendering part is using the old buffers shouldn't I see the undeformed model?
Not if you've changed the buffers' contents by any means.

Rather than calling setupDrawingBuffers(), it should suffice to use just:



glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(MyVertex),
&vertices[0], GL_DYNAMIC_DRAW);