TAGS :Viewed: 7 - Published at: a few seconds ago

[ Correct use of glCopyBufferSubData ]

This is a followup to this question.

I have set up my Copy Constructor like this:

glGenBuffers(1, &m_vertexBuffer);
glGenBuffers(1, &m_colorBuffer);
glGenBuffers(1, &m_indexBuffer);
glGenVertexArrays(1, &m_vertexArray);

glBindVertexArray(m_vertexArray);

GLint size = 0;

glBindBuffer(GL_COPY_READ_BUFFER, other.m_indexBuffer);
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
glCopyBufferSubData(other.m_indexBuffer, m_indexBuffer, 0, 0, size);

glBindBuffer(GL_COPY_READ_BUFFER, other.m_vertexBuffer);
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
glBindBuffer(GL_ARRAY_BUFFER, m_vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
glCopyBufferSubData(other.m_vertexBuffer, m_vertexBuffer, 0, 0, size);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *) 0);
glEnableVertexAttribArray(0);

glBindBuffer(GL_COPY_READ_BUFFER, other.m_colorBuffer);
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
glBindBuffer(GL_ARRAY_BUFFER, m_colorBuffer);
glBufferData(GL_ARRAY_BUFFER, size, nullptr, GL_STATIC_DRAW);
glCopyBufferSubData(other.m_colorBuffer, m_colorBuffer, 0, 0, size);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void *) 0);
glEnableVertexAttribArray(1);

glBindVertexArray(0);  

However, size is 0 after the first glGetBufferParameteriv call. Does it work differently on index buffers? Am I missing something?

Answer 1


You do not pass the actual buffer object names to glCopyBufferSubData (...), you pass the enum for the location the buffer objects are bound to. Interestingly, there is no error state defined for what you tried to do, but realistically it should be creating a GL_INVALID_ENUM error.

You are on the right track with using GL_COPY_READ_BUFFER, etc. That is a special binding location that will not disrupt anything else that is currently using a bound buffer object, but you shot yourself in the foot when you started passing buffer object names.

The simplest solution would be to use GL_COPY_READ_BUFFER for the object you are copying from and GL_COPY_WRITE_BUFFER for the new object you are creating.

Here are a few slightly modified lines of code that show this:

glBindBuffer           (GL_COPY_READ_BUFFER, other.m_indexBuffer);
glGetBufferParameteriv (GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);

glBindBuffer           (GL_COPY_WRITE_BUFFER, m_indexBuffer);
glBufferData           (GL_COPY_WRITE_BUFFER, size, nullptr, GL_STATIC_DRAW);

glCopyBufferSubData    (GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, size);