5985eef44c
This glues CoglMaterial in as the fundamental way that Cogl describes how to fill in geometry. It adds cogl_set_source (), which is used to set the material which will be used by all subsequent drawing functions It adds cogl_set_source_texture as a convenience for setting up a default material with a single texture layer, and cogl_set_source_color is now also a convenience for setting up a material with a solid fill. "drawing functions" include, cogl_rectangle, cogl_texture_rectangle, cogl_texture_multiple_rectangles, cogl_texture_polygon (though the cogl_texture_* funcs have been renamed; see below for details), cogl_path_fill/stroke and cogl_vertex_buffer_draw*. cogl_texture_rectangle, cogl_texture_multiple_rectangles and cogl_texture_polygon no longer take a texture handle; instead the current source material is referenced. The functions have also been renamed to: cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords and cogl_polygon respectivly. Most code that previously did: cogl_texture_rectangle (tex_handle, x, y,...); needs to be changed to now do: cogl_set_source_texture (tex_handle); cogl_rectangle_with_texture_coords (x, y,....); In the less likely case where you were blending your source texture with a color like: cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */ cogl_texture_rectangle (tex_handle, x, y,...); you will need your own material to do that: mat = cogl_material_new (); cogl_material_set_color4ub (r,g,b,a); cogl_material_set_layer (mat, 0, tex_handle)); cogl_set_source_material (mat); Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use cog_rectangle_with_texure_coords since these are the coordinates that cogl_rectangle will use. For cogl_texture_polygon; as well as dropping the texture handle, the n_vertices and vertices arguments were transposed for consistency. So code previously written as: cogl_texture_polygon (tex_handle, 3, verts, TRUE); need to be written as: cogl_set_source_texture (tex_handle); cogl_polygon (verts, 3, TRUE); All of the unit tests have been updated to now use the material API and test-cogl-material has been renamed to test-cogl-multitexture since any textured quad is now technically a test of CoglMaterial but this test specifically creates a material with multiple texture layers. Note: The GLES backend has not been updated yet; that will be done in a following commit.
161 lines
4.6 KiB
C
161 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <glib.h>
|
|
#include <glib-object.h>
|
|
#include <gmodule.h>
|
|
|
|
#include <clutter/clutter.h>
|
|
#include <cogl/cogl.h>
|
|
|
|
#define TIMELINE_FRAME_COUNT 200
|
|
|
|
typedef struct _TestMultiLayerMaterialState
|
|
{
|
|
ClutterActor *group;
|
|
CoglHandle material;
|
|
CoglHandle alpha_tex;
|
|
CoglHandle redhand_tex;
|
|
CoglHandle light_tex0;
|
|
ClutterFixed *tex_coords;
|
|
|
|
CoglMatrix tex_matrix;
|
|
CoglMatrix rot_matrix;
|
|
|
|
} TestMultiLayerMaterialState;
|
|
|
|
|
|
static void
|
|
frame_cb (ClutterTimeline *timeline,
|
|
gint frame_no,
|
|
gpointer data)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static void
|
|
material_rectangle_paint (ClutterActor *actor, gpointer data)
|
|
{
|
|
TestMultiLayerMaterialState *state = data;
|
|
|
|
cogl_set_source (state->material);
|
|
cogl_rectangle_with_multitexture_coords (
|
|
CLUTTER_INT_TO_FIXED(0),
|
|
CLUTTER_INT_TO_FIXED(0),
|
|
CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT),
|
|
CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT),
|
|
state->tex_coords,
|
|
12);
|
|
}
|
|
|
|
G_MODULE_EXPORT int
|
|
test_cogl_multitexture_main (int argc, char *argv[])
|
|
{
|
|
ClutterTimeline *timeline;
|
|
ClutterAlpha *alpha;
|
|
ClutterBehaviour *r_behave;
|
|
ClutterActor *stage;
|
|
ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff };
|
|
TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
|
|
ClutterGeometry geom;
|
|
ClutterFixed tex_coords[] =
|
|
{
|
|
/* tx1 ty1 tx2 ty2 */
|
|
0, 0, CLUTTER_INT_TO_FIXED (1), CLUTTER_INT_TO_FIXED (1),
|
|
0, 0, CLUTTER_INT_TO_FIXED (1), CLUTTER_INT_TO_FIXED (1),
|
|
0, 0, CLUTTER_INT_TO_FIXED (1), CLUTTER_INT_TO_FIXED (1)
|
|
};
|
|
|
|
clutter_init (&argc, &argv);
|
|
|
|
stage = clutter_stage_get_default ();
|
|
clutter_actor_get_geometry (stage, &geom);
|
|
|
|
clutter_stage_set_color (CLUTTER_STAGE (stage),
|
|
&stage_color);
|
|
|
|
/* We create a non-descript actor that we know doesn't have a
|
|
* default paint handler, so that we can easily control
|
|
* painting in a paint signal handler, without having to
|
|
* sub-class anything etc. */
|
|
state->group = clutter_group_new ();
|
|
clutter_actor_set_position (state->group, geom.width/2, geom.height/2);
|
|
g_signal_connect (state->group, "paint",
|
|
G_CALLBACK(material_rectangle_paint), state);
|
|
|
|
state->alpha_tex =
|
|
cogl_texture_new_from_file ("./redhand_alpha.png",
|
|
-1, /* disable slicing */
|
|
TRUE,
|
|
COGL_PIXEL_FORMAT_ANY,
|
|
NULL);
|
|
state->redhand_tex =
|
|
cogl_texture_new_from_file ("./redhand.png",
|
|
-1, /* disable slicing */
|
|
TRUE,
|
|
COGL_PIXEL_FORMAT_ANY,
|
|
NULL);
|
|
state->light_tex0 =
|
|
cogl_texture_new_from_file ("./light0.png",
|
|
-1, /* disable slicing */
|
|
TRUE,
|
|
COGL_PIXEL_FORMAT_ANY,
|
|
NULL);
|
|
|
|
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->tex_coords = tex_coords;
|
|
|
|
cogl_matrix_init_identity (&state->tex_matrix);
|
|
cogl_matrix_init_identity (&state->rot_matrix);
|
|
|
|
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);
|
|
|
|
clutter_actor_set_anchor_point (state->group, 86, 125);
|
|
clutter_container_add_actor (CLUTTER_CONTAINER(stage),
|
|
state->group);
|
|
|
|
timeline = clutter_timeline_new (TIMELINE_FRAME_COUNT, 26 /* fps */);
|
|
g_object_set (timeline, "loop", TRUE, NULL);
|
|
|
|
g_signal_connect (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);
|
|
|
|
/* start the timeline and thus the animations */
|
|
clutter_timeline_start (timeline);
|
|
|
|
clutter_actor_show_all (stage);
|
|
|
|
clutter_main();
|
|
|
|
cogl_material_unref (state->material);
|
|
cogl_texture_unref (state->alpha_tex);
|
|
cogl_texture_unref (state->redhand_tex);
|
|
cogl_texture_unref (state->light_tex0);
|
|
g_free (state);
|
|
|
|
g_object_unref (r_behave);
|
|
|
|
return 0;
|
|
}
|