~gnome3-team/mutter/trunk

« back to all changes in this revision

Viewing changes to cogl/tests/conform/test-texture-3d.c

  • Committer: Rui Matos
  • Date: 2016-04-27 16:36:25 UTC
  • mfrom: (0.87.3184)
  • Revision ID: git-v1:3fcbe1d3ec5c9208dde080f7e9dac24e4c379bc0
Merge cogl's cogl-1.22 branch into mutter

https://bugzilla.gnome.org/show_bug.cgi?id=760439

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <cogl/cogl2-experimental.h>
 
2
#include <string.h>
 
3
 
 
4
#include "test-utils.h"
 
5
 
 
6
#define TEX_WIDTH        4
 
7
#define TEX_HEIGHT       8
 
8
#define TEX_DEPTH        16
 
9
/* Leave four bytes of padding between each row */
 
10
#define TEX_ROWSTRIDE    (TEX_WIDTH * 4 + 4)
 
11
/* Leave four rows of padding between each image */
 
12
#define TEX_IMAGE_STRIDE ((TEX_HEIGHT + 4) * TEX_ROWSTRIDE)
 
13
 
 
14
typedef struct _TestState
 
15
{
 
16
  int fb_width;
 
17
  int fb_height;
 
18
} TestState;
 
19
 
 
20
static CoglTexture3D *
 
21
create_texture_3d (CoglContext *context)
 
22
{
 
23
  int x, y, z;
 
24
  uint8_t *data = g_malloc (TEX_IMAGE_STRIDE * TEX_DEPTH);
 
25
  uint8_t *p = data;
 
26
  CoglTexture3D *tex;
 
27
  CoglError *error = NULL;
 
28
 
 
29
  for (z = 0; z < TEX_DEPTH; z++)
 
30
    {
 
31
      for (y = 0; y < TEX_HEIGHT; y++)
 
32
        {
 
33
          for (x = 0; x < TEX_WIDTH; x++)
 
34
            {
 
35
              /* Set red, green, blue to values based on x, y, z */
 
36
              *(p++) = 255 - x * 8;
 
37
              *(p++) = y * 8;
 
38
              *(p++) = 255 - z * 8;
 
39
              /* Fully opaque */
 
40
              *(p++) = 0xff;
 
41
            }
 
42
 
 
43
          /* Set the padding between rows to 0xde */
 
44
          memset (p, 0xde, TEX_ROWSTRIDE - (TEX_WIDTH * 4));
 
45
          p += TEX_ROWSTRIDE - (TEX_WIDTH * 4);
 
46
        }
 
47
      /* Set the padding between images to 0xad */
 
48
      memset (p, 0xba, TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE));
 
49
      p += TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE);
 
50
    }
 
51
 
 
52
  tex = cogl_texture_3d_new_from_data (context,
 
53
                                       TEX_WIDTH, TEX_HEIGHT, TEX_DEPTH,
 
54
                                       COGL_PIXEL_FORMAT_RGBA_8888,
 
55
                                       TEX_ROWSTRIDE,
 
56
                                       TEX_IMAGE_STRIDE,
 
57
                                       data,
 
58
                                       &error);
 
59
 
 
60
  if (tex == NULL)
 
61
    {
 
62
      g_assert (error != NULL);
 
63
      g_warning ("Failed to create 3D texture: %s", error->message);
 
64
      g_assert_not_reached ();
 
65
    }
 
66
 
 
67
  g_free (data);
 
68
 
 
69
  return tex;
 
70
}
 
71
 
 
72
static void
 
73
draw_frame (TestState *state)
 
