Hello Everyone =)
I would like to have a little program that would allow me to draw a model by using several buffers containing my vertex positions and only one buffer for the indices. In fact, I’m trying to address the problem of Laobracusa as explained in this thread :
http://www.opengl.org/discussion_boards/…6432#Post276432
My explanation is quite long and english is not my mother tongue but I would be grateful If you could help me with this problem.
As Dark Photon and Alphonse Reinheart suggested, I’m using TBO and a GLSL vertex shader to do the trick but I’m still quite new to GLSL. So I have a single triangle with a VBO containing some dummy positions and the indices are simple : 0,1,2.
GLuint vboIndices;
GLuint vboVertices;
float VerticesDummy[] = {
-1.0f,0.0f,0.0f, //V0D
1.0f,0.0f,0.0f, //V2D
0.0f,1.0f,0.0f //V1D
};
int IdxDummy[] = {
0, 1, 2};
// Dummy Triangle : biggest one
// ----------------------------
glGenBuffers(1, &vboIndices);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIndices);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 3, IdxDummy, GL_STATIC_DRAW);
glGenBuffers(1, &vboVertices);
glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 3, VerticesDummy, GL_STATIC_DRAW);
I want to draw two triangles, a small one inside another bigger one. So I create two TBO containing each three vertices for the two triangles.
GLuint tboVertices[2];
float VerticesT1[] = {
-0.5f, 0.0f, 0.5f, 1.0f, //V0
0.5f, 0.0f, 0.5f, 1.0f, //V1
0.0f, 0.5f, 0.5f, 1.0f //V2
};
float VerticesT2[] = {
0.25f, 0.25f, 0.75f, 1.0f, //V3
-0.25f, 0.25f, 0.75f, 1.0f, //V4
0.00f, 0.00f, 0.75f, 1.0f //V5
};
glGenBuffers(2, tboVertices);
// Big Triangle : A
glActiveTexture(GL_TEXTURE0);
glBindBuffer(GL_TEXTURE_BUFFER, tboVertices[0]);
glBufferData(GL_TEXTURE_BUFFER, sizeof(float) * 4 * 3, VerticesT1, GL_STATIC_DRAW);
glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, tboVertices[0]);
glUniform1iARB("positionBuffer1", 0); // pseudo-code : I'm using glUniform correctly
// Small Triangle inside the big one : B
glActiveTexture(GL_TEXTURE1);
glBindBuffer(GL_TEXTURE_BUFFER, tboVertices[1]);
glBufferData(GL_TEXTURE_BUFFER, sizeof(float) * 4 * 3, VerticesT2, GL_STATIC_DRAW);
glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGBA32F, tboVertices[1]);
glUniform1iARB("positionBuffer2", 1);
Then I draw that single dummy triangle several times (2 in this example) with glDrawElementsInstanced(), the positions are “updated” by a GLSL shader.
glEnableClientState(GL_VERTEX_ARRAY);
glColor3f(1.,1.,1.);
glBindBuffer(GL_ARRAY_BUFFER, vboVertices);
glVertexPointer(3, GL_FLOAT, 0, (char *) NULL);
glDrawElementsInstanced(GL_TRIANGLES, 3, GL_INT, (char *) NULL , 2);
glDisableClientState(GL_VERTEX_ARRAY);
In my vertex shader, I pick the real vertices from the positions samplerBuffer. The first triangle A is in positionBuffer1 and the second one B is in positionBuffer2.
#extension GL_EXT_gpu_shader4 : enable
#extension GL_EXT_texture_buffer_object : enable
uniform samplerBuffer positionBuffer1;
uniform samplerBuffer positionBuffer2;
void main(void)
{
vec4 position = gl_Vertex;
if (gl_InstanceID == 0)
{
position = texelFetchBuffer(positionBuffer1, gl_VertexID);
gl_FrontColor = vec4(1.0,0.0,0.0,1.0);
}
if (gl_InstanceID == 1)
{
position = texelFetchBuffer(positionBuffer2, gl_VertexID);
gl_FrontColor = vec4(0.0,1.0,0.0,1.0);
}
gl_Position = gl_ModelViewMatrix * position;
}
My problem is that it seems that my program only draws the last bound triangle (B) two times. I thought that using texture units would allow me to pass multiple samplerBuffer but it is not the case. Another problem is that I can’t get the correct indices from an isamplerBuffer. In the second example, I add a TBO to pass the triangles indices.
int Indices[] = {
0, 1, 2, 0,
0, 2, 1, 0};
GLuint tboIndices;
glGenBuffers(1, &tboIndices);
glActiveTexture(GL_TEXTURE2);
glBindBuffer(GL_TEXTURE_BUFFER, tboIndices);
glBufferData(GL_TEXTURE_BUFFER, sizeof(int) * 4 * 2 , Indices, GL_STATIC_DRAW);
glTexBufferEXT(GL_TEXTURE_BUFFER, GL_RGB32I, tboIndices);
glUniform1iARB("indexBuffer", 2);
My vertex shader would be as followed.
uniform samplerBuffer positionBuffer1;
uniform samplerBuffer positionBuffer2;
uniform isamplerBuffer indexBuffer;
void main(void)
{
vec4 position = gl_Vertex;
ivec4 index = texelFetchBuffer(indexBuffer, gl_InstanceID);
int vertexIndex;
if (gl_VertexID == 0)
vertexIndex=index.x;
if (gl_VertexID == 1)
vertexIndex=index.y;
if (gl_VertexID == 2)
vertexIndex=index.z;
if (gl_InstanceID == 0)
{
position = texelFetchBuffer(positionBuffer1, vertexIndex);
gl_FrontColor = vec4(1.0,0.0,0.0,1.0);
}
if (gl_InstanceID == 1)
{
position = texelFetchBuffer(positionBuffer2, vertexIndex);
gl_FrontColor = vec4(0.0,1.0,0.0,1.0);
}
gl_Position = gl_ModelViewMatrix * position;
}
I think that the problem is probably passing multiple samplerbuffer to the shader. Besides, I’m using 4 coordinates vertices but I would like to have only 3. However, the function texelFetchBuffer seems to read only 4 coordinates. I tried to modify the internal texture format but it doesn’t seem to work without rgba. Is there a way to fetch a 3 coordinates vertices ?
Thank you very much for having read my post. I hope you might help me understanding the problem.