Dynamic VBOs

Started by
1 comment, last by _the_phantom_ 19 years, 5 months ago
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?
Advertisement
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.
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 contentptrBuffer = 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 hereglUnMapBuffer(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)

This topic is closed to new replies.

Advertisement