Sign in to follow this  
noVum

Dynamic VBOs

Recommended Posts

In Direct3D, you can do this (Documentation example)
    // USAGE style 2
    // Reusing one vertex buffer for multiple objects
 
    // Determine the size of data to be moved into the vertex buffer.
    UINT nSizeOfData = nNumberOfVertices * m_nVertexStride;
 
    // No overwrite will be used if the vertices can fit into 
    //   the space remaining in the vertex buffer.
    DWORD dwLockFlags = D3DLOCK_NOOVERWRITE;
    
    // Check to see if the entire vertex buffer has been used up yet.
    if( m_nNextVertexData > m_nSizeOfVB - nSizeOfData )
    {
        // No space remains. Start over from the beginning 
        //   of the vertex buffer.
        dwLockFlags = D3DLOCK_DISCARD;
        m_nNextVertexData = 0;
    }
    
    // Lock the vertex buffer.
    BYTE* pBytes;
    if( FAILED( m_pVertexBuffer->Lock( (UINT)m_nNextVertexData, nSizeOfData, 
               &pBytes, dwLockFlags ) ) )
        return false;
    
    // Copy the vertices into the vertex buffer.
    memcpy( pBytes, pVertices, nSizeOfData );
    m_pVertexBuffer->Unlock();
 
    // Render the primitives.
    m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 
               m_nNextVertexData/m_nVertexStride, nNumberOfVertices/3)
 
    // Advance to the next position in the vertex buffer.
    m_nNextVertexData += nSizeOfData;
But AFAIK VBO doesn't have that "discard" flag. What is the best method of doing this with VBOs?

Share this post


Link to post
Share on other sites
Might be better in the OpenGL forum, but anyway... [smile]

Are you asking how you can rewrite a vertex buffer? Honestly, I'm not quite sure what glBufferData would do if you called it twice on the same buffer. I'm assuming though it would rewrite the buffer.

If you want more control over your buffers, look into mapping buffer objects. There are many good examples at the bottom of this page:
http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_buffer_object.txt

You can map a local pointer to the buffer and rewrite any part of it that you want. When you map it, as far as I know, it always returns a pointer to the beginning of the buffer.

Hope this is what you were asking.

Share this post


Link to post
Share on other sites
Quote:
Original post by noVum
But AFAIK VBO doesn't have that "discard" flag. What is the best method of doing this with VBOs?


I'm only guessing at what the 'discard' flag does, however I suspect the same useage in OpenGL would be;


glBindBuffer(GL_ARRAY_BUFFER_ARB,vertbuffer);
glBufferData(GL_ARRAY_BUFFER_ARB,sizeofbuffer, NULL,GL_STREAM_DRAW); // inform OGL we no longer care about this buffers content
ptrBuffer = glMapBuffer(GL_ARRAY_BUFFER_ARB,WRITE_ONLY_ARB); // make sure you ONLY use WRITE_ONLY_ARB if you want any sort of performance
// write data to buffer here
glUnMapBuffer(GL_ARRAY_BUFFER_ARB);



The call to glBufferData with a NULL pointer basically tells the drivers 'I dont need this buffers content any more, throw it away when the GPU is done with it', at which point the call to glMapBuffer() should/can return a pointer to a new block of data for you to write to without caring about having to sync the old and new data together.
I guess you could use a glBufferData or a glBufferSubData instead of a glMapBuffer/glUnmapBuffer pair.

This method of discarding a buffer should hold true for both NV and ATI hardware at least (its mentioned in the performance pdf in my sig as a way to improve reuse of VBOs)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this