Hi all,
Sorry for this long post but I’m tring to put my problem in such a way that you can understand it really well (btw, my mother tong is not english).
Well, here we go. Suppose I have the following triangle vertices:
float VerticesT1[] = {
-0.5f,0.0f,0.5f, //V0
0.5f,0.0f,0.5f, //V1
0.0f,0.5f,0.5f //V2
};
and indices:
uint IdxT1[] = {0, 1, 2};
and I use VBO to draw a triangle like this:
//buffering vetices
int vboVertices1;
glGenBuffers(1, &vboVertices1);
glBindBuffer(GL_ARRAY_BUFFER, vboVertices1);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 3, VerticesT1, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
//buffering indices
int vboIndices1;
glGenBuffers(1, vboIndices1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices1);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * 3 * 1, IdxT1, GL_STATIC_DRAW);
//drawing
glEnableClientState(GL_VERTEX_ARRAY);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawElements(GL_TRIANGLES, 1 * 3, GL_UNSIGNED_INT, (char *) NULL);
glDisableClientState(GL_VERTEX_ARRAY);
So far, no problem, not really a dificult task to accomplish. But this is just the begining.
Imagine now that I add 3 more points (vertex) into the space:
float VerticesT2[] = {
0.25f, 0.25f, 0.75f,//V3
-0.25f, 0.25f, 0.75f,//V4
0.00f, 0.00f, 0.75f //V5
};
and want to display 4 triangles with the following indices:
uint IdxT2[] = { 3, 4, 5,
0, 5, 4,
1, 3, 5,
4, 3, 2};
where indices 0, 1 and 2 would correspond to the vertices of the first triangle (V0, V1, V2) and the indices 3, 4 and 5 corresponds to the 3 new points (vertices) (V3, V4, V5) in VerticesT2[]. The easiest way to draw these new 4 triangles listed in IdxT2[] would be to send all 6 vetices like this:
float verticesT1andT2[] = {
-0.5f,0.0f,0.5f, //V0
0.5f,0.0f,0.5f, //V1
0.0f,0.5f,0.5f, //V2
0.25f, 0.25f, 0.75f,//V3
-0.25f, 0.25f, 0.75f,//V4
0.00f, 0.00f, 0.75f //V5
};
into a new VBO:
//buffering vetices
int vboVertices2;
glGenBuffers(1, &vboVertices2);
glBindBuffer(GL_ARRAY_BUFFER, vboVertices2);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 6, VerticesT1, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
given that the new index list will also be buffered:
//buffering indices
int vboIndices2;
glGenBuffers(1, vboIndices2);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices2);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(uint) * 3 * 4, IdxT2, GL_STATIC_DRAW);
Well, it surelly does the trick, but the big problem is that it would mean a big waste of time/CPU occupation/RAM->VRAM bandwidth trafic/and all other consequences, since half of the vertices (3 out of the 6) are alredy in the VRAM due to previous data buffering.
Then, the goal here is to draw these 4 triangles by sending only the 3 new points in VerticesT2[] and the new indices IdxT2[] list. I tried to think about some solutions. One would be this one: create a big buffer like:
//buffering vetices
int vboVerticesBigBuffer;
glGenBuffers(1, &vboVerticesBigBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vboVerticesBigBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (3 * 3 + 3 * 3), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * 3 * 3, VerticesT1);
to drawn the first triangle like:
//…
glDrawElements(GL_TRIANGLES, 1 * 3, GL_UNSIGNED_INT, (char *) NULL);
//…
then draw the 4 triangles by passing only VerticesT2[] with:
//…
glBufferSubData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 3, sizeof(float) * 3 * 3, VerticesT1);
//…
and draw like (i suppose we also send the IdxT2[] index table):
//…
glDrawElements(GL_TRIANGLES, 4 * 3, GL_UNSIGNED_INT, (char *) NULL);
//…
The problem of this approach is that I take the double of memory when creating the bigbuffer to draw the first triangle only. Another problem is that once I draw the 4 new trianges and want to draw the first one back, i can’t erase only the memory of the buffer correspond to the 3 new vertices that I won’t use anymore (delete the bigbuffer and create a new one for VerticesT1 is not an option).
You can ask yourself “why this dude want to complecate so much his life if he is hangling only 6 vertices???”. Well, the problem is that I don’t have only 6 vertices, but actually tens or hundreds of millions of vertices to handle (very big 3D models sharing vertices) and can’t afford waste VRAM place nor time to resend data that already is in VRAM.
A second solution I though would be to create two independent buffers with 3 vertices each (VerticesT1[] and VerticesT2[]) and temporally merge them to create a big one (functionally equivalente to verticesT1andT2[]), then i could draw the 4 triangles and, after that, I could split apart to delete one of them (VerticesT2[]) when I want to draw only the fist triangle. But the problem is that i don’t know if it is possible to do that xD The cool thing would be to be able to merge them at least virtually so that the 4th element of the big buffer would correspond to the 1st of the second buffer (virtually, which would avoid the data movement in the VRAM. By the way, this is what is done in the system RAM when we use malloc/new to create big arrays in C/C++: arrays elements are not necesserly physically consecutive in the memory but for the user they are “virtually” consecutive (we can do prt++ to access the next element)).
So I’m really in need of a solution to do so, and i hope that i’m not asking for something that actually is impossible with openGL 4.0!
Thank you for your time,
Leo