test-cogl-multitexture: use several materials with texture matrices

A small doubt has risen about the use of CoglTextureUnit in materials:
will texture matrices still work if we have several materials, each of
them having at texture on the same texture unit? The answer is yes!

test-cogl-multitexture has been extended to use 2 materials with about
the same setup except a little difference: the texture matrices for the
lightmaps rotate in opposite directions.

While at it, changed the rotation behaviour by an implicit animation
with a small additional bonus bling.
This commit is contained in:
Damien Lespiau 2010-01-26 16:59:50 +00:00
parent 06d8ebb0ba
commit de31cbf4f7

View File

@ -11,15 +11,22 @@
typedef struct _TestMultiLayerMaterialState
{
ClutterActor *group;
CoglHandle material;
CoglHandle alpha_tex;
CoglHandle redhand_tex;
CoglHandle light_tex0;
gfloat *tex_coords;
ClutterActor *group;
CoglHandle alpha_tex;
CoglHandle redhand_tex;
gfloat *tex_coords;
CoglMatrix tex_matrix;
CoglMatrix rot_matrix;
ClutterTimeline *timeline;
CoglHandle material0;
CoglMatrix tex_matrix0;
CoglMatrix rot_matrix0;
CoglHandle light_tex0;
CoglHandle material1;
CoglMatrix tex_matrix1;
CoglMatrix rot_matrix1;
CoglHandle light_tex1;
} TestMultiLayerMaterialState;
@ -31,10 +38,15 @@ frame_cb (ClutterTimeline *timeline,
{
TestMultiLayerMaterialState *state = data;
cogl_matrix_multiply (&state->tex_matrix,
&state->tex_matrix,
&state->rot_matrix);
cogl_material_set_layer_matrix (state->material, 2, &state->tex_matrix);
cogl_matrix_multiply (&state->tex_matrix0,
&state->tex_matrix0,
&state->rot_matrix0);
cogl_material_set_layer_matrix (state->material0, 2, &state->tex_matrix0);
cogl_matrix_multiply (&state->tex_matrix1,
&state->tex_matrix1,
&state->rot_matrix1);
cogl_material_set_layer_matrix (state->material1, 2, &state->tex_matrix1);
}
static void
@ -42,18 +54,51 @@ material_rectangle_paint (ClutterActor *actor, gpointer data)
{
TestMultiLayerMaterialState *state = data;
cogl_set_source (state->material);
cogl_rectangle_with_multitexture_coords (0, 0, 200, 200,
cogl_push_matrix ();
cogl_translate (150, 15, 0);
cogl_set_source (state->material0);
cogl_rectangle_with_multitexture_coords (0, 0, 200, 213,
state->tex_coords,
12);
cogl_translate (-300, -30, 0);
cogl_set_source (state->material1);
cogl_rectangle_with_multitexture_coords (0, 0, 200, 213,
state->tex_coords,
12);
cogl_pop_matrix ();
}
static void
animation_completed_cb (ClutterAnimation *animation,
TestMultiLayerMaterialState *state)
{
static gboolean go_back = FALSE;
gdouble new_rotation_y;
if (go_back)
new_rotation_y = 30;
else
new_rotation_y = -30;
go_back = !go_back;
clutter_actor_animate_with_timeline (state->group,
CLUTTER_LINEAR,
state->timeline,
"rotation-angle-y", new_rotation_y,
"signal-after::completed",
animation_completed_cb, state,
NULL);
}
G_MODULE_EXPORT int
test_cogl_multitexture_main (int argc, char *argv[])
{
GError *error = NULL;
ClutterTimeline *timeline;
ClutterBehaviour *r_behave;
ClutterActor *stage;
ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff };
TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
@ -113,55 +158,71 @@ test_cogl_multitexture_main (int argc, char *argv[])
if (!state->light_tex0)
g_critical ("Failed to load light0.png: %s", error->message);
state->light_tex1 =
cogl_texture_new_from_file (files[2],
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY,
&error);
if (!state->light_tex1)
g_critical ("Failed to load light0.png: %s", error->message);
g_strfreev (files);
state->material = cogl_material_new ();
cogl_material_set_layer (state->material, 0, state->alpha_tex);
cogl_material_set_layer (state->material, 1, state->redhand_tex);
cogl_material_set_layer (state->material, 2, state->light_tex0);
state->material0 = cogl_material_new ();
cogl_material_set_layer (state->material0, 0, state->alpha_tex);
cogl_material_set_layer (state->material0, 1, state->redhand_tex);
cogl_material_set_layer (state->material0, 2, state->light_tex0);
state->material1 = cogl_material_new ();
cogl_material_set_layer (state->material1, 0, state->alpha_tex);
cogl_material_set_layer (state->material1, 1, state->redhand_tex);
cogl_material_set_layer (state->material1, 2, state->light_tex1);
state->tex_coords = tex_coords;
cogl_matrix_init_identity (&state->tex_matrix);
cogl_matrix_init_identity (&state->rot_matrix);
cogl_matrix_init_identity (&state->tex_matrix0);
cogl_matrix_init_identity (&state->tex_matrix1);
cogl_matrix_init_identity (&state->rot_matrix0);
cogl_matrix_init_identity (&state->rot_matrix1);
cogl_matrix_translate (&state->rot_matrix, 0.5, 0.5, 0);
cogl_matrix_rotate (&state->rot_matrix, 10.0, 0, 0, 1.0);
cogl_matrix_translate (&state->rot_matrix, -0.5, -0.5, 0);
cogl_matrix_translate (&state->rot_matrix0, 0.5, 0.5, 0);
cogl_matrix_rotate (&state->rot_matrix0, 10.0, 0, 0, 1.0);
cogl_matrix_translate (&state->rot_matrix0, -0.5, -0.5, 0);
cogl_matrix_translate (&state->rot_matrix1, 0.5, 0.5, 0);
cogl_matrix_rotate (&state->rot_matrix1, -10.0, 0, 0, 1.0);
cogl_matrix_translate (&state->rot_matrix1, -0.5, -0.5, 0);
clutter_actor_set_anchor_point (state->group, 86, 125);
clutter_container_add_actor (CLUTTER_CONTAINER(stage),
state->group);
timeline = clutter_timeline_new (7692);
clutter_timeline_set_loop (timeline, TRUE);
state->timeline = clutter_timeline_new (2812);
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), state);
g_signal_connect (state->timeline, "new-frame", G_CALLBACK (frame_cb), state);
r_behave =
clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
CLUTTER_LINEAR),
CLUTTER_Y_AXIS,
CLUTTER_ROTATE_CW,
0.0, 360.0);
/* Apply it to our actor */
clutter_behaviour_apply (r_behave, state->group);
clutter_actor_animate_with_timeline (state->group,
CLUTTER_LINEAR,
state->timeline,
"rotation-angle-y", 30.0,
"signal-after::completed",
animation_completed_cb, state,
NULL);
/* start the timeline and thus the animations */
clutter_timeline_start (timeline);
clutter_timeline_start (state->timeline);
clutter_actor_show_all (stage);
clutter_main();
cogl_handle_unref (state->material);
cogl_handle_unref (state->material1);
cogl_handle_unref (state->material0);
cogl_handle_unref (state->alpha_tex);
cogl_handle_unref (state->redhand_tex);
cogl_handle_unref (state->light_tex0);
cogl_handle_unref (state->light_tex1);
g_free (state);
g_object_unref (r_behave);
return 0;
}