From 98a33e03d32efc8b551b80a1a5af065ea9e1f7a8 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Wed, 9 Feb 2011 15:12:13 +0000 Subject: [PATCH] Add a conformance test for cogl_pipeline_set_layer_matrix This adds a conformance test which paints using a pipeline that has two layers containing textures. Each layer has a different user matrix. When the two layers are combined with the right matrices then all of the colors end up white. The test then verifies this by reading back the pixels. --- tests/conform/Makefile.am | 1 + .../conform/test-cogl-pipeline-user-matrix.c | 144 ++++++++++++++++++ tests/conform/test-conform-main.c | 1 + 3 files changed, 146 insertions(+) create mode 100644 tests/conform/test-cogl-pipeline-user-matrix.c diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index 463764ad4..5d7e2959d 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -32,6 +32,7 @@ units_sources += \ test-cogl-depth-test.c \ test-cogl-fixed.c \ test-cogl-materials.c \ + test-cogl-pipeline-user-matrix.c \ test-cogl-viewport.c \ test-cogl-multitexture.c \ test-cogl-npot-texture.c \ diff --git a/tests/conform/test-cogl-pipeline-user-matrix.c b/tests/conform/test-cogl-pipeline-user-matrix.c new file mode 100644 index 000000000..afbeaaf00 --- /dev/null +++ b/tests/conform/test-cogl-pipeline-user-matrix.c @@ -0,0 +1,144 @@ +#include +#include + +#include "test-conform-common.h" + +static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff }; + +static void +paint_cb (ClutterActor *stage) +{ + /* This texture is painted mirrored around the x-axis */ + guint8 data0[] = { + 0xff, 0x00, 0x00, /* red -> becomes bottom left */ + 0x00, 0xff, 0x00, /* green -> becomes bottom right */ + 0x00, 0x00, 0xff, /* blue -> becomes top left */ + 0xff, 0x00, 0xff /* magenta -> becomes top right */ + }; + /* This texture is painted mirrored about the y-axis */ + guint8 data1[] = { + 0x00, 0xff, 0x00, /* green -> becomes top right */ + 0xff, 0xff, 0x00, /* yellow -> becomes top left */ + 0xff, 0x00, 0xff, /* magenta -> becomes bottom right */ + 0x00, 0xff, 0xff /* cyan -> becomes bottom left */ + }; + CoglHandle tex0, tex1; + CoglPipeline *pipeline; + CoglMatrix matrix; + int width, height; + guint8 *pixels, *p; + + width = clutter_actor_get_width (stage); + height = clutter_actor_get_height (stage); + + tex0 = cogl_texture_new_from_data (2, 2, + COGL_TEXTURE_NO_ATLAS, + COGL_PIXEL_FORMAT_RGB_888, + COGL_PIXEL_FORMAT_ANY, + 6, + data0); + tex1 = cogl_texture_new_from_data (2, 2, + COGL_TEXTURE_NO_ATLAS, + COGL_PIXEL_FORMAT_RGB_888, + COGL_PIXEL_FORMAT_ANY, + 6, + data1); + + pipeline = cogl_pipeline_new (); + + /* Set the two textures as layers */ + cogl_pipeline_set_layer_texture (pipeline, 0, tex0); + cogl_pipeline_set_layer_filters (pipeline, 0, + COGL_PIPELINE_FILTER_NEAREST, + COGL_PIPELINE_FILTER_NEAREST); + cogl_pipeline_set_layer_texture (pipeline, 1, tex1); + cogl_pipeline_set_layer_filters (pipeline, 1, + COGL_PIPELINE_FILTER_NEAREST, + COGL_PIPELINE_FILTER_NEAREST); + + /* Set a combine mode so that the two textures get added together */ + cogl_pipeline_set_layer_combine (pipeline, 1, + "RGBA=ADD(PREVIOUS, TEXTURE)", + NULL); + + /* Set a matrix on the first layer so that it will mirror about the y-axis */ + cogl_matrix_init_identity (&matrix); + cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f); + cogl_matrix_scale (&matrix, 1.0f, -1.0f, 1.0f); + cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix); + + /* Set a matrix on the second layer so that it will mirror about the x-axis */ + cogl_matrix_init_identity (&matrix); + cogl_matrix_translate (&matrix, 1.0f, 0.0f, 0.0f); + cogl_matrix_scale (&matrix, -1.0f, 1.0f, 1.0f); + cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix); + + cogl_set_source (pipeline); + cogl_rectangle (0, 0, width, height); + + cogl_handle_unref (tex1); + cogl_handle_unref (tex0); + cogl_object_unref (pipeline); + + /* The textures are setup so that when added together with the + correct matrices then all of the pixels should be white. We can + verify this by reading back the entire stage */ + pixels = g_malloc (width * height * 4); + + cogl_read_pixels (0, 0, width, height, + COGL_READ_PIXELS_COLOR_BUFFER, + COGL_PIXEL_FORMAT_RGBA_8888_PRE, + pixels); + + for (p = pixels + width * height * 4; p > pixels;) + { + p -= 4; + g_assert_cmpint (p[0], ==, 0xff); + g_assert_cmpint (p[1], ==, 0xff); + g_assert_cmpint (p[2], ==, 0xff); + } + + g_free (pixels); + + clutter_main_quit (); +} + +static gboolean +queue_redraw (gpointer stage) +{ + clutter_actor_queue_redraw (CLUTTER_ACTOR (stage)); + + return TRUE; +} + +void +test_cogl_pipeline_user_matrix (TestConformSimpleFixture *fixture, + gconstpointer data) +{ + ClutterActor *stage; + guint idle_source; + guint paint_handler; + + stage = clutter_stage_get_default (); + + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + + /* We force continuous redrawing of the stage, since we need to skip + * the first few frames, and we wont be doing anything else that + * will trigger redrawing. */ + idle_source = g_idle_add (queue_redraw, stage); + + paint_handler = g_signal_connect_after (stage, "paint", + G_CALLBACK (paint_cb), + NULL); + + clutter_actor_show (stage); + + clutter_main (); + + g_source_remove (idle_source); + g_signal_handler_disconnect (stage, paint_handler); + + if (g_test_verbose ()) + g_print ("OK\n"); +} diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 84d610ead..fae6a2045 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -213,6 +213,7 @@ main (int argc, char **argv) TEST_CONFORM_SIMPLE ("/cogl", test_cogl_fixed); TEST_CONFORM_SIMPLE ("/cogl", test_cogl_backface_culling); TEST_CONFORM_SIMPLE ("/cogl", test_cogl_materials); + TEST_CONFORM_SIMPLE ("/cogl", test_cogl_pipeline_user_matrix); TEST_CONFORM_SIMPLE ("/cogl", test_cogl_blend_strings); TEST_CONFORM_SIMPLE ("/cogl", test_cogl_premult); TEST_CONFORM_SIMPLE ("/cogl", test_cogl_readpixels);