add color to VBOs - best practices

I am working on a visualisation engine (with python and pyopengl bindings) that will display and animate up to 10-20 bodies simultaneously. I am using VBO data object to store vertex data and to display each body. I would like to know what is the best (most practical, easiest and less expensive-GPU) method to assign color to a VBO. Every body has uniform color and the appearance can be set to transparent - optional. As I know this can be done with the following methods (tested method 1 and 2):

  1. glColorf(R, G, B, A)
  2. glMaterialfv(GL_FRONT_AND_BACK, , [R, G, B, A])
  3. assign color to each vertex and create interleaved VBO
    Are there any other methods? And which one is most suited for the job?

Another method is to have separate buffers for the the vertex and colour.

There is no “best” method. It depends on your data. If you have very large data sets, setting a colour in a uniform and rendering all the objects with that colour will save space since the vertex does not need to carry the colour info; but generally it is simplest to have each vertex carry its own colour.

If you plan to use transparency you will have to think about how you are going to sort your objects for rendering.

If I understand correctly; each body will have several (two or three) BOs:

  1. VBO to store vertex data
  2. BO to store normals data for each triangle (GL_TRIANGLES)
  3. BO to store one color vector?
    Or maybe I will join the 1. and 2. buffer object.

I was thinking in that direction, that it would be to memory consuming to store a color vector for each vertex as the color vector is the same for all vertices of the body (I am creating simple CAD style 3D visualisation engine with glOrtho() projection mode, like for example MSC.Adams view has for multi-body dynamics). Can you give a little more directions on how to set a uniform color, with what function?

I don not plan to create rendering like in blender (with reflections and like realistic rendering), the goal is just to have simple visualization of object (as mentioned, like in every CAD software). What do you mean with “…sort your objects for rendering”?

Can you give a little more directions on how to set a uniform color

Do you plan to uses shaders?

What do you mean with “…sort your objects for rendering”?

For alpha blending to work correctly you must draw all your opaque objects first with depth buffers enabled, followed by the translucent object furthest from the camera view point and drawing the translucent object nearest the camera last with depth test enabled but depth setting disabled.

No. If it will be possible I plan to avoid using shaders, as the visualisation engine is just for viewing the results of the dynamics (physics) engine that is the main focus. The visualisation engine should be as simple as possible and only basic properties should be available (color, transparent, zoom, pan, rotate).

To create transparent body I have to look for alpha blending?

uniforms can only be used with shaders.

To create transparent body I have to look for alpha blending [b]

[/b]yes

Thanks for the help! Now it is much easier, when I know what to look for, as OpenGL has quite a lot functions, especially for a beginner with OpenGL:)

I would like to ask a question about how do display a color of each vertex. VBO is created with:


def geometry(self):
	#    generate a new VBO and get the associated vbo_id
	_id = 1
	self.vbo_id = glGenBuffers (_id)
	#    bind VBO in order to use
	glBindBuffer(GL_ARRAY_BUFFER, self.vbo_id)
	#    upload data to VBO
	data = model_loader.Model_loader(filename = "body_1_geometry.stl")
	vertices = data.vertices
	normals = data.normals
	self.N_vertices = len(vertices)
	#    data size in bytes
	self.data_size_vertices = arrays.ArrayDatatype.arrayByteCount(vertices)
	self.data_size_normals = arrays.ArrayDatatype.arrayByteCount(normals)
	color = np.array([1.0, 0.0, 0.0], dtype='float32')
	colors = np.tile(color, self.N_vertices)
	colors = np.array(np.random.rand(3*self.N_vertices), dtype='float32')
	data_size_colors = arrays.ArrayDatatype.arrayByteCount(colors)
	glBufferData(GL_ARRAY_BUFFER,
		self.data_size_vertices+self.data_size_normals+data_size_colors,
	        None,
		GL_STATIC_DRAW)
	glBufferSubData(GL_ARRAY_BUFFER,
			  0,
			  self.data_size_vertices,
			  vertices)
	#    delete data after saved to VBO
	del vertices
	glBufferSubData(GL_ARRAY_BUFFER,
			  self.data_size_vertices,
			  self.data_size_normals,
			  normals)
	#    delete data after saved to VBO
	del normals
	glBufferSubData(GL_ARRAY_BUFFER,
			   self.data_size_vertices+self.data_size_normals,
			   data_size_colors,
			   colors)
	glBindBuffer(GL_ARRAY_BUFFER, self.vbo_id)

I create the VBO that has the data in the form of VBO = [vertices, normals, colors], vertices[0] = [x0, y0, z0], normals[0] = [xn0, yn0, zn0], colors[0] = [R0, G0, B0]. As I import data from .stl file, a normal vector is defined per triangle that is defined by 3 vertices and color vector is defined for every vertex.
VBO is displayed with:


glPushMatrix()
    
glLightfv(GL_LIGHT0, GL_POSITION, np.array([0.0, 0.0, 0.0]))
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, np.array([0.0, 10.0, 10.0]))
glLightModeli( GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE )

glEnableClientState(GL_VERTEX_ARRAY)
glVertexPointer(3, 
		GL_FLOAT, 
		0, 
		None)
glEnableClientState(GL_COLOR_ARRAY)
glColorPointer(3,
		GL_FLOAT,
	        0,
		self.data_size_vertices+self.data_size_normals)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.vbo_id)      
glDrawArrays(GL_TRIANGLES,
		0,
		self.N_vertices)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) # reset
glDisableClientState(GL_COLOR_ARRAY)
glDisableClientState(GL_VERTEX_ARRAY)

glPopMatrix()

I have problem with assigning each vertex the color from VBO, that each vertex will have its own color, or that the color of each triangle will be a mix of colors of all vertices of a triangle. The entire body is the same color, but it should be colorful :slight_smile:

I don’t quite follow what you are saying - if the 3 vertex corner of a triangle each as a different colour, the triangle will have the colours blended across its surface.