3
\$\begingroup\$

My drawing code currently draws by calling glVertex3f(x, y, z) for each of my object's vertexes, and I've been suggested to use VBO as it'd enhance the performance of my drawing code.

After checking how VBOs works, it seems I need to pass a float array of the vertexes I'm going to draw, and this is a problem.

My object class looks like this:

class Vertex
{
    public:
        float positionX, positionY, positionZ;
        //more stuff
}
class Object3D
{
    public:
        //bunch of stuff
    private:
        Vertex* vertexes;
}

So when I create and load a new Object3D, I have an array of Vertex with the positions. If I were to pass a float array, I would need to:

void Graphics::Draw(Object3D* object)
{
    float* vertexArray = new float[object->totalVertexes];

    //fill vertexArray, send it to the card

    delete[] vertexArray;
}

Do I need to do this every frame, or just once (and I just call glDrawArrays() after it's loaded)?

Do I use VBOs on models that will be constantly changing, such as a character, or just for static objects? (If I were to use, I'd have to call the above code every frame, wouldn't it be a bad idea?)

Also, should I separate VBOs by objects, or just group them up by what's changing or not? (For example, I create 1 VBO ID that holds all my terrain and non-animated objects, or should I create 1 VBO ID for each object on my screen?)

\$\endgroup\$
1

1 Answer 1

2
\$\begingroup\$

Functions such as glVertex are marked as deprecated in modern OpenGL and don't even exist in OpenGL ES, so indeed VBOs are preferred way of drawing static and dynamic objects.

If the data is not changing you don't need to send it to the GPU every frame - instead you do that once (e.g. at the beginning of the level) and when the time comes bind the right VBO and call the draw function.

If the model is being translated/rotated/scaled it usually makes more sense to pass a model transform matrix to to the shader and translate all the vertices there (and not to change the VBO every frame). If the model is really being transformed (the distances of vertices are being changed, new vertices are added...) and you can't/don't want to do that with a geometry shader, then update the VBO. Usually you don't want to update the whole VBO, so use functions glBufferSubData and glMapBuffer which can be more efficient.

I think you can group some static data together (terrain and different assets on it) but when doing so think about loading the data. If there's a lot of terrain, then pushing all the data on your GPU isn't the best idea.

\$\endgroup\$
1
  • \$\begingroup\$ Hmm I'm really changing the model vertexes for translation/rotation/scaling/animations so I guess I have a bunch of (re)work to do... though I'm really more worried about having to change my code to remove the "Vertex" class and use a float array instead for VBOs (so I don't have use twice the memory for vertexes). Thanks for the info! \$\endgroup\$
    – Danicco
    Mar 9, 2013 at 23:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .