"Initial commit to Gerrit"
[profile/ivi/cogl.git] / tests / conform / test-custom-attributes.c
1 #include <cogl/cogl.h>
2
3 #include <string.h>
4
5 #include "test-utils.h"
6
7 typedef struct _TestState
8 {
9   CoglPipeline *pipeline;
10 } TestState;
11
12 typedef struct
13 {
14   gint16 x, y;
15   float r, g, b, a;
16 } FloatVert;
17
18 typedef struct
19 {
20   gint16 x, y;
21   guint8 r, g, b, a;
22 } ByteVert;
23
24 typedef struct
25 {
26   gint16 x, y;
27 } ShortVert;
28
29 static void
30 test_float_verts (TestState *state, int offset_x, int offset_y)
31 {
32   CoglAttribute *attributes[2];
33   CoglAttributeBuffer *buffer;
34
35   static const FloatVert float_verts[] =
36     {
37       { 0, 10, /**/ 1, 0, 0, 1 },
38       { 10, 10, /**/ 1, 0, 0, 1 },
39       { 5, 0, /**/ 1, 0, 0, 1 },
40
41       { 10, 10, /**/ 0, 1, 0, 1 },
42       { 20, 10, /**/ 0, 1, 0, 1 },
43       { 15, 0, /**/ 0, 1, 0, 1 }
44     };
45
46   buffer = cogl_attribute_buffer_new (ctx,
47                                       sizeof (float_verts), float_verts);
48   attributes[0] = cogl_attribute_new (buffer,
49                                       "cogl_position_in",
50                                       sizeof (FloatVert),
51                                       G_STRUCT_OFFSET (FloatVert, x),
52                                       2, /* n_components */
53                                       COGL_ATTRIBUTE_TYPE_SHORT);
54   attributes[1] = cogl_attribute_new (buffer,
55                                       "color",
56                                       sizeof (FloatVert),
57                                       G_STRUCT_OFFSET (FloatVert, r),
58                                       4, /* n_components */
59                                       COGL_ATTRIBUTE_TYPE_FLOAT);
60
61   cogl_framebuffer_push_matrix (fb);
62   cogl_framebuffer_translate (fb, offset_x, offset_y, 0.0f);
63
64   cogl_framebuffer_draw_attributes (fb,
65                                     state->pipeline,
66                                     COGL_VERTICES_MODE_TRIANGLES,
67                                     0, /* first_vertex */
68                                     6, /* n_vertices */
69                                     attributes,
70                                     2 /* n_attributes */);
71
72   cogl_framebuffer_pop_matrix (fb);
73
74   cogl_object_unref (attributes[1]);
75   cogl_object_unref (attributes[0]);
76   cogl_object_unref (buffer);
77
78   test_utils_check_pixel (fb, offset_x + 5, offset_y + 5, 0xff0000ff);
79   test_utils_check_pixel (fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
80 }
81
82 static void
83 test_byte_verts (TestState *state, int offset_x, int offset_y)
84 {
85   CoglAttribute *attributes[2];
86   CoglAttributeBuffer *buffer, *unnorm_buffer;
87
88   static const ByteVert norm_verts[] =
89     {
90       { 0, 10, /**/ 255, 0, 0, 255 },
91       { 10, 10, /**/ 255, 0, 0, 255 },
92       { 5, 0, /**/ 255, 0, 0, 255 },
93
94       { 10, 10, /**/ 0, 255, 0, 255 },
95       { 20, 10, /**/ 0, 255, 0, 255 },
96       { 15, 0, /**/ 0, 255, 0, 255 }
97     };
98
99   static const ByteVert unnorm_verts[] =
100     {
101       { 0, 0, /**/ 0, 0, 1, 1 },
102       { 0, 0, /**/ 0, 0, 1, 1 },
103       { 0, 0, /**/ 0, 0, 1, 1 },
104     };
105
106   buffer = cogl_attribute_buffer_new (ctx,
107                                       sizeof (norm_verts), norm_verts);
108   attributes[0] = cogl_attribute_new (buffer,
109                                       "cogl_position_in",
110                                       sizeof (ByteVert),
111                                       G_STRUCT_OFFSET (ByteVert, x),
112                                       2, /* n_components */
113                                       COGL_ATTRIBUTE_TYPE_SHORT);
114   attributes[1] = cogl_attribute_new (buffer,
115                                       "color",
116                                       sizeof (ByteVert),
117                                       G_STRUCT_OFFSET (ByteVert, r),
118                                       4, /* n_components */
119                                       COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
120   cogl_attribute_set_normalized (attributes[1], TRUE);
121
122   cogl_framebuffer_push_matrix (fb);
123   cogl_framebuffer_translate (fb, offset_x, offset_y, 0.0f);
124
125   cogl_framebuffer_draw_attributes (fb,
126                                     state->pipeline,
127                                     COGL_VERTICES_MODE_TRIANGLES,
128                                     0, /* first_vertex */
129                                     6, /* n_vertices */
130                                     attributes,
131                                     2 /* n_attributes */);
132
133   cogl_object_unref (attributes[1]);
134
135   /* Test again with unnormalized attributes */
136   unnorm_buffer = cogl_attribute_buffer_new (ctx,
137                                              sizeof (unnorm_verts),
138                                              unnorm_verts);
139   attributes[1] = cogl_attribute_new (unnorm_buffer,
140                                       "color",
141                                       sizeof (ByteVert),
142                                       G_STRUCT_OFFSET (ByteVert, r),
143                                       4, /* n_components */
144                                       COGL_ATTRIBUTE_TYPE_BYTE);
145
146   cogl_framebuffer_translate (fb, 20, 0, 0);
147
148   cogl_framebuffer_draw_attributes (fb,
149                                     state->pipeline,
150                                     COGL_VERTICES_MODE_TRIANGLES,
151                                     0, /* first_vertex */
152                                     3, /* n_vertices */
153                                     attributes,
154                                     2 /* n_attributes */);
155
156   cogl_framebuffer_pop_matrix (fb);
157
158   cogl_object_unref (attributes[0]);
159   cogl_object_unref (attributes[1]);
160   cogl_object_unref (buffer);
161   cogl_object_unref (unnorm_buffer);
162
163   test_utils_check_pixel (fb, offset_x + 5, offset_y + 5, 0xff0000ff);
164   test_utils_check_pixel (fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
165   test_utils_check_pixel (fb, offset_x + 25, offset_y + 5, 0x0000ffff);
166 }
167
168 static void
169 test_short_verts (TestState *state, int offset_x, int offset_y)
170 {
171   CoglAttribute *attributes[1];
172   CoglAttributeBuffer *buffer;
173   CoglPipeline *pipeline, *pipeline2;
174   CoglSnippet *snippet;
175
176   static const ShortVert short_verts[] =
177     {
178       { -10, -10 },
179       { -1, -10 },
180       { -5, -1 }
181     };
182
183   pipeline = cogl_pipeline_new (ctx);
184   snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM,
185                               "attribute vec2 pos;",
186                               NULL);
187   cogl_snippet_set_replace (snippet,
188                             "cogl_position_out = "
189                             "cogl_modelview_projection_matrix * "
190                             "vec4 (pos, 0.0, 1.0);");
191   cogl_pipeline_add_snippet (pipeline, snippet);
192   cogl_object_unref (snippet);
193
194   cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);
195
196   buffer = cogl_attribute_buffer_new (ctx,
197                                       sizeof (short_verts), short_verts);
198   attributes[0] = cogl_attribute_new (buffer,
199                                       "pos",
200                                       sizeof (ShortVert),
201                                       G_STRUCT_OFFSET (ShortVert, x),
202                                       2, /* n_components */
203                                       COGL_ATTRIBUTE_TYPE_SHORT);
204
205   cogl_framebuffer_push_matrix (fb);
206   cogl_framebuffer_translate (fb,
207                               offset_x + 10.0f,
208                               offset_y + 10.0f,
209                               0.0f);
210
211   cogl_framebuffer_draw_attributes (fb,
212                                     pipeline,
213                                     COGL_VERTICES_MODE_TRIANGLES,
214                                     0, /* first_vertex */
215                                     3, /* n_vertices */
216                                     attributes,
217                                     1 /* n_attributes */);
218
219   cogl_framebuffer_pop_matrix (fb);
220
221   cogl_object_unref (attributes[0]);
222
223   /* Test again treating the attribute as unsigned */
224   attributes[0] = cogl_attribute_new (buffer,
225                                       "pos",
226                                       sizeof (ShortVert),
227                                       G_STRUCT_OFFSET (ShortVert, x),
228                                       2, /* n_components */
229                                       COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);
230
231   pipeline2 = cogl_pipeline_copy (pipeline);
232   cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255);
233
234   cogl_framebuffer_push_matrix (fb);
235   cogl_framebuffer_translate (fb,
236                               offset_x + 10.0f - 65525.0f,
237                               offset_y - 65525,
238                               0.0f);
239
240   cogl_framebuffer_draw_attributes (fb,
241                                     pipeline2,
242                                     COGL_VERTICES_MODE_TRIANGLES,
243                                     0, /* first_vertex */
244                                     3, /* n_vertices */
245                                     attributes,
246                                     1 /* n_attributes */);
247
248   cogl_framebuffer_pop_matrix (fb);
249
250   cogl_object_unref (attributes[0]);
251
252   cogl_object_unref (pipeline2);
253   cogl_object_unref (pipeline);
254   cogl_object_unref (buffer);
255
256   test_utils_check_pixel (fb, offset_x + 5, offset_y + 5, 0xff0000ff);
257   test_utils_check_pixel (fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
258 }
259
260 static void
261 paint (TestState *state)
262 {
263   cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
264
265   test_float_verts (state, 0, 0);
266   test_byte_verts (state, 0, 10);
267   test_short_verts (state, 0, 20);
268 }
269
270 void
271 test_custom_attributes (void)
272 {
273   /* If shaders aren't supported then we can't run the test */
274   if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
275     {
276       CoglSnippet *snippet;
277       TestState state;
278
279       cogl_framebuffer_orthographic (fb,
280                                      0, 0,
281                                      cogl_framebuffer_get_width (fb),
282                                      cogl_framebuffer_get_height (fb),
283                                      -1,
284                                      100);
285
286       state.pipeline = cogl_pipeline_new (ctx);
287       snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
288                                   "attribute vec4 color;",
289                                   "cogl_color_out = color;");
290       cogl_pipeline_add_snippet (state.pipeline, snippet);
291
292       paint (&state);
293
294       cogl_object_unref (state.pipeline);
295       cogl_object_unref (snippet);
296
297       if (cogl_test_verbose ())
298         g_print ("OK\n");
299     }
300   else if (cogl_test_verbose ())
301     g_print ("Skipping\n");
302 }