0
votes

I have a VAO with 3 VBOs, containing a model with vertexes, normals and texture coordinates.

I intend to change all the data in those VBOs quite often, roughly from a 500ms to a 20ms update frequency. The new model downloaded to the VBO can have less or more triangles than the previous one. So the buffer size will also change.

I'm not an expert in OpenGL so I would like some tips if possible on how to improve my code. For now, the program is implemented as follows:

glBindVertexArray(*vao);

if (mesh->HasPositions()) {
    glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
    glBufferData(
        GL_ARRAY_BUFFER,
        3 * *point_count * sizeof (GLfloat),
        points,
        GL_DYNAMIC_DRAW
        );
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);
    free(points); // free our temporary memory
}
if (mesh->HasNormals()) {
    glBindBuffer(GL_ARRAY_BUFFER, vbo_norm);
    glBufferData(
        GL_ARRAY_BUFFER,
        3 * *point_count * sizeof (GLfloat),
        normals,
        GL_DYNAMIC_DRAW
        );
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(2);
    free(normals); // free our temporary memory
}
if (mesh->HasTextureCoords(0)) {
    glBindBuffer(GL_ARRAY_BUFFER, vbo_tex);
    glBufferData(
        GL_ARRAY_BUFFER,
        2 * *point_count * sizeof (GLfloat),
        texcoords,
        GL_DYNAMIC_DRAW
        );
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(1);
    free(texcoords); // free our temporary memory
}

EDIT:

This current solution have the issue that the drawing is not what it should be.

If my first model is a big one (50Mb) and I load another one a bit smaller (25Mb) there's still a part of the previous model that is drawn.

If the first model is the small one (25Mb) and then I changed it for the big one (50Mb) the drawing isn't changed (or at least it doesn't seem to change). If I charge after an even smaller one (216kb) the drawing changes (but there's still a part remaining).

So I suppose there's something wrong with my VBO management?

1
20 ms is not that quick really, unless you are doing disk I/O then that might be unreasonable. 20 ms is 50 Hz (which means it might happen a little less than once every frame if you draw at 60 FPS); 500 ms is 2 Hz, easily manageable at any framerate. In any case, there is nothing wrong with this solution - it is actually common practice to allocate new storage for your buffer everytime you change data to avoid pipeline synchronization for commands still using the old data; a concept referred to as buffer orphaning. Is there something in particular you do not like about this design?Andon M. Coleman
I should maybe step back for a second and ask: do you ever reuse the old model data? If so, rather than recycling an old VBO you might consider simply creating multiple VBOs, one for each model.Andon M. Coleman
@Andon M. Coleman: Doesn't he need to use glBufferData with a NULL pointer, before the real call to glBufferData for the orphaning to be executed properly? What even happens to the old buffer data, when he just allocates it over and over again, never freeing it. Does OpenGL have any magical way of handling it?Elvithari
Considering you cannot actually free buffer object memory (using a dedicated command) in OpenGL, it is not an issue. When you call glBufferData (...) it allocates new storage and also effectively puts the old storage onto a list of memory to be freed (same applies to things like glTexImage2D (...) etc.). After no pending commands are using that old memory OpenGL can go about freeing it. The reason you would want to pass NULL when you orphan a buffer is if you are going to call glBufferSubData (...) one or more times later. In this case data is setup at the same time it is allocated.Andon M. Coleman
20ms is because the model is brought by an other computer via tcp. but actually with my curent solution i have an issue on what is drown, i'll edit the post to describe this issueuser3544665

1 Answers

0
votes

ok i found the issue

I was updating vbo data in a thread. I didn't know that it doesn't work :/