"Initial commit to Gerrit"
[profile/ivi/cogl.git] / tests / conform / test-primitive.c
1 #include <cogl/cogl.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #include "test-utils.h"
6
7 typedef struct _TestState
8 {
9   int fb_width;
10   int fb_height;
11 } TestState;
12
13 #define PRIM_COLOR 0xff00ffff
14 #define TEX_COLOR 0x0000ffff
15
16 #define N_ATTRIBS 8
17
18 typedef CoglPrimitive * (* TestPrimFunc) (CoglContext *ctx, guint32 *expected_color);
19
20 static CoglPrimitive *
21 test_prim_p2 (CoglContext *ctx, guint32 *expected_color)
22 {
23   static const CoglVertexP2 verts[] =
24     { { 0, 0 }, { 0, 10 }, { 10, 0 } };
25
26   return cogl_primitive_new_p2 (ctx,
27                                 COGL_VERTICES_MODE_TRIANGLES,
28                                 3, /* n_vertices */
29                                 verts);
30 }
31
32 static CoglPrimitive *
33 test_prim_p3 (CoglContext *ctx, guint32 *expected_color)
34 {
35   static const CoglVertexP3 verts[] =
36     { { 0, 0, 0 }, { 0, 10, 0 }, { 10, 0, 0 } };
37
38   return cogl_primitive_new_p3 (ctx,
39                                 COGL_VERTICES_MODE_TRIANGLES,
40                                 3, /* n_vertices */
41                                 verts);
42 }
43
44 static CoglPrimitive *
45 test_prim_p2c4 (CoglContext *ctx, guint32 *expected_color)
46 {
47   static const CoglVertexP2C4 verts[] =
48     { { 0, 0, 255, 255, 0, 255 },
49       { 0, 10, 255, 255, 0, 255 },
50       { 10, 0, 255, 255, 0, 255 } };
51
52   *expected_color = 0xffff00ff;
53
54   return cogl_primitive_new_p2c4 (ctx,
55                                   COGL_VERTICES_MODE_TRIANGLES,
56                                   3, /* n_vertices */
57                                   verts);
58 }
59
60 static CoglPrimitive *
61 test_prim_p3c4 (CoglContext *ctx, guint32 *expected_color)
62 {
63   static const CoglVertexP3C4 verts[] =
64     { { 0, 0, 0, 255, 255, 0, 255 },
65       { 0, 10, 0, 255, 255, 0, 255 },
66       { 10, 0, 0, 255, 255, 0, 255 } };
67
68   *expected_color = 0xffff00ff;
69
70   return cogl_primitive_new_p3c4 (ctx,
71                                   COGL_VERTICES_MODE_TRIANGLES,
72                                   3, /* n_vertices */
73                                   verts);
74 }
75
76 static CoglPrimitive *
77 test_prim_p2t2 (CoglContext *ctx, guint32 *expected_color)
78 {
79   static const CoglVertexP2T2 verts[] =
80     { { 0, 0, 1, 0 },
81       { 0, 10, 1, 0 },
82       { 10, 0, 1, 0 } };
83
84   *expected_color = TEX_COLOR;
85
86   return cogl_primitive_new_p2t2 (ctx,
87                                   COGL_VERTICES_MODE_TRIANGLES,
88                                   3, /* n_vertices */
89                                   verts);
90 }
91
92 static CoglPrimitive *
93 test_prim_p3t2 (CoglContext *ctx, guint32 *expected_color)
94 {
95   static const CoglVertexP3T2 verts[] =
96     { { 0, 0, 0, 1, 0 },
97       { 0, 10, 0, 1, 0 },
98       { 10, 0, 0, 1, 0 } };
99
100   *expected_color = TEX_COLOR;
101
102   return cogl_primitive_new_p3t2 (ctx,
103                                   COGL_VERTICES_MODE_TRIANGLES,
104                                   3, /* n_vertices */
105                                   verts);
106 }
107
108 static CoglPrimitive *
109 test_prim_p2t2c4 (CoglContext *ctx, guint32 *expected_color)
110 {
111   static const CoglVertexP2T2C4 verts[] =
112     { { 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
113       { 0, 10, 1, 0, 0xff, 0xff, 0xf0, 0xff },
114       { 10, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff } };
115
116   /* The blue component of the texture color should be replaced with 0xf0 */
117   *expected_color = (TEX_COLOR & 0xffff00ff) | 0x0000f000;
118
119   return cogl_primitive_new_p2t2c4 (ctx,
120                                     COGL_VERTICES_MODE_TRIANGLES,
121                                     3, /* n_vertices */
122                                     verts);
123 }
124
125 static CoglPrimitive *
126 test_prim_p3t2c4 (CoglContext *ctx, guint32 *expected_color)
127 {
128   static const CoglVertexP3T2C4 verts[] =
129     { { 0, 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
130       { 0, 10, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
131       { 10, 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff } };
132
133   /* The blue component of the texture color should be replaced with 0xf0 */
134   *expected_color = (TEX_COLOR & 0xffff00ff) | 0x0000f000;
135
136   return cogl_primitive_new_p3t2c4 (ctx,
137                                     COGL_VERTICES_MODE_TRIANGLES,
138                                     3, /* n_vertices */
139                                     verts);
140 }
141
142 static const TestPrimFunc
143 test_prim_funcs[] =
144   {
145     test_prim_p2,
146     test_prim_p3,
147     test_prim_p2c4,
148     test_prim_p3c4,
149     test_prim_p2t2,
150     test_prim_p3t2,
151     test_prim_p2t2c4,
152     test_prim_p3t2c4
153   };
154
155 static void
156 test_paint (TestState *state)
157 {
158   CoglPipeline *pipeline;
159   CoglTexture *tex;
160   guint8 tex_data[6];
161   int i;
162
163   /* Create a two pixel texture. The first pixel is white and the
164      second pixel is tex_color. The assumption is that if no texture
165      coordinates are specified then it will default to 0,0 and get
166      white */
167   tex_data[0] = 255;
168   tex_data[1] = 255;
169   tex_data[2] = 255;
170   tex_data[3] = (TEX_COLOR >> 24) & 0xff;
171   tex_data[4] = (TEX_COLOR >> 16) & 0xff;
172   tex_data[5] = (TEX_COLOR >> 8) & 0xff;
173   tex = cogl_texture_new_from_data (2, 1, /* size */
174                                     COGL_TEXTURE_NO_ATLAS,
175                                     COGL_PIXEL_FORMAT_RGB_888,
176                                     COGL_PIXEL_FORMAT_ANY,
177                                     6, /* rowstride */
178                                     tex_data);
179   pipeline = cogl_pipeline_new (ctx);
180   cogl_pipeline_set_color4ub (pipeline,
181                               (PRIM_COLOR >> 24) & 0xff,
182                               (PRIM_COLOR >> 16) & 0xff,
183                               (PRIM_COLOR >> 8) & 0xff,
184                               (PRIM_COLOR >> 0) & 0xff);
185   cogl_pipeline_set_layer_texture (pipeline, 0, tex);
186   cogl_object_unref (tex);
187
188   for (i = 0; i < G_N_ELEMENTS (test_prim_funcs); i++)
189     {
190       CoglPrimitive *prim;
191       guint32 expected_color = PRIM_COLOR;
192
193       prim = test_prim_funcs[i] (ctx, &expected_color);
194
195       cogl_framebuffer_push_matrix (fb);
196       cogl_framebuffer_translate (fb, i * 10, 0, 0);
197       cogl_framebuffer_draw_primitive (fb, pipeline, prim);
198       cogl_framebuffer_pop_matrix (fb);
199
200       test_utils_check_pixel (fb, i * 10 + 2, 2, expected_color);
201
202       cogl_object_unref (prim);
203     }
204
205   cogl_object_unref (pipeline);
206 }
207
208 static gboolean
209 get_attributes_cb (CoglPrimitive *prim,
210                    CoglAttribute *attrib,
211                    void *user_data)
212 {
213   CoglAttribute ***p = user_data;
214   *((* p)++) = attrib;
215   return TRUE;
216 }
217
218 static int
219 compare_pointers (const void *a, const void *b)
220 {
221   CoglAttribute *pa = *(CoglAttribute **) a;
222   CoglAttribute *pb = *(CoglAttribute **) b;
223
224   if (pa < pb)
225     return -1;
226   else if (pa > pb)
227     return 1;
228   else
229     return 0;
230 }
231
232 static void
233 test_copy (TestState *state)
234 {
235   static const guint16 indices_data[2] = { 1, 2 };
236   CoglAttributeBuffer *buffer =
237     cogl_attribute_buffer_new (ctx, 100, NULL);
238   CoglAttribute *attributes[N_ATTRIBS];
239   CoglAttribute *attributes_a[N_ATTRIBS], *attributes_b[N_ATTRIBS];
240   CoglAttribute **p;
241   CoglPrimitive *prim_a, *prim_b;
242   CoglIndices *indices;
243   int i;
244
245   for (i = 0; i < N_ATTRIBS; i++)
246     {
247       char *name = g_strdup_printf ("foo_%i", i);
248       attributes[i] = cogl_attribute_new (buffer,
249                                           name,
250                                           16, /* stride */
251                                           16, /* offset */
252                                           2, /* components */
253                                           COGL_ATTRIBUTE_TYPE_FLOAT);
254       g_free (name);
255     }
256
257   prim_a = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
258                                                8, /* n_vertices */
259                                                attributes,
260                                                N_ATTRIBS);
261
262   indices = cogl_indices_new (ctx,
263                               COGL_INDICES_TYPE_UNSIGNED_SHORT,
264                               indices_data,
265                               2 /* n_indices */);
266
267   cogl_primitive_set_first_vertex (prim_a, 12);
268   cogl_primitive_set_indices (prim_a, indices, 2);
269
270   prim_b = cogl_primitive_copy (prim_a);
271
272   p = attributes_a;
273   cogl_primitive_foreach_attribute (prim_a,
274                                     get_attributes_cb,
275                                     &p);
276   g_assert_cmpint (p - attributes_a, ==, N_ATTRIBS);
277
278   p = attributes_b;
279   cogl_primitive_foreach_attribute (prim_b,
280                                     get_attributes_cb,
281                                     &p);
282   g_assert_cmpint (p - attributes_b, ==, N_ATTRIBS);
283
284   qsort (attributes_a, N_ATTRIBS, sizeof (CoglAttribute *), compare_pointers);
285   qsort (attributes_b, N_ATTRIBS, sizeof (CoglAttribute *), compare_pointers);
286
287   g_assert (memcmp (attributes_a, attributes_b, sizeof (attributes_a)) == 0);
288
289   g_assert_cmpint (cogl_primitive_get_first_vertex (prim_a),
290                    ==,
291                    cogl_primitive_get_first_vertex (prim_b));
292
293   g_assert_cmpint (cogl_primitive_get_n_vertices (prim_a),
294                    ==,
295                    cogl_primitive_get_n_vertices (prim_b));
296
297   g_assert_cmpint (cogl_primitive_get_mode (prim_a),
298                    ==,
299                    cogl_primitive_get_mode (prim_b));
300
301   g_assert (cogl_primitive_get_indices (prim_a) ==
302             cogl_primitive_get_indices (prim_b));
303
304   cogl_object_unref (prim_a);
305   cogl_object_unref (prim_b);
306   cogl_object_unref (indices);
307
308   for (i = 0; i < N_ATTRIBS; i++)
309     cogl_object_unref (attributes[i]);
310
311   cogl_object_unref (buffer);
312 }
313
314 void
315 test_primitive (void)
316 {
317   TestState state;
318
319   state.fb_width = cogl_framebuffer_get_width (fb);
320   state.fb_height = cogl_framebuffer_get_height (fb);
321
322   cogl_framebuffer_orthographic (fb,
323                                  0, 0,
324                                  state.fb_width,
325                                  state.fb_height,
326                                  -1,
327                                  100);
328
329   test_paint (&state);
330   test_copy (&state);
331
332   if (cogl_test_verbose ())
333     g_print ("OK\n");
334 }