~ubuntu-branches/ubuntu/precise/clutter-1.0/precise

« back to all changes in this revision

Viewing changes to tests/conform/test-cogl-multitexture.c

  • Committer: Bazaar Package Importer
  • Author(s): Emilio Pozuelo Monfort
  • Date: 2010-03-21 13:27:56 UTC
  • mto: (2.1.3 experimental) (1.3.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 8.
  • Revision ID: james.westby@ubuntu.com-20100321132756-nf8yd30yxo3zzwcm
Tags: upstream-1.2.2
ImportĀ upstreamĀ versionĀ 1.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <clutter/clutter.h>
 
2
#include <cogl/cogl.h>
 
3
#include <string.h>
 
4
 
 
5
#include "test-conform-common.h"
 
6
 
 
7
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
 
8
 
 
9
#define QUAD_WIDTH 20
 
10
 
 
11
#define RED   0
 
12
#define GREEN 1
 
13
#define BLUE  2
 
14
#define ALPHA 3
 
15
 
 
16
typedef struct _TestState
 
17
{
 
18
  guint frame;
 
19
} TestState;
 
20
 
 
21
static void
 
22
assert_region_color (int x,
 
23
                     int y,
 
24
                     int width,
 
25
                     int height,
 
26
                     guint8 red,
 
27
                     guint8 green,
 
28
                     guint8 blue,
 
29
                     guint8 alpha)
 
30
{
 
31
  guint8 *data = g_malloc0 (width * height * 4);
 
32
  cogl_read_pixels (x, y, width, height,
 
33
                    COGL_READ_PIXELS_COLOR_BUFFER,
 
34
                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
 
35
                    data);
 
36
  for (y = 0; y < height; y++)
 
37
    for (x = 0; x < width; x++)
 
38
      {
 
39
        guint8 *pixel = &data[y * width * 4 + x * 4];
 
40
#if 1
 
41
        g_assert (pixel[RED] == red &&
 
42
                  pixel[GREEN] == green &&
 
43
                  pixel[BLUE] == blue &&
 
44
                  pixel[ALPHA] == alpha);
 
45
#endif
 
46
      }
 
47
  g_free (data);
 
48
}
 
49
 
 
50
/* Creates a texture divided into 4 quads with colors arranged as follows:
 
51
 * (The same value are used in all channels for each texel)
 
52
 *
 
53
 * |-----------|
 
54
 * |0x11 |0x00 |
 
55
 * |+ref |     |
 
56
 * |-----------|
 
57
 * |0x00 |0x33 |
 
58
 * |     |+ref |
 
59
 * |-----------|
 
60
 *
 
61
 *
 
62
 */
 
63
static CoglHandle
 
64
make_texture (guchar ref)
 
65
{
 
66
  int x;
 
67
  int y;
 
68
  guchar *tex_data, *p;
 
69
  CoglHandle tex;
 
70
  guchar val;
 
71
 
 
72
  tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 16);
 
73
 
 
74
  for (y = 0; y < QUAD_WIDTH * 2; y++)
 
75
    for (x = 0; x < QUAD_WIDTH * 2; x++)
 
76
      {
 
77
        p = tex_data + (QUAD_WIDTH * 8 * y) + x * 4;
 
78
        if (x < QUAD_WIDTH && y < QUAD_WIDTH)
 
79
          val = 0x11 + ref;
 
80
        else if (x >= QUAD_WIDTH && y >= QUAD_WIDTH)
 
81
          val = 0x33 + ref;
 
82
        else
 
83
          val = 0x00;
 
84
        p[0] = p[1] = p[2] = p[3] = val;
 
85
      }
 
86
 
 
87
  /* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here
 
88
   * since we don't want to allow Cogl to premultiply our data. */
 
89
  tex = cogl_texture_new_from_data (QUAD_WIDTH * 2,
 
90
                                    QUAD_WIDTH * 2,
 
91
                                    COGL_TEXTURE_NONE,
 
92
                                    COGL_PIXEL_FORMAT_RGBA_8888,
 
93
                                    COGL_PIXEL_FORMAT_RGBA_8888,
 
94
                                    QUAD_WIDTH * 8,
 
95
                                    tex_data);
 
96
 
 
97
  g_free (tex_data);
 
98
 
 
99
  return tex;
 
100
}
 
