PDA

View Full Version : add color to VBOs - best practices



avstenit
11-28-2013, 11:35 AM
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?

tonyo_au
11-28-2013, 02:43 PM
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.

avstenit
11-29-2013, 12:36 AM
Another method is to have separate buffers for the the vertex and colour.
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.


...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.
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?


...If you plan to use transparency you will have to think about how you are going to sort your objects for rendering.
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"?

tonyo_au
11-29-2013, 12:53 AM
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.

avstenit
11-29-2013, 02:08 AM
Do you plan to uses shaders?
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?

tonyo_au
11-30-2013, 04:37 PM
uniforms can only be used with shaders.


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

avstenit
12-02-2013, 12:47 AM
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:)

avstenit
12-02-2013, 05:57 AM
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+dat a_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 :)

tonyo_au
12-03-2013, 03:15 PM
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.