mutter/tests/test-clip.c
Neil Roberts 8bdb98736d Applied 'final patch' from bug #874
* clutter/cogl/gles/cogl.c:
	* clutter/cogl/gl/cogl.c: The clip planes are now set using the
	inverse projection matrix as the modelview matrix so that they can
	be specified in screen coordinates.

	* clutter/cogl/gles/cogl-context.h (CoglContext):
	* clutter/cogl/gl/cogl-context.h (CoglContext): Added a member to
	cache the inverse projection matrix

	* clutter/clutter-fixed.h: Added a constant for converting from
	radians to degrees.

	* clutter/clutter-fixed.c (clutter_atani, clutter_atan2i): Added
	fixed-point versions of atan and atan2.

	* tests/test-clip.c: Added a test for clipping with various
	rotations and depths.

	* tests/Makefile.am (noinst_PROGRAMS): Added test-clip
2008-06-02 12:34:10 +00:00

129 lines
3.5 KiB
C

#include <clutter/clutter.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define TL_SCALE 5.0f
typedef struct _CallbackData CallbackData;
struct _CallbackData
{
ClutterActor *stage, *group, *rect, *hand;
};
static void
on_new_frame (ClutterTimeline *tl, int frame_num, CallbackData *data)
{
int i;
int stage_width = clutter_actor_get_width (data->stage);
int stage_height = clutter_actor_get_height (data->stage);
gdouble progress = clutter_timeline_get_progress (tl);
gdouble angle = progress * 2 * M_PI * TL_SCALE;
gdouble rotation[3];
gdouble xpos = stage_width * 0.45 * sin (angle) + stage_width / 8;
gdouble ypos = stage_height * 0.45 * sin (angle) + stage_height / 8;
gdouble zpos = stage_width * cos (angle) - stage_width / 2;
clutter_actor_set_position (data->hand, xpos, ypos);
clutter_actor_set_depth (data->hand, zpos);
clutter_actor_set_rotation (data->hand, CLUTTER_Y_AXIS,
angle / M_PI * 180.0 * 3,
clutter_actor_get_width (data->hand) / 2,
clutter_actor_get_height (data->hand) / 2,
0);
memset (rotation, 0, sizeof (rotation));
if (progress < 1 / 3.0)
rotation[2] = 360 * progress * 3;
else if (progress < 2 / 3.0)
rotation[1] = 360 * progress * 3;
else
rotation[0] = 360 * progress * 3;
for (i = 0; i < 3; i++)
{
clutter_actor_set_rotation (data->group, i,
rotation[i],
clutter_actor_get_width (data->rect) / 2,
clutter_actor_get_height (data->rect) / 2,
0);
clutter_actor_set_rotation (data->rect, i,
rotation[i],
clutter_actor_get_width (data->rect) / 2,
clutter_actor_get_height (data->rect) / 2,
0);
}
}
int
main (int argc, char **argv)
{
ClutterGeometry geom;
ClutterTimeline *tl;
ClutterColor blue = { 0x40, 0x40, 0xff, 0xff };
CallbackData data;
ClutterActor *other_hand;
int x, y;
clutter_init (&argc, &argv);
data.stage = clutter_stage_get_default ();
data.group = clutter_group_new ();
clutter_actor_get_geometry (data.stage, &geom);
geom.x = geom.width / 4;
geom.y = geom.height / 4;
geom.width /= 2;
geom.height /= 2;
clutter_actor_set_geometry (data.group, &geom);
data.rect = clutter_rectangle_new_with_color (&blue);
clutter_actor_set_geometry (data.rect, &geom);
clutter_container_add (CLUTTER_CONTAINER (data.stage), data.rect, NULL);
clutter_container_add (CLUTTER_CONTAINER (data.stage), data.group, NULL);
clutter_actor_set_clip (data.group, 0, 0, geom.width, geom.height);
data.hand = clutter_texture_new_from_file ("redhand.png", NULL);
if (data.hand == NULL)
{
g_critical ("pixbuf loading failed");
exit (1);
}
clutter_container_add (CLUTTER_CONTAINER (data.group), data.hand, NULL);
/* Add a hand at each of the four corners of the group */
for (y = 0; y < 2; y++)
for (x = 0; x < 2; x++)
{
other_hand = clutter_clone_texture_new (CLUTTER_TEXTURE (data.hand));
clutter_actor_set_anchor_point_from_gravity
(other_hand, CLUTTER_GRAVITY_CENTER);
clutter_actor_set_position (other_hand,
x * geom.width,
y * geom.height);
clutter_container_add (CLUTTER_CONTAINER (data.group),
other_hand, NULL);
}
clutter_actor_raise_top (data.hand);
tl = clutter_timeline_new (360 * TL_SCALE, 60);
clutter_timeline_start (tl);
clutter_timeline_set_loop (tl, TRUE);
g_signal_connect (tl, "new-frame", G_CALLBACK (on_new_frame), &data);
clutter_actor_show (data.stage);
clutter_main ();
return 0;
}