Proper teardown of VBOs

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
So, I optimized my mesh code last week in a separate test app to use vertex arrays ( in immediate mode, e.g., not VBOs ) to display the shadow volume and capping. In the test program, it works beautifully.

Now, my game engine uses VBOs for drawing terrain. Where the terrain (static) has a huge VBO representing the vertices, and "patches" maintain their own uploaded VBO indices arrays to draw their respective parts of the terrain. This also works beautifully.

When I integrated my new mesh code into the game, the shadows volumes ( vertex arrays ) 99.99% of the time draw *nothing* at all, the other 0.01% of the time they draw essentially random noise. If I switch it over to glVertex calls it works. On the other hand, if I keep the vertex array shadow volume implementation and turn *off* terrain drawing completely, the shadow volumes draw correctly.

In other words, the terrain class is not shutting down its VBOs correctly, or something to that effect. That said, the terrain class is calling glDisableClientState( GL_VERTEX_ARRAY ) and glDisableClientState( GL_INDEX_ARRAY ) after its done drawing.

Here's snippets from my terrain draw method:

Code:
    /*
        Upload vertices
    */
    if ( _vboSupported )
    {
        /*
            Take lazy upload approach
        */
        if ( !_vboLoaded )
        {
            _uploadVBOs();
        }
    
        glEnableClientState( GL_VERTEX_ARRAY );
        glBindBufferARB( GL_ARRAY_BUFFER_ARB, _vertexBufferID );
        glVertexPointer( 3, GL_FLOAT, 0, 0 );        
    }
    else
    {    
        glEnableClientState( GL_VERTEX_ARRAY );
        glVertexPointer( 3, GL_FLOAT, 0, _vertices );
    }
        
    /*
        Draw!
    */
    for ( int i = 0; i < _numRootPatches; i++ )
        _rootPatches[i].draw( cameraPos );

    /*
        Turn off VBO
    */
    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_INDEX_ARRAY );

and a snippet from my patch drawing code:

Code:
void RootPatch::draw( GLvector4f cameraPos )
{
    if ( !BoxInFrustum( pos[0], pos[1], pos[2],
                        size[0], size[1], size[2] )) return;

    if ( !vboSupported )
    {        
        glDrawElements( GL_TRIANGLES, iCount,
                        GL_UNSIGNED_INT, condensedIndices );
    }
    else
    {
        /*
            Otherwise, VBOs are supported, so lets upload
            our index array ( first time only ) and subsequently
            just call that.
        */
        if ( !indexBufferID )
        {
            glGenBuffersARB(1, &indexBufferID);
            glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, indexBufferID);
            glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, iCount * sizeof(int), condensedIndices, GL_STATIC_DRAW_ARB);
            glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
        }
    
        glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, indexBufferID );

        glDrawElements( GL_TRIANGLES, iCount,
                        GL_UNSIGNED_INT, 0L );
    
    }    
}

And here's my shadow volume code:

Code:
void Geometry::drawShadowVolume( void )
{
    glEnableClientState( GL_VERTEX_ARRAY );

    glVertexPointer( 3, GL_FLOAT, 0, _shadowVolumePoints );
    glDrawArrays( GL_QUADS, 0, _shadowVolumeTop );

    glDisableClientState( GL_VERTEX_ARRAY );
    
    /*
        Caps need to be pushed *backwards* in depth buffer so
        as to eliminate z-fighting with occluder geometry
    */

    glEnable( GL_POLYGON_OFFSET_FILL );
    glPolygonOffset( 1.0, 1.0 );
    
    glEnableClientState( GL_VERTEX_ARRAY );
    glVertexPointer( 3, GL_FLOAT, 0, _shadowCapPoints );
    glDrawArrays( GL_TRIANGLES, 0, _shadowCapTop );
    
    glDisable( GL_POLYGON_OFFSET_FILL );
    glDisableClientState( GL_VERTEX_ARRAY );
}

Can anybody tell what's going on here? I'm baffled.
Quote this message in a reply
Member
Posts: 79
Joined: 2002.08
Post: #2
Well, I can't comment on your code but from my own experience I found out that if you use VBO you must use it exlusively. In other words mixing plain vertex arrays and VBO's did not work. So if you want to draw something using arrays that is not in a VBO you need to completely disable all VBO stuff first. It's quite a long time ago I messed with this so I don't remember the details. But I decided to not use VBO for now because of those problems.

KenD

CodeBlender Software - http://www.codeblender.com
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #3
Did you submit a bug report?
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #4
Criminy! Hellfire! I think I'll post to mac-opengl to see if anybody there has some insight. If worse comes to worst I'll give a shot seeing how well my terrain draws as display-lists -- because the speedup of using vertex arrays for shadow volumes is significant.
Quote this message in a reply
Member
Posts: 79
Joined: 2002.08
Post: #5
OneSadCookie Wrote:Did you submit a bug report?

If you are asking me, no. I'm not even sure it's a bug, I just assumed that's the way it works and I just couldn't figure out how to do it correctly.

KenD

CodeBlender Software - http://www.codeblender.com
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #6
Is this consistent with behavior on other platforms? It seems to me that if it works this way also on windows and linux then it's by design. Otherwise it's clearly an Apple bug...
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  VBOs and Vertex Arrays in OpenGL not working Talyn 6 6,213 Jul 8, 2008 01:14 PM
Last Post: Fenris
  Text rendering problem with VBOs on myfeng 9 5,806 Feb 29, 2008 04:54 PM
Last Post: OneSadCookie
  GL_SELECT mode in VBOs myfeng 0 2,286 Feb 28, 2008 10:38 AM
Last Post: myfeng
  Trouble with VBOs TomorrowPlusX 17 9,156 May 4, 2007 05:26 PM
Last Post: OneSadCookie
  Will VBOs be faster than display lists for simple meshes? TomorrowPlusX 14 5,758 Nov 30, 2004 03:32 PM
Last Post: arekkusu