"Initial commit to Gerrit"
[profile/ivi/cogl.git] / tests / conform / test-pipeline-user-matrix.c
1 #include <cogl/cogl.h>
2
3 #include <string.h>
4
5 #include "test-utils.h"
6
7 typedef struct _TestState
8 {
9   int width;
10   int height;
11 } TestState;
12
13 static void
14 validate_result (TestState *state)
15 {
16   guint32 *pixels, *p;
17   char *screen_pixel;
18   const char *intended_pixel = "#ffffff";
19
20   /* The textures are setup so that when added together with the
21      correct matrices then all of the pixels should be white. We can
22      verify this by reading back the entire stage */
23   pixels = g_malloc (state->width * state->height * 4);
24
25   cogl_framebuffer_read_pixels (fb, 0, 0, state->width, state->height,
26                                 COGL_PIXEL_FORMAT_RGBA_8888_PRE,
27                                 (guint8 *)pixels);
28
29   for (p = pixels; p < pixels + state->width * state->height; p++)
30     {
31       screen_pixel = g_strdup_printf ("#%06x", GUINT32_FROM_BE (*p) >> 8);
32       g_assert_cmpstr (screen_pixel, ==, intended_pixel);
33       g_free (screen_pixel);
34     }
35 }
36
37 static void
38 paint (TestState *state)
39 {
40   /* This texture is painted mirrored around the x-axis */
41   guint8 data0[] = {
42     0xff, 0x00, 0x00, /* red -> becomes bottom left */
43     0x00, 0xff, 0x00, /* green -> becomes bottom right */
44     0x00, 0x00, 0xff, /* blue -> becomes top left */
45     0xff, 0x00, 0xff  /* magenta -> becomes top right */
46   };
47   /* This texture is painted mirrored about the y-axis */
48   guint8 data1[] = {
49     0x00, 0xff, 0x00, /* green -> becomes top right */
50     0xff, 0xff, 0x00, /* yellow -> becomes top left */
51     0xff, 0x00, 0xff, /* magenta -> becomes bottom right */
52     0x00, 0xff, 0xff  /* cyan -> becomes bottom left */
53   };
54   CoglTexture *tex0, *tex1;
55   CoglPipeline *pipeline;
56   CoglMatrix matrix;
57   GError *error = NULL;
58
59   cogl_framebuffer_orthographic (fb,
60                                  0, 0,
61                                  state->width,
62                                  state->height,
63                                  -1,
64                                  100);
65
66   cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
67
68   cogl_matrix_init_identity (&matrix);
69   cogl_framebuffer_set_modelview_matrix (fb, &matrix);
70
71   tex0 = cogl_texture_new_from_data (2, 2,
72                                      COGL_TEXTURE_NO_ATLAS,
73                                      COGL_PIXEL_FORMAT_RGB_888,
74                                      COGL_PIXEL_FORMAT_ANY,
75                                      6,
76                                      data0);
77   tex1 = cogl_texture_new_from_data (2, 2,
78                                      COGL_TEXTURE_NO_ATLAS,
79                                      COGL_PIXEL_FORMAT_RGB_888,
80                                      COGL_PIXEL_FORMAT_ANY,
81                                      6,
82                                      data1);
83
84   pipeline = cogl_pipeline_new (ctx);
85
86   /* Set the two textures as layers */
87   cogl_pipeline_set_layer_texture (pipeline, 0, tex0);
88   cogl_pipeline_set_layer_filters (pipeline, 0,
89                                    COGL_PIPELINE_FILTER_NEAREST,
90                                    COGL_PIPELINE_FILTER_NEAREST);
91   cogl_pipeline_set_layer_texture (pipeline, 1, tex1);
92   cogl_pipeline_set_layer_filters (pipeline, 1,
93                                    COGL_PIPELINE_FILTER_NEAREST,
94                                    COGL_PIPELINE_FILTER_NEAREST);
95
96   /* Set a combine mode so that the two textures get added together */
97   if (!cogl_pipeline_set_layer_combine (pipeline, 1,
98                                         "RGBA=ADD(PREVIOUS, TEXTURE)",
99                                         &error))
100     {
101       g_warning ("Error setting blend string: %s", error->message);
102       g_assert_not_reached ();
103     }
104
105   /* Set a matrix on the first layer so that it will mirror about the y-axis */
106   cogl_matrix_init_identity (&matrix);
107   cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
108   cogl_matrix_scale (&matrix, 1.0f, -1.0f, 1.0f);
109   cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
110
111   /* Set a matrix on the second layer so that it will mirror about the x-axis */
112   cogl_matrix_init_identity (&matrix);
113   cogl_matrix_translate (&matrix, 1.0f, 0.0f, 0.0f);
114   cogl_matrix_scale (&matrix, -1.0f, 1.0f, 1.0f);
115   cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
116
117   cogl_framebuffer_draw_rectangle (fb,
118                                    pipeline,
119                                    0, 0,
120                                    state->width, state->height);
121
122   cogl_object_unref (tex1);
123   cogl_object_unref (tex0);
124   cogl_object_unref (pipeline);
125 }
126
127 void
128 test_pipeline_user_matrix (void)
129 {
130   TestState state;
131
132   state.width = cogl_framebuffer_get_width (fb);
133   state.height = cogl_framebuffer_get_height (fb);
134
135   paint (&state);
136   validate_result (&state);
137
138   if (cogl_test_verbose ())
139     g_print ("OK\n");
140 }