Bizarre VBO performance/deletion issues

I’ve spent the last several hours trying to figure out why after I call glBufferDataARB, if I delete the data I passed it, nothing is displayed. From my understanding I should be able to do this because the data should be safely copied into the card’s video memory. Here’s my code to build the VBOs:

void Hex2DPlot::BuildVBOs()
{  
    glGenBuffersARB( 1, &m_VBOVertices );		
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBOVertices );
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_vertices.size()*sizeof(GLdouble), &(m_vertices[0]), GL_STATIC_DRAW_ARB );
        
    glGenBuffersARB( 1, &m_VBOColors );		
    glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_VBOColors );	// Bind The Buffer
    glBufferDataARB( GL_ARRAY_BUFFER_ARB, m_colors.size()*sizeof(GLubyte), &(m_colors[0]), GL_STATIC_DRAW_ARB );

    // PROBLEM: I should be able to uncomment this but for some reason I can't
    //m_vertices.clear();
    //m_colors.clear();
}

Notice the commented out part there. Uncommenting it makes it so nothing is drawn (thus the problem). Here’s the code I use to draw:

void Hex2DPlot::DrawPlot()
{   
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_VBOVertices);
    glVertexPointer( 2, GL_DOUBLE, 0, (char *) NULL );
        
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, m_VBOColors);
    glColorPointer( 3, GL_UNSIGNED_BYTE, 0, (char *) NULL );
    
    glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertices.size() / 2);
     
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
}

I’ve been tearing my hair out trying to figure out why I can’t uncomment those two lines. I made a really weird discovery though. The call to DrawPlot normally happens inside a display list. When this is the case, the program chokes when glDrawArrays is called – it pauses there for about twenty seconds. But after that the calls to draw the list are very speedy and the scene draws just fine (this is assuming that the lines above are still commented out).

Now, if I don’t use a display list and just call DrawPlot every frame, drawing is terribly slow, but the scene appears instantly instead of choking for 20 seconds. I think this is somehow related, but I can’t figure it out.

Any ideas on why the weird performance load/render tradeoff or why I can’t uncomment those lines? :stuck_out_tongue:

Because you are using the m_vertices to get number of vertices in your call to glDrawArrays.

glDrawArrays(GL_TRIANGLE_STRIP, 0, m_vertices.size() / 2);

If you clear it, m_vertices.size() will be zero and nothing will be drawn.

Using elements that are not aligned on 4 bytes, like your colors, in vbo is very slow on ATI cards. If you use the display list, the driver probably reorganizes the geometry into supported format which is the pause you see.

The m_vertices is array of doubles? If it is not, you are uploading incorrect number values to the VBO (the same goes for colors being glubyte). However because your geometry is drawn, it probably is.

Komat, in the second quote, we can see he uses GL_DOUBLE for vertices and GL_UNSIGNED_BYTE for the colors. So, he’s surely using those types correctly.

Yeah Jengu when you have a problem that looks really ‘ununderstandable’, then the solution is, undoubtely, evident, but hidden somewhere.
See, yesterday I wanted to count how much cards I had in my 54 card set box. And I realized I had zero card… strange… This was just because they all were out of the box (I had played with them before !) :slight_smile:

Friendly.

DOH! I hate stupid one liner fixes. Thanks :slight_smile:

How do I align my color data to 4 bytes? I’m not actually sure what you mean. If you mean my color data isn’t a multiple of 4 bytes, I tried adding an alpha unsigned byte that’s always 255, and got about the same speed.

Also, I’m still having the weird problem where if the call to glDrawArrays is inside a display list there is a long stall, but if it’s outside then there isn’t.

Depending on your graphic hardware, DrawArrays can give quiete good result when inside a display list or not. I know on geforces, using vertex arrays and DrawArrays inside DL is not a hurt at all.
But, in another hand, doing so is a bit of non-sense. DL are compiled to give the best performance they could, and they won’t be faster whether you use vertex arrays or glBegin() commands since DrawArrays would be called just once, when compiling the DL.
Also, I could see you use VBO, then, I recommand you not to use display list anymore, or not to use VBO/vertex arrays anymore.

The choice is up to you.

How do I align my color data to 4 bytes? I’m not actually sure what you mean. If you mean my color data isn’t a multiple of 4 bytes, I tried adding an alpha unsigned byte that’s always 255, and got about the same speed.

Something like that. Since your VBO contains only colors, color data that is multiple of 4 bytes should suffice. First time I mis one thing: The doubles you are using for positions are also not natively supported in VBO on ATI cards (and likely on other cards as well) so the same speed problem like with unaligned colors applies to them, try to replace them with floats.


Also, I’m still having the weird problem where if the call to glDrawArrays is inside a display list there is a long stall, but if it’s outside then there isn’t.

The driver is likely doing some optimalization and format conversion to ensure that further rendering will be fast which is taking some time.

EDIT: Because your VBOs use STATIC_DRAW flag they are probably stored in video memory which is slow to read from CPU. When the driver creates that display list, it probably reads content of VBOs used by the draw call from the video memory which may explay why it takes so long.

Originally posted by jide:
Komat, in the second quote, we can see he uses GL_DOUBLE for vertices and GL_UNSIGNED_BYTE for the colors. So, he’s surely using those types correctly.

This is not what i meant. When I see array named like m_vertices I expect that each element of that array contains all position coordinates for one vertex and not that vertex is stored in two or three consecutive elements of that array.

Right, I didn’t understood it this way.