tests: Remove conformance tests that have been ported to Cogl
A lot of the conformance tests that were just testing Cogl functionality have been ported to be standalone Cogl tests in the Cogl source tree. This patch removes those from Clutter so we don't have to maintain them in two places. Reviewed-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
parent
0e542aa306
commit
0f04a1cd11
@ -27,23 +27,15 @@ units_sources += \
|
||||
|
||||
# cogl tests
|
||||
units_sources += \
|
||||
test-cogl-backface-culling.c \
|
||||
test-cogl-blend-strings.c \
|
||||
test-cogl-depth-test.c \
|
||||
test-cogl-fixed.c \
|
||||
test-cogl-materials.c \
|
||||
test-cogl-pipeline-user-matrix.c \
|
||||
test-cogl-viewport.c \
|
||||
test-cogl-multitexture.c \
|
||||
test-cogl-npot-texture.c \
|
||||
test-cogl-object.c \
|
||||
test-cogl-offscreen.c \
|
||||
test-cogl-path.c \
|
||||
test-cogl-pixel-buffer.c \
|
||||
test-cogl-premult.c \
|
||||
test-cogl-readpixels.c \
|
||||
test-cogl-sub-texture.c \
|
||||
test-cogl-texture-3d.c \
|
||||
test-cogl-texture-get-set-data.c \
|
||||
test-cogl-texture-mipmaps.c \
|
||||
test-cogl-texture-pixmap-x11.c \
|
||||
@ -52,9 +44,6 @@ units_sources += \
|
||||
test-cogl-vertex-buffer-contiguous.c \
|
||||
test-cogl-vertex-buffer-interleved.c \
|
||||
test-cogl-vertex-buffer-mutability.c \
|
||||
test-cogl-wrap-modes.c \
|
||||
test-cogl-primitive.c \
|
||||
test-cogl-just-vertex-shader.c \
|
||||
$(NULL)
|
||||
|
||||
# actors tests
|
||||
|
@ -1,340 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#ifdef CLUTTER_COGL_HAS_GL
|
||||
|
||||
/* Size the texture so that it is just off a power of two to enourage
|
||||
it so use software tiling when NPOTs aren't available */
|
||||
#define TEXTURE_SIZE 257
|
||||
|
||||
#else /* CLUTTER_COGL_HAS_GL */
|
||||
|
||||
/* We can't use the funny-sized texture on GL ES because it will break
|
||||
cogl_texture_polygon. However there is only one code path for
|
||||
rendering quads so there is no need */
|
||||
#define TEXTURE_SIZE 32
|
||||
|
||||
#endif /* CLUTTER_COGL_HAS_GL */
|
||||
|
||||
/* Amount of pixels to skip off the top, bottom, left and right of the
|
||||
texture when reading back the stage */
|
||||
#define TEST_INSET 4
|
||||
|
||||
/* Size to actually render the texture at */
|
||||
#define TEXTURE_RENDER_SIZE 32
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
CoglHandle texture;
|
||||
CoglHandle offscreen;
|
||||
CoglHandle offscreen_tex;
|
||||
} TestState;
|
||||
|
||||
static gboolean
|
||||
validate_part (int xnum, int ynum, gboolean shown)
|
||||
{
|
||||
guchar *pixels, *p;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
pixels = g_malloc0 ((TEXTURE_RENDER_SIZE - TEST_INSET * 2)
|
||||
* (TEXTURE_RENDER_SIZE - TEST_INSET * 2) * 4);
|
||||
|
||||
/* Read the appropriate part but skip out a few pixels around the
|
||||
edges */
|
||||
cogl_read_pixels (xnum * TEXTURE_RENDER_SIZE + TEST_INSET,
|
||||
ynum * TEXTURE_RENDER_SIZE + TEST_INSET,
|
||||
TEXTURE_RENDER_SIZE - TEST_INSET * 2,
|
||||
TEXTURE_RENDER_SIZE - TEST_INSET * 2,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixels);
|
||||
|
||||
/* Make sure every pixels is the appropriate color */
|
||||
for (p = pixels;
|
||||
p < pixels + ((TEXTURE_RENDER_SIZE - TEST_INSET * 2)
|
||||
* (TEXTURE_RENDER_SIZE - TEST_INSET * 2));
|
||||
p += 4)
|
||||
{
|
||||
if (p[0] != (shown ? 255 : 0))
|
||||
ret = FALSE;
|
||||
if (p[1] != 0)
|
||||
ret = FALSE;
|
||||
if (p[2] != 0)
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
g_free (pixels);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
do_test_backface_culling (TestState *state)
|
||||
{
|
||||
int i;
|
||||
CoglHandle material = cogl_material_new ();
|
||||
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
|
||||
cogl_set_backface_culling_enabled (TRUE);
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
/* Render the scene twice - once with backface culling enabled and
|
||||
once without. The second time is translated so that it is below
|
||||
the first */
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
float x1 = 0, x2, y1 = 0, y2 = (float)(TEXTURE_RENDER_SIZE);
|
||||
CoglTextureVertex verts[4];
|
||||
|
||||
cogl_set_source (material);
|
||||
|
||||
memset (verts, 0, sizeof (verts));
|
||||
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a front-facing texture */
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_rectangle (x1, y1, x2, y2);
|
||||
|
||||
x1 = x2;
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a front-facing texture with flipped texcoords */
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_rectangle_with_texture_coords (x1, y1, x2, y2,
|
||||
1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
x1 = x2;
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a back-facing texture */
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_rectangle (x2, y1, x1, y2);
|
||||
|
||||
x1 = x2;
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a front-facing texture polygon */
|
||||
verts[0].x = x1; verts[0].y = y2;
|
||||
verts[1].x = x2; verts[1].y = y2;
|
||||
verts[2].x = x2; verts[2].y = y1;
|
||||
verts[3].x = x1; verts[3].y = y1;
|
||||
verts[0].tx = 0; verts[0].ty = 0;
|
||||
verts[1].tx = 1.0; verts[1].ty = 0;
|
||||
verts[2].tx = 1.0; verts[2].ty = 1.0;
|
||||
verts[3].tx = 0; verts[3].ty = 1.0;
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_polygon (verts, 4, FALSE);
|
||||
|
||||
x1 = x2;
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a back-facing texture polygon */
|
||||
verts[0].x = x1; verts[0].y = y1;
|
||||
verts[1].x = x2; verts[1].y = y1;
|
||||
verts[2].x = x2; verts[2].y = y2;
|
||||
verts[3].x = x1; verts[3].y = y2;
|
||||
verts[0].tx = 0; verts[0].ty = 0;
|
||||
verts[1].tx = 1.0; verts[1].ty = 0;
|
||||
verts[2].tx = 1.0; verts[2].ty = 1.0;
|
||||
verts[3].tx = 0; verts[3].ty = 1.0;
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_polygon (verts, 4, FALSE);
|
||||
|
||||
x1 = x2;
|
||||
x2 = x1 + (float)(TEXTURE_RENDER_SIZE);
|
||||
|
||||
/* Draw a regular rectangle (this should always show) */
|
||||
cogl_set_source_color4f (1.0, 0, 0, 1.0);
|
||||
cogl_rectangle (x1, y1, x2, y2);
|
||||
|
||||
/* The second time round draw beneath the first with backface
|
||||
culling disabled */
|
||||
cogl_translate (0, TEXTURE_RENDER_SIZE, 0);
|
||||
cogl_set_backface_culling_enabled (FALSE);
|
||||
}
|
||||
|
||||
cogl_handle_unref (material);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
|
||||
/* Front-facing texture */
|
||||
g_assert (validate_part (0, 0, TRUE));
|
||||
/* Front-facing texture with flipped tex coords */
|
||||
g_assert (validate_part (1, 0, TRUE));
|
||||
/* Back-facing texture */
|
||||
g_assert (validate_part (2, 0, FALSE));
|
||||
/* Front-facing texture polygon */
|
||||
g_assert (validate_part (3, 0, TRUE));
|
||||
/* Back-facing texture polygon */
|
||||
g_assert (validate_part (4, 0, FALSE));
|
||||
/* Regular rectangle */
|
||||
g_assert (validate_part (5, 0, TRUE));
|
||||
|
||||
/* Backface culling disabled - everything should be shown */
|
||||
|
||||
/* Front-facing texture */
|
||||
g_assert (validate_part (0, 1, TRUE));
|
||||
/* Front-facing texture with flipped tex coords */
|
||||
g_assert (validate_part (1, 1, TRUE));
|
||||
/* Back-facing texture */
|
||||
g_assert (validate_part (2, 1, TRUE));
|
||||
/* Front-facing texture polygon */
|
||||
g_assert (validate_part (3, 1, TRUE));
|
||||
/* Back-facing texture polygon */
|
||||
g_assert (validate_part (4, 1, TRUE));
|
||||
/* Regular rectangle */
|
||||
g_assert (validate_part (5, 1, TRUE));
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglColor clr;
|
||||
float stage_viewport[4];
|
||||
CoglMatrix stage_projection;
|
||||
CoglMatrix stage_modelview;
|
||||
|
||||
cogl_color_init_from_4ub (&clr, 0x00, 0x00, 0x00, 0xff);
|
||||
|
||||
do_test_backface_culling (state);
|
||||
|
||||
/* Since we are going to repeat the test rendering offscreen we clear the
|
||||
* stage, just to minimize the chance of a some other bug causing us
|
||||
* mistakenly reading back the results from the stage and giving a false
|
||||
* posistive. */
|
||||
cogl_clear (&clr, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_STENCIL);
|
||||
|
||||
/*
|
||||
* Now repeat the test but rendered to an offscreen framebuffer...
|
||||
*/
|
||||
|
||||
cogl_get_viewport (stage_viewport);
|
||||
cogl_get_projection_matrix (&stage_projection);
|
||||
cogl_get_modelview_matrix (&stage_modelview);
|
||||
|
||||
cogl_push_framebuffer (state->offscreen);
|
||||
|
||||
cogl_clear (&clr, COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_STENCIL);
|
||||
|
||||
cogl_set_viewport (stage_viewport[0],
|
||||
stage_viewport[1],
|
||||
stage_viewport[2],
|
||||
stage_viewport[3]);
|
||||
cogl_set_projection_matrix (&stage_projection);
|
||||
cogl_set_modelview_matrix (&stage_modelview);
|
||||
|
||||
do_test_backface_culling (state);
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
/* Incase we want feedback of what was drawn offscreen we draw it
|
||||
* to the stage... */
|
||||
cogl_set_source_texture (state->offscreen_tex);
|
||||
cogl_rectangle (0, 0, stage_viewport[2], stage_viewport[3]);
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
make_texture (void)
|
||||
{
|
||||
guchar *tex_data, *p;
|
||||
CoglHandle tex;
|
||||
|
||||
tex_data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4);
|
||||
|
||||
for (p = tex_data + TEXTURE_SIZE * TEXTURE_SIZE * 4; p > tex_data;)
|
||||
{
|
||||
*(--p) = 255;
|
||||
*(--p) = 0;
|
||||
*(--p) = 0;
|
||||
*(--p) = 255;
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (TEXTURE_SIZE,
|
||||
TEXTURE_SIZE,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
TEXTURE_SIZE * 4,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_backface_culling (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
CoglHandle tex;
|
||||
ClutterActor *stage;
|
||||
float stage_width;
|
||||
float stage_height;
|
||||
const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
clutter_actor_get_size (stage, &stage_width, &stage_height);
|
||||
|
||||
state.offscreen = COGL_INVALID_HANDLE;
|
||||
|
||||
state.texture = make_texture ();
|
||||
|
||||
tex = cogl_texture_new_with_size (stage_width, stage_height,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_ANY); /* internal fmt */
|
||||
state.offscreen = cogl_offscreen_new_to_texture (tex);
|
||||
state.offscreen_tex = tex;
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = clutter_threads_add_idle (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
cogl_handle_unref (state.offscreen);
|
||||
cogl_handle_unref (state.offscreen_tex);
|
||||
cogl_handle_unref (state.texture);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,433 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
#define QUAD_WIDTH 20
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
#define ALPHA 3
|
||||
|
||||
#define MASK_RED(COLOR) ((COLOR & 0xff000000) >> 24)
|
||||
#define MASK_GREEN(COLOR) ((COLOR & 0xff0000) >> 16)
|
||||
#define MASK_BLUE(COLOR) ((COLOR & 0xff00) >> 8)
|
||||
#define MASK_ALPHA(COLOR) (COLOR & 0xff)
|
||||
|
||||
#define BLEND_CONSTANT_UNUSED 0xDEADBEEF
|
||||
#define TEX_CONSTANT_UNUSED 0xDEADBEEF
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
|
||||
static void
|
||||
check_pixel (GLubyte *pixel, guint32 color)
|
||||
{
|
||||
guint8 r = MASK_RED (color);
|
||||
guint8 g = MASK_GREEN (color);
|
||||
guint8 b = MASK_BLUE (color);
|
||||
guint8 a = MASK_ALPHA (color);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print (" expected = %x, %x, %x, %x\n",
|
||||
r, g, b, a);
|
||||
g_assert_cmpint (abs(pixel[RED] - r), <=, 1);
|
||||
g_assert_cmpint (abs(pixel[GREEN] - g), <=, 1);
|
||||
g_assert_cmpint (abs(pixel[BLUE] - b), <=, 1);
|
||||
|
||||
/* FIXME
|
||||
* We ignore the alpha, since we don't know if our render target is
|
||||
* RGB or RGBA */
|
||||
/* g_assert (pixel[ALPHA] == a); */
|
||||
}
|
||||
|
||||
static void
|
||||
test_blend (TestState *state,
|
||||
int x,
|
||||
int y,
|
||||
guint32 src_color,
|
||||
guint32 dst_color,
|
||||
const char *blend_string,
|
||||
guint32 blend_constant,
|
||||
guint32 expected_result)
|
||||
{
|
||||
/* src color */
|
||||
guint8 Sr = MASK_RED (src_color);
|
||||
guint8 Sg = MASK_GREEN (src_color);
|
||||
guint8 Sb = MASK_BLUE (src_color);
|
||||
guint8 Sa = MASK_ALPHA (src_color);
|
||||
/* dest color */
|
||||
guint8 Dr = MASK_RED (dst_color);
|
||||
guint8 Dg = MASK_GREEN (dst_color);
|
||||
guint8 Db = MASK_BLUE (dst_color);
|
||||
guint8 Da = MASK_ALPHA (dst_color);
|
||||
/* blend constant - when applicable */
|
||||
guint8 Br = MASK_RED (blend_constant);
|
||||
guint8 Bg = MASK_GREEN (blend_constant);
|
||||
guint8 Bb = MASK_BLUE (blend_constant);
|
||||
guint8 Ba = MASK_ALPHA (blend_constant);
|
||||
CoglColor blend_const_color;
|
||||
|
||||
CoglHandle material;
|
||||
gboolean status;
|
||||
GError *error = NULL;
|
||||
GLubyte pixel[4];
|
||||
GLint y_off;
|
||||
GLint x_off;
|
||||
|
||||
/* First write out the destination color without any blending... */
|
||||
material = cogl_material_new ();
|
||||
cogl_material_set_color4ub (material, Dr, Dg, Db, Da);
|
||||
cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
cogl_set_source (material);
|
||||
cogl_rectangle (x * QUAD_WIDTH,
|
||||
y * QUAD_WIDTH,
|
||||
x * QUAD_WIDTH + QUAD_WIDTH,
|
||||
y * QUAD_WIDTH + QUAD_WIDTH);
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/*
|
||||
* Now blend a rectangle over our well defined destination:
|
||||
*/
|
||||
|
||||
material = cogl_material_new ();
|
||||
cogl_material_set_color4ub (material, Sr, Sg, Sb, Sa);
|
||||
|
||||
status = cogl_material_set_blend (material, blend_string, &error);
|
||||
if (!status)
|
||||
{
|
||||
/* It's not strictly a test failure; you need a more capable GPU or
|
||||
* driver to test this blend string. */
|
||||
g_debug ("Failed to test blend string %s: %s",
|
||||
blend_string, error->message);
|
||||
}
|
||||
|
||||
cogl_color_init_from_4ub (&blend_const_color, Br, Bg, Bb, Ba);
|
||||
cogl_material_set_blend_constant (material, &blend_const_color);
|
||||
|
||||
cogl_set_source (material);
|
||||
cogl_rectangle (x * QUAD_WIDTH,
|
||||
y * QUAD_WIDTH,
|
||||
x * QUAD_WIDTH + QUAD_WIDTH,
|
||||
y * QUAD_WIDTH + QUAD_WIDTH);
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/* See what we got... */
|
||||
|
||||
y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
|
||||
cogl_read_pixels (x_off, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
g_print ("test_blend (%d, %d):\n%s\n", x, y, blend_string);
|
||||
g_print (" src color = %02x, %02x, %02x, %02x\n", Sr, Sg, Sb, Sa);
|
||||
g_print (" dst color = %02x, %02x, %02x, %02x\n", Dr, Dg, Db, Da);
|
||||
if (blend_constant != BLEND_CONSTANT_UNUSED)
|
||||
g_print (" blend constant = %02x, %02x, %02x, %02x\n",
|
||||
Br, Bg, Bb, Ba);
|
||||
else
|
||||
g_print (" blend constant = UNUSED\n");
|
||||
g_print (" result = %x, %x, %x, %x\n",
|
||||
pixel[RED], pixel[GREEN], pixel[BLUE], pixel[ALPHA]);
|
||||
}
|
||||
|
||||
check_pixel (pixel, expected_result);
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
make_texture (guint32 color)
|
||||
{
|
||||
guchar *tex_data, *p;
|
||||
guint8 r = MASK_RED (color);
|
||||
guint8 g = MASK_GREEN (color);
|
||||
guint8 b = MASK_BLUE (color);
|
||||
guint8 a = MASK_ALPHA (color);
|
||||
CoglHandle tex;
|
||||
|
||||
tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 4);
|
||||
|
||||
for (p = tex_data + QUAD_WIDTH * QUAD_WIDTH * 4; p > tex_data;)
|
||||
{
|
||||
*(--p) = a;
|
||||
*(--p) = b;
|
||||
*(--p) = g;
|
||||
*(--p) = r;
|
||||
}
|
||||
|
||||
/* Note: we don't use COGL_PIXEL_FORMAT_ANY for the internal format here
|
||||
* since we don't want to allow Cogl to premultiply our data. */
|
||||
tex = cogl_texture_new_from_data (QUAD_WIDTH,
|
||||
QUAD_WIDTH,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
QUAD_WIDTH * 4,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
test_tex_combine (TestState *state,
|
||||
int x,
|
||||
int y,
|
||||
guint32 tex0_color,
|
||||
guint32 tex1_color,
|
||||
guint32 combine_constant,
|
||||
const char *combine_string,
|
||||
guint32 expected_result)
|
||||
{
|
||||
CoglHandle tex0, tex1;
|
||||
|
||||
/* combine constant - when applicable */
|
||||
guint8 Cr = MASK_RED (combine_constant);
|
||||
guint8 Cg = MASK_GREEN (combine_constant);
|
||||
guint8 Cb = MASK_BLUE (combine_constant);
|
||||
guint8 Ca = MASK_ALPHA (combine_constant);
|
||||
CoglColor combine_const_color;
|
||||
|
||||
CoglHandle material;
|
||||
gboolean status;
|
||||
GError *error = NULL;
|
||||
GLubyte pixel[4];
|
||||
GLint y_off;
|
||||
GLint x_off;
|
||||
|
||||
|
||||
tex0 = make_texture (tex0_color);
|
||||
tex1 = make_texture (tex1_color);
|
||||
|
||||
material = cogl_material_new ();
|
||||
|
||||
cogl_material_set_color4ub (material, 0x80, 0x80, 0x80, 0x80);
|
||||
cogl_material_set_blend (material, "RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
|
||||
cogl_material_set_layer (material, 0, tex0);
|
||||
cogl_material_set_layer_combine (material, 0,
|
||||
"RGBA = REPLACE (TEXTURE)", NULL);
|
||||
|
||||
cogl_material_set_layer (material, 1, tex1);
|
||||
status = cogl_material_set_layer_combine (material, 1,
|
||||
combine_string, &error);
|
||||
if (!status)
|
||||
{
|
||||
/* It's not strictly a test failure; you need a more capable GPU or
|
||||
* driver to test this texture combine string. */
|
||||
g_debug ("Failed to test texture combine string %s: %s",
|
||||
combine_string, error->message);
|
||||
}
|
||||
|
||||
cogl_color_init_from_4ub (&combine_const_color, Cr, Cg, Cb, Ca);
|
||||
cogl_material_set_layer_combine_constant (material, 1, &combine_const_color);
|
||||
|
||||
cogl_set_source (material);
|
||||
cogl_rectangle (x * QUAD_WIDTH,
|
||||
y * QUAD_WIDTH,
|
||||
x * QUAD_WIDTH + QUAD_WIDTH,
|
||||
y * QUAD_WIDTH + QUAD_WIDTH);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
cogl_handle_unref (tex0);
|
||||
cogl_handle_unref (tex1);
|
||||
|
||||
/* See what we got... */
|
||||
|
||||
y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
|
||||
cogl_read_pixels (x_off, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
g_print ("test_tex_combine (%d, %d):\n%s\n", x, y, combine_string);
|
||||
g_print (" texture 0 color = 0x%08lX\n", (unsigned long)tex0_color);
|
||||
g_print (" texture 1 color = 0x%08lX\n", (unsigned long)tex1_color);
|
||||
if (combine_constant != TEX_CONSTANT_UNUSED)
|
||||
g_print (" combine constant = %02x, %02x, %02x, %02x\n",
|
||||
Cr, Cg, Cb, Ca);
|
||||
else
|
||||
g_print (" combine constant = UNUSED\n");
|
||||
g_print (" result = %02x, %02x, %02x, %02x\n",
|
||||
pixel[RED], pixel[GREEN], pixel[BLUE], pixel[ALPHA]);
|
||||
}
|
||||
|
||||
check_pixel (pixel, expected_result);
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
test_blend (state, 0, 0, /* position */
|
||||
0xff0000ff, /* src */
|
||||
0xffffffff, /* dst */
|
||||
"RGBA = ADD (SRC_COLOR, 0)",
|
||||
BLEND_CONSTANT_UNUSED,
|
||||
0xff0000ff); /* expected */
|
||||
|
||||
test_blend (state, 1, 0, /* position */
|
||||
0x11223344, /* src */
|
||||
0x11223344, /* dst */
|
||||
"RGBA = ADD (SRC_COLOR, DST_COLOR)",
|
||||
BLEND_CONSTANT_UNUSED,
|
||||
0x22446688); /* expected */
|
||||
|
||||
test_blend (state, 2, 0, /* position */
|
||||
0x80808080, /* src */
|
||||
0xffffffff, /* dst */
|
||||
"RGBA = ADD (SRC_COLOR * (CONSTANT), 0)",
|
||||
0x80808080, /* constant (RGBA all = 0.5 when normalized) */
|
||||
0x40404040); /* expected */
|
||||
|
||||
test_blend (state, 3, 0, /* position */
|
||||
0x80000080, /* src (alpha = 0.5 when normalized) */
|
||||
0x40000000, /* dst */
|
||||
"RGBA = ADD (SRC_COLOR * (SRC_COLOR[A]),"
|
||||
" DST_COLOR * (1-SRC_COLOR[A]))",
|
||||
BLEND_CONSTANT_UNUSED,
|
||||
0x60000040); /* expected */
|
||||
|
||||
/* XXX:
|
||||
* For all texture combine tests tex0 will use a combine mode of
|
||||
* "RGBA = REPLACE (TEXTURE)"
|
||||
*/
|
||||
|
||||
test_tex_combine (state, 4, 0, /* position */
|
||||
0x11111111, /* texture 0 color */
|
||||
0x22222222, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = ADD (PREVIOUS, TEXTURE)", /* tex combine */
|
||||
0x33333333); /* expected */
|
||||
|
||||
test_tex_combine (state, 5, 0, /* position */
|
||||
0x40404040, /* texture 0 color */
|
||||
0x80808080, /* texture 1 color (RGBA all = 0.5) */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = MODULATE (PREVIOUS, TEXTURE)", /* tex combine */
|
||||
0x20202020); /* expected */
|
||||
|
||||
test_tex_combine (state, 6, 0, /* position */
|
||||
0xffffff80, /* texture 0 color (alpha = 0.5) */
|
||||
0xDEADBE40, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGB = REPLACE (PREVIOUS)"
|
||||
"A = MODULATE (PREVIOUS, TEXTURE)", /* tex combine */
|
||||
0xffffff20); /* expected */
|
||||
|
||||
/* XXX: we are assuming test_tex_combine creates a material with
|
||||
* a color of 0x80808080 (i.e. the "PRIMARY" color) */
|
||||
test_tex_combine (state, 7, 0, /* position */
|
||||
0xffffff80, /* texture 0 color (alpha = 0.5) */
|
||||
0xDEADBE20, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGB = REPLACE (PREVIOUS)"
|
||||
"A = MODULATE (PRIMARY, TEXTURE)", /* tex combine */
|
||||
0xffffff10); /* expected */
|
||||
|
||||
test_tex_combine (state, 8, 0, /* position */
|
||||
0x11111111, /* texture 0 color */
|
||||
0x22222222, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = ADD (PREVIOUS, 1-TEXTURE)", /* tex combine */
|
||||
0xeeeeeeee); /* expected */
|
||||
|
||||
/* this is again assuming a primary color of 0x80808080 */
|
||||
test_tex_combine (state, 9, 0, /* position */
|
||||
0x10101010, /* texture 0 color */
|
||||
0x20202020, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = INTERPOLATE (PREVIOUS, TEXTURE, PRIMARY)",
|
||||
0x18181818); /* expected */
|
||||
|
||||
test_tex_combine (state, 0, 1, /* position */
|
||||
0xDEADBEEF, /* texture 0 color (not used) */
|
||||
0x11223344, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = ADD (TEXTURE_1, TEXTURE)", /* tex combine */
|
||||
0x22446688); /* expected */
|
||||
|
||||
test_tex_combine (state, 1, 1, /* position */
|
||||
0x21314151, /* texture 0 color */
|
||||
0x99999999, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = ADD_SIGNED (PREVIOUS, TEXTURE)", /* tex combine */
|
||||
0x3a4a5a6a); /* expected */
|
||||
|
||||
test_tex_combine (state, 2, 1, /* position */
|
||||
0xfedcba98, /* texture 0 color */
|
||||
0x11111111, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGBA = SUBTRACT (PREVIOUS, TEXTURE)", /* tex combine */
|
||||
0xedcba987); /* expected */
|
||||
|
||||
test_tex_combine (state, 3, 1, /* position */
|
||||
0x8899aabb, /* texture 0 color */
|
||||
0xbbaa9988, /* texture 1 color */
|
||||
TEX_CONSTANT_UNUSED,
|
||||
"RGB = DOT3_RGBA (PREVIOUS, TEXTURE)"
|
||||
"A = REPLACE (PREVIOUS)",
|
||||
0x2a2a2abb); /* expected */
|
||||
|
||||
/* Comment this out if you want visual feedback for what this test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_blend_strings (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_actor_get_geometry (stage, &state.stage_geom);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||
|
||||
/* We force continuous redrawing incase someone comments out the
|
||||
* clutter_main_quit and wants visual feedback for the test since we
|
||||
* wont be doing anything else that will trigger redrawing. */
|
||||
idle_source = clutter_threads_add_idle (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,336 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#ifndef COGL_ENABLE_EXPERIMENTAL_API
|
||||
#define COGL_ENABLE_EXPERIMENTAL_API
|
||||
#endif
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
#define QUAD_WIDTH 20
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
#define ALPHA 3
|
||||
|
||||
#define MASK_RED(COLOR) ((COLOR & 0xff000000) >> 24)
|
||||
#define MASK_GREEN(COLOR) ((COLOR & 0xff0000) >> 16)
|
||||
#define MASK_BLUE(COLOR) ((COLOR & 0xff00) >> 8)
|
||||
#define MASK_ALPHA(COLOR) (COLOR & 0xff)
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
guint32 color;
|
||||
float depth;
|
||||
gboolean test_enable;
|
||||
CoglDepthTestFunction test_function;
|
||||
gboolean write_enable;
|
||||
float range_near;
|
||||
float range_far;
|
||||
} TestDepthState;
|
||||
|
||||
static void
|
||||
check_pixel (GLubyte *pixel, guint32 color)
|
||||
{
|
||||
guint8 r = MASK_RED (color);
|
||||
guint8 g = MASK_GREEN (color);
|
||||
guint8 b = MASK_BLUE (color);
|
||||
guint8 a = MASK_ALPHA (color);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print (" expected = %x, %x, %x, %x\n",
|
||||
r, g, b, a);
|
||||
/* FIXME - allow for hardware in-precision */
|
||||
g_assert_cmpint (pixel[RED], ==, r);
|
||||
g_assert_cmpint (pixel[GREEN], ==, g);
|
||||
g_assert_cmpint (pixel[BLUE], ==, b);
|
||||
|
||||
/* FIXME
|
||||
* We ignore the alpha, since we don't know if our render target is
|
||||
* RGB or RGBA */
|
||||
/* g_assert (pixel[ALPHA] == a); */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_rectangle (TestState *state,
|
||||
int x,
|
||||
int y,
|
||||
TestDepthState *rect_state)
|
||||
{
|
||||
CoglDepthState depth_state;
|
||||
guint8 Cr = MASK_RED (rect_state->color);
|
||||
guint8 Cg = MASK_GREEN (rect_state->color);
|
||||
guint8 Cb = MASK_BLUE (rect_state->color);
|
||||
guint8 Ca = MASK_ALPHA (rect_state->color);
|
||||
CoglPipeline *pipeline;
|
||||
|
||||
pipeline = cogl_pipeline_new ();
|
||||
cogl_depth_state_init (&depth_state);
|
||||
cogl_depth_state_set_test_enabled (&depth_state, rect_state->test_enable);
|
||||
cogl_depth_state_set_test_function (&depth_state, rect_state->test_function);
|
||||
cogl_depth_state_set_write_enabled (&depth_state, rect_state->write_enable);
|
||||
cogl_depth_state_set_range (&depth_state,
|
||||
rect_state->range_near,
|
||||
rect_state->range_far);
|
||||
if (!cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL))
|
||||
{
|
||||
cogl_object_unref (pipeline);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);
|
||||
|
||||
cogl_set_source (pipeline);
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (0, 0, rect_state->depth);
|
||||
cogl_rectangle (x * QUAD_WIDTH,
|
||||
y * QUAD_WIDTH,
|
||||
x * QUAD_WIDTH + QUAD_WIDTH,
|
||||
y * QUAD_WIDTH + QUAD_WIDTH);
|
||||
cogl_pop_matrix ();
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_depth (TestState *state,
|
||||
int x,
|
||||
int y,
|
||||
TestDepthState *rect0_state,
|
||||
TestDepthState *rect1_state,
|
||||
TestDepthState *rect2_state,
|
||||
guint32 expected_result)
|
||||
{
|
||||
GLubyte pixel[4];
|
||||
GLint y_off;
|
||||
GLint x_off;
|
||||
gboolean missing_feature = FALSE;
|
||||
|
||||
if (rect0_state)
|
||||
missing_feature |= !draw_rectangle (state, x, y, rect0_state);
|
||||
if (rect1_state)
|
||||
missing_feature |= !draw_rectangle (state, x, y, rect1_state);
|
||||
if (rect2_state)
|
||||
missing_feature |= !draw_rectangle (state, x, y, rect2_state);
|
||||
|
||||
/* We don't consider it an error that we can't test something
|
||||
* the driver doesn't support. */
|
||||
if (missing_feature)
|
||||
return;
|
||||
|
||||
/* See what we got... */
|
||||
|
||||
y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2);
|
||||
|
||||
cogl_read_pixels (x_off, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
|
||||
check_pixel (pixel, expected_result);
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglMatrix projection_save;
|
||||
CoglMatrix identity;
|
||||
|
||||
/* We don't want the effects of perspective division to interfere
|
||||
* with the positions of our test rectangles on the x and y axis
|
||||
* so we use an orthographic projection...
|
||||
*/
|
||||
|
||||
cogl_get_projection_matrix (&projection_save);
|
||||
|
||||
cogl_ortho (0, state->stage_geom.width, /* left, right */
|
||||
state->stage_geom.height, 0, /* bottom, top */
|
||||
-1, 100 /* z near, far */);
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_matrix_init_identity (&identity);
|
||||
cogl_set_modelview_matrix (&identity);
|
||||
|
||||
/* Sanity check a few of the different depth test functions
|
||||
* and that depth writing can be disabled... */
|
||||
|
||||
{
|
||||
/* Closest */
|
||||
TestDepthState rect0_state = {
|
||||
0xff0000ff, /* rgba color */
|
||||
-10, /* depth */
|
||||
FALSE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||
TRUE, /* depth write enable */
|
||||
0, 1 /* depth range */
|
||||
};
|
||||
/* Furthest */
|
||||
TestDepthState rect1_state = {
|
||||
0x00ff00ff, /* rgba color */
|
||||
-70, /* depth */
|
||||
TRUE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||
TRUE, /* depth write enable */
|
||||
0, 1 /* depth range */
|
||||
};
|
||||
/* In the middle */
|
||||
TestDepthState rect2_state = {
|
||||
0x0000ffff, /* rgba color */
|
||||
-20, /* depth */
|
||||
TRUE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_NEVER,
|
||||
TRUE, /* depth write enable */
|
||||
0, 1 /* depth range */
|
||||
};
|
||||
|
||||
test_depth (state, 0, 0, /* position */
|
||||
&rect0_state, &rect1_state, &rect2_state,
|
||||
0x00ff00ff); /* expected */
|
||||
|
||||
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_ALWAYS;
|
||||
test_depth (state, 1, 0, /* position */
|
||||
&rect0_state, &rect1_state, &rect2_state,
|
||||
0x0000ffff); /* expected */
|
||||
|
||||
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_LESS;
|
||||
test_depth (state, 2, 0, /* position */
|
||||
&rect0_state, &rect1_state, &rect2_state,
|
||||
0x0000ffff); /* expected */
|
||||
|
||||
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_GREATER;
|
||||
test_depth (state, 3, 0, /* position */
|
||||
&rect0_state, &rect1_state, &rect2_state,
|
||||
0x00ff00ff); /* expected */
|
||||
|
||||
rect0_state.test_enable = TRUE;
|
||||
rect1_state.write_enable = FALSE;
|
||||
test_depth (state, 4, 0, /* position */
|
||||
&rect0_state, &rect1_state, &rect2_state,
|
||||
0x0000ffff); /* expected */
|
||||
}
|
||||
|
||||
/* Check that the depth buffer values can be mapped into different
|
||||
* ranges... */
|
||||
|
||||
{
|
||||
/* Closest by depth, furthest by depth range */
|
||||
TestDepthState rect0_state = {
|
||||
0xff0000ff, /* rgba color */
|
||||
-10, /* depth */
|
||||
TRUE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
|
||||
TRUE, /* depth write enable */
|
||||
0.5, 1 /* depth range */
|
||||
};
|
||||
/* Furthest by depth, nearest by depth range */
|
||||
TestDepthState rect1_state = {
|
||||
0x00ff00ff, /* rgba color */
|
||||
-70, /* depth */
|
||||
TRUE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_GREATER,
|
||||
TRUE, /* depth write enable */
|
||||
0, 0.5 /* depth range */
|
||||
};
|
||||
|
||||
test_depth (state, 0, 1, /* position */
|
||||
&rect0_state, &rect1_state, NULL,
|
||||
0xff0000ff); /* expected */
|
||||
}
|
||||
|
||||
/* Test that the legacy cogl_set_depth_test_enabled() API still
|
||||
* works... */
|
||||
|
||||
{
|
||||
/* Nearest */
|
||||
TestDepthState rect0_state = {
|
||||
0xff0000ff, /* rgba color */
|
||||
-10, /* depth */
|
||||
FALSE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_LESS,
|
||||
TRUE, /* depth write enable */
|
||||
0, 1 /* depth range */
|
||||
};
|
||||
/* Furthest */
|
||||
TestDepthState rect1_state = {
|
||||
0x00ff00ff, /* rgba color */
|
||||
-70, /* depth */
|
||||
FALSE, /* depth test enable */
|
||||
COGL_DEPTH_TEST_FUNCTION_LESS,
|
||||
TRUE, /* depth write enable */
|
||||
0, 1 /* depth range */
|
||||
};
|
||||
|
||||
cogl_set_depth_test_enabled (TRUE);
|
||||
test_depth (state, 0, 2, /* position */
|
||||
&rect0_state, &rect1_state, NULL,
|
||||
0xff0000ff); /* expected */
|
||||
cogl_set_depth_test_enabled (FALSE);
|
||||
test_depth (state, 1, 2, /* position */
|
||||
&rect0_state, &rect1_state, NULL,
|
||||
0x00ff00ff); /* expected */
|
||||
}
|
||||
|
||||
cogl_pop_matrix ();
|
||||
cogl_set_projection_matrix (&projection_save);
|
||||
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_depth_test (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
clutter_actor_get_geometry (stage, &state.stage_geom);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_container_add_actor (CLUTTER_CONTAINER (stage), group);
|
||||
|
||||
/* We force continuous redrawing incase someone comments out the
|
||||
* clutter_main_quit and wants visual feedback for the test since we
|
||||
* wont be doing anything else that will trigger redrawing. */
|
||||
idle_source = clutter_threads_add_idle (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
static void
|
||||
draw_frame (void)
|
||||
{
|
||||
CoglHandle material = cogl_material_new ();
|
||||
CoglColor color;
|
||||
GError *error = NULL;
|
||||
CoglHandle shader, program;
|
||||
|
||||
/* Set the primary vertex color as red */
|
||||
cogl_color_set_from_4ub (&color, 0xff, 0x00, 0x00, 0xff);
|
||||
cogl_material_set_color (material, &color);
|
||||
|
||||
/* Override the vertex color in the texture environment with a
|
||||
constant green color */
|
||||
cogl_color_set_from_4ub (&color, 0x00, 0xff, 0x00, 0xff);
|
||||
cogl_material_set_layer_combine_constant (material, 0, &color);
|
||||
if (!cogl_material_set_layer_combine (material, 0,
|
||||
"RGBA=REPLACE(CONSTANT)",
|
||||
&error))
|
||||
{
|
||||
g_warning ("Error setting blend constant: %s", error->message);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
/* Set up a dummy vertex shader that does nothing but the usual
|
||||
fixed function transform */
|
||||
shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX);
|
||||
cogl_shader_source (shader,
|
||||
"void\n"
|
||||
"main ()\n"
|
||||
"{\n"
|
||||
" cogl_position_out = "
|
||||
"cogl_modelview_projection_matrix * "
|
||||
"cogl_position_in;\n"
|
||||
" cogl_color_out = cogl_color_in;\n"
|
||||
"}\n");
|
||||
cogl_shader_compile (shader);
|
||||
if (!cogl_shader_is_compiled (shader))
|
||||
{
|
||||
char *log = cogl_shader_get_info_log (shader);
|
||||
g_warning ("Shader compilation failed:\n%s", log);
|
||||
g_free (log);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
program = cogl_create_program ();
|
||||
cogl_program_attach_shader (program, shader);
|
||||
cogl_program_link (program);
|
||||
|
||||
cogl_handle_unref (shader);
|
||||
|
||||
/* Draw something using the material */
|
||||
cogl_set_source (material);
|
||||
cogl_rectangle (0, 0, 50, 50);
|
||||
|
||||
/* Draw it again using the program. It should look exactly the same */
|
||||
cogl_program_use (program);
|
||||
cogl_rectangle (50, 0, 100, 50);
|
||||
cogl_program_use (COGL_INVALID_HANDLE);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
cogl_handle_unref (program);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_pixel (int x, int y)
|
||||
{
|
||||
guint8 pixels[4];
|
||||
|
||||
cogl_read_pixels (x, y, 1, 1, COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, pixels);
|
||||
|
||||
/* The final color should be green. If it's blue then the layer
|
||||
state is being ignored. If it's green then the stage is showing
|
||||
through */
|
||||
g_assert_cmpint (pixels[0], ==, 0x00);
|
||||
g_assert_cmpint (pixels[1], ==, 0xff);
|
||||
g_assert_cmpint (pixels[2], ==, 0x00);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (void)
|
||||
{
|
||||
/* Non-shader version */
|
||||
validate_pixel (25, 25);
|
||||
/* Shader version */
|
||||
validate_pixel (75, 25);
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (void)
|
||||
{
|
||||
draw_frame ();
|
||||
|
||||
validate_result ();
|
||||
|
||||
/* Comment this out to see what the test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_just_vertex_shader (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint paint_handler;
|
||||
|
||||
/* If shaders aren't supported then we can't run the test */
|
||||
if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL))
|
||||
{
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
paint_handler = g_signal_connect_after (stage, "paint",
|
||||
G_CALLBACK (on_paint), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_signal_handler_disconnect (stage, paint_handler);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
||||
else if (g_test_verbose ())
|
||||
g_print ("Skipping\n");
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
|
||||
#define FRAMEBUFFER_WIDTH 640
|
||||
#define FRAMEBUFFER_HEIGHT 480
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, void *state)
|
||||
{
|
||||
float saved_viewport[4];
|
||||
CoglMatrix saved_projection;
|
||||
CoglMatrix projection;
|
||||
CoglMatrix modelview;
|
||||
guchar *data;
|
||||
CoglHandle tex;
|
||||
CoglHandle offscreen;
|
||||
guint8 pixel[4];
|
||||
|
||||
/* Save the Clutter viewport/matrices and load identity matrices */
|
||||
|
||||
cogl_get_viewport (saved_viewport);
|
||||
cogl_get_projection_matrix (&saved_projection);
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_matrix_init_identity (&projection);
|
||||
cogl_matrix_init_identity (&modelview);
|
||||
|
||||
cogl_set_projection_matrix (&projection);
|
||||
cogl_set_modelview_matrix (&modelview);
|
||||
|
||||
data = g_malloc (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
|
||||
tex = cogl_texture_new_from_data (FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data fmt */
|
||||
COGL_PIXEL_FORMAT_ANY, /* internal fmt */
|
||||
FRAMEBUFFER_WIDTH * 4, /* rowstride */
|
||||
data);
|
||||
g_free (data);
|
||||
offscreen = cogl_offscreen_new_to_texture (tex);
|
||||
|
||||
/* Set a scale and translate transform on the window framebuffer before
|
||||
* switching to the offscreen framebuffer so we can verify it gets restored
|
||||
* when we switch back
|
||||
*
|
||||
* The test is going to draw a grid of 4 colors to a texture which we
|
||||
* subsequently draw to the window with a fullscreen rectangle. This
|
||||
* transform will flip the texture left to right, scale it to a quater of the
|
||||
* window size and slide it to the top right of the window.
|
||||
*/
|
||||
cogl_translate (0.5, 0.5, 0);
|
||||
cogl_scale (-0.5, 0.5, 1);
|
||||
|
||||
cogl_push_framebuffer (offscreen);
|
||||
|
||||
/* Cogl should release the last reference when we call cogl_pop_framebuffer()
|
||||
*/
|
||||
cogl_handle_unref (offscreen);
|
||||
|
||||
/* Setup something other than the identity matrix for the modelview so we can
|
||||
* verify it gets restored when we call cogl_pop_framebuffer () */
|
||||
cogl_scale (2, 2, 1);
|
||||
|
||||
/* red, top left */
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_rectangle (-0.5, 0.5, 0, 0);
|
||||
/* green, top right */
|
||||
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
|
||||
cogl_rectangle (0, 0.5, 0.5, 0);
|
||||
/* blue, bottom left */
|
||||
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-0.5, 0, 0, -0.5);
|
||||
/* white, bottom right */
|
||||
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
|
||||
cogl_rectangle (0, 0, 0.5, -0.5);
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
|
||||
cogl_set_source_texture (tex);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
|
||||
cogl_handle_unref (tex);
|
||||
|
||||
/* NB: The texture is drawn flipped horizontally and scaled to fit in the
|
||||
* top right corner of the window. */
|
||||
|
||||
/* red, top right */
|
||||
cogl_read_pixels (FRAMEBUFFER_WIDTH - 1, 0, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
g_assert (pixel[RED] == 0xff && pixel[GREEN] == 0x00 && pixel[BLUE] == 0x00);
|
||||
|
||||
/* green, top left */
|
||||
cogl_read_pixels ((FRAMEBUFFER_WIDTH/2), 0, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
g_assert (pixel[RED] == 0x00 && pixel[GREEN] == 0xff && pixel[BLUE] == 0x00);
|
||||
|
||||
/* blue, bottom right */
|
||||
cogl_read_pixels (FRAMEBUFFER_WIDTH - 1, (FRAMEBUFFER_HEIGHT/2) - 1, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
g_assert (pixel[RED] == 0x00 && pixel[GREEN] == 0x00 && pixel[BLUE] == 0xff);
|
||||
|
||||
/* white, bottom left */
|
||||
cogl_read_pixels ((FRAMEBUFFER_WIDTH/2), (FRAMEBUFFER_HEIGHT/2) - 1, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
g_assert (pixel[RED] == 0xff && pixel[GREEN] == 0xff && pixel[BLUE] == 0xff);
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_offscreen (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
guint idle_source;
|
||||
ClutterActor *stage;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = clutter_threads_add_idle (queue_redraw, stage);
|
||||
g_signal_connect_after (stage, "paint", G_CALLBACK (on_paint), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,235 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define BLOCK_SIZE 16
|
||||
|
||||
/* Number of pixels at the border of a block quadrant to skip when verifying */
|
||||
#define TEST_INSET 1
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
static const ClutterColor block_color = { 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint frame;
|
||||
} TestState;
|
||||
|
||||
static void
|
||||
draw_path_at (int x, int y)
|
||||
{
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (x * BLOCK_SIZE, y * BLOCK_SIZE, 0.0f);
|
||||
cogl_path_fill ();
|
||||
cogl_pop_matrix ();
|
||||
}
|
||||
|
||||
static void
|
||||
verify_block (int block_x, int block_y, int block_mask)
|
||||
{
|
||||
guint8 data[BLOCK_SIZE * BLOCK_SIZE * 4];
|
||||
int qx, qy;
|
||||
|
||||
/* Block mask represents which quarters of the block should be
|
||||
filled. The bits from 0->3 represent the top left, top right,
|
||||
bottom left and bottom right respectively */
|
||||
|
||||
cogl_read_pixels (block_x * BLOCK_SIZE,
|
||||
block_y * BLOCK_SIZE,
|
||||
BLOCK_SIZE, BLOCK_SIZE,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
data);
|
||||
|
||||
for (qy = 0; qy < 2; qy++)
|
||||
for (qx = 0; qx < 2; qx++)
|
||||
{
|
||||
int bit = qx | (qy << 1);
|
||||
const ClutterColor *color =
|
||||
((block_mask & (1 << bit)) ? &block_color : &stage_color);
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < BLOCK_SIZE / 2 - TEST_INSET * 2; x++)
|
||||
for (y = 0; y < BLOCK_SIZE / 2 - TEST_INSET * 2; y++)
|
||||
{
|
||||
const guint8 *p = data + (qx * BLOCK_SIZE / 2 * 4 +
|
||||
qy * BLOCK_SIZE * 4 * BLOCK_SIZE / 2 +
|
||||
(x + TEST_INSET) * 4 +
|
||||
(y + TEST_INSET) * BLOCK_SIZE * 4);
|
||||
g_assert_cmpint (p[0], ==, color->red);
|
||||
g_assert_cmpint (p[1], ==, color->green);
|
||||
g_assert_cmpint (p[2], ==, color->blue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglHandle path_a, path_b, path_c;
|
||||
|
||||
if (state->frame++ < 2)
|
||||
return;
|
||||
|
||||
cogl_set_source_color4ub (255, 255, 255, 255);
|
||||
|
||||
/* Create a path filling just a quarter of a block. It will use two
|
||||
rectangles so that we have a sub path in the path */
|
||||
cogl_path_new ();
|
||||
cogl_path_rectangle (BLOCK_SIZE * 3 / 4, BLOCK_SIZE / 2,
|
||||
BLOCK_SIZE, BLOCK_SIZE);
|
||||
cogl_path_rectangle (BLOCK_SIZE / 2, BLOCK_SIZE / 2,
|
||||
BLOCK_SIZE * 3 / 4, BLOCK_SIZE);
|
||||
path_a = cogl_handle_ref (cogl_get_path ());
|
||||
draw_path_at (0, 0);
|
||||
|
||||
/* Create another path filling the whole block */
|
||||
cogl_path_rectangle (0, 0, BLOCK_SIZE, BLOCK_SIZE);
|
||||
path_b = cogl_handle_ref (cogl_get_path ());
|
||||
draw_path_at (1, 0);
|
||||
|
||||
/* Draw the first path again */
|
||||
cogl_set_path (path_a);
|
||||
draw_path_at (2, 0);
|
||||
|
||||
/* Draw a copy of path a */
|
||||
path_c = cogl_path_copy (path_a);
|
||||
cogl_set_path (path_c);
|
||||
draw_path_at (3, 0);
|
||||
|
||||
/* Add another rectangle to path a. We'll use line_to's instead of
|
||||
cogl_rectangle so that we don't create another sub-path because
|
||||
that is more likely to break the copy */
|
||||
cogl_set_path (path_a);
|
||||
cogl_path_line_to (0, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (0, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, BLOCK_SIZE / 2);
|
||||
draw_path_at (4, 0);
|
||||
|
||||
/* Draw the copy again. It should not have changed */
|
||||
cogl_set_path (path_c);
|
||||
draw_path_at (5, 0);
|
||||
|
||||
/* Add another rectangle to path c. It will be added in two halves,
|
||||
one as an extension of the previous path and the other as a new
|
||||
sub path */
|
||||
cogl_set_path (path_c);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE * 3 / 4, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE * 3 / 4, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, BLOCK_SIZE / 2);
|
||||
cogl_path_rectangle (BLOCK_SIZE * 3 / 4, 0, BLOCK_SIZE, BLOCK_SIZE / 2);
|
||||
draw_path_at (6, 0);
|
||||
|
||||
/* Draw the original path again. It should not have changed */
|
||||
cogl_set_path (path_a);
|
||||
draw_path_at (7, 0);
|
||||
|
||||
cogl_handle_unref (path_a);
|
||||
cogl_handle_unref (path_b);
|
||||
cogl_handle_unref (path_c);
|
||||
|
||||
/* Draw a self-intersecting path. The part that intersects should be
|
||||
inverted */
|
||||
cogl_path_rectangle (0, 0, BLOCK_SIZE, BLOCK_SIZE);
|
||||
cogl_path_line_to (0, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, 0);
|
||||
cogl_path_close ();
|
||||
draw_path_at (8, 0);
|
||||
|
||||
/* Draw two sub paths. Where the paths intersect it should be
|
||||
inverted */
|
||||
cogl_path_rectangle (0, 0, BLOCK_SIZE, BLOCK_SIZE);
|
||||
cogl_path_rectangle (BLOCK_SIZE / 2, BLOCK_SIZE / 2, BLOCK_SIZE, BLOCK_SIZE);
|
||||
draw_path_at (9, 0);
|
||||
|
||||
/* Draw a clockwise outer path */
|
||||
cogl_path_move_to (0, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE, BLOCK_SIZE);
|
||||
cogl_path_line_to (0, BLOCK_SIZE);
|
||||
cogl_path_close ();
|
||||
/* Add a clockwise sub path in the upper left quadrant */
|
||||
cogl_path_move_to (0, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (0, BLOCK_SIZE / 2);
|
||||
cogl_path_close ();
|
||||
/* Add a counter-clockwise sub path in the upper right quadrant */
|
||||
cogl_path_move_to (BLOCK_SIZE / 2, 0);
|
||||
cogl_path_line_to (BLOCK_SIZE / 2, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (BLOCK_SIZE, BLOCK_SIZE / 2);
|
||||
cogl_path_line_to (BLOCK_SIZE, 0);
|
||||
cogl_path_close ();
|
||||
/* Retain the path for the next test */
|
||||
path_a = cogl_handle_ref (cogl_get_path ());
|
||||
draw_path_at (10, 0);
|
||||
|
||||
/* Draw the same path again with the other fill rule */
|
||||
cogl_set_path (path_a);
|
||||
cogl_path_set_fill_rule (COGL_PATH_FILL_RULE_NON_ZERO);
|
||||
draw_path_at (11, 0);
|
||||
|
||||
cogl_handle_unref (path_a);
|
||||
|
||||
verify_block (0, 0, 0x8 /* bottom right */);
|
||||
verify_block (1, 0, 0xf /* all of them */);
|
||||
verify_block (2, 0, 0x8 /* bottom right */);
|
||||
verify_block (3, 0, 0x8 /* bottom right */);
|
||||
verify_block (4, 0, 0x9 /* top left and bottom right */);
|
||||
verify_block (5, 0, 0x8 /* bottom right */);
|
||||
verify_block (6, 0, 0xa /* bottom right and top right */);
|
||||
verify_block (7, 0, 0x9 /* top_left and bottom right */);
|
||||
verify_block (8, 0, 0xe /* all but top left */);
|
||||
verify_block (9, 0, 0x7 /* all but bottom right */);
|
||||
verify_block (10, 0, 0xc /* bottom two */);
|
||||
verify_block (11, 0, 0xd /* all but top right */);
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_path (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
unsigned int idle_source;
|
||||
unsigned int paint_handler;
|
||||
|
||||
state.frame = 0;
|
||||
state.stage = clutter_stage_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = g_idle_add (queue_redraw, state.stage);
|
||||
paint_handler = g_signal_connect_after (state.stage, "paint",
|
||||
G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show (state.stage);
|
||||
clutter_main ();
|
||||
|
||||
g_signal_handler_disconnect (state.stage, paint_handler);
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (state.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,146 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
|
||||
|
||||
static void
|
||||
paint_cb (ClutterActor *stage)
|
||||
{
|
||||
/* This texture is painted mirrored around the x-axis */
|
||||
guint8 data0[] = {
|
||||
0xff, 0x00, 0x00, /* red -> becomes bottom left */
|
||||
0x00, 0xff, 0x00, /* green -> becomes bottom right */
|
||||
0x00, 0x00, 0xff, /* blue -> becomes top left */
|
||||
0xff, 0x00, 0xff /* magenta -> becomes top right */
|
||||
};
|
||||
/* This texture is painted mirrored about the y-axis */
|
||||
guint8 data1[] = {
|
||||
0x00, 0xff, 0x00, /* green -> becomes top right */
|
||||
0xff, 0xff, 0x00, /* yellow -> becomes top left */
|
||||
0xff, 0x00, 0xff, /* magenta -> becomes bottom right */
|
||||
0x00, 0xff, 0xff /* cyan -> becomes bottom left */
|
||||
};
|
||||
CoglHandle tex0, tex1;
|
||||
CoglPipeline *pipeline;
|
||||
CoglMatrix matrix;
|
||||
int width, height;
|
||||
guint8 *pixels, *p;
|
||||
|
||||
width = clutter_actor_get_width (stage);
|
||||
height = clutter_actor_get_height (stage);
|
||||
|
||||
tex0 = cogl_texture_new_from_data (2, 2,
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
6,
|
||||
data0);
|
||||
tex1 = cogl_texture_new_from_data (2, 2,
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
6,
|
||||
data1);
|
||||
|
||||
pipeline = cogl_pipeline_new ();
|
||||
|
||||
/* Set the two textures as layers */
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, tex0);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 0,
|
||||
COGL_PIPELINE_FILTER_NEAREST,
|
||||
COGL_PIPELINE_FILTER_NEAREST);
|
||||
cogl_pipeline_set_layer_texture (pipeline, 1, tex1);
|
||||
cogl_pipeline_set_layer_filters (pipeline, 1,
|
||||
COGL_PIPELINE_FILTER_NEAREST,
|
||||
COGL_PIPELINE_FILTER_NEAREST);
|
||||
|
||||
/* Set a combine mode so that the two textures get added together */
|
||||
cogl_pipeline_set_layer_combine (pipeline, 1,
|
||||
"RGBA=ADD(PREVIOUS, TEXTURE)",
|
||||
NULL);
|
||||
|
||||
/* Set a matrix on the first layer so that it will mirror about the y-axis */
|
||||
cogl_matrix_init_identity (&matrix);
|
||||
cogl_matrix_translate (&matrix, 0.0f, 1.0f, 0.0f);
|
||||
cogl_matrix_scale (&matrix, 1.0f, -1.0f, 1.0f);
|
||||
cogl_pipeline_set_layer_matrix (pipeline, 0, &matrix);
|
||||
|
||||
/* Set a matrix on the second layer so that it will mirror about the x-axis */
|
||||
cogl_matrix_init_identity (&matrix);
|
||||
cogl_matrix_translate (&matrix, 1.0f, 0.0f, 0.0f);
|
||||
cogl_matrix_scale (&matrix, -1.0f, 1.0f, 1.0f);
|
||||
cogl_pipeline_set_layer_matrix (pipeline, 1, &matrix);
|
||||
|
||||
cogl_set_source (pipeline);
|
||||
cogl_rectangle (0, 0, width, height);
|
||||
|
||||
cogl_handle_unref (tex1);
|
||||
cogl_handle_unref (tex0);
|
||||
cogl_object_unref (pipeline);
|
||||
|
||||
/* The textures are setup so that when added together with the
|
||||
correct matrices then all of the pixels should be white. We can
|
||||
verify this by reading back the entire stage */
|
||||
pixels = g_malloc (width * height * 4);
|
||||
|
||||
cogl_read_pixels (0, 0, width, height,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixels);
|
||||
|
||||
for (p = pixels + width * height * 4; p > pixels;)
|
||||
{
|
||||
p -= 4;
|
||||
g_assert_cmpint (p[0], ==, 0xff);
|
||||
g_assert_cmpint (p[1], ==, 0xff);
|
||||
g_assert_cmpint (p[2], ==, 0xff);
|
||||
}
|
||||
|
||||
g_free (pixels);
|
||||
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_pipeline_user_matrix (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint idle_source;
|
||||
guint paint_handler;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = g_idle_add (queue_redraw, stage);
|
||||
|
||||
paint_handler = g_signal_connect_after (stage, "paint",
|
||||
G_CALLBACK (paint_cb),
|
||||
NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
g_signal_handler_disconnect (stage, paint_handler);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
#define COGL_ENABLE_EXPERIMENTAL_2_0_API
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x00, 0xff, 0x00, 0xff };
|
||||
static const ClutterColor prim_color = { 0xff, 0x00, 0xff, 0xff };
|
||||
static const ClutterColor tex_color = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
typedef CoglPrimitive * (* TestPrimFunc) (CoglContext *ctx,
|
||||
ClutterColor *expected_color);
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p2 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP2 verts[] =
|
||||
{ { 0, 0 }, { 0, 10 }, { 10, 0 } };
|
||||
|
||||
return cogl_primitive_new_p2 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p3 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP3 verts[] =
|
||||
{ { 0, 0, 0 }, { 0, 10, 0 }, { 10, 0, 0 } };
|
||||
|
||||
return cogl_primitive_new_p3 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p2c4 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP2C4 verts[] =
|
||||
{ { 0, 0, 255, 255, 0, 255 },
|
||||
{ 0, 10, 255, 255, 0, 255 },
|
||||
{ 10, 0, 255, 255, 0, 255 } };
|
||||
|
||||
expected_color->red = 255;
|
||||
expected_color->green = 255;
|
||||
expected_color->blue = 0;
|
||||
|
||||
return cogl_primitive_new_p2c4 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p3c4 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP3C4 verts[] =
|
||||
{ { 0, 0, 0, 255, 255, 0, 255 },
|
||||
{ 0, 10, 0, 255, 255, 0, 255 },
|
||||
{ 10, 0, 0, 255, 255, 0, 255 } };
|
||||
|
||||
expected_color->red = 255;
|
||||
expected_color->green = 255;
|
||||
expected_color->blue = 0;
|
||||
|
||||
return cogl_primitive_new_p3c4 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p2t2 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP2T2 verts[] =
|
||||
{ { 0, 0, 1, 0 },
|
||||
{ 0, 10, 1, 0 },
|
||||
{ 10, 0, 1, 0 } };
|
||||
|
||||
*expected_color = tex_color;
|
||||
|
||||
return cogl_primitive_new_p2t2 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p3t2 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP3T2 verts[] =
|
||||
{ { 0, 0, 0, 1, 0 },
|
||||
{ 0, 10, 0, 1, 0 },
|
||||
{ 10, 0, 0, 1, 0 } };
|
||||
|
||||
*expected_color = tex_color;
|
||||
|
||||
return cogl_primitive_new_p3t2 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p2t2c4 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP2T2C4 verts[] =
|
||||
{ { 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
|
||||
{ 0, 10, 1, 0, 0xff, 0xff, 0xf0, 0xff },
|
||||
{ 10, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff } };
|
||||
|
||||
*expected_color = tex_color;
|
||||
expected_color->blue = 0xf0;
|
||||
|
||||
return cogl_primitive_new_p2t2c4 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static CoglPrimitive *
|
||||
test_prim_p3t2c4 (CoglContext *ctx, ClutterColor *expected_color)
|
||||
{
|
||||
static const CoglVertexP3T2C4 verts[] =
|
||||
{ { 0, 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
|
||||
{ 0, 10, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff },
|
||||
{ 10, 0, 0, 1, 0, 0xff, 0xff, 0xf0, 0xff } };
|
||||
|
||||
*expected_color = tex_color;
|
||||
expected_color->blue = 0xf0;
|
||||
|
||||
return cogl_primitive_new_p3t2c4 (ctx,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
3, /* n_vertices */
|
||||
verts);
|
||||
}
|
||||
|
||||
static const TestPrimFunc
|
||||
test_prim_funcs[] =
|
||||
{
|
||||
test_prim_p2,
|
||||
test_prim_p3,
|
||||
test_prim_p2c4,
|
||||
test_prim_p3c4,
|
||||
test_prim_p2t2,
|
||||
test_prim_p3t2,
|
||||
test_prim_p2t2c4,
|
||||
test_prim_p3t2c4
|
||||
};
|
||||
|
||||
static void
|
||||
paint_cb (void)
|
||||
{
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
CoglFramebuffer *fb = cogl_get_draw_framebuffer ();
|
||||
CoglPipeline *pipeline;
|
||||
CoglTexture *tex;
|
||||
guint8 tex_data[6];
|
||||
int i;
|
||||
|
||||
/* Create a two pixel texture. The first pixel is white and the
|
||||
second pixel is tex_color. The assumption is that if no texture
|
||||
coordinates are specified then it will default to 0,0 and get
|
||||
white */
|
||||
tex_data[0] = 255;
|
||||
tex_data[1] = 255;
|
||||
tex_data[2] = 255;
|
||||
tex_data[3] = tex_color.red;
|
||||
tex_data[4] = tex_color.green;
|
||||
tex_data[5] = tex_color.blue;
|
||||
tex = cogl_texture_new_from_data (2, 1, /* size */
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
6, /* rowstride */
|
||||
tex_data);
|
||||
pipeline = cogl_pipeline_new ();
|
||||
cogl_pipeline_set_color4ub (pipeline,
|
||||
prim_color.red,
|
||||
prim_color.green,
|
||||
prim_color.blue,
|
||||
prim_color.alpha);
|
||||
cogl_pipeline_set_layer_texture (pipeline, 0, tex);
|
||||
cogl_object_unref (tex);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_prim_funcs); i++)
|
||||
{
|
||||
CoglPrimitive *prim;
|
||||
ClutterColor expected_color = prim_color;
|
||||
guint8 pixel[4];
|
||||
|
||||
prim = test_prim_funcs[i] (ctx, &expected_color);
|
||||
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (i * 10, 0, 0);
|
||||
cogl_framebuffer_draw_primitive (fb, pipeline, prim);
|
||||
cogl_pop_matrix ();
|
||||
|
||||
cogl_read_pixels (i * 10 + 2, 2, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
|
||||
g_assert_cmpint (pixel[0], ==, expected_color.red);
|
||||
g_assert_cmpint (pixel[1], ==, expected_color.green);
|
||||
g_assert_cmpint (pixel[2], ==, expected_color.blue);
|
||||
|
||||
cogl_object_unref (prim);
|
||||
}
|
||||
|
||||
cogl_object_unref (pipeline);
|
||||
|
||||
/* Comment this out to see what the test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_primitive (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint paint_handler;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
paint_handler = g_signal_connect_after (stage, "paint",
|
||||
G_CALLBACK (paint_cb), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_signal_handler_disconnect (stage, paint_handler);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,368 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define SOURCE_SIZE 32
|
||||
#define SOURCE_DIVISIONS_X 2
|
||||
#define SOURCE_DIVISIONS_Y 2
|
||||
#define DIVISION_WIDTH (SOURCE_SIZE / SOURCE_DIVISIONS_X)
|
||||
#define DIVISION_HEIGHT (SOURCE_SIZE / SOURCE_DIVISIONS_Y)
|
||||
|
||||
#define TEST_INSET 1
|
||||
|
||||
static const ClutterColor
|
||||
corner_colors[SOURCE_DIVISIONS_X * SOURCE_DIVISIONS_Y] =
|
||||
{
|
||||
{ 0xff, 0x00, 0x00, 0xff }, /* red top left */
|
||||
{ 0x00, 0xff, 0x00, 0xff }, /* green top right */
|
||||
{ 0x00, 0x00, 0xff, 0xff }, /* blue bottom left */
|
||||
{ 0xff, 0x00, 0xff, 0xff } /* purple bottom right */
|
||||
};
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint frame;
|
||||
|
||||
CoglHandle tex;
|
||||
} TestState;
|
||||
|
||||
static CoglHandle
|
||||
create_source (void)
|
||||
{
|
||||
int dx, dy;
|
||||
guchar *data = g_malloc (SOURCE_SIZE * SOURCE_SIZE * 4);
|
||||
|
||||
/* Create a texture with a different coloured rectangle at each
|
||||
corner */
|
||||
for (dy = 0; dy < SOURCE_DIVISIONS_Y; dy++)
|
||||
for (dx = 0; dx < SOURCE_DIVISIONS_X; dx++)
|
||||
{
|
||||
guchar *p = (data + dy * DIVISION_HEIGHT * SOURCE_SIZE * 4 +
|
||||
dx * DIVISION_WIDTH * 4);
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < DIVISION_HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < DIVISION_WIDTH; x++)
|
||||
{
|
||||
memcpy (p, corner_colors + dx + dy * SOURCE_DIVISIONS_X, 4);
|
||||
p += 4;
|
||||
}
|
||||
|
||||
p += SOURCE_SIZE * 4 - DIVISION_WIDTH * 4;
|
||||
}
|
||||
}
|
||||
|
||||
return cogl_texture_new_from_data (SOURCE_SIZE, SOURCE_SIZE,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
SOURCE_SIZE * 4,
|
||||
data);
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
create_test_texture (void)
|
||||
{
|
||||
CoglHandle tex;
|
||||
guint8 *data = g_malloc (256 * 256 * 4), *p = data;
|
||||
int x, y;
|
||||
|
||||
/* Create a texture that is 256x256 where the red component ranges
|
||||
from 0->255 along the x axis and the green component ranges from
|
||||
0->255 along the y axis. The blue and alpha components are all
|
||||
255 */
|
||||
for (y = 0; y < 256; y++)
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
*(p++) = x;
|
||||
*(p++) = y;
|
||||
*(p++) = 255;
|
||||
*(p++) = 255;
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (256, 256, COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
256 * 4,
|
||||
data);
|
||||
|
||||
g_free (data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_frame (TestState *state)
|
||||
{
|
||||
CoglHandle full_texture, sub_texture, sub_sub_texture;
|
||||
|
||||
/* Create a sub texture of the bottom right quarter of the texture */
|
||||
sub_texture = cogl_texture_new_from_sub_texture (state->tex,
|
||||
DIVISION_WIDTH,
|
||||
DIVISION_HEIGHT,
|
||||
DIVISION_WIDTH,
|
||||
DIVISION_HEIGHT);
|
||||
|
||||
/* Paint it */
|
||||
cogl_set_source_texture (sub_texture);
|
||||
cogl_rectangle (0.0f, 0.0f, DIVISION_WIDTH, DIVISION_HEIGHT);
|
||||
|
||||
cogl_handle_unref (sub_texture);
|
||||
|
||||
/* Repeat a sub texture of the top half of the full texture. This is
|
||||
documented to be undefined so it doesn't technically have to work
|
||||
but it will with the current implementation */
|
||||
sub_texture = cogl_texture_new_from_sub_texture (state->tex,
|
||||
0, 0,
|
||||
SOURCE_SIZE,
|
||||
DIVISION_HEIGHT);
|
||||
cogl_set_source_texture (sub_texture);
|
||||
cogl_rectangle_with_texture_coords (0.0f, SOURCE_SIZE,
|
||||
SOURCE_SIZE * 2.0f, SOURCE_SIZE * 1.5f,
|
||||
0.0f, 0.0f,
|
||||
2.0f, 1.0f);
|
||||
cogl_handle_unref (sub_texture);
|
||||
|
||||
/* Create a sub texture of a sub texture */
|
||||
full_texture = create_test_texture ();
|
||||
sub_texture = cogl_texture_new_from_sub_texture (full_texture,
|
||||
20, 10, 30, 20);
|
||||
sub_sub_texture = cogl_texture_new_from_sub_texture (sub_texture,
|
||||
20, 10, 10, 10);
|
||||
cogl_set_source_texture (sub_sub_texture);
|
||||
cogl_rectangle (0.0f, SOURCE_SIZE * 2.0f,
|
||||
10.0f, SOURCE_SIZE * 2.0f + 10.0f);
|
||||
cogl_handle_unref (sub_sub_texture);
|
||||
cogl_handle_unref (sub_texture);
|
||||
cogl_handle_unref (full_texture);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
validate_part (TestState *state,
|
||||
int xpos, int ypos,
|
||||
int width, int height,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
int x, y;
|
||||
gboolean pass = TRUE;
|
||||
guchar *pixels, *p;
|
||||
|
||||
p = pixels = clutter_stage_read_pixels (CLUTTER_STAGE (state->stage),
|
||||
xpos + TEST_INSET,
|
||||
ypos + TEST_INSET,
|
||||
width - TEST_INSET - 2,
|
||||
height - TEST_INSET - 2);
|
||||
|
||||
/* Check whether the center of each division is the right color */
|
||||
for (y = 0; y < height - TEST_INSET - 2; y++)
|
||||
for (x = 0; x < width - TEST_INSET - 2; x++)
|
||||
{
|
||||
if (p[0] != color->red ||
|
||||
p[1] != color->green ||
|
||||
p[2] != color->blue)
|
||||
pass = FALSE;
|
||||
|
||||
p += 4;
|
||||
}
|
||||
|
||||
return pass;
|
||||
}
|
||||
|
||||
static guint8 *
|
||||
create_update_data (void)
|
||||
{
|
||||
guint8 *data = g_malloc (256 * 256 * 4), *p = data;
|
||||
int x, y;
|
||||
|
||||
/* Create some image data that is 256x256 where the blue component
|
||||
ranges from 0->255 along the x axis and the alpha component
|
||||
ranges from 0->255 along the y axis. The red and green components
|
||||
are all zero */
|
||||
for (y = 0; y < 256; y++)
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
*(p++) = 0;
|
||||
*(p++) = 0;
|
||||
*(p++) = x;
|
||||
*(p++) = y;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
int i, division_num, x, y;
|
||||
CoglHandle sub_texture, test_tex;
|
||||
guchar *texture_data, *p;
|
||||
gint tex_width, tex_height;
|
||||
|
||||
/* Sub texture of the bottom right corner of the texture */
|
||||
g_assert (validate_part (state, 0, 0, DIVISION_WIDTH, DIVISION_HEIGHT,
|
||||
corner_colors +
|
||||
(SOURCE_DIVISIONS_Y - 1) * SOURCE_DIVISIONS_X +
|
||||
SOURCE_DIVISIONS_X - 1));
|
||||
|
||||
/* Sub texture of the top half repeated horizontally */
|
||||
for (i = 0; i < 2; i++)
|
||||
for (division_num = 0; division_num < SOURCE_DIVISIONS_X; division_num++)
|
||||
g_assert (validate_part (state,
|
||||
i * SOURCE_SIZE + division_num * DIVISION_WIDTH,
|
||||
SOURCE_SIZE,
|
||||
DIVISION_WIDTH, DIVISION_HEIGHT,
|
||||
corner_colors + division_num));
|
||||
|
||||
/* Sub sub texture */
|
||||
p = texture_data = clutter_stage_read_pixels (CLUTTER_STAGE (state->stage),
|
||||
0, SOURCE_SIZE * 2, 10, 10);
|
||||
for (y = 0; y < 10; y++)
|
||||
for (x = 0; x < 10; x++)
|
||||
{
|
||||
g_assert_cmpint (abs(*(p++) - (x + 40)), <=, 1);
|
||||
g_assert_cmpint (abs(*(p++) - (y + 20)), <=, 1);
|
||||
p += 2;
|
||||
}
|
||||
g_free (texture_data);
|
||||
|
||||
/* Try reading back the texture data */
|
||||
sub_texture = cogl_texture_new_from_sub_texture (state->tex,
|
||||
SOURCE_SIZE / 4,
|
||||
SOURCE_SIZE / 4,
|
||||
SOURCE_SIZE / 2,
|
||||
SOURCE_SIZE / 2);
|
||||
tex_width = cogl_texture_get_width (sub_texture);
|
||||
tex_height = cogl_texture_get_height (sub_texture);
|
||||
p = texture_data = g_malloc (tex_width * tex_height * 4);
|
||||
cogl_texture_get_data (sub_texture, COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
tex_width * 4,
|
||||
texture_data);
|
||||
for (y = 0; y < tex_height; y++)
|
||||
for (x = 0; x < tex_width; x++)
|
||||
{
|
||||
int div_x = ((x * SOURCE_SIZE / 2 / tex_width + SOURCE_SIZE / 4) /
|
||||
DIVISION_WIDTH);
|
||||
int div_y = ((y * SOURCE_SIZE / 2 / tex_height + SOURCE_SIZE / 4) /
|
||||
DIVISION_HEIGHT);
|
||||
const ClutterColor *color = (corner_colors + div_x +
|
||||
div_y * SOURCE_DIVISIONS_X);
|
||||
g_assert (p[0] == color->red);
|
||||
g_assert (p[1] == color->green);
|
||||
g_assert (p[2] == color->blue);
|
||||
p += 4;
|
||||
}
|
||||
g_free (texture_data);
|
||||
cogl_handle_unref (sub_texture);
|
||||
|
||||
/* Create a 256x256 test texture */
|
||||
test_tex = create_test_texture ();
|
||||
/* Create a sub texture the views the center half of the texture */
|
||||
sub_texture = cogl_texture_new_from_sub_texture (test_tex,
|
||||
64, 64, 128, 128);
|
||||
/* Update the center half of the sub texture */
|
||||
texture_data = create_update_data ();
|
||||
cogl_texture_set_region (sub_texture, 0, 0, 32, 32, 64, 64, 256, 256,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, 256 * 4,
|
||||
texture_data);
|
||||
g_free (texture_data);
|
||||
cogl_handle_unref (sub_texture);
|
||||
/* Get the texture data */
|
||||
p = texture_data = g_malloc (256 * 256 * 4);
|
||||
cogl_texture_get_data (test_tex, COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
256 * 4, texture_data);
|
||||
|
||||
/* Verify the texture data */
|
||||
for (y = 0; y < 256; y++)
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
/* If we're in the center quarter */
|
||||
if (x >= 96 && x < 160 && y >= 96 && y < 160)
|
||||
{
|
||||
g_assert ((*p++) == 0);
|
||||
g_assert ((*p++) == 0);
|
||||
g_assert ((*p++) == x - 96);
|
||||
g_assert ((*p++) == y - 96);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert ((*p++) == x);
|
||||
g_assert ((*p++) == y);
|
||||
g_assert ((*p++) == 255);
|
||||
g_assert ((*p++) == 255);
|
||||
}
|
||||
}
|
||||
g_free (texture_data);
|
||||
cogl_handle_unref (test_tex);
|
||||
|
||||
/* Comment this out to see what the test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
int frame_num;
|
||||
|
||||
draw_frame (state);
|
||||
|
||||
/* XXX: validate_result calls clutter_stage_read_pixels which will result in
|
||||
* another paint run so to avoid infinite recursion we only aim to validate
|
||||
* the first frame. */
|
||||
frame_num = state->frame++;
|
||||
if (frame_num == 1)
|
||||
validate_result (state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_sub_texture (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
guint idle_source;
|
||||
guint paint_handler;
|
||||
|
||||
state.frame = 0;
|
||||
|
||||
state.stage = clutter_stage_new ();
|
||||
state.tex = create_source ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = g_idle_add (queue_redraw, state.stage);
|
||||
|
||||
paint_handler = g_signal_connect_after (state.stage, "paint",
|
||||
G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show_all (state.stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
g_signal_handler_disconnect (state.stage, paint_handler);
|
||||
|
||||
cogl_handle_unref (state.tex);
|
||||
|
||||
clutter_actor_destroy (state.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0xff, 0x0, 0xff };
|
||||
|
||||
#define TEX_WIDTH 4
|
||||
#define TEX_HEIGHT 8
|
||||
#define TEX_DEPTH 16
|
||||
/* Leave four bytes of padding between each row */
|
||||
#define TEX_ROWSTRIDE (TEX_WIDTH * 4 + 4)
|
||||
/* Leave four rows of padding between each image */
|
||||
#define TEX_IMAGE_STRIDE ((TEX_HEIGHT + 4) * TEX_ROWSTRIDE)
|
||||
|
||||
static CoglHandle
|
||||
create_texture_3d (void)
|
||||
{
|
||||
int x, y, z;
|
||||
guint8 *data = g_malloc (TEX_IMAGE_STRIDE * TEX_DEPTH);
|
||||
guint8 *p = data;
|
||||
CoglHandle tex;
|
||||
GError *error = NULL;
|
||||
|
||||
for (z = 0; z < TEX_DEPTH; z++)
|
||||
{
|
||||
for (y = 0; y < TEX_HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < TEX_WIDTH; x++)
|
||||
{
|
||||
/* Set red, green, blue to values based on x, y, z */
|
||||
*(p++) = 255 - x * 8;
|
||||
*(p++) = y * 8;
|
||||
*(p++) = 255 - z * 8;
|
||||
/* Fully opaque */
|
||||
*(p++) = 0xff;
|
||||
}
|
||||
|
||||
/* Set the padding between rows to 0xde */
|
||||
memset (p, 0xde, TEX_ROWSTRIDE - (TEX_WIDTH * 4));
|
||||
p += TEX_ROWSTRIDE - (TEX_WIDTH * 4);
|
||||
}
|
||||
/* Set the padding between images to 0xad */
|
||||
memset (p, 0xba, TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE));
|
||||
p += TEX_IMAGE_STRIDE - (TEX_HEIGHT * TEX_ROWSTRIDE);
|
||||
}
|
||||
|
||||
tex = cogl_texture_3d_new_from_data (TEX_WIDTH, TEX_HEIGHT, TEX_DEPTH,
|
||||
COGL_TEXTURE_NO_AUTO_MIPMAP,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
TEX_ROWSTRIDE,
|
||||
TEX_IMAGE_STRIDE,
|
||||
data,
|
||||
&error);
|
||||
|
||||
if (tex == COGL_INVALID_HANDLE)
|
||||
{
|
||||
g_assert (error != NULL);
|
||||
g_warning ("Failed to create 3D texture: %s", error->message);
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_frame (void)
|
||||
{
|
||||
CoglHandle tex = create_texture_3d ();
|
||||
CoglHandle material = cogl_material_new ();
|
||||
typedef struct { float x, y, s, t, r; } Vert;
|
||||
CoglHandle vbo, indices;
|
||||
Vert *verts, *v;
|
||||
int i;
|
||||
|
||||
cogl_material_set_layer (material, 0, tex);
|
||||
cogl_handle_unref (tex);
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_set_source (material);
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/* Render the texture repeated horizontally twice using a regular
|
||||
cogl rectangle. This should end up with the r texture coordinates
|
||||
as zero */
|
||||
cogl_rectangle_with_texture_coords (0.0f, 0.0f, TEX_WIDTH * 2, TEX_HEIGHT,
|
||||
0.0f, 0.0f, 2.0f, 1.0f);
|
||||
|
||||
/* Render all of the images in the texture using coordinates from a VBO */
|
||||
v = verts = g_new (Vert, 4 * TEX_DEPTH);
|
||||
for (i = 0; i < TEX_DEPTH; i++)
|
||||
{
|
||||
float r = (i + 0.5f) / TEX_DEPTH;
|
||||
|
||||
v->x = i * TEX_WIDTH;
|
||||
v->y = TEX_HEIGHT;
|
||||
v->s = 0;
|
||||
v->t = 0;
|
||||
v->r = r;
|
||||
v++;
|
||||
|
||||
v->x = i * TEX_WIDTH;
|
||||
v->y = TEX_HEIGHT * 2;
|
||||
v->s = 0;
|
||||
v->t = 1;
|
||||
v->r = r;
|
||||
v++;
|
||||
|
||||
v->x = i * TEX_WIDTH + TEX_WIDTH;
|
||||
v->y = TEX_HEIGHT * 2;
|
||||
v->s = 1;
|
||||
v->t = 1;
|
||||
v->r = r;
|
||||
v++;
|
||||
|
||||
v->x = i * TEX_WIDTH + TEX_WIDTH;
|
||||
v->y = TEX_HEIGHT;
|
||||
v->s = 1;
|
||||
v->t = 0;
|
||||
v->r = r;
|
||||
v++;
|
||||
}
|
||||
|
||||
vbo = cogl_vertex_buffer_new (4 * TEX_DEPTH);
|
||||
cogl_vertex_buffer_add (vbo, "gl_Vertex",
|
||||
2, COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
||||
sizeof (Vert),
|
||||
&verts->x);
|
||||
cogl_vertex_buffer_add (vbo, "gl_MultiTexCoord0",
|
||||
3, COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
||||
sizeof (Vert),
|
||||
&verts->s);
|
||||
cogl_vertex_buffer_submit (vbo);
|
||||
|
||||
g_free (verts);
|
||||
|
||||
indices = cogl_vertex_buffer_indices_get_for_quads (6 * TEX_DEPTH);
|
||||
|
||||
cogl_vertex_buffer_draw_elements (vbo,
|
||||
COGL_VERTICES_MODE_TRIANGLES,
|
||||
indices,
|
||||
0, TEX_DEPTH * 4 - 1,
|
||||
0, TEX_DEPTH * 6);
|
||||
|
||||
cogl_handle_unref (vbo);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_block (int block_x, int block_y, int z)
|
||||
{
|
||||
guint8 *data, *p;
|
||||
int x, y;
|
||||
|
||||
p = data = g_malloc (TEX_WIDTH * TEX_HEIGHT * 4);
|
||||
|
||||
cogl_read_pixels (block_x * TEX_WIDTH, block_y * TEX_HEIGHT,
|
||||
TEX_WIDTH, TEX_HEIGHT,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
data);
|
||||
|
||||
for (y = 0; y < TEX_HEIGHT; y++)
|
||||
for (x = 0; x < TEX_WIDTH; x++)
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, 255 - x * 8);
|
||||
g_assert_cmpint (p[1], ==, y * 8);
|
||||
g_assert_cmpint (p[2], ==, 255 - z * 8);
|
||||
p += 4;
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
validate_block (0, 0, 0);
|
||||
|
||||
for (i = 0; i < TEX_DEPTH; i++)
|
||||
validate_block (i, 1, i);
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (void)
|
||||
{
|
||||
draw_frame ();
|
||||
|
||||
validate_result ();
|
||||
|
||||
/* Comment this out to see what the test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_texture_3d (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint paint_handler;
|
||||
|
||||
/* Check whether GL supports the rectangle extension. If not we'll
|
||||
just assume the test passes */
|
||||
if (cogl_features_available (COGL_FEATURE_TEXTURE_3D))
|
||||
{
|
||||
stage = clutter_stage_new ();
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
|
||||
|
||||
paint_handler = g_signal_connect_after (stage, "paint",
|
||||
G_CALLBACK (on_paint), NULL);
|
||||
|
||||
clutter_actor_show (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_signal_handler_disconnect (stage, paint_handler);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
||||
else if (g_test_verbose ())
|
||||
g_print ("Skipping\n");
|
||||
}
|
@ -1,319 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define TEX_SIZE 4
|
||||
|
||||
static const ClutterColor stage_color = { 0x80, 0x80, 0x80, 0xff };
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
CoglHandle texture;
|
||||
} TestState;
|
||||
|
||||
static CoglHandle
|
||||
create_texture (CoglTextureFlags flags)
|
||||
{
|
||||
guint8 *data = g_malloc (TEX_SIZE * TEX_SIZE * 4), *p = data;
|
||||
CoglHandle tex;
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < TEX_SIZE; y++)
|
||||
for (x = 0; x < TEX_SIZE; x++)
|
||||
{
|
||||
*(p++) = 0;
|
||||
*(p++) = (x & 1) * 255;
|
||||
*(p++) = (y & 1) * 255;
|
||||
*(p++) = 255;
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (TEX_SIZE, TEX_SIZE, flags,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
TEX_SIZE * 4,
|
||||
data);
|
||||
|
||||
g_free (data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
create_material (TestState *state,
|
||||
CoglMaterialWrapMode wrap_mode_s,
|
||||
CoglMaterialWrapMode wrap_mode_t)
|
||||
{
|
||||
CoglHandle material;
|
||||
|
||||
material = cogl_material_new ();
|
||||
cogl_material_set_layer (material, 0, state->texture);
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_material_set_layer_wrap_mode_s (material, 0, wrap_mode_s);
|
||||
cogl_material_set_layer_wrap_mode_t (material, 0, wrap_mode_t);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
static CoglMaterialWrapMode
|
||||
test_wrap_modes[] =
|
||||
{
|
||||
COGL_MATERIAL_WRAP_MODE_REPEAT,
|
||||
COGL_MATERIAL_WRAP_MODE_REPEAT,
|
||||
|
||||
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE,
|
||||
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE,
|
||||
|
||||
COGL_MATERIAL_WRAP_MODE_REPEAT,
|
||||
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE,
|
||||
|
||||
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE,
|
||||
COGL_MATERIAL_WRAP_MODE_REPEAT,
|
||||
|
||||
COGL_MATERIAL_WRAP_MODE_AUTOMATIC,
|
||||
COGL_MATERIAL_WRAP_MODE_AUTOMATIC,
|
||||
|
||||
COGL_MATERIAL_WRAP_MODE_AUTOMATIC,
|
||||
COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE
|
||||
};
|
||||
|
||||
static void
|
||||
draw_tests (TestState *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_wrap_modes); i += 2)
|
||||
{
|
||||
CoglMaterialWrapMode wrap_mode_s, wrap_mode_t;
|
||||
CoglHandle material;
|
||||
|
||||
/* Create a separate material for each pair of wrap modes so
|
||||
that we can verify whether the batch splitting works */
|
||||
wrap_mode_s = test_wrap_modes[i];
|
||||
wrap_mode_t = test_wrap_modes[i + 1];
|
||||
material = create_material (state, wrap_mode_s, wrap_mode_t);
|
||||
cogl_set_source (material);
|
||||
cogl_handle_unref (material);
|
||||
/* Render the material at four times the size of the texture */
|
||||
cogl_rectangle_with_texture_coords (i * TEX_SIZE, 0,
|
||||
(i + 2) * TEX_SIZE, TEX_SIZE * 2,
|
||||
0, 0, 2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
static const CoglTextureVertex vertices[4] =
|
||||
{
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, TEX_SIZE * 2, 0.0f, 0.0f, 2.0f },
|
||||
{ TEX_SIZE * 2, TEX_SIZE * 2, 0.0f, 2.0f, 2.0f },
|
||||
{ TEX_SIZE * 2, 0.0f, 0.0f, 2.0f, 0.0f }
|
||||
};
|
||||
|
||||
static void
|
||||
draw_tests_polygon (TestState *state)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_wrap_modes); i += 2)
|
||||
{
|
||||
CoglMaterialWrapMode wrap_mode_s, wrap_mode_t;
|
||||
CoglHandle material;
|
||||
|
||||
wrap_mode_s = test_wrap_modes[i];
|
||||
wrap_mode_t = test_wrap_modes[i + 1];
|
||||
material = create_material (state, wrap_mode_s, wrap_mode_t);
|
||||
cogl_set_source (material);
|
||||
cogl_handle_unref (material);
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (TEX_SIZE * i, 0.0f, 0.0f);
|
||||
/* Render the material at four times the size of the texture */
|
||||
cogl_polygon (vertices, G_N_ELEMENTS (vertices), FALSE);
|
||||
cogl_pop_matrix ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
draw_tests_vbo (TestState *state)
|
||||
{
|
||||
CoglHandle vbo;
|
||||
int i;
|
||||
|
||||
vbo = cogl_vertex_buffer_new (4);
|
||||
cogl_vertex_buffer_add (vbo, "gl_Vertex", 3,
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
||||
sizeof (vertices[0]),
|
||||
&vertices[0].x);
|
||||
cogl_vertex_buffer_add (vbo, "gl_MultiTexCoord0", 2,
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT, FALSE,
|
||||
sizeof (vertices[0]),
|
||||
&vertices[0].tx);
|
||||
cogl_vertex_buffer_submit (vbo);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_wrap_modes); i += 2)
|
||||
{
|
||||
CoglMaterialWrapMode wrap_mode_s, wrap_mode_t;
|
||||
CoglHandle material;
|
||||
|
||||
wrap_mode_s = test_wrap_modes[i];
|
||||
wrap_mode_t = test_wrap_modes[i + 1];
|
||||
material = create_material (state, wrap_mode_s, wrap_mode_t);
|
||||
cogl_set_source (material);
|
||||
cogl_handle_unref (material);
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (TEX_SIZE * i, 0.0f, 0.0f);
|
||||
/* Render the material at four times the size of the texture */
|
||||
cogl_vertex_buffer_draw (vbo, COGL_VERTICES_MODE_TRIANGLE_FAN, 0, 4);
|
||||
cogl_pop_matrix ();
|
||||
}
|
||||
|
||||
cogl_handle_unref (vbo);
|
||||
}
|
||||
|
||||
static void
|
||||
draw_frame (TestState *state)
|
||||
{
|
||||
/* Draw the tests first with a non atlased texture */
|
||||
state->texture = create_texture (COGL_TEXTURE_NO_ATLAS);
|
||||
draw_tests (state);
|
||||
cogl_handle_unref (state->texture);
|
||||
|
||||
/* Draw the tests again with a possible atlased texture. This should
|
||||
end up testing software repeats */
|
||||
state->texture = create_texture (COGL_TEXTURE_NONE);
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (0.0f, TEX_SIZE * 2.0f, 0.0f);
|
||||
draw_tests (state);
|
||||
cogl_pop_matrix ();
|
||||
cogl_handle_unref (state->texture);
|
||||
|
||||
/* Draw the tests using cogl_polygon */
|
||||
state->texture = create_texture (COGL_TEXTURE_NO_ATLAS);
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (0.0f, TEX_SIZE * 4.0f, 0.0f);
|
||||
draw_tests_polygon (state);
|
||||
cogl_pop_matrix ();
|
||||
cogl_handle_unref (state->texture);
|
||||
|
||||
/* Draw the tests using a vertex buffer */
|
||||
state->texture = create_texture (COGL_TEXTURE_NO_ATLAS);
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (0.0f, TEX_SIZE * 6.0f, 0.0f);
|
||||
draw_tests_vbo (state);
|
||||
cogl_pop_matrix ();
|
||||
cogl_handle_unref (state->texture);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_set (TestState *state, int offset)
|
||||
{
|
||||
guint8 data[TEX_SIZE * 2 * TEX_SIZE * 2 * 4], *p;
|
||||
int x, y, i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (test_wrap_modes); i += 2)
|
||||
{
|
||||
CoglMaterialWrapMode wrap_mode_s, wrap_mode_t;
|
||||
|
||||
wrap_mode_s = test_wrap_modes[i];
|
||||
wrap_mode_t = test_wrap_modes[i + 1];
|
||||
|
||||
cogl_read_pixels (i * TEX_SIZE, offset * TEX_SIZE * 2,
|
||||
TEX_SIZE * 2, TEX_SIZE * 2,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
data);
|
||||
|
||||
p = data;
|
||||
|
||||
for (y = 0; y < TEX_SIZE * 2; y++)
|
||||
for (x = 0; x < TEX_SIZE * 2; x++)
|
||||
{
|
||||
guint8 green, blue;
|
||||
|
||||
if (x < TEX_SIZE ||
|
||||
wrap_mode_s == COGL_MATERIAL_WRAP_MODE_REPEAT ||
|
||||
wrap_mode_s == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||
green = (x & 1) * 255;
|
||||
else
|
||||
green = ((TEX_SIZE - 1) & 1) * 255;
|
||||
|
||||
if (y < TEX_SIZE ||
|
||||
wrap_mode_t == COGL_MATERIAL_WRAP_MODE_REPEAT ||
|
||||
wrap_mode_t == COGL_MATERIAL_WRAP_MODE_AUTOMATIC)
|
||||
blue = (y & 1) * 255;
|
||||
else
|
||||
blue = ((TEX_SIZE - 1) & 1) * 255;
|
||||
|
||||
g_assert_cmpint (p[0], ==, 0);
|
||||
g_assert_cmpint (p[1], ==, green);
|
||||
g_assert_cmpint (p[2], ==, blue);
|
||||
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
validate_set (state, 0); /* non-atlased rectangle */
|
||||
#if 0 /* this doesn't currently work */
|
||||
validate_set (state, 1); /* atlased rectangle */
|
||||
#endif
|
||||
validate_set (state, 2); /* cogl_polygon */
|
||||
validate_set (state, 3); /* vertex buffer */
|
||||
|
||||
/* Comment this out to see what the test paints */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
draw_frame (state);
|
||||
|
||||
validate_result (state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_wrap_modes (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
guint idle_source;
|
||||
guint paint_handler;
|
||||
|
||||
state.stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
|
||||
|
||||
/* We force continuous redrawing of the stage, since we need to skip
|
||||
* the first few frames, and we wont be doing anything else that
|
||||
* will trigger redrawing. */
|
||||
idle_source = g_idle_add (queue_redraw, state.stage);
|
||||
|
||||
paint_handler = g_signal_connect_after (state.stage, "paint",
|
||||
G_CALLBACK (on_paint), &state);
|
||||
|
||||
clutter_actor_show_all (state.stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_source_remove (idle_source);
|
||||
g_signal_handler_disconnect (state.stage, paint_handler);
|
||||
|
||||
clutter_actor_destroy (state.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -234,23 +234,15 @@ main (int argc, char **argv)
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_object);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_fixed);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_backface_culling);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_materials);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_pipeline_user_matrix);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_blend_strings);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_premult);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_readpixels);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_path);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_depth_test);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_npot_texture);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_multitexture);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_mipmaps);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_sub_texture);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_pixel_array);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_rectangle);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_3d);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_wrap_modes);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_pixmap_x11);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_texture_get_set_data);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/texture", test_cogl_atlas_migration);
|
||||
@ -259,14 +251,9 @@ main (int argc, char **argv)
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_interleved);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_mutability);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-array", test_cogl_primitive);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl/shaders", test_cogl_just_vertex_shader);
|
||||
|
||||
/* left to the end because they aren't currently very orthogonal and tend to
|
||||
* break subsequent tests! */
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_viewport);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_offscreen);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user