bb3dc013bf
The cookbook should also include fully functional code examples. We can even XInclude them into the docbook XML itself. The examples should be built with the coobook, so that we can always make sure they are up to date.
111 lines
3.5 KiB
C
111 lines
3.5 KiB
C
#include <stdlib.h>
|
|
#include <clutter/clutter.h>
|
|
|
|
/* pixels between the source and its reflection */
|
|
#define V_PADDING 4
|
|
|
|
static void
|
|
_clone_paint_cb (ClutterActor *actor)
|
|
{
|
|
ClutterActor *source;
|
|
ClutterActorBox box;
|
|
CoglHandle material;
|
|
gfloat width, height;
|
|
guint8 opacity;
|
|
CoglColor color_1, color_2;
|
|
CoglTextureVertex vertices[4];
|
|
|
|
/* if we don't have a source actor, don't paint */
|
|
source = clutter_clone_get_source (CLUTTER_CLONE (actor));
|
|
if (source == NULL)
|
|
goto out;
|
|
|
|
/* if the source texture does not have any content, don't paint */
|
|
material = clutter_texture_get_cogl_material (CLUTTER_TEXTURE (source));
|
|
if (material == NULL)
|
|
goto out;
|
|
|
|
/* get the size of the reflection */
|
|
clutter_actor_get_allocation_box (actor, &box);
|
|
clutter_actor_box_get_size (&box, &width, &height);
|
|
|
|
/* get the composite opacity of the actor */
|
|
opacity = clutter_actor_get_paint_opacity (actor);
|
|
|
|
/* figure out the two colors for the reflection: the first is
|
|
* full color and the second is the same, but at 0 opacity
|
|
*/
|
|
cogl_color_set_from_4f (&color_1, 1.0, 1.0, 1.0, opacity / 255.);
|
|
cogl_color_premultiply (&color_1);
|
|
cogl_color_set_from_4f (&color_2, 1.0, 1.0, 1.0, 0.0);
|
|
cogl_color_premultiply (&color_2);
|
|
|
|
/* now describe the four vertices of the quad; since it has
|
|
* to be a reflection, we need to invert it as well
|
|
*/
|
|
vertices[0].x = 0; vertices[0].y = 0; vertices[0].z = 0;
|
|
vertices[0].tx = 0.0; vertices[0].ty = 1.0;
|
|
vertices[0].color = color_1;
|
|
|
|
vertices[1].x = width; vertices[1].y = 0; vertices[1].z = 0;
|
|
vertices[1].tx = 1.0; vertices[1].ty = 1.0;
|
|
vertices[1].color = color_1;
|
|
|
|
vertices[2].x = width; vertices[2].y = height; vertices[2].z = 0;
|
|
vertices[2].tx = 1.0; vertices[2].ty = 0.0;
|
|
vertices[2].color = color_2;
|
|
|
|
vertices[3].x = 0; vertices[3].y = height; vertices[3].z = 0;
|
|
vertices[3].tx = 0.0; vertices[3].ty = 0.0;
|
|
vertices[3].color = color_2;
|
|
|
|
/* paint the same texture but with a different geometry */
|
|
cogl_set_source (material);
|
|
cogl_polygon (vertices, 4, TRUE);
|
|
|
|
out:
|
|
/* prevent the default clone handler from running */
|
|
g_signal_stop_emission_by_name (actor, "paint");
|
|
}
|
|
|
|
int
|
|
main (int argc, char *argv[])
|
|
{
|
|
clutter_init (&argc, &argv);
|
|
|
|
ClutterActor *stage;
|
|
|
|
stage = clutter_stage_new ();
|
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Reflection");
|
|
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);
|
|
|
|
ClutterActor *texture;
|
|
GError *error = NULL;
|
|
|
|
texture = clutter_texture_new ();
|
|
clutter_texture_set_from_file (CLUTTER_TEXTURE (texture),
|
|
"redhand.png",
|
|
&error);
|
|
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_X_AXIS, 0.5));
|
|
clutter_actor_add_constraint (texture, clutter_align_constraint_new (stage, CLUTTER_ALIGN_Y_AXIS, 0.2));
|
|
|
|
ClutterActor *clone;
|
|
gfloat y_offset = clutter_actor_get_height (texture) + V_PADDING;
|
|
|
|
clone = clutter_clone_new (texture);
|
|
clutter_actor_add_constraint (clone, clutter_bind_constraint_new (texture, CLUTTER_BIND_X, 0.0));
|
|
clutter_actor_add_constraint (clone, clutter_bind_constraint_new (texture, CLUTTER_BIND_Y, y_offset));
|
|
g_signal_connect (clone,
|
|
"paint",
|
|
G_CALLBACK (_clone_paint_cb),
|
|
NULL);
|
|
|
|
clutter_container_add (CLUTTER_CONTAINER (stage), texture, clone, NULL);
|
|
|
|
clutter_actor_show (stage);
|
|
|
|
clutter_main ();
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|