Buffer Objects and Speed

Started by
5 comments, last by V-man 15 years, 8 months ago
Hey all, So I'm planning on moving into the game industry and I figured the best way to get started would be to build a game. Toward that end I am teaching myself OpenGL out of the "OpenGL Super Bible(3rd edition)" and I just got through the chapter on buffer objects. It sets up a vertex array of 30,000 random(each frame) vertices in a sphere and draws them as points. It allows you to run it using regular vertex arrays or as a buffer object and it records the frames per second so you can see how much faster using a buffer object is. But it isn't. It's about 2% slower every time. Can anyone think of a good reason why? Here's the code:

// Switch between buffer objects and plain old vertex arrays
void SetRenderingMethod(void)
{
    if (useBufferObject)
    {
        glBindBuffer(GL_ARRAY_BUFFER, bufferID);
        // No stride, no offset
        glNormalPointer(GL_FLOAT, 0, 0);
        glVertexPointer(3, GL_FLOAT, 0, 0);

        if (!mapBufferObject)
        {
            if (animating)
            {
                glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(GLfloat) * 
                                numSphereVertices * 3, sphereVertexArray);
            }
            else
            {
                // If not animating, this gets called once
                // to establish new static buffer object
                glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 
                             numSphereVertices * 3, sphereVertexArray, 
                             GL_STATIC_DRAW);
            }
        }
    }
    else
    {
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glNormalPointer(GL_FLOAT, 0, sphereVertexArray);
        glVertexPointer(3, GL_FLOAT, 0, sphereVertexArray);
    }
}
By the way, if mapBufferObject is turned on then the buffer object is, well, mapped already and we don't have to copy it over.
Advertisement
The flag you are using is GL_STATIC_DRAW while you seem to be updating the data at every frame.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
That's true, but only when animating is turned off. When it's turned on is when I was looking at the frame rate decrease.

Thanks for the reply.
When you are animating, you could try to set the buffer using glBufferData once with the parameter GL_DYNAMIC_DRAW to indicate that this buffer will change often and then do the modifications using glBufferSubData per Frame.

The driver might choose a different type of memory for GL_DYNAMIC_DRAW where you can upload the data faster compared to GL_STATIC_DRAW.
Also, if you will be updating a VBO every frame, it is better to use 2 VBOs and ping pong. I've found this increases performance.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);
Quote:Original post by V-man
Also, if you will be updating a VBO every frame, it is better to use 2 VBOs and ping pong. I've found this increases performance.


Does that make it perform the update asynchronously?
Author Freeworld3Dhttp://www.freeworld3d.org
Quote:Original post by soconne
Does that make it perform the update asynchronously?


It's not asynchronous in the sense that PBOs are.
It is just for avoiding the stall. The GPU might be rendering from the first VBO so it is better for you to update the second VBO.
I was using glBufferData as recommended by some nVidia document but that wasn't giving the performance I wanted on ATI, so I implemented double VBOs.
Sig: http://glhlib.sourceforge.net
an open source GLU replacement library. Much more modern than GLU.
float matrix[16], inverse_matrix[16];
glhLoadIdentityf2(matrix);
glhTranslatef2(matrix, 0.0, 0.0, 5.0);
glhRotateAboutXf2(matrix, angleInRadians);
glhScalef2(matrix, 1.0, 1.0, -1.0);
glhQuickInvertMatrixf2(matrix, inverse_matrix);
glUniformMatrix4fv(uniformLocation1, 1, FALSE, matrix);
glUniformMatrix4fv(uniformLocation2, 1, FALSE, inverse_matrix);

This topic is closed to new replies.

Advertisement