2
#include <clutter/clutter.h>
6
#include "test-conform-common.h"
8
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
10
#ifdef CLUTTER_COGL_HAS_GL
12
/* Size the texture so that it is just off a power of two to enourage
13
it so use software tiling when NPOTs aren't available */
14
#define TEXTURE_SIZE 257
16
#else /* CLUTTER_COGL_HAS_GL */
18
/* We can't use the funny-sized texture on GL ES because it will break
19
cogl_texture_polygon. However there is only one code path for
20
rendering quads so there is no need */
21
#define TEXTURE_SIZE 32
23
#endif /* CLUTTER_COGL_HAS_GL */
25
/* Amount of pixels to skip off the top, bottom, left and right of the
26
texture when reading back the stage */
29
/* Size to actually render the texture at */
30
#define TEXTURE_RENDER_SIZE 32
32
typedef struct _TestState
39
validate_part (int xnum, int ynum, gboolean shown)
42
ClutterActor *stage = clutter_stage_get_default ();
45
/* Read the appropriate part but skip out a few pixels around the
47
pixels = clutter_stage_read_pixels (CLUTTER_STAGE (stage),
48
xnum * TEXTURE_RENDER_SIZE + TEST_INSET,
49
ynum * TEXTURE_RENDER_SIZE + TEST_INSET,
50
TEXTURE_RENDER_SIZE - TEST_INSET * 2,
51
TEXTURE_RENDER_SIZE - TEST_INSET * 2);
53
/* Make sure every pixels is the appropriate color */
55
p < pixels + ((TEXTURE_RENDER_SIZE - TEST_INSET * 2)
56
* (TEXTURE_RENDER_SIZE - TEST_INSET * 2));
59
if (p[0] != (shown ? 255 : 0))
73
validate_result (TestState *state)
75
/* Front-facing texture */
76
g_assert (validate_part (0, 0, TRUE));
77
/* Back-facing texture */
78
g_assert (validate_part (1, 0, FALSE));
79
/* Front-facing texture polygon */
80
g_assert (validate_part (2, 0, TRUE));
81
/* Back-facing texture polygon */
82
g_assert (validate_part (3, 0, FALSE));
83
/* Regular rectangle */
84
g_assert (validate_part (4, 0, TRUE));
86
/* Backface culling disabled - everything should be shown */
88
/* Front-facing texture */
89
g_assert (validate_part (0, 1, TRUE));
90
/* Back-facing texture */
91
g_assert (validate_part (1, 1, TRUE));
92
/* Front-facing texture polygon */
93
g_assert (validate_part (2, 1, TRUE));
94
/* Back-facing texture polygon */
95
g_assert (validate_part (3, 1, TRUE));
96
/* Regular rectangle */
97
g_assert (validate_part (4, 1, TRUE));
99
/* Comment this out if you want visual feedback of what this test
102
clutter_main_quit ();
106
on_paint (ClutterActor *actor, TestState *state)
110
CoglHandle material = cogl_material_new ();
112
cogl_material_set_layer_filters (material, 0,
113
COGL_MATERIAL_FILTER_NEAREST,
114
COGL_MATERIAL_FILTER_NEAREST);
116
cogl_set_backface_culling_enabled (TRUE);
120
/* Render the scene twice - once with backface culling enabled and
121
once without. The second time is translated so that it is below
123
for (i = 0; i < 2; i++)
125
float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_RENDER_SIZE);
126
CoglTextureVertex verts[4];
128
cogl_set_source (material);
130
memset (verts, 0, sizeof (verts));
132
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
134
/* Draw a front-facing texture */
135
cogl_material_set_layer (material, 0, state->texture);
136
cogl_rectangle (x1, y1, x2, y2);
139
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
141
/* Draw a back-facing texture */
142
cogl_material_set_layer (material, 0, state->texture);
143
cogl_rectangle (x2, y1, x1, y2);
146
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
148
/* Draw a front-facing texture polygon */
149
verts[0].x = x1; verts[0].y = y2;
150
verts[1].x = x2; verts[1].y = y2;
151
verts[2].x = x2; verts[2].y = y1;
152
verts[3].x = x1; verts[3].y = y1;
153
verts[0].tx = 0; verts[0].ty = 0;
154
verts[1].tx = 1.0; verts[1].ty = 0;
155
verts[2].tx = 1.0; verts[2].ty = 1.0;
156
verts[3].tx = 0; verts[3].ty = 1.0;
157
cogl_material_set_layer (material, 0, state->texture);
158
cogl_polygon (verts, 4, FALSE);
161
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
163
/* Draw a back-facing texture polygon */
164
verts[0].x = x1; verts[0].y = y1;
165
verts[1].x = x2; verts[1].y = y1;
166
verts[2].x = x2; verts[2].y = y2;
167
verts[3].x = x1; verts[3].y = y2;
168
verts[0].tx = 0; verts[0].ty = 0;
169
verts[1].tx = 1.0; verts[1].ty = 0;
170
verts[2].tx = 1.0; verts[2].ty = 1.0;
171
verts[3].tx = 0; verts[3].ty = 1.0;
172
cogl_material_set_layer (material, 0, state->texture);
173
cogl_polygon (verts, 4, FALSE);
176
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
178
/* Draw a regular rectangle (this should always show) */
179
cogl_set_source_color4f (1.0, 0, 0, 1.0);
180
cogl_rectangle (x1, y1, x2, y2);
182
/* The second time round draw beneath the first with backface
184
cogl_translate (0, TEXTURE_RENDER_SIZE, 0);
185
cogl_set_backface_culling_enabled (FALSE);
190
cogl_handle_unref (material);
192
/* XXX: Experiments have shown that for some buggy drivers, when using
193
* glReadPixels there is some kind of race, so we delay our test for a
194
* few frames and a few seconds:
196
/* Need to increment frame first because clutter_stage_read_pixels
198
frame_num = state->frame++;
200
validate_result (state);
201
else if (frame_num < 2)
202
g_usleep (G_USEC_PER_SEC);
206
queue_redraw (gpointer stage)
208
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
216
guchar *tex_data, *p;
219
tex_data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4);
221
for (p = tex_data + TEXTURE_SIZE * TEXTURE_SIZE * 4; p > tex_data;)
229
tex = cogl_texture_new_from_data (TEXTURE_SIZE,
232
COGL_PIXEL_FORMAT_RGBA_8888,
233
COGL_PIXEL_FORMAT_ANY,
243
test_backface_culling (TestConformSimpleFixture *fixture,
253
state.texture = make_texture ();
255
stage = clutter_stage_get_default ();
257
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
259
group = clutter_group_new ();
260
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
262
/* We force continuous redrawing of the stage, since we need to skip
263
* the first few frames, and we wont be doing anything else that
264
* will trigger redrawing. */
265
idle_source = g_idle_add (queue_redraw, stage);
267
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
269
clutter_actor_show_all (stage);
273
g_source_remove (idle_source);
275
cogl_handle_unref (state.texture);
277
if (g_test_verbose ())