Problem updating the indices of a VBO

Hi I’m trying to update the VBOs of a VAO in my OpenGL application, I think that the “indexes” VBO updated is not working.

Here I show the update function that I’m using:

template <typename T>
void Update( GLuint vboId, GLenum vboType, Array <T> &source )
    GLvoid *buffer;

    if ( source.Len() )
        glBindBuffer( vboType, vboId );

        glBufferData( vboType, source.Size(), 0, GL_STATIC_DRAW );

        buffer = glMapBuffer( vboType, GL_WRITE_ONLY );

        if ( buffer )
        	// memcpy from source data to mapped buffer
            source.CopyTo( buffer );

            glUnmapBuffer( vboType );

            this->SetUpdated( true );
            Print( "WARNING: [GL_VBO::Update] Mapped pointer is null." );

        glBindBuffer( vboType, 0 );
    	Print( "WARNING: [GL_VBO::Update] Buffer is empty." );

The ‘vboType’ parameter that I pass to the function is GL_ELEMENT_ARRAY_BUFFER for “indexes” and GL_ARRAY_BUFFER for others things like “vertices”, “normals”, “uv”, etc

Update anything other than “indexes” works fine, but it seems that for indexes it’s not workig.

So I have a doubt if the function is wrong or if the problem is elsewhere in the code…


This will cause the buffer to be unbound after the function returns. For GL_ARRAY_BUFFER, it doesn’t matter; that binding only affects calls which refer to that target (e.g. glMapBuffer) and glVertexAttribPointer (which stores the current binding as part of the state for the attribute). But the GL_ELEMENT_ARRAY_BUFFER binding is stored in the current VAO and the stored binding is used for draw calls which use an element array (glDrawElements etc). So if you remove the binding, those draw calls won’t work.

Thanks, I have removed that line, and the update still doesn’t work.

Is the rest of the code right?

Buffer objects are not inherently typed. It does not matter what binding point you use if all you’re doing is manipulating their storage. The binding point only matters when you’re about to use them in some rendering process.

The purpose of this function is to modify their storage. As such, this function should just use GL_ARRAY_BUFFER, or any other innocuous binding like GL_COPY_READ_BUFFER.

This is important because GL_ELEMENT_ARRAY_BUFFER is special. It is part of the VAO state, so in order to bind to that target you must first have a VAO bound to the context. Otherwise, you will get (in core OpenGL) an OpenGL error for any functions that attempt to act on this binding point.

So just change the function to bind to an innocuous binding point to upload data to it (it shouldn’t take a target), then bind it as an index buffer when you’re building your VAO.

Sorry but I don’t understand, the VAO is already built, I am trying to update a VBO of it, in this case where the ‘indexes’ are stored.

If you use GL_ELEMENT_ARRAY_BUFFER as the target, the correct VAO needs to be bound before calling that function, as that particular binding is stored within the VAO (all other buffer bindings are part of the context). If no VAO is bound, the behaviour is unspecified. If the wrong VAO is bound, you’ve just changed the element buffer for that VAO.

As Alfonse says, there’s no reason to use any specific target if you’re just updating the buffer’s contents, and a good reason not to use GL_ELEMENT_ARRAY_BUFFER specifically. Just use GL_COPY_READ_BUFFER or GL_COPY_WRITE_BUFFER, as those don’t have any specific use; they exist solely as targets to which buffers can be bound for read/write/copy. Or, if you’re using OpenGL 4.5 (or the ARB_direct_state_access extension), you can use the *NamedBuffer* functions instead (glNamedBufferData, glMapNamedBuffer, glUnmapNamedBuffer).