From ffb592de5908d844b527cb4fe75b7195eb0dc55d Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Thu, 22 Oct 2009 19:01:27 +0100 Subject: [PATCH] [tests] test-backface-culling: test culling with offscreen rendering Since offscreen rendering is internally forced to be upside down Cogl needs to reverse the glFrontFace winding order so as not to interfere with the use of cogl_set_backface_culling_enabled() This ensures we test that mechanism. --- tests/conform/test-backface-culling.c | 174 +++++++++++++++++--------- 1 file changed, 112 insertions(+), 62 deletions(-) diff --git a/tests/conform/test-backface-culling.c b/tests/conform/test-backface-culling.c index 56cb8c45a..af45d3c9c 100644 --- a/tests/conform/test-backface-culling.c +++ b/tests/conform/test-backface-culling.c @@ -5,8 +5,6 @@ #include "test-conform-common.h" -static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; - #ifdef CLUTTER_COGL_HAS_GL /* Size the texture so that it is just off a power of two to enourage @@ -31,24 +29,31 @@ static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; typedef struct _TestState { - guint frame; CoglHandle texture; + CoglHandle offscreen; + CoglHandle offscreen_tex; } TestState; +#include + static gboolean validate_part (int xnum, int ynum, gboolean shown) { guchar *pixels, *p; - ClutterActor *stage = clutter_stage_get_default (); gboolean ret = TRUE; + pixels = g_malloc0 ((TEXTURE_RENDER_SIZE - TEST_INSET * 2) + * (TEXTURE_RENDER_SIZE - TEST_INSET * 2) * 4); + /* Read the appropriate part but skip out a few pixels around the edges */ - pixels = clutter_stage_read_pixels (CLUTTER_STAGE (stage), - xnum * TEXTURE_RENDER_SIZE + TEST_INSET, - ynum * TEXTURE_RENDER_SIZE + TEST_INSET, - TEXTURE_RENDER_SIZE - TEST_INSET * 2, - TEXTURE_RENDER_SIZE - TEST_INSET * 2); + cogl_read_pixels (xnum * TEXTURE_RENDER_SIZE + TEST_INSET, + ynum * TEXTURE_RENDER_SIZE + TEST_INSET, + TEXTURE_RENDER_SIZE - TEST_INSET * 2, + TEXTURE_RENDER_SIZE - TEST_INSET * 2, + COGL_READ_PIXELS_COLOR_BUFFER, + COGL_PIXEL_FORMAT_RGBA_8888, + pixels); /* Make sure every pixels is the appropriate color */ for (p = pixels; @@ -70,47 +75,9 @@ validate_part (int xnum, int ynum, gboolean shown) } static void -validate_result (TestState *state) -{ - /* Front-facing texture */ - g_assert (validate_part (0, 0, TRUE)); - /* Front-facing texture with flipped tex coords */ - g_assert (validate_part (1, 0, TRUE)); - /* Back-facing texture */ - g_assert (validate_part (2, 0, FALSE)); - /* Front-facing texture polygon */ - g_assert (validate_part (3, 0, TRUE)); - /* Back-facing texture polygon */ - g_assert (validate_part (4, 0, FALSE)); - /* Regular rectangle */ - g_assert (validate_part (5, 0, TRUE)); - - /* Backface culling disabled - everything should be shown */ - - /* Front-facing texture */ - g_assert (validate_part (0, 1, TRUE)); - /* Front-facing texture with flipped tex coords */ - g_assert (validate_part (1, 1, TRUE)); - /* Back-facing texture */ - g_assert (validate_part (2, 1, TRUE)); - /* Front-facing texture polygon */ - g_assert (validate_part (3, 1, TRUE)); - /* Back-facing texture polygon */ - g_assert (validate_part (4, 1, TRUE)); - /* Regular rectangle */ - g_assert (validate_part (5, 1, TRUE)); - - /* Comment this out if you want visual feedback of what this test - * paints. - */ - clutter_main_quit (); -} - -static void -on_paint (ClutterActor *actor, TestState *state) +do_test_backface_culling (TestState *state) { int i; - int frame_num; CoglHandle material = cogl_material_new (); cogl_material_set_layer_filters (material, 0, @@ -197,21 +164,91 @@ on_paint (ClutterActor *actor, TestState *state) cogl_set_backface_culling_enabled (FALSE); } - cogl_pop_matrix (); - cogl_handle_unref (material); - /* XXX: Experiments have shown that for some buggy drivers, when using - * glReadPixels there is some kind of race, so we delay our test for a - * few frames and a few seconds: + cogl_pop_matrix (); + + /* Front-facing texture */ + g_assert (validate_part (0, 0, TRUE)); + /* Front-facing texture with flipped tex coords */ + g_assert (validate_part (1, 0, TRUE)); + /* Back-facing texture */ + g_assert (validate_part (2, 0, FALSE)); + /* Front-facing texture polygon */ + g_assert (validate_part (3, 0, TRUE)); + /* Back-facing texture polygon */ + g_assert (validate_part (4, 0, FALSE)); + /* Regular rectangle */ + g_assert (validate_part (5, 0, TRUE)); + + /* Backface culling disabled - everything should be shown */ + + /* Front-facing texture */ + g_assert (validate_part (0, 1, TRUE)); + /* Front-facing texture with flipped tex coords */ + g_assert (validate_part (1, 1, TRUE)); + /* Back-facing texture */ + g_assert (validate_part (2, 1, TRUE)); + /* Front-facing texture polygon */ + g_assert (validate_part (3, 1, TRUE)); + /* Back-facing texture polygon */ + g_assert (validate_part (4, 1, TRUE)); + /* Regular rectangle */ + g_assert (validate_part (5, 1, TRUE)); + +} + +static void +on_paint (ClutterActor *actor, TestState *state) +{ + CoglColor clr; + float stage_viewport[4]; + CoglMatrix stage_projection; + CoglMatrix stage_modelview; + + cogl_color_set_from_4ub (&clr, 0x00, 0x00, 0x00, 0xff); + + do_test_backface_culling (state); + + /* Since we are going to repeat the test rendering offscreen we clear the + * stage, just to minimize the chance of a some other bug causing us + * mistakenly reading back the results from the stage and giving a false + * posistive. */ + cogl_clear (&clr, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_STENCIL); + + /* + * Now repeat the test but rendered to an offscreen draw buffer... */ - /* Need to increment frame first because clutter_stage_read_pixels - fires a redraw */ - frame_num = state->frame++; - if (frame_num == 2) - validate_result (state); - else if (frame_num < 2) - g_usleep (G_USEC_PER_SEC); + + cogl_get_viewport (stage_viewport); + cogl_get_projection_matrix (&stage_projection); + cogl_get_modelview_matrix (&stage_modelview); + + cogl_push_draw_buffer (); + cogl_set_draw_buffer (0 /* unused */, state->offscreen); + + cogl_clear (&clr, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_STENCIL); + + cogl_set_viewport (stage_viewport[0], + stage_viewport[1], + stage_viewport[2], + stage_viewport[3]); + cogl_set_projection_matrix (&stage_projection); + cogl_set_modelview_matrix (&stage_modelview); + + do_test_backface_culling (state); + + cogl_pop_draw_buffer (); + + /* Incase we want feedback of what was drawn offscreen we draw it + * to the stage... */ + cogl_set_source_texture (state->offscreen_tex); + cogl_rectangle (0, 0, stage_viewport[2], stage_viewport[3]); + + /* Comment this out if you want visual feedback of what this test + * paints. + */ + clutter_main_quit (); } static gboolean @@ -256,15 +293,26 @@ test_backface_culling (TestConformSimpleFixture *fixture, gconstpointer data) { TestState state; + CoglHandle tex; ClutterActor *stage; + float stage_width; + float stage_height; + const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff }; ClutterActor *group; guint idle_source; - state.frame = 0; + stage = clutter_stage_get_default (); + clutter_actor_get_size (stage, &stage_width, &stage_height); + + state.offscreen = COGL_INVALID_HANDLE; state.texture = make_texture (); - stage = clutter_stage_get_default (); + tex = cogl_texture_new_with_size (stage_width, stage_height, + COGL_TEXTURE_NO_SLICING, + COGL_PIXEL_FORMAT_ANY); /* internal fmt */ + state.offscreen = cogl_offscreen_new_to_texture (tex); + state.offscreen_tex = tex; clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); @@ -284,6 +332,8 @@ test_backface_culling (TestConformSimpleFixture *fixture, g_source_remove (idle_source); + cogl_handle_unref (state.offscreen); + cogl_handle_unref (state.offscreen_tex); cogl_handle_unref (state.texture); if (g_test_verbose ())