View Full Version : VBO and indices

Paolo Selva
01-20-2009, 08:22 PM
first of all "Nice to join the forum" and "Happy new year to everybody".
Now, I have a question: can I use two different index-arrays to avoid repeating same data in vertices ?
Going deeper, a little example.
I have a VBO with couples of vertices. Each couple has the same color so I don't want a layout like this:

vbo -> xA,yA,zA,rA,gA,bA,xB,yB,zB,rA,gA,bA,...,...,...

or two different vbo like these:

vboVertices -> xA,yA,zA,xB,yB,zB,...,...,...
vboColors -> rA,gA,bA,rA,gA,bA,...,...,...

I would like to have something like this:

vboVertices -> xA,yA,zA,xB,yB,zB,...,...,...
vboColors -> rA,gA,bA,...,...,...

and arrays of indices these:

vboVertices_i -> 0,1,...,...,...
vboColors_i -> 0,0,...,...,...

so I can match one color to two different vertices.

Is it possible ? or maybe it's not as fast as repeating colors...

I was searching in the forum but I think this is the fastest way to find an answer.

Thanks to all.

01-20-2009, 08:45 PM
In my experience no. But I'd love to be proved wrong.

Certainly on any card which does not have Geometry shaders, or some kind of vertex counting in the shaders, it is not possible the way you describe (assuming I understood), and the only way I could think of was to have yet another table in an attribute array. But even then... How to index each vertex independently from the automatic/blind indexing OpenGL is doing?

Basically the index for vertices, colours, normals etc. etc. all run concurrent AFAIK.

I have tried to do Quad based billboards in a similar way, so that I only had to store one vertex (it's coordinate) per quad by re-indexing it four times in an index array. The problem is when you use index arrays the fixed function pipeline, or the shaders don't know which vertex is which.. So you cannot then generate the corner offsets based on a vertex index. i.e. 0,1,2,3,0,1,2,3

Like I said, if anyone knows a way on cards without the newer shader models, instancing and geometry shaders.. I'd love to hear it..

01-21-2009, 05:53 AM
By simply using the ARB_vertex_buffer_object extension this is not possible.

However you should check out the functionality of the extension ARB_instanced_arrays.

Using this extension you can probably resolve your problem.

Paolo Selva
01-21-2009, 04:46 PM
Thanks guys.
I'm looking at instances but I've to manage them with a vertex shader and if I write this:

bindable uniform vec4 mypositions[instancescount];

instancescount can't be more then 4096.
is it right?
This is what I'm doing:

// load geometry
// ..creating vertex array and other data...
GLint _size = glGetUniformBufferSizeEXT(prog, uniformlocation);
glGenBuffers(1, &ptr_vertexdataforinstances);
glBindBuffer(GL_UNIFORM_BUFFER_EXT, ptr_vertexdataforinstances);
glBufferData(GL_UNIFORM_BUFFER_EXT, _size, vertexdataforinstances, GL_STATIC_READ);
glUniformBufferEXT(prog, uniformlocation, ptr_vertexdataforinstances);

// draw GL
glBindBuffer(GL_ARRAY_BUFFER, ptr_vertices);
glVertexPointer(3, GL_FLOAT, 3*_floatsize, ELEMENTDATA(0));
glBindBuffer(GL_UNIFORM_BUFFER_EXT, ptr_vertices);
glUniformBufferEXT(getActiveProgram(), uniformlocation, ptr_vertexdataforinstances);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ptr_indices);
glDrawElementsInstancedEXT(GL_POINTS, indicescount, GL_UNSIGNED_INT, ELEMENTDATA(0), instancescount);

this example has 1 vertex with 1 index and a lot of vertexdata to create instances of a vertex in different positions.
And the vertex shader is:

vec3 _center = g_positions[gl_InstanceID].xyz;
vec3 _pos = gl_Vertex.xyz + _center;
gl_Position = gl_ModelViewProjectionMatrix * vec4(_pos, 1.0);

where g_positions is declared as:

bindable uniform vec4 g_positions[4096];

where 4096 is the limit but I have 4millions vertices to load.
Can I do this directly while drawing GL context without usign a vertex shader?

01-21-2009, 06:30 PM
@aqnuep If only ATI would give me ARB_instanced_arrays... :)

Paolo.. I am not sure about the limitations on your GPU. But I would hazard a guess that if you have ARB_instanced_arrays then you can also do Geometry Shaders. They would be even more efficient at what you are trying to do...

Paolo Selva
01-27-2009, 12:25 PM
Thanks scratt.
Finally I found the best way to do that with a geometry shader.
Very cool stuff :)

01-27-2009, 02:58 PM
Thanks scratt.
Finally I found the best way to do that with a geometry shader.
Very cool stuff :)

It has been my experience, at least on latest Nvidia cards, that indexing uniform arrays with a dynamic variable can become very slow. Have you tried using a texture with point filtering to send the instance positions to the shader? This could prove to be much faster depending on how you implemented your solution. You could also render many more instances in a batch (max_tex_size * max_tex_size).