mutter/src/tests/clutter/interactive/test-cogl-multitexture.c
Jonas Ådahl 2b95ec40c6 clutter/timeline: Deprecate timelines without an actor or frame clock
Without an associated actor, or explicit frame clock set, in the future
a timeline will not know how to progress, as there will be no singe
frame clock to assume is the main one. Thus, deprecate the construction
of timelines without either an actor or frame clock set.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
2020-07-02 19:36:50 +02:00

250 lines
8.0 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>
typedef struct _TestMultiLayerMaterialState
{
ClutterActor *group;
CoglHandle alpha_tex;
CoglHandle redhand_tex;
gfloat *tex_coords;
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;
int
test_cogl_multitexture_main (int argc, char *argv[]);
const char *
test_cogl_multitexture_describe (void);
static void
frame_cb (ClutterTimeline *timeline,
gint frame_no,
gpointer data)
{
TestMultiLayerMaterialState *state = data;
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
material_rectangle_paint (ClutterActor *actor,
ClutterPaintContext *paint_context,
gpointer data)
{
TestMultiLayerMaterialState *state = data;
CoglFramebuffer *framebuffer =
clutter_paint_context_get_framebuffer (paint_context);
cogl_framebuffer_push_matrix (framebuffer);
cogl_framebuffer_translate (framebuffer, 150, 15, 0);
cogl_framebuffer_draw_multitextured_rectangle (framebuffer,
COGL_FRAMEBUFFER (state->material0),
0, 0, 200, 213,
state->tex_coords,
12);
cogl_framebuffer_translate (framebuffer, -300, -30, 0);
cogl_framebuffer_draw_multitextured_rectangle (framebuffer,
COGL_FRAMEBUFFER (state->material1),
0, 0, 200, 213,
state->tex_coords,
12);
cogl_framebuffer_pop_matrix (framebuffer);
}
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;
ClutterActor *stage;
ClutterColor stage_color = { 0x61, 0x56, 0x56, 0xff };
g_autofree TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
gfloat stage_w, stage_h;
gchar **files;
gfloat tex_coords[] =
{
/* tx1 ty1 tx2 ty2 */
0, 0, 1, 1,
0, 0, 1, 1,
0, 0, 1, 1
};
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
return 1;
stage = clutter_stage_new ();
clutter_actor_get_size (stage, &stage_w, &stage_h);
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl: Multi-texturing");
clutter_actor_set_background_color (CLUTTER_ACTOR (stage), &stage_color);
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
/* 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_actor_new ();
clutter_actor_set_position (state->group, stage_w / 2, stage_h / 2);
g_signal_connect (state->group, "paint",
G_CALLBACK(material_rectangle_paint), state);
files = g_new (gchar*, 4);
files[0] = g_build_filename (TESTS_DATADIR, "redhand_alpha.png", NULL);
files[1] = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
files[2] = g_build_filename (TESTS_DATADIR, "light0.png", NULL);
files[3] = NULL;
state->alpha_tex =
cogl_texture_new_from_file (files[0],
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY,
&error);
if (!state->alpha_tex)
g_critical ("Failed to load redhand_alpha.png: %s", error->message);
state->redhand_tex =
cogl_texture_new_from_file (files[1],
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY,
&error);
if (!state->redhand_tex)
g_critical ("Failed to load redhand.png: %s", error->message);
state->light_tex0 =
cogl_texture_new_from_file (files[2],
COGL_TEXTURE_NO_SLICING,
COGL_PIXEL_FORMAT_ANY,
&error);
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->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_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_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_translation (data->parent_container, -86.f, -125.f, 0.f);
clutter_container_add_actor (CLUTTER_CONTAINER(stage),
state->group);
state->timeline = clutter_timeline_new_for_actor (stage, 2812);
g_signal_connect (state->timeline, "new-frame", G_CALLBACK (frame_cb), state);
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 (state->timeline);
clutter_actor_show (stage);
clutter_main();
cogl_object_unref (state->material1);
cogl_object_unref (state->material0);
cogl_object_unref (state->alpha_tex);
cogl_object_unref (state->redhand_tex);
cogl_object_unref (state->light_tex0);
cogl_object_unref (state->light_tex1);
g_free (state);
return 0;
}
G_MODULE_EXPORT const char *
test_cogl_multitexture_describe (void)
{
return "Multi-texturing support in Cogl.";
}