static void uqi_scene_view_real_paint (ClutterActor* base) { UqiSceneView *self; UqiSceneViewPrivate *priv; self = (UqiSceneView*) base; priv = self->priv; CoglColor color = priv->color; cogl_push_matrix (); cogl_translate (priv->translate_x, priv->translate_y, priv->translate_z); cogl_rotate (priv->rx, 1, 0, 0); cogl_rotate (priv->ry, 0, 1, 0); cogl_set_depth_test_enabled (TRUE); if (self->printable != NULL) { GSList *it = NULL; for (it = self->printable->vertex_list; it != NULL; it = it->next) { Vertex3D *v1 = (Vertex3D*)it->data; it = it->next; Vertex3D *v2 = (Vertex3D*)it->data; it = it->next; Vertex3D *v3 = (Vertex3D*)it->data; CoglTextureVertex vertex[3] = { {7*v1->x, 7*v1->y, 7*v1->z, .color = color}, {7*v2->x, 7*v2->y, 7*v2->z, .color = color}, {7*v3->x, 7*v3->y, 7*v3->z, .color = color}, };
static void aisleriot_card_paint (ClutterActor *actor) { AisleriotCard *card = (AisleriotCard *) actor; AisleriotCardPrivate *priv = card->priv; CoglHandle top_tex, bottom_tex; ClutterActorBox alloc_box; cogl_enable_backface_culling (TRUE); top_tex = games_card_textures_cache_get_card_texture (priv->cache, priv->top_card); bottom_tex = games_card_textures_cache_get_card_texture (priv->cache, priv->bottom_card); if (G_UNLIKELY (top_tex == COGL_INVALID_HANDLE || bottom_tex == COGL_INVALID_HANDLE)) return; clutter_actor_get_allocation_box (actor, &alloc_box); /* Draw both sides of the card. Backface culling is enabled so only one side will actually be rendered */ cogl_set_source_texture (top_tex); cogl_rectangle (0.0f, 0.0f, CLUTTER_UNITS_TO_FLOAT (alloc_box.x2 - alloc_box.x1), CLUTTER_UNITS_TO_FLOAT (alloc_box.y2 - alloc_box.y1)); cogl_set_source_texture (bottom_tex); /* Rotate along the y-axis about the center of the card to make the bottom of the card face the other way */ cogl_push_matrix (); cogl_translate (CLUTTER_UNITS_TO_DEVICE (alloc_box.x2 - alloc_box.x1) / 2, 0, 0); cogl_rotate (180, 0, 1, 0); cogl_translate (-CLUTTER_UNITS_TO_DEVICE (alloc_box.x2 - alloc_box.x1) / 2, 0, 0); cogl_rectangle (0.0f, 0.0f, CLUTTER_UNITS_TO_FLOAT (alloc_box.x2 - alloc_box.x1), CLUTTER_UNITS_TO_FLOAT (alloc_box.y2 - alloc_box.y1)); cogl_pop_matrix (); cogl_enable_backface_culling (FALSE); }
static void on_paint (ClutterActor *actor, CallbackData *data) { int i; ClutterGeometry stage_size; gint hand_width, hand_height; GSList *node; clutter_actor_get_allocation_geometry (data->stage, &stage_size); hand_width = cogl_texture_get_width (data->hand); hand_height = cogl_texture_get_height (data->hand); /* Setup the clipping */ for (node = data->clips; node; node = node->next) { Clip *clip = (Clip *) node->data; if (clip->type == CLIP_RECTANGLE) cogl_clip_push_rectangle (clip->x1, clip->y1, clip->x2, clip->y2); else if (clip->type == CLIP_ROTATED_RECTANGLE) { float size = MIN (ABS (clip->x2 - clip->x1), ABS (clip->y2 - clip->y1)); int cx = (clip->x1 + clip->x2) / 2; int cy = (clip->y1 + clip->y2) / 2; size = sqrtf ((size / 2) * (size / 2) * 2); cogl_push_matrix (); /* Rotate 45° about the centre point */ cogl_translate (cx, cy, 0.0f); cogl_rotate (45.0f, 0.0f, 0.0f, 1.0f); cogl_clip_push_rectangle (-size / 2, -size / 2, size / 2, size / 2); cogl_pop_matrix (); } else { make_clip_path (clip); cogl_clip_push_from_path (); } } /* Draw a rectangle filling the entire stage */ cogl_set_source_color4ub (0x80, 0x80, 0xff, 0xff); cogl_rectangle (0, 0, stage_size.width, stage_size.height); draw_shapes (10, 10); /* Draw the hand at different rotations */ for (i = -2; i <= 2; i++) { cogl_push_matrix (); cogl_translate (stage_size.width / 2 + stage_size.width / 6 * i, stage_size.height / 2, 0); cogl_rotate (i * 40, 0, 1, 0); cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); cogl_set_source_texture (data->hand); cogl_rectangle_with_texture_coords ((-hand_width / 2), (-hand_height / 2), (hand_width / 2), (hand_height / 2), 0, 0, 1, 1); cogl_pop_matrix (); } draw_shapes (stage_size.width - 310, stage_size.height - 110); /* Remove all of the clipping */ g_slist_foreach (data->clips, (GFunc) cogl_clip_pop, NULL); /* Draw the bounding box for each of the clips */ for (node = data->clips; node; node = node->next) { Clip *clip = (Clip *) node->data; make_clip_path (clip); cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff); cogl_path_stroke (); } /* Draw the bounding box for the pending new clip */ if (data->current_clip.type != CLIP_NONE) { make_clip_path (&data->current_clip); cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); cogl_path_stroke (); } }
static void test_rectangles (TestState *state) { #define RECT_WIDTH 5 #define RECT_HEIGHT 5 int x; int y; /* Should the rectangles be randomly positioned/colored/rotated? * * It could be good to develop equivalent GL and Cairo tests so we can * have a sanity check for our Cogl performance. * * The color should vary to check that we correctly batch color changes * The use of alpha should vary so we have a variation of which rectangles * require blending. * Should this be a random variation? * It could be good to experiment with focibly enabling blending for * rectangles that don't technically need it for the sake of extending * batching. E.g. if you a long run of interleved rectangles with every * other rectangle needing blending then it may be worth enabling blending * for all the rectangles to avoid the state changes. * The modelview should change between rectangles to check the software * transform codepath. * Should we group some rectangles under the same modelview? Potentially * we could avoid software transform for long runs of rectangles with the * same modelview. * */ for (y = 0; y < STAGE_HEIGHT; y += RECT_HEIGHT) { for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH) { cogl_push_matrix (); cogl_translate (x, y, 0); cogl_rotate (45, 0, 0, 1); cogl_set_source_color4f (1, (1.0f/STAGE_WIDTH)*y, (1.0f/STAGE_HEIGHT)*x, 1); cogl_rectangle (0, 0, RECT_WIDTH, RECT_HEIGHT); cogl_pop_matrix (); } } for (y = 0; y < STAGE_HEIGHT; y += RECT_HEIGHT) { for (x = 0; x < STAGE_WIDTH; x += RECT_WIDTH) { cogl_push_matrix (); cogl_translate (x, y, 0); cogl_rotate (0, 0, 0, 1); cogl_set_source_color4f (1, (1.0f/STAGE_WIDTH)*x, (1.0f/STAGE_HEIGHT)*y, (1.0f/STAGE_WIDTH)*x); cogl_rectangle (0, 0, RECT_WIDTH, RECT_HEIGHT); cogl_pop_matrix (); } } }
static void on_paint (ClutterActor *actor, void *state) { float saved_viewport[4]; CoglMatrix saved_projection; CoglMatrix projection; CoglMatrix modelview; guchar *data; CoglHandle tex; CoglHandle offscreen; CoglColor black; float x0; float y0; float width; float height; /* for clearing the offscreen framebuffer to black... */ cogl_color_init_from_4ub (&black, 0x00, 0x00, 0x00, 0xff); cogl_get_viewport (saved_viewport); cogl_get_projection_matrix (&saved_projection); cogl_push_matrix (); cogl_matrix_init_identity (&projection); cogl_matrix_init_identity (&modelview); cogl_set_projection_matrix (&projection); cogl_set_modelview_matrix (&modelview); /* - Create a 100x200 viewport (i.e. smaller than the onscreen framebuffer) * and position it a (20, 10) inside the framebuffer. * - Fill the whole viewport with a purple rectangle * - Verify that the framebuffer is black with a 100x200 purple rectangle at * (20, 10) */ cogl_set_viewport (20, /* x */ 10, /* y */ 100, /* width */ 200); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* fill the viewport with purple.. */ cogl_set_source_color4ub (0xff, 0x00, 0xff, 0xff); cogl_rectangle (-1, 1, 1, -1); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0xff, 0x00, 0xff); /* - Create a viewport twice the size of the onscreen framebuffer with * a negative offset positioning it at (-20, -10) relative to the * buffer itself. * - Draw a 100x200 green rectangle at (40, 20) within the viewport (which * is (20, 10) within the framebuffer) * - Verify that the framebuffer is black with a 100x200 green rectangle at * (20, 10) */ cogl_set_viewport (-20, /* x */ -10, /* y */ FRAMEBUFFER_WIDTH * 2, /* width */ FRAMEBUFFER_HEIGHT * 2); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* draw a 100x200 green rectangle offset into the viewport such that its * top left corner should be found at (20, 10) in the offscreen buffer */ /* (offset 40 pixels right from the left of the viewport) */ x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f; /* (offset 20 pixels down from the top of the viewport) */ y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f; width = (1.0f / FRAMEBUFFER_WIDTH) * 100; height = (1.0f / FRAMEBUFFER_HEIGHT) * 200; cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff); cogl_rectangle (x0, y0, x0 + width, y0 - height); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0x00, 0xff, 0x00); /* - Create a 200x400 viewport and position it a (20, 10) inside the draw * buffer. * - Push a 100x200 window space clip rectangle at (20, 10) * - Fill the whole viewport with a blue rectangle * - Verify that the framebuffer is black with a 100x200 blue rectangle at * (20, 10) */ cogl_set_viewport (20, /* x */ 10, /* y */ 200, /* width */ 400); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); cogl_clip_push_window_rectangle (20, 10, 100, 200); /* fill the viewport with blue.. */ cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff); cogl_rectangle (-1, 1, 1, -1); cogl_clip_pop (); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0x00, 0x00, 0xff); /* - Create a 200x400 viewport and position it a (20, 10) inside the draw * buffer. * - Push a 100x200 model space clip rectangle at (20, 10) in the viewport * (i.e. (40, 20) inside the framebuffer) * - Fill the whole viewport with a green rectangle * - Verify that the framebuffer is black with a 100x200 green rectangle at * (40, 20) */ cogl_set_viewport (20, /* x */ 10, /* y */ 200, /* width */ 400); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* figure out where to position our clip rectangle in model space * coordinates... */ /* (offset 40 pixels right from the left of the viewport) */ x0 = -1.0f + (2.0f / 200) * 20.f; /* (offset 20 pixels down from the top of the viewport) */ y0 = 1.0f - (2.0f / 400) * 10.0f; width = (2.0f / 200) * 100; height = (2.0f / 400) * 200; /* add the clip rectangle... */ cogl_push_matrix (); cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0); /* XXX: Rotate just enough to stop Cogl from converting our model space * rectangle into a window space rectangle.. */ cogl_rotate (0.1, 0, 0, 1); cogl_clip_push_rectangle (-(width/2.0), -(height/2.0), width/2.0, height/2.0); cogl_pop_matrix (); /* fill the viewport with green.. */ cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff); cogl_rectangle (-1, 1, 1, -1); cogl_clip_pop (); assert_rectangle_color_and_black_border (40, 20, 100, 200, 0x00, 0xff, 0x00); /* Set the viewport to something specific so we can verify that it gets * restored after we are done testing with an offscreen framebuffer... */ cogl_set_viewport (20, 10, 100, 200); /* * Next test offscreen drawing... */ data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT); tex = cogl_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT, COGL_TEXTURE_NO_SLICING, COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */ COGL_PIXEL_FORMAT_ANY, /* internal fmt */ FRAMEBUFFER_WIDTH * 4, /* rowstride */ data); g_free (data); offscreen = cogl_offscreen_new_to_texture (tex); cogl_push_framebuffer (offscreen); /* - Create a 100x200 viewport (i.e. smaller than the offscreen framebuffer) * and position it a (20, 10) inside the framebuffer. * - Fill the whole viewport with a blue rectangle * - Verify that the framebuffer is black with a 100x200 blue rectangle at * (20, 10) */ cogl_set_viewport (20, /* x */ 10, /* y */ 100, /* width */ 200); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* fill the viewport with blue.. */ cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff); cogl_rectangle (-1, 1, 1, -1); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0x00, 0x00, 0xff); /* - Create a viewport twice the size of the offscreen framebuffer with * a negative offset positioning it at (-20, -10) relative to the * buffer itself. * - Draw a 100x200 red rectangle at (40, 20) within the viewport (which * is (20, 10) within the framebuffer) * - Verify that the framebuffer is black with a 100x200 red rectangle at * (20, 10) */ cogl_set_viewport (-20, /* x */ -10, /* y */ FRAMEBUFFER_WIDTH * 2, /* width */ FRAMEBUFFER_HEIGHT * 2); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* draw a 100x200 red rectangle offset into the viewport such that its * top left corner should be found at (20, 10) in the offscreen buffer */ /* (offset 40 pixels right from the left of the viewport) */ x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f; /* (offset 20 pixels down from the top of the viewport) */ y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f; width = (1.0f / FRAMEBUFFER_WIDTH) * 100; height = (1.0f / FRAMEBUFFER_HEIGHT) * 200; cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff); cogl_rectangle (x0, y0, x0 + width, y0 - height); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0xff, 0x00, 0x00); /* - Create a 200x400 viewport and position it a (20, 10) inside the draw * buffer. * - Push a 100x200 window space clip rectangle at (20, 10) * - Fill the whole viewport with a blue rectangle * - Verify that the framebuffer is black with a 100x200 blue rectangle at * (20, 10) */ cogl_set_viewport (20, /* x */ 10, /* y */ 200, /* width */ 400); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); cogl_clip_push_window_rectangle (20, 10, 100, 200); /* fill the viewport with blue.. */ cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff); cogl_rectangle (-1, 1, 1, -1); cogl_clip_pop (); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0x00, 0x00, 0xff); /* - Create a 200x400 viewport and position it a (20, 10) inside the draw * buffer. * - Push a 100x200 model space clip rectangle at (20, 10) in the viewport * (i.e. (40, 20) inside the framebuffer) * - Fill the whole viewport with a green rectangle * - Verify that the framebuffer is black with a 100x200 green rectangle at * (40, 20) */ cogl_set_viewport (20, /* x */ 10, /* y */ 200, /* width */ 400); /* height */ /* clear everything... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); /* figure out where to position our clip rectangle in model space * coordinates... */ /* (offset 40 pixels right from the left of the viewport) */ x0 = -1.0f + (2.0f / 200) * 20.f; /* (offset 20 pixels down from the top of the viewport) */ y0 = 1.0f - (2.0f / 400) * 10.0f; width = (2.0f / 200) * 100; height = (2.0f / 400) * 200; /* add the clip rectangle... */ cogl_push_matrix (); cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0); /* XXX: Rotate just enough to stop Cogl from converting our model space * rectangle into a window space rectangle.. */ cogl_rotate (0.1, 0, 0, 1); cogl_clip_push_rectangle (-(width/2.0), -(height/2.0), width/2, height/2); cogl_pop_matrix (); /* fill the viewport with green.. */ cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff); cogl_rectangle (-1, 1, 1, -1); cogl_clip_pop (); assert_rectangle_color_and_black_border (40, 20, 100, 200, 0x00, 0xff, 0x00); /* Set the viewport to something obscure to verify that it gets * replace when we switch back to the onscreen framebuffer... */ cogl_set_viewport (0, 0, 10, 10); cogl_pop_framebuffer (); cogl_handle_unref (offscreen); /* * Verify that the previous onscreen framebuffer's viewport was restored * by drawing a white rectangle across the whole viewport. This should * draw a 100x200 rectangle at (20,10) relative to the onscreen draw * buffer... */ cogl_clear (&black, COGL_BUFFER_BIT_COLOR); cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); cogl_rectangle (-1, 1, 1, -1); assert_rectangle_color_and_black_border (20, 10, 100, 200, 0xff, 0xff, 0xff); /* Uncomment to display the last contents of the offscreen framebuffer */ #if 1 cogl_matrix_init_identity (&projection); cogl_matrix_init_identity (&modelview); cogl_set_viewport (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT); cogl_set_projection_matrix (&projection); cogl_set_modelview_matrix (&modelview); cogl_set_source_texture (tex); cogl_rectangle (-1, 1, 1, -1); #endif cogl_handle_unref (tex); /* Finally restore the stage's original state... */ cogl_pop_matrix (); cogl_set_projection_matrix (&saved_projection); cogl_set_viewport (saved_viewport[0], saved_viewport[1], saved_viewport[2], saved_viewport[3]); /* Comment this out if you want visual feedback of what this test * paints. */ clutter_main_quit (); }