VBO - non interleaved {vertex, color, texCoord, n}

Hi,
I’m learning/adjusting to the new 3.0+ standard. I’ve been reading tutorials and wikis. The approach presented in the wiki (http://www.opengl.org/wiki/Vertex_Buffer_Objects) and this tutorial (http://openglbook.com/the-book/) is to interleave vertex, texture coord, color and normals in the VBO.

To me it seems it can be improved. If I’m drawing 1000 verticies all of the same color, I can cut down the amount of data transmitted to the card. Upload 1 color value, and an array of 1000 index values referring to that color - as opposed to an array of 1000 vec4 color values.

Same can be said for normals. I see that multi index rendering is not the way to go - http://www.opengl.org/wiki/FAQ#Multi_indexed_rendering. The solution offered is to allocate separate VBOs for each, or stack the values in blocks in the same VBO. That’s fine but in practice how do I render that? Say I want to render a square, 4 verticies, 1 color, 1 normal, can someone provide a sample?

Thanks.

I’m afraid you need to repeat the values.
I usually think of a vertex as the tuple of its attributes (position, normal, color, texcoord, etc.). Then if even if just one of the attributes varies between two vertices it is a different vertex and needs to be stored in its entirety.

For your example you store the 4 different positions and repeat 4 times the color and normal (either each in a separate VBO or first the positions then colors then normals in a single one). Then (after setting up the attribute pointers) you use a draw call like glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

I see. That’s a shame.

Is aligning to 32 byte necessary or is that dated information?

Is aligning to 32 byte necessary or is that dated information?

It was never “necessary”. It was merely something that, on some hardware, could improve performance hint.

If all your vertices are the same color. You can pass that color as an uniform rather than an attribute to your shaders.

Or you can just pass a constant vertex color for the color vertex attribute for all vertices with:

glVertexAttrib4f( MY_COLOR0_ATTR, r,g,b,a );

or:

glColor4f( r,g,b,a );

Just make sure you don’t enable the color vertex attribute, so that it uses the constant color set above.

This is somewhat like using a uniform variable, but allows you to stick with a vertex attribute (and sometimes use a constant color and other times use varying colors).

Thanks, didn’t know that you could use attribute as a uniform. So I tried some stuff.

Lets say that you are using the color attribute to specify a color to be used by all vertices using glVertexAttrib4f. If you then want to specify colors for each vertex, then you would need to use glVertexAttribPointer instead when using vbo’s and gldrawelement, right?

And in this case (when you only specify one color) the rest of the vertices would be black.

So I don’t see the switch between using a constant color and other times a varying color seamlessly in the client. However the attribute declared variable in the shader it self doesn’t need to change. Have I missed something?

One color was a bit of an oversimplification to make a point.

For a small set of colors - say 1000 verticies and 2 colors. I could pass an index with each vertex, and a bound texture as a uniform. Pass the index along to fragment shader. Then use texelFetch (ref http://www.opengl.org/wiki/GLSL_Sampler) based on the index value.

I wonder if it will pay off. The saved time on transfer to GPU vs the time to setup textures and do lookup in the fragment shader…

Thanks for the above suggestions.