diff --git a/tests/conform/test-backface-culling.c b/tests/conform/test-backface-culling.c index 4beff1eb6..fc7caa457 100644 --- a/tests/conform/test-backface-culling.c +++ b/tests/conform/test-backface-culling.c @@ -10,10 +10,10 @@ /* Amount of pixels to skip off the top, bottom, left and right of the texture when reading back the stage */ -#define TEST_INSET 4 +#define TEST_INSET 2 /* Size to actually render the texture at */ -#define TEXTURE_RENDER_SIZE 32 +#define TEXTURE_RENDER_SIZE 8 typedef struct _TestState { @@ -24,49 +24,29 @@ typedef struct _TestState int width, height; } TestState; -static gboolean +static void validate_part (int xnum, int ynum, gboolean shown) { - guchar *pixels, *p; - 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 */ - 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_PRE, - pixels); - - /* Make sure every pixel is the appropriate color */ - for (p = pixels; - p < pixels + ((TEXTURE_RENDER_SIZE - TEST_INSET * 2) - * (TEXTURE_RENDER_SIZE - TEST_INSET * 2)); - p += 4) - { - if (p[0] != (shown ? 255 : 0)) - ret = FALSE; - if (p[1] != 0) - ret = FALSE; - if (p[2] != 0) - ret = FALSE; - } - - g_free (pixels); - - return ret; + test_utils_check_region (xnum * TEXTURE_RENDER_SIZE + TEST_INSET, + ynum * TEXTURE_RENDER_SIZE + TEST_INSET, + TEXTURE_RENDER_SIZE - TEST_INSET * 2, + TEXTURE_RENDER_SIZE - TEST_INSET * 2, + shown ? 0xff0000ff : 0x000000ff); } +/* We draw everything 16 times. The draw number is used as a bitmask + to test all of the combinations of enabling legacy state, both + winding orders and all four culling modes */ + +#define USE_LEGACY_STATE(draw_num) (((draw_num) & 0x01) >> 0) +#define FRONT_WINDING(draw_num) (((draw_num) & 0x02) >> 1) +#define CULL_FACE_MODE(draw_num) (((draw_num) & 0x0c) >> 2) + static void paint_test_backface_culling (TestState *state) { - int i; - CoglPipeline *pipeline = cogl_pipeline_new (); + int draw_num; + CoglPipeline *base_pipeline = cogl_pipeline_new (); CoglColor clear_color; cogl_ortho (0, state->width, /* left, right */ @@ -76,25 +56,30 @@ paint_test_backface_culling (TestState *state) cogl_color_init_from_4ub (&clear_color, 0x00, 0x00, 0x00, 0xff); cogl_clear (&clear_color, COGL_BUFFER_BIT_COLOR | COGL_BUFFER_BIT_STENCIL); - cogl_pipeline_set_layer_texture (pipeline, 0, state->texture); + cogl_pipeline_set_layer_texture (base_pipeline, 0, state->texture); - cogl_pipeline_set_layer_filters (pipeline, 0, + cogl_pipeline_set_layer_filters (base_pipeline, 0, COGL_PIPELINE_FILTER_NEAREST, COGL_PIPELINE_FILTER_NEAREST); - cogl_set_backface_culling_enabled (TRUE); - - cogl_push_matrix (); - - /* Render the scene twice - once with backface culling enabled and - once without. The second time is translated so that it is below - the first */ - for (i = 0; i < 2; i++) + /* Render the scene sixteen times to test all of the combinations of + cull face mode, legacy state and winding orders */ + for (draw_num = 0; draw_num < 16; draw_num++) { float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_RENDER_SIZE); CoglTextureVertex verts[4]; + CoglPipeline *pipeline; - cogl_set_source (pipeline); + cogl_push_matrix (); + cogl_translate (0, TEXTURE_RENDER_SIZE * draw_num, 0); + + pipeline = cogl_pipeline_copy (base_pipeline); + + cogl_set_backface_culling_enabled (USE_LEGACY_STATE (draw_num)); + cogl_pipeline_set_front_face_winding (pipeline, FRONT_WINDING (draw_num)); + cogl_pipeline_set_cull_face_mode (pipeline, CULL_FACE_MODE (draw_num)); + + cogl_push_source (pipeline); memset (verts, 0, sizeof (verts)); @@ -152,51 +137,71 @@ paint_test_backface_culling (TestState *state) x1 = x2; x2 = x1 + (float)(TEXTURE_RENDER_SIZE); - /* Draw a regular rectangle (this should always show) */ - cogl_set_source_color4f (1.0, 0, 0, 1.0); - cogl_rectangle (x1, y1, x2, y2); + cogl_pop_matrix (); - /* The second time round draw beneath the first with backface - culling disabled */ - cogl_translate (0, TEXTURE_RENDER_SIZE, 0); - cogl_set_backface_culling_enabled (FALSE); + cogl_pop_source (); + cogl_object_unref (pipeline); } - cogl_object_unref (pipeline); - - cogl_pop_matrix (); + cogl_object_unref (base_pipeline); } static void validate_result (int y_offset) { - /* Front-facing texture */ - g_assert (validate_part (0, y_offset + 0, TRUE)); - /* Front-facing texture with flipped tex coords */ - g_assert (validate_part (1, y_offset + 0, TRUE)); - /* Back-facing texture */ - g_assert (validate_part (2, y_offset + 0, FALSE)); - /* Front-facing texture polygon */ - g_assert (validate_part (3, y_offset + 0, TRUE)); - /* Back-facing texture polygon */ - g_assert (validate_part (4, y_offset + 0, FALSE)); - /* Regular rectangle */ - g_assert (validate_part (5, y_offset + 0, TRUE)); + int draw_num; - /* Backface culling disabled - everything should be shown */ + for (draw_num = 0; draw_num < 16; draw_num++) + { + gboolean cull_front, cull_back; + CoglPipelineCullFaceMode cull_mode; - /* Front-facing texture */ - g_assert (validate_part (0, y_offset + 1, TRUE)); - /* Front-facing texture with flipped tex coords */ - g_assert (validate_part (1, y_offset + 1, TRUE)); - /* Back-facing texture */ - g_assert (validate_part (2, y_offset + 1, TRUE)); - /* Front-facing texture polygon */ - g_assert (validate_part (3, y_offset + 1, TRUE)); - /* Back-facing texture polygon */ - g_assert (validate_part (4, y_offset + 1, TRUE)); - /* Regular rectangle */ - g_assert (validate_part (5, y_offset + 1, TRUE)); + if (USE_LEGACY_STATE (draw_num)) + cull_mode = COGL_PIPELINE_CULL_FACE_MODE_BACK; + else + cull_mode = CULL_FACE_MODE (draw_num); + + switch (cull_mode) + { + case COGL_PIPELINE_CULL_FACE_MODE_NONE: + cull_front = FALSE; + cull_back = FALSE; + break; + + case COGL_PIPELINE_CULL_FACE_MODE_FRONT: + cull_front = TRUE; + cull_back = FALSE; + break; + + case COGL_PIPELINE_CULL_FACE_MODE_BACK: + cull_front = FALSE; + cull_back = TRUE; + break; + + case COGL_PIPELINE_CULL_FACE_MODE_BOTH: + cull_front = TRUE; + cull_back = TRUE; + break; + } + + if (FRONT_WINDING (draw_num) == COGL_WINDING_CLOCKWISE) + { + gboolean tmp = cull_front; + cull_front = cull_back; + cull_back = tmp; + } + + /* Front-facing texture */ + validate_part (0, y_offset + draw_num, !cull_front); + /* Front-facing texture with flipped tex coords */ + validate_part (1, y_offset + draw_num, !cull_front); + /* Back-facing texture */ + validate_part (2, y_offset + draw_num, !cull_back); + /* Front-facing texture polygon */ + validate_part (3, y_offset + draw_num, !cull_front); + /* Back-facing texture polygon */ + validate_part (4, y_offset + draw_num, !cull_back); + } } static void @@ -235,12 +240,12 @@ paint (TestState *state) /* 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, TEXTURE_RENDER_SIZE * 2, + cogl_rectangle (0, TEXTURE_RENDER_SIZE * 16, stage_viewport[2], - stage_viewport[3] + TEXTURE_RENDER_SIZE * 2); + stage_viewport[3] + TEXTURE_RENDER_SIZE * 16); validate_result (0); - validate_result (2); + validate_result (16); } static CoglHandle