PDA

View Full Version : Correct way to copy buffers



gartenriese
02-28-2014, 06:27 AM
I have an Object class and I want to implement the copy constructor. I have set it up 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);

I can see the orignal object, but the new object won't show up. How do I correctly copy the buffers?

I hope someone can help me! Thanks!

tonyo_au
02-28-2014, 05:13 PM
try binding the receive buffer with GL_COPY_WRITE_BUFFER instead of GL_ARRAY_BUFFER

gartenriese
03-03-2014, 03:04 AM
Thanks, that worked for my vertex and color buffers. However, there is still some error with index buffers.


IndexBuffer::IndexBuffer(const IndexBuffer & other)
: Buffer()
{

other.bind(GL_COPY_READ_BUFFER);
bind(GL_COPY_WRITE_BUFFER);

GLint size = 0;
glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size);
if (size != 0) {
glBufferData(GL_COPY_WRITE_BUFFER, size, nullptr, GL_STATIC_DRAW);
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, size);
}

}

If I want to draw an object that uses an index buffer, I get a segmentation fault. I guess there is still something wrong with my copy constructor. Size is correct, though.

gartenriese
03-03-2014, 05:16 AM
I get the segmentation fault at the following call:

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (void*)0);
My object is a quadrilateral, so 6 as count is correct, right?
When I change count to 1 or 2, it does not crash, but I don't see anything either. With count being 3 or more, it crashes.

tonyo_au
03-03-2014, 04:38 PM
glBufferData and glCopyBufferSubData size is in bytes

gartenriese
03-04-2014, 03:12 AM
glBufferData and glCopyBufferSubData size is in bytes

Yes, but glGetBufferParameteriv(GL_COPY_READ_BUFFER, GL_BUFFER_SIZE, &size); is also in bytes, so that should be ok.

tonyo_au
03-04-2014, 04:03 PM
Sorry can't think why it shouldn't work. I assume you can render using the original index buffer?

gartenriese
03-05-2014, 12:55 AM
Yes, the original objects work just fine. It's just the copied objects that use an index buffer that won't work. Copied objects without an index buffer work fine, too.

gartenriese
03-06-2014, 06:13 AM
My error was that I tried to bind to 0. This thread can be closed.