Hi all,
well, I created a little code using the glCopyBufferSubData function. However, there’s something still missing to glCopyBufferSubData be a nice solution or I miss something (which would not be a surprise!). Imagine this simple code:
int vbo1, ibo;
glGenBuffers(1, &vbo1);
glGenBuffers(1, &ibo);
//mesh
float geo_TRI[] = {-1,0,0, 0,1,0, 1,0,0};
uint topo_TRI[] = { 0, 1, 2};
//vertex buffer
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 3, geo_TRI, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
//index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * 3, topo_TRI, GL_STATIC_DRAW);
//draw
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, (char *) NULL);
glDisableClientState(GL_VERTEX_ARRAY);
very well, now I want to copy part of vbo1 to another buffer and draw from it. There is where I have the problem. If I bind the second buffer as an GL_COPY_READ_BUFFER or GL_COPY_WRITE_BUFFER and copy like:
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
//create vbo2 of type GL_COPY_WRITE_BUFFER
glGenBuffers(1, &vbo2);
glBindBuffer(GL_COPY_WRITE_BUFFER, vbo2);
glBufferData(GL_COPY_WRITE_BUFFER, sizeof(float) * 2 * 3, NULL, GL_STATIC_COPY);
//copy data from vbo1 to it
glCopyBufferSubData(GL_ARRAY_BUFFER,GL_COPY_WRITE_BUFFER,0,0,sizeof(float) * 2 * 3);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
//delete buffer vbo1
Gl.glDeleteBuffers(1, vbo1);
vbo1 = 0;
//draw from vbo2
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, (char *) NULL);
glDisableClientState(GL_VERTEX_ARRAY);
then it “draws” a big red X. I believe that it is so because the draw functions seeks for an array with type GL_ARRAY_BUFFER to draw, which has been deleted. It finds only a buffer with type GL_COPY_WRITE_BUFFER (or GL_COPY_READ_BUFFER). A first question: these new buffer types (GL_COPY_WRITE_BUFFER or GL_COPY_READ_BUFFER) can’t be used to draw??? The second buffer can’t be GL_ARRAY_BUFFER neither, because the copy function will do a copy of the last binded buffer of type GL_ARRAY_BUFFER over itself! Therefore, if GL_COPY_READ_BUFFER or GL_COPY_WRITE_BUFFER cannot be used to draw, it would means that I have to use a GL_ARRAY_BUFFER through two copies like:
int vbotemp;
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
//create a temp buffer of type GL_COPY_READ_BUFFER
glGenBuffers(1, &vbotemp);
glBindBuffer(GL_COPY_READ_BUFFER, vbotemp);
glBufferData(GL_COPY_READ_BUFFER, sizeof(float) * 2 * 3, NULL, GL_STATIC_COPY);
//copy data from vbo1 to it
glCopyBufferSubData(GL_ARRAY_BUFFER,GL_COPY_READ_BUFFER,0,0,sizeof(float) * 2 * 3);
//Delete buffer vbo1
Gl.glDeleteBuffers(1, vbo1);
vbo1 = 0;
//generate buffer vbo2 of type GL_ARRAY_BUFFER
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 2 * 3, NULL, GL_STATIC_COPY);
//copy data from vbotemp to it
glCopyBufferSubData(GL_COPY_READ_BUFFER,GL_ARRAY_BUFFER,0,0,sizeof(float) * 2 * 3);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
//Delete buffer vbotemp
Gl.glDeleteBuffers(1, vbotemp);
vbotemp = 0;
//draw from vbo2
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, (char *) NULL);
glDisableClientState(GL_VERTEX_ARRAY);
or eventually do not create a vbo2 but “resize” vbo1:
int vbotemp;
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
//create a temp buffer of type GL_COPY_READ_BUFFER
glGenBuffers(1, &vbotemp);
glBindBuffer(GL_COPY_READ_BUFFER, vbotemp);
glBufferData(GL_COPY_READ_BUFFER, sizeof(float) * 2 * 3, NULL, GL_STATIC_COPY);
//copy data from vbo1 to it
glCopyBufferSubData(GL_ARRAY_BUFFER,GL_COPY_READ_BUFFER,0,0,sizeof(float) * 2 * 3);
//Resize buffer vbo1
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 2 * 3, NULL, GL_STATIC_COPY);
//copy data from vbotemp to vbo1
glCopyBufferSubData(GL_COPY_READ_BUFFER,GL_ARRAY_BUFFER,0,0,sizeof(float) * 2 * 3);
//Delete buffer vbotemp
Gl.glDeleteBuffers(1, vbotemp);
vbotemp = 0;
//draw from vbo1
glEnableClientState(GL_VERTEX_ARRAY);
glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, (char *) NULL);
glDisableClientState(GL_VERTEX_ARRAY);
either ways, this would means an undesirable additional copy…
A second question: when I reuse glBufferData over the same buffer with a different size it delete and allocates a buffer with the new size? Or do not change the size but just delete?
But the main question still is: is there a way to draw from the second buffer without double copy?
Thx,
leo