101
 
 
102
static void
 
103
on_paint (ClutterActor *actor, TestState *state)
 
104
{
 
105
  CoglHandle tex0, tex1;
 
106
  CoglHandle material;
 
107
  gboolean status;
 
108
  GError *error = NULL;
 
109
  float tex_coords[] = {
 
110
    0, 0, 0.5, 0.5, /* tex0 */
 
111
    0.5, 0.5, 1, 1 /* tex1 */
 
112
  };
 
113
 
 
114
  /* XXX:
 
115
   * We haven't always had good luck with GL drivers implementing glReadPixels
 
116
   * reliably and skipping the first two frames improves our chances... */
 
117
  if (state->frame++ <= 2)
 
118
    {
 
119
      g_usleep (G_USEC_PER_SEC);
 
120
      return;
 
121
    }
 
122
 
 
123
  tex0 = make_texture (0x00);
 
124
  tex1 = make_texture (0x11);
 
125
 
 
126
  material = cogl_material_new ();
 
127
 
 
128
  /* An arbitrary color which should be replaced by the first texture layer */
 
129
  cogl_material_set_color4ub (material, 0x80, 0x80, 0x80, 0x80);
 
130
  cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL);
 
131
 
 
132
  cogl_material_set_layer (material, 0, tex0);
 
133
  cogl_material_set_layer_combine (material, 0,
 
134
                                   "RGBA = REPLACE (TEXTURE)", NULL);
 
135
 
 
136
  cogl_material_set_layer (material, 1, tex1);
 
137
  status = cogl_material_set_layer_combine (material, 1,
 
138
                                            "RGBA = ADD (PREVIOUS, TEXTURE)",
 
139
                                            &error);
 
140
  if (!status)
 
141
    {
 
142
      /* It's not strictly a test failure; you need a more capable GPU or
 
143
       * driver to test this texture combine string. */
 
144
      g_debug ("Failed to setup texture combine string "
 
145
               "RGBA = ADD (PREVIOUS, TEXTURE): %s",
 
146
               error->message);
 
147
    }
 
148
 
 
149
  cogl_set_source (material);
 
150
  cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH,
 
151
                                           tex_coords, 8);
 
152
 
 
153
  cogl_handle_unref (material);
 
154
  cogl_handle_unref (tex0);
 
155
  cogl_handle_unref (tex1);
 
156
 
 
157
  /* See what we got... */
 
158
 
 
159
  assert_region_color (0, 0, QUAD_WIDTH, QUAD_WIDTH,
 
160
                       0x55, 0x55, 0x55, 0x55);
 
161
 
 
162
  /* Comment this out if you want visual feedback for what this test paints */
 
163
#if 1
 
164
  clutter_main_quit ();
 
165
#endif
 
166
}
 
167
 
 
168
static gboolean
 
169
queue_redraw (gpointer stage)
 
170
{
 
171
  clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 
172
 
 
173
  return TRUE;
 
174
}
 
175
 
 
176
void
 
177
test_cogl_multitexture (TestConformSimpleFixture *fixture,
 
178
                        gconstpointer data)
 
179
{
 
180
  TestState state;
 
181
  ClutterActor *stage;
 
182
  ClutterActor *group;
 
183
  guint idle_source;
 
184
 
 
185
  state.frame = 0;
 
186
 
 
187
  stage = clutter_stage_get_default ();
 
188
 
 
189
  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
 
190
 
 
191
  group = clutter_group_new ();
 
192
  clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
 
193
 
 
194
  /* We force continuous redrawing of the stage, since we need to skip
 
195
   * the first few frames, and we wont be doing anything else that
 
196
   * will trigger redrawing. */
 
197
  idle_source = g_idle_add (queue_redraw, stage);
 
198
 
 
199
  g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
 
200
 
 
201
  clutter_actor_show_all (stage);
 
202
 
 
203
  clutter_main ();
 
204
 
 
205
  g_source_remove (idle_source);
 
206
 
 
207
  if (g_test_verbose ())
 
208
    g_print ("OK\n");
 
209
}