74
{
 
75
  CoglTexture *tex = create_texture_3d (test_ctx);
 
76
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
 
77
  typedef struct { float x, y, s, t, r; } Vert;
 
78
  CoglPrimitive *primitive;
 
79
  CoglAttributeBuffer *attribute_buffer;
 
80
  CoglAttribute *attributes[2];
 
81
  Vert *verts, *v;
 
82
  int i;
 
83
 
 
84
  cogl_pipeline_set_layer_texture (pipeline, 0, tex);
 
85
  cogl_object_unref (tex);
 
86
  cogl_pipeline_set_layer_filters (pipeline, 0,
 
87
                                   COGL_PIPELINE_FILTER_NEAREST,
 
88
                                   COGL_PIPELINE_FILTER_NEAREST);
 
89
 
 
90
  /* Render the texture repeated horizontally twice using a regular
 
91
     cogl rectangle. This should end up with the r texture coordinates
 
92
     as zero */
 
93
  cogl_framebuffer_draw_textured_rectangle (test_fb, pipeline,
 
94
                                            0.0f, 0.0f, TEX_WIDTH * 2, TEX_HEIGHT,
 
95
                                            0.0f, 0.0f, 2.0f, 1.0f);
 
96
 
 
97
  /* Render all of the images in the texture using coordinates from a
 
98
     CoglPrimitive */
 
99
  v = verts = g_new (Vert, 4 * TEX_DEPTH);
 
100
  for (i = 0; i < TEX_DEPTH; i++)
 
101
    {
 
102
      float r = (i + 0.5f) / TEX_DEPTH;
 
103
 
 
104
      v->x = i * TEX_WIDTH;
 
105
      v->y = TEX_HEIGHT;
 
106
      v->s = 0;
 
107
      v->t = 0;
 
108
      v->r = r;
 
109
      v++;
 
110
 
 
111
      v->x = i * TEX_WIDTH;
 
112
      v->y = TEX_HEIGHT * 2;
 
113
      v->s = 0;
 
114
      v->t = 1;
 
115
      v->r = r;
 
116
      v++;
 
117
 
 
118
      v->x = i * TEX_WIDTH + TEX_WIDTH;
 
119
      v->y = TEX_HEIGHT * 2;
 
120
      v->s = 1;
 
121
      v->t = 1;
 
122
      v->r = r;
 
123
      v++;
 
124
 
 
125
      v->x = i * TEX_WIDTH + TEX_WIDTH;
 
126
      v->y = TEX_HEIGHT;
 
127
      v->s = 1;
 
128
      v->t = 0;
 
129
      v->r = r;
 
130
      v++;
 
131
    }
 
132
 
 
133
  attribute_buffer = cogl_attribute_buffer_new (test_ctx,
 
134
                                                4 * TEX_DEPTH * sizeof (Vert),
 
135
                                                verts);
 
136
  attributes[0] = cogl_attribute_new (attribute_buffer,
 
137
                                      "cogl_position_in",
 
138
                                      sizeof (Vert),
 
139
                                      G_STRUCT_OFFSET (Vert, x),
 
140
                                      2, /* n_components */
 
141
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
 
142
  attributes[1] = cogl_attribute_new (attribute_buffer,
 
143
                                      "cogl_tex_coord_in",
 
144
                                      sizeof (Vert),
 
145
                                      G_STRUCT_OFFSET (Vert, s),
 
146
                                      3, /* n_components */
 
147
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
 
148
  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
 
149
                                                  6 * TEX_DEPTH,
 
150
                                                  attributes,
 
151
                                                  2 /* n_attributes */);
 
152
 
 
153
  cogl_primitive_set_indices (primitive,
 
154
                              cogl_get_rectangle_indices (test_ctx,
 
155
                                                          TEX_DEPTH),
 
156
                              6 * TEX_DEPTH);
 
157
 
 
158
  cogl_primitive_draw (primitive, test_fb, pipeline);
 
159
 
 
160
  g_free (verts);
 
161
 
 
162
  cogl_object_unref (primitive);
 
163
  cogl_object_unref (attributes[0]);
 
164
  cogl_object_unref (attributes[1]);
 
165
  cogl_object_unref (attribute_buffer);
 
166
  cogl_object_unref (pipeline);
 
167
}
 
168
 
 
169
static void
 
170
validate_block (int block_x, int block_y, int z)
 
171
{
 
172
  int x, y;
 
173
 
 
174
  for (y = 0; y < TEX_HEIGHT; y++)
 
175
    for (x = 0; x < TEX_WIDTH; x++)
 
176
      test_utils_check_pixel_rgb (test_fb,
 
177
                                  block_x * TEX_WIDTH + x,
 
178
                                  block_y * TEX_HEIGHT + y,
 
179
                                  255 - x * 8,
 
180
                                  y * 8,
 
181
                                  255 - z * 8);
 
182
}
 
183
 
 
184
static void
 
185
validate_result (void)
 
186
{
 
187
  int i;
 
188
 
 
189
  validate_block (0, 0, 0);
 
190
 
 
191
  for (i = 0; i < TEX_DEPTH; i++)
 
192
    validate_block (i, 1, i);
 
193
}
 
194
 
 
195
static void
 
196
test_multi_texture (TestState *state)
 
197
{
 
198
  CoglPipeline *pipeline;
 
199
  CoglTexture3D *tex_3d;
 
200
  CoglTexture2D *tex_2d;
 
201
  uint8_t tex_data[4];
 
202
 
 
203
  cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
 
204
 
 
205
  /* Tests a pipeline that is using multi-texturing to combine a 3D
 
206
     texture with a 2D texture. The texture from another layer is
 
207
     sampled with TEXTURE_? just to pick up a specific bug that was
 
208
     happening with the ARBfp fragend */
 
209
 
 
210
  pipeline = cogl_pipeline_new (test_ctx);
 
211
 
 
212
  tex_data[0] = 0xff;
 
213
  tex_data[1] = 0x00;
 
214
  tex_data[2] = 0x00;
 
215
  tex_data[3] = 0xff;
 
216
  tex_2d = cogl_texture_2d_new_from_data (test_ctx,
 
217
                                          1, 1, /* width/height */
 
218
                                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
 
219
                                          4, /* rowstride */
 
220
                                          tex_data,
 
221
                                          NULL);
 
222
  cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d);
 
223
 
 
224
  tex_data[0] = 0x00;
 
225
  tex_data[1] = 0xff;
 
226
  tex_data[2] = 0x00;
 
227
  tex_data[3] = 0xff;
 
228
  tex_3d = cogl_texture_3d_new_from_data (test_ctx,
 
229
                                          1, 1, 1, /* width/height/depth */
 
230
                                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
 
231
                                          4, /* rowstride */
 
232
                                          4, /* image_stride */
 
233
                                          tex_data,
 
234
                                          NULL);
 
235
  cogl_pipeline_set_layer_texture (pipeline, 1, tex_3d);
 
236
 
 
237
  cogl_pipeline_set_layer_combine (pipeline, 0,
 
238
                                   "RGBA = REPLACE(PREVIOUS)",
 
239
                                   NULL);
 
240
  cogl_pipeline_set_layer_combine (pipeline, 1,
 
241
                                   "RGBA = ADD(TEXTURE_0, TEXTURE_1)",
 
242
                                   NULL);
 
243
 
 
244
  cogl_framebuffer_draw_rectangle (test_fb, pipeline, 0, 0, 10, 10);
 
245
 
 
246
  test_utils_check_pixel (test_fb, 5, 5, 0xffff00ff);
 
247
 
 
248
  cogl_object_unref (tex_2d);
 
249
  cogl_object_unref (tex_3d);
 
250
  cogl_object_unref (pipeline);
 
251
}
 
252
 
 
253
void
 
254
test_texture_3d (void)
 
255
{
 
256
  TestState state;
 
257
 
 
258
  state.fb_width = cogl_framebuffer_get_width (test_fb);
 
259
  state.fb_height = cogl_framebuffer_get_height (test_fb);
 
260
 
 
261
  cogl_framebuffer_orthographic (test_fb,
 
262
                                 0, 0, /* x_1, y_1 */
 
263
                                 state.fb_width, /* x_2 */
 
264
                                 state.fb_height /* y_2 */,
 
265
                                 -1, 100 /* near/far */);
 
266
 
 
267
  draw_frame (&state);
 
268
  validate_result ();
 
269
 
 
270
  test_multi_texture (&state);
 
271
 
 
272
  if (cogl_test_verbose ())
 
273
    g_print ("OK\n");
 
274
}