Thank Robert, this is very nice explanation. I almost figured it out on my
own but with your help it is all clear now. Another question though, how it
all works with materials? Do I just set source material and use vertex
buffer API to draw? 

Regards,
Dmitri


-----Original Message-----
From: Robert Bragg [mailto:rob...@linux.intel.com] 
Sent: July 18, 2009 6:09 PM
To: Dmitri Toubelis
Cc: clutter@o-hand.com
Subject: Re: [clutter] Using COGL for 3D drawing

On Fri, 2009-07-17 at 09:15 -0400, Dmitri Toubelis wrote:
> Hi,
>  
> I need to create few 3D objects in clutter and I would like to use 
> OpenGL for this. So, what is officially recommended approach for this?

The officially recommended approach is to use the Cogl vertex buffer API for
this. Although there is some limited Cogl API to allow you to break out into
raw GL in exceptional circumstances, I would discourage this.
If Cogl doesn't already support what you need, I'd much rather discuss
improving Cogl.

>  My thinking was to get absolute coordinates of the actor and then use 
> vertex buffer API to draw. Is it right thing to do? Could anyone share 
> some code samples?

If you use the cogl vertex buffer API then you can just create an actor
subclass and use cogl_vertex_buffer_draw () in your paint function. You
shouldn't need to muck about getting the absolute coordinates of any actor
since the geometry will be transformed by the actors model view matrix. This
API is also integrated with the CoglMaterial API.

Essentially you can use this api something like this:

typedef struct {
        float x, y, z;
        float u, v;
        uint8_t r, g, b, a;
} MyVertex;

MyVertex my_vertices[100] = {
...
};

vbo = cogl_vertex_buffer_new (100); /* declares the number of vertices in
your VBO */

/* Add X,Y,Z vertex attributes: */
cogl_vertex_buffer_add (
        vbo, /* handle of vertex buffer object */
        "gl_Vertex", /* name of attribute */
        3, /* number of components (3 for X, Y and Z) */
        COGL_ATTRIBUTE_TYPE_FLOAT, /* attribute data type */
        FALSE, /* should integer types be normalized [0,1]?: no */
        sizeof (MyVertex), /* stride between vertices */
        &my_vertices[0].x); /* pointer to first vertex attribute */

/* Add u,v texture coordinate attributes: */ cogl_vertex_buffer_add (vbo,
"gl_MultiTexCoord0", 2, COGL_ATTRIBUTE_TYPE_FLOAT, FALSE, sizeof (MyVertex),
&my_vertices[0].u);

/* Add RGBA color attributes : */
cogl_vertex_buffer_add (vbo, "gl_Color", 4,
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE, TRUE, sizeof (MyVertex),
&my_vertices[0].r);

NOTE: For the unsigned byte color attribute we want the values 0-255 to be
normalized to the range [0,1]

NOTE: The names "gl_Vertex", "gl_MultiTexCoord0" and "gl_Color" aren't
arbitrary, they correspond to builtin glsl names. Even if you aren't using
glsl you must use the builtin glsl name if one exists, otherwise you are
free to create custom attributes with any name you like.

You can add multiple "gl_Vertex" attributes - assuming only one is enabled
at draw time. To differentiate them the names can have a detail, such as
"gl_Vertex::active" or "gl_Color::enabled".

/* Now upload all data from your client side arrays to GPU buffers...
 *
 * note: at this point if your xyz, texture and color attributes were
 * allocated on the heap you could free them if you like here.
 * note: calling cogl_vertex_buffer_submit is optional, but if you don't
 * explicitly call it then your client side arrays must remain valid
 * until you draw e.g. using cogl_vertex_buffer_draw ().
 */
cogl_vertex_buffer_submit ();

Ideally you would only do the above construction work once and you wouldn't
need to modify your vertex buffer per-frame.

In your paint function you can then do:

cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_TRIANGLE_STRIP, 0, 100);


If you want to morph your geometry, then you can do that by re-adding the
attributes that change over time.

Note: if you are morphing geometry then you should avoid uploading more data
than necessary per-frame. To help here it may be best to avoid using
interleaved attributes - as my example above does - (i.e. the vertex buffer
data above is arranged as X,Y,X,U,V,R,G,B,A) For morphing geometry create
separate arrays for each attribute and pass 0 for the stride argument. Then
in your paint function you would do:

/* apply your morphing.. */
my_update_vertex_positions();
/* Re-add just the attributes that have changed... */ cogl_vertex_buffer_add
(vbo, "gl_Vertex",,,0, &my_vertices[0]);
/* note the cogl_vertex_buffer_submit can be skipped since it's
 * implied when you call cogl_vertex_buffer_draw() */
cogl_vertex_buffer_draw (vbo, ...);

anyhow, that's quite a lot to dump in an email. More details about this API
are available here:
http://www.clutter-project.org/docs/cogl/0.9/cogl-Vertex-Buffers.html

I hope that helps,
kind regards,

- Robert


-- 
To unsubscribe send a mail to clutter+unsubscr...@o-hand.com

Reply via email to