Created
December 18, 2012 19:16
-
-
Save emanueleaina/4331002 to your computer and use it in GitHub Desktop.
Experiment with setting an ortographic projection matrix on the framebuffer from a container Actor.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define COGL_ENABLE_EXPERIMENTAL_API | |
#include <stdlib.h> | |
#include <cogl/cogl.h> | |
#include <clutter/clutter.h> | |
/* TrContainerActor * | |
********************/ | |
typedef struct _TrContainerActor TrContainerActor; | |
#define TR_TYPE_CONTAINER_ACTOR (tr_container_actor_get_type ()) | |
#define TR_CONTAINER_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TR_TYPE_CONTAINER_ACTOR, TrContainerActor)) | |
#define TR_IS_CONTAINER_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TR_TYPE_CONTAINER_ACTOR)) | |
#define TR_CONTAINER_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TR_TYPE_CONTAINER_ACTOR, TrContainerActorClass)) | |
#define TR_IS_CONTAINER_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TR_TYPE_CONTAINER_ACTOR)) | |
#define TR_CONTAINER_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TR_TYPE_CONTAINER_ACTOR, TrContainerActorClass)) | |
typedef struct _TrContainerActorPrivate TrContainerActorPrivate; | |
typedef struct _TrContainerActorClass TrContainerActorClass; | |
struct _TrContainerActor | |
{ | |
ClutterActor parent_instance; | |
TrContainerActorPrivate *priv; | |
}; | |
struct _TrContainerActorClass | |
{ | |
ClutterActorClass parent_instance; | |
}; | |
enum _TrProjectionType | |
{ | |
PROJECTION_PERSPECTIVE, | |
PROJECTION_ORTHOGRAPHIC | |
}; | |
typedef enum _TrProjectionType TrProjectionType; | |
struct _TrContainerActorPrivate | |
{ | |
TrProjectionType projection_type; | |
}; | |
G_DEFINE_TYPE (TrContainerActor, tr_container_actor, CLUTTER_TYPE_ACTOR) | |
static void | |
tr_container_actor_apply_transform (ClutterActor *actor, | |
CoglMatrix *transform) | |
{ | |
CLUTTER_ACTOR_CLASS (tr_container_actor_parent_class)->apply_transform (actor, transform); | |
} | |
static void | |
tr_container_actor_paint (ClutterActor *actor) | |
{ | |
CoglMatrix saved_projection; | |
CoglFramebuffer *fb; | |
fb = cogl_get_draw_framebuffer (); | |
cogl_framebuffer_get_projection_matrix (fb, &saved_projection); | |
{ | |
float viewport[4]; | |
cogl_framebuffer_get_viewport4fv (fb, viewport); | |
g_print ("viewport:%.2fx%.2f+%.2f+%.2f size:%dx%d\n", viewport[2], viewport[3], viewport[0], viewport[1], cogl_framebuffer_get_width (fb), cogl_framebuffer_get_height (fb)); | |
switch (TR_CONTAINER_ACTOR(actor)->priv->projection_type) | |
{ | |
case PROJECTION_PERSPECTIVE: | |
cogl_framebuffer_perspective (fb, 90, viewport[2]/ viewport[3], 0.1, 10.0); | |
CLUTTER_ACTOR_CLASS (tr_container_actor_parent_class)->paint (actor); | |
break; | |
case PROJECTION_ORTHOGRAPHIC: | |
cogl_framebuffer_orthographic (fb, viewport[0], viewport[1], viewport[2], viewport[3], -100.0, 100.0); | |
cogl_framebuffer_push_matrix (fb); | |
cogl_framebuffer_identity_matrix (fb); | |
CLUTTER_ACTOR_CLASS (tr_container_actor_parent_class)->paint (actor); | |
cogl_framebuffer_pop_matrix (fb); | |
break; | |
} | |
} | |
cogl_framebuffer_set_projection_matrix (fb, &saved_projection); | |
} | |
static void | |
tr_container_actor_class_init (TrContainerActorClass *klass) | |
{ | |
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); | |
g_type_class_add_private (klass, sizeof (TrContainerActorPrivate)); | |
actor_class->apply_transform = tr_container_actor_apply_transform; | |
actor_class->paint = tr_container_actor_paint; | |
} | |
static void | |
tr_container_actor_init (TrContainerActor *self) | |
{ | |
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TR_TYPE_CONTAINER_ACTOR, | |
TrContainerActorPrivate); | |
} | |
ClutterActor * | |
tr_container_actor_new (void) | |
{ | |
return g_object_new (TR_TYPE_CONTAINER_ACTOR, NULL); | |
} | |
/* TrActor * | |
***********/ | |
typedef struct _TrActor TrActor; | |
#define TR_TYPE_ACTOR (tr_actor_get_type ()) | |
#define TR_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TR_TYPE_ACTOR, TrActor)) | |
#define TR_IS_ACTOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TR_TYPE_ACTOR)) | |
#define TR_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TR_TYPE_ACTOR, TrActorClass)) | |
#define TR_IS_ACTOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TR_TYPE_ACTOR)) | |
#define TR_ACTOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TR_TYPE_ACTOR, TrActorClass)) | |
typedef struct _TrActorPrivate TrActorPrivate; | |
typedef struct _TrActorClass TrActorClass; | |
struct _TrActor | |
{ | |
ClutterActor parent_instance; | |
TrActorPrivate *priv; | |
}; | |
struct _TrActorClass | |
{ | |
ClutterActorClass parent_instance; | |
}; | |
struct _TrActorPrivate | |
{ | |
gint _placeholder; // Prevents the private struct from being 0-sized | |
}; | |
G_DEFINE_TYPE (TrActor, tr_actor, CLUTTER_TYPE_ACTOR) | |
static void | |
tr_actor_apply_transform (ClutterActor *actor, | |
CoglMatrix *transform) | |
{ | |
CLUTTER_ACTOR_CLASS (tr_actor_parent_class)->apply_transform (actor, transform); | |
} | |
static void | |
tr_actor_paint (ClutterActor *actor) | |
{ | |
CLUTTER_ACTOR_CLASS (tr_actor_parent_class)->paint (actor); | |
} | |
static void | |
tr_actor_class_init (TrActorClass *klass) | |
{ | |
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass); | |
g_type_class_add_private (klass, sizeof (TrActorPrivate)); | |
actor_class->apply_transform = tr_actor_apply_transform; | |
actor_class->paint = tr_actor_paint; | |
} | |
static void | |
tr_actor_init (TrActor *self) | |
{ | |
self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, TR_TYPE_ACTOR, | |
TrActorPrivate); | |
} | |
ClutterActor * | |
tr_actor_new (void) | |
{ | |
return g_object_new (TR_TYPE_ACTOR, NULL); | |
} | |
/* main * | |
********/ | |
static gboolean | |
on_key_press (ClutterActor *stage G_GNUC_UNUSED, | |
ClutterEvent *event, | |
gpointer data) | |
{ | |
guint key_symbol; | |
ClutterActor *actor = CLUTTER_ACTOR (data); | |
key_symbol = clutter_event_get_key_symbol (event); | |
if (key_symbol == CLUTTER_KEY_space) | |
{ | |
TrContainerActor *container = TR_CONTAINER_ACTOR (clutter_actor_get_parent (actor)); | |
if (container->priv->projection_type == PROJECTION_PERSPECTIVE) | |
container->priv->projection_type = PROJECTION_ORTHOGRAPHIC; | |
else | |
container->priv->projection_type = PROJECTION_PERSPECTIVE; | |
clutter_actor_queue_redraw (CLUTTER_ACTOR (container)); | |
} | |
else if (key_symbol == CLUTTER_KEY_Right) | |
{ | |
float angle = clutter_actor_get_rotation_angle (actor, CLUTTER_Y_AXIS); | |
angle += 5; | |
clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, angle); | |
g_print ("angle:%.2f°\n", angle); | |
} | |
else if (key_symbol == CLUTTER_KEY_Left) | |
{ | |
float angle = clutter_actor_get_rotation_angle (actor, CLUTTER_Y_AXIS); | |
angle -= 5; | |
clutter_actor_set_rotation_angle (actor, CLUTTER_Y_AXIS, angle); | |
g_print ("angle:%.2f°\n", angle); | |
} | |
return CLUTTER_EVENT_STOP; | |
} | |
int | |
main (int argc, char *argv[]) | |
{ | |
ClutterActor *stage, *container, *untransformed, *transformed, *info; | |
ClutterAction *pan; | |
if (argc < 1) | |
{ | |
g_error ("Usage: %s", argv[0]); | |
return EXIT_FAILURE; | |
} | |
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) | |
{ | |
g_error ("Failed to initialize clutter\n"); | |
return EXIT_FAILURE; | |
} | |
stage = clutter_stage_new (); | |
clutter_actor_set_name (stage, "stage"); | |
pan = clutter_pan_action_new (); | |
clutter_actor_add_action (stage, pan); | |
container = tr_container_actor_new (); | |
clutter_actor_set_name (container, "container"); | |
clutter_actor_add_child (stage, container); | |
/* Reference actor */ | |
untransformed = tr_actor_new (); | |
clutter_actor_set_name (untransformed, "untransformed"); | |
clutter_actor_set_position (untransformed, 20, 40); | |
clutter_actor_set_size (untransformed, 60, 90); | |
clutter_actor_set_background_color (untransformed, CLUTTER_COLOR_Blue); | |
clutter_actor_add_child (container, untransformed); | |
/* Transformed actor */ | |
transformed = tr_actor_new (); | |
clutter_actor_set_name (transformed, "transformed"); | |
clutter_actor_set_position (transformed, 20, 40); | |
clutter_actor_set_size (transformed, 60, 90); | |
clutter_actor_set_background_color (transformed, CLUTTER_COLOR_Red); | |
clutter_actor_add_child (container, transformed); | |
clutter_actor_set_pivot_point (transformed, 0.5, 0.5); | |
clutter_actor_set_rotation_angle (transformed, CLUTTER_Y_AXIS, 45); | |
info = clutter_text_new_with_text (NULL, "3d transformation experiments"); | |
clutter_actor_add_child (stage, info); | |
clutter_actor_set_position (info, 12, 12); | |
g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); | |
g_signal_connect (stage, "key-press-event", G_CALLBACK (on_key_press), transformed); | |
clutter_actor_show (stage); | |
clutter_main (); | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment