conform: Drop the Cogl tests
Cogl has its own (way, way better) test suite these days, so we can drop our own units here.
This commit is contained in:
parent
1124fa9a10
commit
3dad01ac22
@ -26,26 +26,6 @@ units_sources += \
|
||||
timeline-rewind.c \
|
||||
$(NULL)
|
||||
|
||||
# cogl tests
|
||||
units_sources += \
|
||||
test-cogl-fixed.c \
|
||||
test-cogl-materials.c \
|
||||
test-cogl-viewport.c \
|
||||
test-cogl-multitexture.c \
|
||||
test-cogl-npot-texture.c \
|
||||
test-cogl-object.c \
|
||||
test-cogl-premult.c \
|
||||
test-cogl-readpixels.c \
|
||||
test-cogl-texture-get-set-data.c \
|
||||
test-cogl-texture-mipmaps.c \
|
||||
test-cogl-texture-pixmap-x11.c \
|
||||
test-cogl-texture-rectangle.c \
|
||||
test-cogl-atlas-migration.c \
|
||||
test-cogl-vertex-buffer-contiguous.c \
|
||||
test-cogl-vertex-buffer-interleved.c \
|
||||
test-cogl-vertex-buffer-mutability.c \
|
||||
$(NULL)
|
||||
|
||||
# actors tests
|
||||
units_sources += \
|
||||
actor-anchors.c \
|
||||
|
@ -1,133 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
#define N_TEXTURES 128
|
||||
|
||||
#define OPACITY_FOR_ROW(y) \
|
||||
(0xff - ((y) & 0xf) * 0x10)
|
||||
|
||||
#define COLOR_FOR_SIZE(size) \
|
||||
(colors + (size) % 3)
|
||||
|
||||
static const ClutterColor colors[] =
|
||||
{ { 0xff, 0x00, 0x00, 0xff },
|
||||
{ 0x00, 0xff, 0x00, 0xff },
|
||||
{ 0x00, 0x00, 0xff, 0xff } };
|
||||
|
||||
static CoglHandle
|
||||
create_texture (int size)
|
||||
{
|
||||
CoglHandle texture;
|
||||
const ClutterColor *color;
|
||||
guint8 *data, *p;
|
||||
int x, y;
|
||||
|
||||
/* Create a red, green or blue texture depending on the size */
|
||||
color = COLOR_FOR_SIZE (size);
|
||||
|
||||
p = data = g_malloc (size * size * 4);
|
||||
|
||||
/* Fill the data with the color but fade the opacity out with
|
||||
increasing y coordinates so that we can see the blending it the
|
||||
atlas migration accidentally blends with garbage in the
|
||||
texture */
|
||||
for (y = 0; y < size; y++)
|
||||
{
|
||||
int opacity = OPACITY_FOR_ROW (y);
|
||||
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
/* Store the colors premultiplied */
|
||||
p[0] = color->red * opacity / 255;
|
||||
p[1] = color->green * opacity / 255;
|
||||
p[2] = color->blue * opacity / 255;
|
||||
p[3] = opacity;
|
||||
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
|
||||
texture = cogl_texture_new_from_data (size, /* width */
|
||||
size, /* height */
|
||||
COGL_TEXTURE_NONE, /* flags */
|
||||
/* format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
/* rowstride */
|
||||
size * 4,
|
||||
data);
|
||||
|
||||
g_free (data);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
static void
|
||||
verify_texture (CoglHandle texture, int size)
|
||||
{
|
||||
guint8 *data, *p;
|
||||
int x, y;
|
||||
const ClutterColor *color;
|
||||
|
||||
color = COLOR_FOR_SIZE (size);
|
||||
|
||||
p = data = g_malloc (size * size * 4);
|
||||
|
||||
cogl_texture_get_data (texture,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
size * 4,
|
||||
data);
|
||||
|
||||
for (y = 0; y < size; y++)
|
||||
{
|
||||
int opacity = OPACITY_FOR_ROW (y);
|
||||
|
||||
for (x = 0; x < size; x++)
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, color->red * opacity / 255);
|
||||
g_assert_cmpint (p[1], ==, color->green * opacity / 255);
|
||||
g_assert_cmpint (p[2], ==, color->blue * opacity / 255);
|
||||
g_assert_cmpint (p[3], ==, opacity);
|
||||
|
||||
p += 4;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_atlas_migration (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
CoglHandle textures[N_TEXTURES];
|
||||
int i, tex_num;
|
||||
|
||||
/* Create and destroy all of the textures a few times to increase
|
||||
the chances that we'll end up reusing the buffers for previously
|
||||
discarded atlases */
|
||||
for (i = 0; i < 5; i++)
|
||||
{
|
||||
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
||||
textures[tex_num] = create_texture (tex_num + 1);
|
||||
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
||||
cogl_object_unref (textures[tex_num]);
|
||||
}
|
||||
|
||||
/* Create all the textures again */
|
||||
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
||||
textures[tex_num] = create_texture (tex_num + 1);
|
||||
|
||||
/* Verify that they all still have the right data */
|
||||
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
||||
verify_texture (textures[tex_num], tex_num + 1);
|
||||
|
||||
/* Destroy them all */
|
||||
for (tex_num = 0; tex_num < N_TEXTURES; tex_num++)
|
||||
cogl_object_unref (textures[tex_num]);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
void
|
||||
test_cogl_fixed (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
g_assert_cmpint (COGL_FIXED_1, ==, COGL_FIXED_FROM_FLOAT (1.0));
|
||||
g_assert_cmpint (COGL_FIXED_1, ==, COGL_FIXED_FROM_INT (1));
|
||||
|
||||
g_assert_cmpint (COGL_FIXED_0_5, ==, COGL_FIXED_FROM_FLOAT (0.5));
|
||||
|
||||
g_assert_cmpfloat (COGL_FIXED_TO_FLOAT (COGL_FIXED_1), ==, 1.0);
|
||||
g_assert_cmpfloat (COGL_FIXED_TO_FLOAT (COGL_FIXED_0_5), ==, 0.5);
|
||||
}
|
||||
|
@ -1,383 +0,0 @@
|
||||
#include "config.h"
|
||||
|
||||
/* XXX: we currently include config.h above as a hack so we can
|
||||
* determine if we are running with GLES2 or not but since Clutter
|
||||
* uses the experimental Cogl api that will also define
|
||||
* COGL_ENABLE_EXPERIMENTAL_2_0_API. The cogl_material_ api isn't
|
||||
* exposed if COGL_ENABLE_EXPERIMENTAL_2_0_API is defined though so we
|
||||
* undef it before cogl.h is included */
|
||||
#undef COGL_ENABLE_EXPERIMENTAL_2_0_API
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
static TestConformGLFunctions gl_functions;
|
||||
|
||||
#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)
|
||||
|
||||
#ifndef GL_VERSION
|
||||
#define GL_VERSION 0x1F02
|
||||
#endif
|
||||
|
||||
#ifndef GL_MAX_TEXTURE_IMAGE_UNITS
|
||||
#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872
|
||||
#endif
|
||||
#ifndef GL_MAX_VERTEX_ATTRIBS
|
||||
#define GL_MAX_VERTEX_ATTRIBS 0x8869
|
||||
#endif
|
||||
#ifndef GL_MAX_TEXTURE_UNITS
|
||||
#define GL_MAX_TEXTURE_UNITS 0x84E2
|
||||
#endif
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
|
||||
static void
|
||||
check_pixel (TestState *state, int x, int y, guint32 color)
|
||||
{
|
||||
int y_off;
|
||||
int x_off;
|
||||
guint8 pixel[4];
|
||||
guint8 r = MASK_RED (color);
|
||||
guint8 g = MASK_GREEN (color);
|
||||
guint8 b = MASK_BLUE (color);
|
||||
guint8 a = MASK_ALPHA (color);
|
||||
|
||||
/* 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 (" result = %02x, %02x, %02x, %02x\n",
|
||||
pixel[RED], pixel[GREEN], pixel[BLUE], pixel[ALPHA]);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print (" expected = %x, %x, %x, %x\n",
|
||||
r, g, b, a);
|
||||
/* FIXME - allow for hardware in-precision */
|
||||
g_assert (pixel[RED] == r);
|
||||
g_assert (pixel[GREEN] == g);
|
||||
g_assert (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 void
|
||||
test_material_with_primitives (TestState *state,
|
||||
int x, int y,
|
||||
guint32 color)
|
||||
{
|
||||
CoglTextureVertex verts[4];
|
||||
CoglHandle vbo;
|
||||
|
||||
verts[0].x = 0;
|
||||
verts[0].y = 0;
|
||||
verts[0].z = 0;
|
||||
verts[1].x = 0;
|
||||
verts[1].y = QUAD_WIDTH;
|
||||
verts[1].z = 0;
|
||||
verts[2].x = QUAD_WIDTH;
|
||||
verts[2].y = QUAD_WIDTH;
|
||||
verts[2].z = 0;
|
||||
verts[3].x = QUAD_WIDTH;
|
||||
verts[3].y = 0;
|
||||
verts[3].z = 0;
|
||||
|
||||
cogl_push_matrix ();
|
||||
|
||||
cogl_translate (x * QUAD_WIDTH, y * QUAD_WIDTH, 0);
|
||||
|
||||
cogl_rectangle (0, 0, QUAD_WIDTH, QUAD_WIDTH);
|
||||
|
||||
cogl_translate (0, QUAD_WIDTH, 0);
|
||||
cogl_polygon (verts, 4, FALSE);
|
||||
|
||||
cogl_translate (0, QUAD_WIDTH, 0);
|
||||
vbo = cogl_vertex_buffer_new (4);
|
||||
cogl_vertex_buffer_add (vbo,
|
||||
"gl_Vertex",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
sizeof (CoglTextureVertex), /* stride */
|
||||
verts);
|
||||
cogl_vertex_buffer_draw (vbo,
|
||||
COGL_VERTICES_MODE_TRIANGLE_FAN,
|
||||
0, /* first */
|
||||
4); /* count */
|
||||
cogl_handle_unref (vbo);
|
||||
|
||||
cogl_pop_matrix ();
|
||||
|
||||
check_pixel (state, x, y, color);
|
||||
check_pixel (state, x, y+1, color);
|
||||
check_pixel (state, x, y+2, color);
|
||||
}
|
||||
|
||||
static void
|
||||
test_invalid_texture_layers (TestState *state, int x, int y)
|
||||
{
|
||||
CoglHandle material = cogl_material_new ();
|
||||
|
||||
/* explicitly create a layer with an invalid handle. This may be desireable
|
||||
* if the user also sets a texture combine string that e.g. refers to a
|
||||
* constant color. */
|
||||
cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE);
|
||||
|
||||
cogl_set_source (material);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/* We expect a white fallback material to be used */
|
||||
test_material_with_primitives (state, x, y, 0xffffffff);
|
||||
}
|
||||
|
||||
#ifdef COGL_HAS_GLES2
|
||||
static gboolean
|
||||
using_gles2_driver (void)
|
||||
{
|
||||
/* FIXME: This should probably be replaced with some way to query
|
||||
the driver from Cogl */
|
||||
return g_str_has_prefix ((const char *) gl_functions.glGetString (GL_VERSION),
|
||||
"OpenGL ES 2");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
test_using_all_layers (TestState *state, int x, int y)
|
||||
{
|
||||
CoglHandle material = cogl_material_new ();
|
||||
guint8 white_pixel[] = { 0xff, 0xff, 0xff, 0xff };
|
||||
guint8 red_pixel[] = { 0xff, 0x00, 0x00, 0xff };
|
||||
CoglHandle white_texture;
|
||||
CoglHandle red_texture;
|
||||
int n_layers;
|
||||
int i;
|
||||
|
||||
/* Create a material that uses the maximum number of layers. All but
|
||||
the last layer will use a solid white texture. The last layer
|
||||
will use a red texture. The layers will all be modulated together
|
||||
so the final fragment should be red. */
|
||||
|
||||
white_texture = cogl_texture_new_from_data (1, 1, COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4, white_pixel);
|
||||
red_texture = cogl_texture_new_from_data (1, 1, COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
4, red_pixel);
|
||||
|
||||
/* FIXME: Cogl doesn't provide a way to query the maximum number of
|
||||
texture layers so for now we'll just ask GL directly. */
|
||||
#ifdef COGL_HAS_GLES2
|
||||
if (using_gles2_driver ())
|
||||
{
|
||||
int n_image_units, n_attribs;
|
||||
/* GLES 2 doesn't have GL_MAX_TEXTURE_UNITS and it uses
|
||||
GL_MAX_TEXTURE_IMAGE_UNITS instead */
|
||||
gl_functions.glGetIntegerv (GL_MAX_TEXTURE_IMAGE_UNITS, &n_image_units);
|
||||
/* Cogl needs a vertex attrib for each layer to upload the texture
|
||||
coordinates */
|
||||
gl_functions.glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &n_attribs);
|
||||
/* We can't use two of the attribs because they are used by the
|
||||
position and color */
|
||||
n_attribs -= 2;
|
||||
n_layers = MIN (n_attribs, n_image_units);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
#if defined(COGL_HAS_GLES1) || defined(COGL_HAS_GL)
|
||||
gl_functions.glGetIntegerv (GL_MAX_TEXTURE_UNITS, &n_layers);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIXME: is this still true? */
|
||||
/* Cogl currently can't cope with more than 32 layers so we'll also
|
||||
limit the maximum to that. */
|
||||
if (n_layers > 32)
|
||||
n_layers = 32;
|
||||
|
||||
for (i = 0; i < n_layers; i++)
|
||||
{
|
||||
cogl_material_set_layer_filters (material, i,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_material_set_layer (material, i,
|
||||
i == n_layers - 1 ? red_texture : white_texture);
|
||||
}
|
||||
|
||||
cogl_set_source (material);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
cogl_handle_unref (white_texture);
|
||||
cogl_handle_unref (red_texture);
|
||||
|
||||
/* We expect the final fragment to be red */
|
||||
test_material_with_primitives (state, x, y, 0xff0000ff);
|
||||
}
|
||||
|
||||
static void
|
||||
test_invalid_texture_layers_with_constant_colors (TestState *state,
|
||||
int x, int y)
|
||||
{
|
||||
CoglHandle material = cogl_material_new ();
|
||||
CoglColor constant_color;
|
||||
|
||||
/* explicitly create a layer with an invalid handle */
|
||||
cogl_material_set_layer (material, 0, COGL_INVALID_HANDLE);
|
||||
|
||||
/* ignore the fallback texture on the layer and use a constant color
|
||||
instead */
|
||||
cogl_color_init_from_4ub (&constant_color, 0, 0, 255, 255);
|
||||
cogl_material_set_layer_combine (material, 0,
|
||||
"RGBA=REPLACE(CONSTANT)",
|
||||
NULL);
|
||||
cogl_material_set_layer_combine_constant (material, 0, &constant_color);
|
||||
|
||||
cogl_set_source (material);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/* We expect the final fragments to be green */
|
||||
test_material_with_primitives (state, x, y, 0x0000ffff);
|
||||
}
|
||||
|
||||
static void
|
||||
basic_ref_counting_destroy_cb (void *user_data)
|
||||
{
|
||||
gboolean *destroyed_flag = user_data;
|
||||
|
||||
g_assert (*destroyed_flag == FALSE);
|
||||
|
||||
*destroyed_flag = TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_basic_ref_counting (void)
|
||||
{
|
||||
CoglMaterial *material_parent;
|
||||
gboolean parent_destroyed = FALSE;
|
||||
CoglMaterial *material_child;
|
||||
gboolean child_destroyed = FALSE;
|
||||
static CoglUserDataKey user_data_key;
|
||||
|
||||
/* This creates a material with a copy and then just unrefs them
|
||||
both without setting them as a source. They should immediately be
|
||||
freed. We can test whether they were freed or not by registering
|
||||
a destroy callback with some user data */
|
||||
|
||||
material_parent = cogl_material_new ();
|
||||
/* Set some user data so we can detect when the material is
|
||||
destroyed */
|
||||
cogl_object_set_user_data (COGL_OBJECT (material_parent),
|
||||
&user_data_key,
|
||||
&parent_destroyed,
|
||||
basic_ref_counting_destroy_cb);
|
||||
|
||||
material_child = cogl_material_copy (material_parent);
|
||||
cogl_object_set_user_data (COGL_OBJECT (material_child),
|
||||
&user_data_key,
|
||||
&child_destroyed,
|
||||
basic_ref_counting_destroy_cb);
|
||||
|
||||
cogl_object_unref (material_child);
|
||||
cogl_object_unref (material_parent);
|
||||
|
||||
g_assert (parent_destroyed);
|
||||
g_assert (child_destroyed);
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
test_invalid_texture_layers (state,
|
||||
0, 0 /* position */
|
||||
);
|
||||
test_invalid_texture_layers_with_constant_colors (state,
|
||||
1, 0 /* position */
|
||||
);
|
||||
test_using_all_layers (state,
|
||||
2, 0 /* position */
|
||||
);
|
||||
|
||||
test_basic_ref_counting ();
|
||||
|
||||
/* Comment this out if you want visual feedback for what this test paints */
|
||||
#if 1
|
||||
clutter_main_quit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_materials (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
test_conform_get_gl_functions (&gl_functions);
|
||||
|
||||
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 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);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,208 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#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
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
guint padding;
|
||||
} TestState;
|
||||
|
||||
static void
|
||||
assert_region_color (int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha)
|
||||
{
|
||||
guint8 *data = g_malloc0 (width * height * 4);
|
||||
cogl_read_pixels (x, y, width, height,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
data);
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guint8 *pixel = &data[y * width * 4 + x * 4];
|
||||
#if 1
|
||||
g_assert (pixel[RED] == red &&
|
||||
pixel[GREEN] == green &&
|
||||
pixel[BLUE] == blue);
|
||||
#endif
|
||||
}
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
/* Creates a texture divided into 4 quads with colors arranged as follows:
|
||||
* (The same value are used in all channels for each texel)
|
||||
*
|
||||
* |-----------|
|
||||
* |0x11 |0x00 |
|
||||
* |+ref | |
|
||||
* |-----------|
|
||||
* |0x00 |0x33 |
|
||||
* | |+ref |
|
||||
* |-----------|
|
||||
*
|
||||
*
|
||||
*/
|
||||
static CoglHandle
|
||||
make_texture (guchar ref)
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
guchar *tex_data, *p;
|
||||
CoglHandle tex;
|
||||
guchar val;
|
||||
|
||||
tex_data = g_malloc (QUAD_WIDTH * QUAD_WIDTH * 16);
|
||||
|
||||
for (y = 0; y < QUAD_WIDTH * 2; y++)
|
||||
for (x = 0; x < QUAD_WIDTH * 2; x++)
|
||||
{
|
||||
p = tex_data + (QUAD_WIDTH * 8 * y) + x * 4;
|
||||
if (x < QUAD_WIDTH && y < QUAD_WIDTH)
|
||||
val = 0x11 + ref;
|
||||
else if (x >= QUAD_WIDTH && y >= QUAD_WIDTH)
|
||||
val = 0x33 + ref;
|
||||
else
|
||||
val = 0x00;
|
||||
p[0] = p[1] = p[2] = p[3] = val;
|
||||
}
|
||||
|
||||
/* 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 * 2,
|
||||
QUAD_WIDTH * 2,
|
||||
COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
QUAD_WIDTH * 8,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglHandle tex0, tex1;
|
||||
CoglHandle material;
|
||||
gboolean status;
|
||||
GError *error = NULL;
|
||||
float tex_coords[] = {
|
||||
0, 0, 0.5, 0.5, /* tex0 */
|
||||
0.5, 0.5, 1, 1 /* tex1 */
|
||||
};
|
||||
|
||||
tex0 = make_texture (0x00);
|
||||
tex1 = make_texture (0x11);
|
||||
|
||||
material = cogl_material_new ();
|
||||
|
||||
/* An arbitrary color which should be replaced by the first texture layer */
|
||||
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);
|
||||
/* We'll use nearest filtering mode on the textures, otherwise the
|
||||
edge of the quad can pull in texels from the neighbouring
|
||||
quarters of the texture due to imprecision */
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
|
||||
cogl_material_set_layer (material, 1, tex1);
|
||||
cogl_material_set_layer_filters (material, 1,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
status = cogl_material_set_layer_combine (material, 1,
|
||||
"RGBA = ADD (PREVIOUS, TEXTURE)",
|
||||
&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 setup texture combine string "
|
||||
"RGBA = ADD (PREVIOUS, TEXTURE): %s",
|
||||
error->message);
|
||||
}
|
||||
|
||||
cogl_set_source (material);
|
||||
cogl_rectangle_with_multitexture_coords (0, 0, QUAD_WIDTH, QUAD_WIDTH,
|
||||
tex_coords, 8);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
cogl_handle_unref (tex0);
|
||||
cogl_handle_unref (tex1);
|
||||
|
||||
/* See what we got... */
|
||||
|
||||
assert_region_color (0, 0, QUAD_WIDTH, QUAD_WIDTH,
|
||||
0x55, 0x55, 0x55, 0x55);
|
||||
|
||||
/* Comment this out if you want visual feedback for what this test paints */
|
||||
#if 1
|
||||
clutter_main_quit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_multitexture (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);
|
||||
|
||||
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,240 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
/* Non-power-of-two sized texture that should cause slicing */
|
||||
#define TEXTURE_SIZE 384
|
||||
/* Number of times to split the texture up on each axis */
|
||||
#define PARTS 2
|
||||
/* The texture is split into four parts, each with a different colour */
|
||||
#define PART_SIZE (TEXTURE_SIZE / PARTS)
|
||||
|
||||
/* 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 TEXTURE_SIZE
|
||||
/* The size of a part once rendered */
|
||||
#define PART_RENDER_SIZE (TEXTURE_RENDER_SIZE / PARTS)
|
||||
|
||||
static const ClutterColor corner_colors[PARTS * PARTS] =
|
||||
{
|
||||
/* Top left - red */ { 255, 0, 0, 255 },
|
||||
/* Top right - green */ { 0, 255, 0, 255 },
|
||||
/* Bottom left - blue */ { 0, 0, 255, 255 },
|
||||
/* Bottom right - yellow */ { 255, 255, 0, 255 }
|
||||
};
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint frame;
|
||||
CoglHandle texture;
|
||||
} TestState;
|
||||
|
||||
static gboolean
|
||||
validate_part (ClutterActor *stage,
|
||||
int xnum,
|
||||
int ynum,
|
||||
const ClutterColor *color)
|
||||
{
|
||||
guchar *pixels, *p;
|
||||
gboolean ret = TRUE;
|
||||
|
||||
/* Read the appropriate part but skip out a few pixels around the
|
||||
edges */
|
||||
pixels = clutter_stage_read_pixels (CLUTTER_STAGE (stage),
|
||||
xnum * PART_RENDER_SIZE + TEST_INSET,
|
||||
ynum * PART_RENDER_SIZE + TEST_INSET,
|
||||
PART_RENDER_SIZE - TEST_INSET * 2,
|
||||
PART_RENDER_SIZE - TEST_INSET * 2);
|
||||
|
||||
/* Make sure every pixels is the appropriate color */
|
||||
for (p = pixels;
|
||||
p < pixels + ((PART_RENDER_SIZE - TEST_INSET * 2)
|
||||
* (PART_RENDER_SIZE - TEST_INSET * 2));
|
||||
p += 4)
|
||||
{
|
||||
if (p[0] != color->red)
|
||||
ret = FALSE;
|
||||
if (p[1] != color->green)
|
||||
ret = FALSE;
|
||||
if (p[2] != color->blue)
|
||||
ret = FALSE;
|
||||
}
|
||||
|
||||
g_free (pixels);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
/* Validate that all four corners of the texture are drawn in the
|
||||
right color */
|
||||
g_assert (validate_part (state->stage, 0, 0, corner_colors + 0));
|
||||
g_assert (validate_part (state->stage, 1, 0, corner_colors + 1));
|
||||
g_assert (validate_part (state->stage, 0, 1, corner_colors + 2));
|
||||
g_assert (validate_part (state->stage, 1, 1, corner_colors + 3));
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
int frame_num;
|
||||
int y, x;
|
||||
|
||||
/* Just render the texture in the top left corner */
|
||||
cogl_set_source_texture (state->texture);
|
||||
/* Render the texture using four separate rectangles */
|
||||
for (y = 0; y < 2; y++)
|
||||
for (x = 0; x < 2; x++)
|
||||
cogl_rectangle_with_texture_coords (x * TEXTURE_RENDER_SIZE / 2,
|
||||
y * TEXTURE_RENDER_SIZE / 2,
|
||||
(x + 1) * TEXTURE_RENDER_SIZE / 2,
|
||||
(y + 1) * TEXTURE_RENDER_SIZE / 2,
|
||||
x / 2.0f,
|
||||
y / 2.0f,
|
||||
(x + 1) / 2.0f,
|
||||
(y + 1) / 2.0f);
|
||||
|
||||
/* 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 G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
make_texture (void)
|
||||
{
|
||||
guchar *tex_data, *p;
|
||||
CoglHandle tex;
|
||||
int partx, party, width, height;
|
||||
|
||||
p = tex_data = g_malloc (TEXTURE_SIZE * TEXTURE_SIZE * 4);
|
||||
|
||||
/* Make a texture with a different color for each part */
|
||||
for (party = 0; party < PARTS; party++)
|
||||
{
|
||||
height = (party < PARTS - 1
|
||||
? PART_SIZE
|
||||
: TEXTURE_SIZE - PART_SIZE * (PARTS - 1));
|
||||
|
||||
for (partx = 0; partx < PARTS; partx++)
|
||||
{
|
||||
const ClutterColor *color = corner_colors + party * PARTS + partx;
|
||||
width = (partx < PARTS - 1
|
||||
? PART_SIZE
|
||||
: TEXTURE_SIZE - PART_SIZE * (PARTS - 1));
|
||||
|
||||
while (width-- > 0)
|
||||
{
|
||||
*(p++) = color->red;
|
||||
*(p++) = color->green;
|
||||
*(p++) = color->blue;
|
||||
*(p++) = color->alpha;
|
||||
}
|
||||
}
|
||||
|
||||
while (--height > 0)
|
||||
{
|
||||
memcpy (p, p - TEXTURE_SIZE * 4, TEXTURE_SIZE * 4);
|
||||
p += TEXTURE_SIZE * 4;
|
||||
}
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (TEXTURE_SIZE,
|
||||
TEXTURE_SIZE,
|
||||
COGL_TEXTURE_NO_ATLAS,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
TEXTURE_SIZE * 4,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
if (cogl_texture_is_sliced (tex))
|
||||
g_print ("Texture is sliced\n");
|
||||
else
|
||||
g_print ("Texture is not sliced\n");
|
||||
}
|
||||
|
||||
/* The texture should be sliced unless NPOTs are supported */
|
||||
g_assert (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT)
|
||||
? !cogl_texture_is_sliced (tex)
|
||||
: cogl_texture_is_sliced (tex));
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_npot_texture (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
if (g_test_verbose ())
|
||||
{
|
||||
if (cogl_features_available (COGL_FEATURE_TEXTURE_NPOT))
|
||||
g_print ("NPOT textures are supported\n");
|
||||
else
|
||||
g_print ("NPOT textures are not supported\n");
|
||||
}
|
||||
|
||||
state.frame = 0;
|
||||
|
||||
state.texture = make_texture ();
|
||||
|
||||
state.stage = stage = clutter_stage_new ();
|
||||
|
||||
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.texture);
|
||||
|
||||
clutter_actor_destroy (state.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
CoglUserDataKey private_key0;
|
||||
CoglUserDataKey private_key1;
|
||||
CoglUserDataKey private_key2;
|
||||
|
||||
static int user_data0;
|
||||
static int user_data1;
|
||||
static int user_data2;
|
||||
|
||||
static int destroy0_count = 0;
|
||||
static int destroy1_count = 0;
|
||||
static int destroy2_count = 0;
|
||||
|
||||
static void
|
||||
destroy0_cb (void *user_data)
|
||||
{
|
||||
g_assert (user_data == &user_data0);
|
||||
destroy0_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy1_cb (void *user_data)
|
||||
{
|
||||
g_assert (user_data == &user_data1);
|
||||
destroy1_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy2_cb (void *user_data)
|
||||
{
|
||||
g_assert (user_data == &user_data2);
|
||||
destroy2_count++;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_object (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
CoglPath *path;
|
||||
|
||||
/* Assuming that COGL_OBJECT_N_PRE_ALLOCATED_USER_DATA_ENTRIES == 2
|
||||
* test associating 2 pointers to private data with an object */
|
||||
cogl_path_new ();
|
||||
path = cogl_get_path ();
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (path),
|
||||
&private_key0,
|
||||
&user_data0,
|
||||
destroy0_cb);
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (path),
|
||||
&private_key1,
|
||||
&user_data1,
|
||||
destroy1_cb);
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (path),
|
||||
&private_key2,
|
||||
&user_data2,
|
||||
destroy2_cb);
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (path),
|
||||
&private_key1,
|
||||
NULL,
|
||||
destroy1_cb);
|
||||
|
||||
cogl_object_set_user_data (COGL_OBJECT (path),
|
||||
&private_key1,
|
||||
&user_data1,
|
||||
destroy1_cb);
|
||||
|
||||
cogl_object_unref (path);
|
||||
|
||||
g_assert_cmpint (destroy0_count, ==, 1);
|
||||
g_assert_cmpint (destroy1_count, ==, 2);
|
||||
g_assert_cmpint (destroy2_count, ==, 1);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
||||
|
@ -1,368 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#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;
|
||||
CoglHandle passthrough_material;
|
||||
} TestState;
|
||||
|
||||
|
||||
static void
|
||||
check_pixel (guint8 *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 (pixel[RED] == r);
|
||||
g_assert (pixel[GREEN] == g);
|
||||
g_assert (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 guchar *
|
||||
gen_tex_data (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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return tex_data;
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
make_texture (guint32 color,
|
||||
CoglPixelFormat src_format,
|
||||
CoglPixelFormat internal_format)
|
||||
{
|
||||
CoglHandle tex;
|
||||
guchar *tex_data = gen_tex_data (color);
|
||||
|
||||
tex = cogl_texture_new_from_data (QUAD_WIDTH,
|
||||
QUAD_WIDTH,
|
||||
COGL_TEXTURE_NONE,
|
||||
src_format,
|
||||
internal_format,
|
||||
QUAD_WIDTH * 4,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
check_texture (TestState *state,
|
||||
int x,
|
||||
int y,
|
||||
CoglHandle tex,
|
||||
guint32 expected_result)
|
||||
{
|
||||
guchar pixel[4];
|
||||
int y_off;
|
||||
int x_off;
|
||||
|
||||
cogl_material_set_layer (state->passthrough_material, 0, tex);
|
||||
|
||||
cogl_set_source (state->passthrough_material);
|
||||
cogl_rectangle (x * QUAD_WIDTH,
|
||||
y * QUAD_WIDTH,
|
||||
x * QUAD_WIDTH + QUAD_WIDTH,
|
||||
y * QUAD_WIDTH + QUAD_WIDTH);
|
||||
|
||||
/* 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 ("check texture (%d, %d):\n", x, y);
|
||||
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)
|
||||
{
|
||||
CoglHandle tex;
|
||||
guchar *tex_data;
|
||||
|
||||
/* If the user explicitly specifies an unmultiplied internal format then
|
||||
* Cogl shouldn't automatically premultiply the given texture data... */
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xff00ff80, "
|
||||
"src = RGBA_8888, internal = RGBA_8888)\n");
|
||||
tex = make_texture (0xff00ff80,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */
|
||||
check_texture (state, 0, 0, /* position */
|
||||
tex,
|
||||
0xff00ff80); /* expected */
|
||||
|
||||
/* If the user explicitly requests a premultiplied internal format and
|
||||
* gives unmultiplied src data then Cogl should always premultiply that
|
||||
* for us */
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xff00ff80, "
|
||||
"src = RGBA_8888, internal = RGBA_8888_PRE)\n");
|
||||
tex = make_texture (0xff00ff80,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */
|
||||
check_texture (state, 1, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* expected */
|
||||
|
||||
/* If the user gives COGL_PIXEL_FORMAT_ANY for the internal format then
|
||||
* by default Cogl should premultiply the given texture data...
|
||||
* (In the future there will be additional Cogl API to control this
|
||||
* behaviour) */
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xff00ff80, "
|
||||
"src = RGBA_8888, internal = ANY)\n");
|
||||
tex = make_texture (0xff00ff80,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* src format */
|
||||
COGL_PIXEL_FORMAT_ANY); /* internal format */
|
||||
check_texture (state, 2, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* expected */
|
||||
|
||||
/* If the user requests a premultiplied internal texture format and supplies
|
||||
* premultiplied source data, Cogl should never modify that source data...
|
||||
*/
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0x80008080, "
|
||||
"src = RGBA_8888_PRE, "
|
||||
"internal = RGBA_8888_PRE)\n");
|
||||
tex = make_texture (0x80008080,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */
|
||||
check_texture (state, 3, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* expected */
|
||||
|
||||
/* If the user requests an unmultiplied internal texture format, but
|
||||
* supplies premultiplied source data, then Cogl should always
|
||||
* un-premultiply the source data... */
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0x80008080, "
|
||||
"src = RGBA_8888_PRE, internal = RGBA_8888)\n");
|
||||
tex = make_texture (0x80008080,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */
|
||||
check_texture (state, 4, 0, /* position */
|
||||
tex,
|
||||
0xff00ff80); /* expected */
|
||||
|
||||
/* If the user allows any internal texture format and provides premultipled
|
||||
* source data then by default Cogl shouldn't modify the source data...
|
||||
* (In the future there will be additional Cogl API to control this
|
||||
* behaviour) */
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0x80008080, "
|
||||
"src = RGBA_8888_PRE, internal = ANY)\n");
|
||||
tex = make_texture (0x80008080,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */
|
||||
COGL_PIXEL_FORMAT_ANY); /* internal format */
|
||||
check_texture (state, 5, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* expected */
|
||||
|
||||
/*
|
||||
* Test cogl_texture_set_region() ....
|
||||
*/
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xDEADBEEF, "
|
||||
"src = RGBA_8888, internal = RGBA_8888)\n");
|
||||
tex = make_texture (0xDEADBEEF,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */
|
||||
if (g_test_verbose ())
|
||||
g_print ("set_region (0xff00ff80, RGBA_8888)\n");
|
||||
tex_data = gen_tex_data (0xff00ff80);
|
||||
cogl_texture_set_region (tex,
|
||||
0, 0, /* src x, y */
|
||||
0, 0, /* dst x, y */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* src width, height */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto compute row stride */
|
||||
tex_data);
|
||||
check_texture (state, 6, 0, /* position */
|
||||
tex,
|
||||
0xff00ff80); /* expected */
|
||||
|
||||
/* Updating a texture region for an unmultiplied texture using premultiplied
|
||||
* region data should result in Cogl unmultiplying the given region data...
|
||||
*/
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xDEADBEEF, "
|
||||
"src = RGBA_8888, internal = RGBA_8888)\n");
|
||||
tex = make_texture (0xDEADBEEF,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888); /* internal format */
|
||||
if (g_test_verbose ())
|
||||
g_print ("set_region (0x80008080, RGBA_8888_PRE)\n");
|
||||
tex_data = gen_tex_data (0x80008080);
|
||||
cogl_texture_set_region (tex,
|
||||
0, 0, /* src x, y */
|
||||
0, 0, /* dst x, y */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* src width, height */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
0, /* auto compute row stride */
|
||||
tex_data);
|
||||
check_texture (state, 7, 0, /* position */
|
||||
tex,
|
||||
0xff00ff80); /* expected */
|
||||
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xDEADBEEF, "
|
||||
"src = RGBA_8888_PRE, "
|
||||
"internal = RGBA_8888_PRE)\n");
|
||||
tex = make_texture (0xDEADBEEF,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */
|
||||
if (g_test_verbose ())
|
||||
g_print ("set_region (0x80008080, RGBA_8888_PRE)\n");
|
||||
tex_data = gen_tex_data (0x80008080);
|
||||
cogl_texture_set_region (tex,
|
||||
0, 0, /* src x, y */
|
||||
0, 0, /* dst x, y */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* src width, height */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
0, /* auto compute row stride */
|
||||
tex_data);
|
||||
check_texture (state, 8, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* expected */
|
||||
|
||||
|
||||
/* Updating a texture region for a premultiplied texture using unmultiplied
|
||||
* region data should result in Cogl premultiplying the given region data...
|
||||
*/
|
||||
if (g_test_verbose ())
|
||||
g_print ("make_texture (0xDEADBEEF, "
|
||||
"src = RGBA_8888_PRE, "
|
||||
"internal = RGBA_8888_PRE)\n");
|
||||
tex = make_texture (0xDEADBEEF,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE, /* src format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE); /* internal format */
|
||||
if (g_test_verbose ())
|
||||
g_print ("set_region (0xff00ff80, RGBA_8888)\n");
|
||||
tex_data = gen_tex_data (0xff00ff80);
|
||||
cogl_texture_set_region (tex,
|
||||
0, 0, /* src x, y */
|
||||
0, 0, /* dst x, y */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* dst width, height */
|
||||
QUAD_WIDTH, QUAD_WIDTH, /* src width, height */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto compute row stride */
|
||||
tex_data);
|
||||
check_texture (state, 9, 0, /* position */
|
||||
tex,
|
||||
0x80008080); /* 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 TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_premult (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
state.passthrough_material = cogl_material_new ();
|
||||
cogl_material_set_blend (state.passthrough_material,
|
||||
"RGBA = ADD (SRC_COLOR, 0)", NULL);
|
||||
cogl_material_set_layer_combine (state.passthrough_material, 0,
|
||||
"RGBA = REPLACE (TEXTURE)", NULL);
|
||||
|
||||
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 = g_idle_add (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,174 +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;
|
||||
guint32 *pixels;
|
||||
guint8 *pixelsc;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* All offscreen rendering is done upside down so the first thing we
|
||||
* verify is reading back grid of colors from a CoglOffscreen framebuffer
|
||||
*/
|
||||
|
||||
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);
|
||||
|
||||
cogl_push_framebuffer (offscreen);
|
||||
|
||||
/* red, top left */
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_rectangle (-1, 1, 0, 0);
|
||||
/* green, top right */
|
||||
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
|
||||
cogl_rectangle (0, 1, 1, 0);
|
||||
/* blue, bottom left */
|
||||
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 0, 0, -1);
|
||||
/* white, bottom right */
|
||||
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
|
||||
cogl_rectangle (0, 0, 1, -1);
|
||||
|
||||
pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
|
||||
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
(guchar *)pixels);
|
||||
|
||||
g_assert_cmpint (pixels[0], ==, 0xff0000ff);
|
||||
g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00);
|
||||
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000);
|
||||
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff);
|
||||
g_free (pixels);
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
cogl_handle_unref (offscreen);
|
||||
|
||||
/* Now verify reading back from an onscreen framebuffer...
|
||||
*/
|
||||
|
||||
cogl_set_source_texture (tex);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
|
||||
pixels = g_malloc0 (FRAMEBUFFER_WIDTH * 4 * FRAMEBUFFER_HEIGHT);
|
||||
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
(guchar *)pixels);
|
||||
|
||||
g_assert_cmpint (pixels[0], ==, 0xff0000ff);
|
||||
g_assert_cmpint (pixels[FRAMEBUFFER_WIDTH - 1], ==, 0xff00ff00);
|
||||
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH], ==, 0xffff0000);
|
||||
g_assert_cmpint (pixels[(FRAMEBUFFER_HEIGHT - 1) * FRAMEBUFFER_WIDTH + FRAMEBUFFER_WIDTH - 1], ==, 0xffffffff);
|
||||
g_free (pixels);
|
||||
|
||||
/* Verify using BGR format */
|
||||
|
||||
cogl_set_source_texture (tex);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
|
||||
pixelsc = g_malloc0 (FRAMEBUFFER_WIDTH * 3 * FRAMEBUFFER_HEIGHT);
|
||||
cogl_read_pixels (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_BGR_888,
|
||||
(guchar *)pixelsc);
|
||||
|
||||
g_assert_cmpint (pixelsc[0], ==, 0x00);
|
||||
g_assert_cmpint (pixelsc[1], ==, 0x00);
|
||||
g_assert_cmpint (pixelsc[2], ==, 0xff);
|
||||
|
||||
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 0], ==, 0x00);
|
||||
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 1], ==, 0xff);
|
||||
g_assert_cmpint (pixelsc[(FRAMEBUFFER_WIDTH - 1) * 3 + 2], ==, 0x00);
|
||||
|
||||
g_free (pixelsc);
|
||||
|
||||
cogl_handle_unref (tex);
|
||||
|
||||
/* Restore the viewport and matrices state */
|
||||
cogl_set_viewport (saved_viewport[0],
|
||||
saved_viewport[1],
|
||||
saved_viewport[2],
|
||||
saved_viewport[3]);
|
||||
cogl_set_projection_matrix (&saved_projection);
|
||||
cogl_pop_matrix ();
|
||||
|
||||
/* 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_readpixels (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 = g_idle_add (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,168 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static void
|
||||
check_texture (int width, int height, CoglTextureFlags flags)
|
||||
{
|
||||
CoglHandle tex;
|
||||
guint8 *data, *p;
|
||||
int y, x;
|
||||
|
||||
p = data = g_malloc (width * height * 4);
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
*(p++) = x;
|
||||
*(p++) = y;
|
||||
*(p++) = 128;
|
||||
*(p++) = (x ^ y);
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (width, height,
|
||||
flags,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
width * 4,
|
||||
data);
|
||||
|
||||
/* Replace the bottom right quarter of the data with negated data to
|
||||
test set_region */
|
||||
p = data + (height + 1) * width * 2;
|
||||
for (y = 0; y < height / 2; y++)
|
||||
{
|
||||
for (x = 0; x < width / 2; x++)
|
||||
{
|
||||
p[0] = ~p[0];
|
||||
p[1] = ~p[1];
|
||||
p[2] = ~p[2];
|
||||
p[3] = ~p[3];
|
||||
p += 4;
|
||||
}
|
||||
p += width * 2;
|
||||
}
|
||||
cogl_texture_set_region (tex,
|
||||
width / 2, /* src_x */
|
||||
height / 2, /* src_y */
|
||||
width / 2, /* dst_x */
|
||||
height / 2, /* dst_y */
|
||||
width / 2, /* dst_width */
|
||||
height / 2, /* dst_height */
|
||||
width,
|
||||
height,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
width * 4, /* rowstride */
|
||||
data);
|
||||
|
||||
/* Check passing a NULL pointer and a zero rowstride. The texture
|
||||
should calculate the needed data size and return it */
|
||||
g_assert_cmpint (cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_ANY, 0, NULL),
|
||||
==,
|
||||
width * height * 4);
|
||||
|
||||
/* Try first receiving the data as RGB. This should cause a
|
||||
* conversion */
|
||||
memset (data, 0, width * height * 4);
|
||||
|
||||
cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGB_888,
|
||||
width * 3, data);
|
||||
|
||||
p = data;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
if (x >= width / 2 && y >= height / 2)
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, ~x & 0xff);
|
||||
g_assert_cmpint (p[1], ==, ~y & 0xff);
|
||||
g_assert_cmpint (p[2], ==, ~128 & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, x & 0xff);
|
||||
g_assert_cmpint (p[1], ==, y & 0xff);
|
||||
g_assert_cmpint (p[2], ==, 128);
|
||||
}
|
||||
p += 3;
|
||||
}
|
||||
|
||||
/* Now try receiving the data as RGBA. This should not cause a
|
||||
* conversion and no unpremultiplication because we explicitly set
|
||||
* the internal format when we created the texture */
|
||||
memset (data, 0, width * height * 4);
|
||||
|
||||
cogl_texture_get_data (tex, COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
width * 4, data);
|
||||
|
||||
p = data;
|
||||
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
if (x >= width / 2 && y >= height / 2)
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, ~x & 0xff);
|
||||
g_assert_cmpint (p[1], ==, ~y & 0xff);
|
||||
g_assert_cmpint (p[2], ==, ~128 & 0xff);
|
||||
g_assert_cmpint (p[3], ==, ~(x ^ y) & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, x & 0xff);
|
||||
g_assert_cmpint (p[1], ==, y & 0xff);
|
||||
g_assert_cmpint (p[2], ==, 128);
|
||||
g_assert_cmpint (p[3], ==, (x ^ y) & 0xff);
|
||||
}
|
||||
p += 4;
|
||||
}
|
||||
|
||||
cogl_handle_unref (tex);
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
paint_cb (void)
|
||||
{
|
||||
/* First try without atlasing */
|
||||
check_texture (256, 256, COGL_TEXTURE_NO_ATLAS);
|
||||
/* Try again with atlasing. This should end up testing the atlas
|
||||
backend and the sub texture backend */
|
||||
check_texture (256, 256, 0);
|
||||
/* Try with a really big texture in the hope that it will end up
|
||||
sliced. */
|
||||
check_texture (4, 5128, COGL_TEXTURE_NO_ATLAS);
|
||||
/* And in the other direction. */
|
||||
check_texture (5128, 4, COGL_TEXTURE_NO_ATLAS);
|
||||
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_texture_get_set_data (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
ClutterActor *stage;
|
||||
guint paint_handler;
|
||||
|
||||
/* We create a stage even though we don't usually need it so that if
|
||||
the draw-and-read texture fallback is needed then it will have
|
||||
something to draw to */
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
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,137 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
|
||||
|
||||
#define TEX_SIZE 64
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
guint padding;
|
||||
} TestState;
|
||||
|
||||
/* Creates a texture where the pixels are evenly divided between
|
||||
selecting just one of the R,G and B components */
|
||||
static CoglHandle
|
||||
make_texture (void)
|
||||
{
|
||||
guchar *tex_data = g_malloc (TEX_SIZE * TEX_SIZE * 3), *p = tex_data;
|
||||
CoglHandle tex;
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < TEX_SIZE; y++)
|
||||
for (x = 0; x < TEX_SIZE; x++)
|
||||
{
|
||||
memset (p, 0, 3);
|
||||
/* Set one of the components to full. The components should be
|
||||
evenly represented so that each gets a third of the
|
||||
texture */
|
||||
p[(p - tex_data) / (TEX_SIZE * TEX_SIZE * 3 / 3)] = 255;
|
||||
p += 3;
|
||||
}
|
||||
|
||||
tex = cogl_texture_new_from_data (TEX_SIZE, TEX_SIZE, COGL_TEXTURE_NONE,
|
||||
COGL_PIXEL_FORMAT_RGB_888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
TEX_SIZE * 3,
|
||||
tex_data);
|
||||
|
||||
g_free (tex_data);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglHandle tex;
|
||||
CoglHandle material;
|
||||
guint8 pixels[8];
|
||||
|
||||
tex = make_texture ();
|
||||
material = cogl_material_new ();
|
||||
cogl_material_set_layer (material, 0, tex);
|
||||
cogl_handle_unref (tex);
|
||||
|
||||
/* Render a 1x1 pixel quad without mipmaps */
|
||||
cogl_set_source (material);
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_rectangle (0, 0, 1, 1);
|
||||
/* Then with mipmaps */
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_rectangle (1, 0, 2, 1);
|
||||
|
||||
cogl_handle_unref (material);
|
||||
|
||||
/* Read back the two pixels we rendered */
|
||||
cogl_read_pixels (0, 0, 2, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixels);
|
||||
|
||||
/* The first pixel should be just one of the colors from the
|
||||
texture. It doesn't matter which one */
|
||||
g_assert ((pixels[0] == 255 && pixels[1] == 0 && pixels[2] == 0) ||
|
||||
(pixels[0] == 0 && pixels[1] == 255 && pixels[2] == 0) ||
|
||||
(pixels[0] == 0 && pixels[1] == 0 && pixels[2] == 255));
|
||||
/* The second pixel should be more or less the average of all of the
|
||||
pixels in the texture. Each component gets a third of the image
|
||||
so each component should be approximately 255/3 */
|
||||
g_assert (ABS (pixels[4] - 255 / 3) <= 3 &&
|
||||
ABS (pixels[5] - 255 / 3) <= 3 &&
|
||||
ABS (pixels[6] - 255 / 3) <= 3);
|
||||
|
||||
/* Comment this out if you want visual feedback for what this test paints */
|
||||
#if 1
|
||||
clutter_main_quit ();
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_texture_mipmaps (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);
|
||||
|
||||
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 = g_idle_add (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,250 +0,0 @@
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#define CLUTTER_ENABLE_EXPERIMENTAL_API
|
||||
#include <clutter/clutter.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x00, 0x00, 0x00, 0xff };
|
||||
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
|
||||
#include <clutter/x11/clutter-x11.h>
|
||||
#include <cogl/cogl-texture-pixmap-x11.h>
|
||||
|
||||
#define PIXMAP_WIDTH 512
|
||||
#define PIXMAP_HEIGHT 256
|
||||
#define GRID_SQUARE_SIZE 16
|
||||
|
||||
/* Coordinates of a square that we'll update */
|
||||
#define PIXMAP_CHANGE_X 1
|
||||
#define PIXMAP_CHANGE_Y 1
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
CoglHandle tfp;
|
||||
Pixmap pixmap;
|
||||
guint frame_count;
|
||||
Display *display;
|
||||
} TestState;
|
||||
|
||||
static Pixmap
|
||||
create_pixmap (TestState *state)
|
||||
{
|
||||
Pixmap pixmap;
|
||||
XGCValues gc_values = { 0, };
|
||||
GC black_gc, white_gc;
|
||||
int screen = DefaultScreen (state->display);
|
||||
int x, y;
|
||||
|
||||
pixmap = XCreatePixmap (state->display,
|
||||
DefaultRootWindow (state->display),
|
||||
PIXMAP_WIDTH, PIXMAP_HEIGHT,
|
||||
DefaultDepth (state->display, screen));
|
||||
|
||||
gc_values.foreground = BlackPixel (state->display, screen);
|
||||
black_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values);
|
||||
gc_values.foreground = WhitePixel (state->display, screen);
|
||||
white_gc = XCreateGC (state->display, pixmap, GCForeground, &gc_values);
|
||||
|
||||
/* Draw a grid of alternative black and white rectangles to the
|
||||
pixmap */
|
||||
for (y = 0; y < PIXMAP_HEIGHT / GRID_SQUARE_SIZE; y++)
|
||||
for (x = 0; x < PIXMAP_WIDTH / GRID_SQUARE_SIZE; x++)
|
||||
XFillRectangle (state->display, pixmap,
|
||||
((x ^ y) & 1) ? black_gc : white_gc,
|
||||
x * GRID_SQUARE_SIZE,
|
||||
y * GRID_SQUARE_SIZE,
|
||||
GRID_SQUARE_SIZE,
|
||||
GRID_SQUARE_SIZE);
|
||||
|
||||
XFreeGC (state->display, black_gc);
|
||||
XFreeGC (state->display, white_gc);
|
||||
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
static void
|
||||
update_pixmap (TestState *state)
|
||||
{
|
||||
XGCValues gc_values = { 0, };
|
||||
GC black_gc;
|
||||
int screen = DefaultScreen (state->display);
|
||||
|
||||
gc_values.foreground = BlackPixel (state->display, screen);
|
||||
black_gc = XCreateGC (state->display, state->pixmap,
|
||||
GCForeground, &gc_values);
|
||||
|
||||
/* Fill in one the rectangles with black */
|
||||
XFillRectangle (state->display, state->pixmap,
|
||||
black_gc,
|
||||
PIXMAP_CHANGE_X * GRID_SQUARE_SIZE,
|
||||
PIXMAP_CHANGE_Y * GRID_SQUARE_SIZE,
|
||||
GRID_SQUARE_SIZE, GRID_SQUARE_SIZE);
|
||||
|
||||
XFreeGC (state->display, black_gc);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_paint (TestState *state, int x, int y, int scale)
|
||||
{
|
||||
guint8 *data, *p, update_value = 0;
|
||||
|
||||
p = data = g_malloc (PIXMAP_WIDTH * PIXMAP_HEIGHT * 4);
|
||||
|
||||
cogl_read_pixels (x, y, PIXMAP_WIDTH / scale, PIXMAP_HEIGHT / scale,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
data);
|
||||
|
||||
for (y = 0; y < PIXMAP_HEIGHT / scale; y++)
|
||||
for (x = 0; x < PIXMAP_WIDTH / scale; x++)
|
||||
{
|
||||
int grid_x = x * scale / GRID_SQUARE_SIZE;
|
||||
int grid_y = y * scale / GRID_SQUARE_SIZE;
|
||||
|
||||
/* If this is the updatable square then we'll let it be either
|
||||
color but we'll return which one it was */
|
||||
if (grid_x == PIXMAP_CHANGE_X && grid_y == PIXMAP_CHANGE_Y)
|
||||
{
|
||||
if (x % (GRID_SQUARE_SIZE / scale) == 0 &&
|
||||
y % (GRID_SQUARE_SIZE / scale) == 0)
|
||||
update_value = *p;
|
||||
else
|
||||
g_assert_cmpint (p[0], ==, update_value);
|
||||
|
||||
g_assert (p[1] == update_value);
|
||||
g_assert (p[2] == update_value);
|
||||
p += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
guint8 value = ((grid_x ^ grid_y) & 1) ? 0x00 : 0xff;
|
||||
g_assert_cmpint (*(p++), ==, value);
|
||||
g_assert_cmpint (*(p++), ==, value);
|
||||
g_assert_cmpint (*(p++), ==, value);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
|
||||
return update_value == 0x00;
|
||||
}
|
||||
|
||||
/* We skip these frames first */
|
||||
#define FRAME_COUNT_BASE 5
|
||||
/* First paint the tfp with no mipmaps */
|
||||
#define FRAME_COUNT_NORMAL 6
|
||||
/* Then use mipmaps */
|
||||
#define FRAME_COUNT_MIPMAP 7
|
||||
/* After this frame will start waiting for the pixmap to change */
|
||||
#define FRAME_COUNT_UPDATED 8
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
CoglHandle material;
|
||||
|
||||
material = cogl_material_new ();
|
||||
cogl_material_set_layer (material, 0, state->tfp);
|
||||
if (state->frame_count == FRAME_COUNT_MIPMAP)
|
||||
{
|
||||
const CoglMaterialFilter min_filter =
|
||||
COGL_MATERIAL_FILTER_NEAREST_MIPMAP_NEAREST;
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
min_filter,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
}
|
||||
else
|
||||
cogl_material_set_layer_filters (material, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
cogl_set_source (material);
|
||||
|
||||
cogl_rectangle (0, 0, PIXMAP_WIDTH, PIXMAP_HEIGHT);
|
||||
|
||||
cogl_rectangle (0, PIXMAP_HEIGHT,
|
||||
PIXMAP_WIDTH / 4, PIXMAP_HEIGHT * 5 / 4);
|
||||
|
||||
if (state->frame_count >= 5)
|
||||
{
|
||||
gboolean big_updated, small_updated;
|
||||
|
||||
big_updated = check_paint (state, 0, 0, 1);
|
||||
small_updated = check_paint (state, 0, PIXMAP_HEIGHT, 4);
|
||||
|
||||
g_assert (big_updated == small_updated);
|
||||
|
||||
if (state->frame_count < FRAME_COUNT_UPDATED)
|
||||
g_assert (big_updated == FALSE);
|
||||
else if (state->frame_count == FRAME_COUNT_UPDATED)
|
||||
/* Change the pixmap and keep drawing until it updates */
|
||||
update_pixmap (state);
|
||||
else if (big_updated)
|
||||
/* If we successfully got the update then the test is over */
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
state->frame_count++;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* CLUTTER_WINDOWING_X11 */
|
||||
|
||||
void
|
||||
test_cogl_texture_pixmap_x11 (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
#ifdef CLUTTER_WINDOWING_X11
|
||||
if (clutter_check_windowing_backend (CLUTTER_WINDOWING_X11))
|
||||
{
|
||||
TestState state;
|
||||
guint idle_handler;
|
||||
guint paint_handler;
|
||||
CoglContext *ctx =
|
||||
clutter_backend_get_cogl_context (clutter_get_default_backend ());
|
||||
|
||||
state.frame_count = 0;
|
||||
state.stage = clutter_stage_new ();
|
||||
|
||||
state.display = clutter_x11_get_default_display ();
|
||||
|
||||
state.pixmap = create_pixmap (&state);
|
||||
state.tfp = cogl_texture_pixmap_x11_new (ctx, state.pixmap, TRUE, NULL);
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (state.stage), &stage_color);
|
||||
|
||||
paint_handler = g_signal_connect_after (state.stage, "paint",
|
||||
G_CALLBACK (on_paint), &state);
|
||||
|
||||
idle_handler = g_idle_add (queue_redraw, state.stage);
|
||||
|
||||
clutter_actor_show_all (state.stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
g_signal_handler_disconnect (state.stage, paint_handler);
|
||||
|
||||
g_source_remove (idle_handler);
|
||||
|
||||
XFreePixmap (state.display, state.pixmap);
|
||||
|
||||
clutter_actor_destroy (state.stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (g_test_verbose ())
|
||||
g_print ("Skipping\n");
|
||||
}
|
@ -1,307 +0,0 @@
|
||||
#include <clutter/clutter.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
static TestConformGLFunctions gl_functions;
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
ClutterActor *stage;
|
||||
} TestState;
|
||||
|
||||
#ifndef GL_EXTENSIONS
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_RECTANGLE_ARB
|
||||
#define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
||||
#endif
|
||||
#ifndef GL_UNPACK_ROW_LENGTH
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#endif
|
||||
#ifndef GL_UNPACK_ALIGNMENT
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#endif
|
||||
#ifndef GL_UNPACK_SKIP_ROWS
|
||||
#define GL_UNPACK_SKIP_ROWS 0x0CF3
|
||||
#endif
|
||||
#ifndef GL_UNPACK_SKIP_PIXELS
|
||||
#define GL_UNPACK_SKIP_PIXELS 0x0CF4
|
||||
#endif
|
||||
#ifndef GL_RGBA
|
||||
#define GL_RGBA 0x1908
|
||||
#endif
|
||||
#ifndef GL_UNSIGNED_BYTE
|
||||
#define GL_UNSIGNED_BYTE 0x1401
|
||||
#endif
|
||||
#ifndef GL_NO_ERROR
|
||||
#define GL_NO_ERROR 0x0
|
||||
#endif
|
||||
#ifndef GL_TEXTURE_BINDING_RECTANGLE_ARB
|
||||
#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6
|
||||
#endif
|
||||
|
||||
static CoglHandle
|
||||
create_source_rect (void)
|
||||
{
|
||||
int x, y;
|
||||
int prev_unpack_row_length;
|
||||
int prev_unpack_alignment;
|
||||
int prev_unpack_skip_rows;
|
||||
int prev_unpack_skip_pixles;
|
||||
int prev_rectangle_binding;
|
||||
guint8 *data = g_malloc (256 * 256 * 4), *p = data;
|
||||
CoglHandle tex;
|
||||
guint gl_tex;
|
||||
|
||||
for (y = 0; y < 256; y++)
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
*(p++) = x;
|
||||
*(p++) = y;
|
||||
*(p++) = 0;
|
||||
*(p++) = 255;
|
||||
}
|
||||
|
||||
/* We are about to use OpenGL directly to create a TEXTURE_RECTANGLE
|
||||
* texture so we need to save the state that we modify so we can
|
||||
* restore it afterwards and be sure not to interfere with any state
|
||||
* caching that Cogl may do internally.
|
||||
*/
|
||||
gl_functions.glGetIntegerv (GL_UNPACK_ROW_LENGTH, &prev_unpack_row_length);
|
||||
gl_functions.glGetIntegerv (GL_UNPACK_ALIGNMENT, &prev_unpack_alignment);
|
||||
gl_functions.glGetIntegerv (GL_UNPACK_SKIP_ROWS, &prev_unpack_skip_rows);
|
||||
gl_functions.glGetIntegerv (GL_UNPACK_SKIP_PIXELS, &prev_unpack_skip_pixles);
|
||||
gl_functions.glGetIntegerv (GL_TEXTURE_BINDING_RECTANGLE_ARB,
|
||||
&prev_rectangle_binding);
|
||||
|
||||
gl_functions.glPixelStorei (GL_UNPACK_ROW_LENGTH, 256);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_ALIGNMENT, 8);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
|
||||
|
||||
gl_functions.glGenTextures (1, &gl_tex);
|
||||
gl_functions.glBindTexture (GL_TEXTURE_RECTANGLE_ARB, gl_tex);
|
||||
gl_functions.glTexImage2D (GL_TEXTURE_RECTANGLE_ARB, 0,
|
||||
GL_RGBA, 256, 256, 0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
data);
|
||||
|
||||
/* Now restore the original GL state as Cogl had left it */
|
||||
gl_functions.glPixelStorei (GL_UNPACK_ROW_LENGTH, prev_unpack_row_length);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_ALIGNMENT, prev_unpack_alignment);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_SKIP_ROWS, prev_unpack_skip_rows);
|
||||
gl_functions.glPixelStorei (GL_UNPACK_SKIP_PIXELS, prev_unpack_skip_pixles);
|
||||
gl_functions.glBindTexture (GL_TEXTURE_RECTANGLE_ARB, prev_rectangle_binding);
|
||||
|
||||
g_assert (gl_functions.glGetError () == GL_NO_ERROR);
|
||||
|
||||
g_free (data);
|
||||
|
||||
tex = cogl_texture_new_from_foreign (gl_tex,
|
||||
GL_TEXTURE_RECTANGLE_ARB,
|
||||
256, 256, 0, 0,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888);
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
static CoglHandle
|
||||
create_source_2d (void)
|
||||
{
|
||||
int x, y;
|
||||
guint8 *data = g_malloc (256 * 256 * 4), *p = data;
|
||||
CoglHandle tex;
|
||||
|
||||
for (y = 0; y < 256; y++)
|
||||
for (x = 0; x < 256; x++)
|
||||
{
|
||||
*(p++) = 0;
|
||||
*(p++) = x;
|
||||
*(p++) = y;
|
||||
*(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)
|
||||
{
|
||||
guint gl_tex;
|
||||
CoglHandle tex_rect = create_source_rect ();
|
||||
CoglHandle material_rect = cogl_material_new ();
|
||||
CoglHandle tex_2d = create_source_2d ();
|
||||
CoglHandle material_2d = cogl_material_new ();
|
||||
|
||||
g_assert (tex_rect != COGL_INVALID_HANDLE);
|
||||
|
||||
cogl_material_set_layer (material_rect, 0, tex_rect);
|
||||
cogl_material_set_layer_filters (material_rect, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
|
||||
cogl_material_set_layer (material_2d, 0, tex_2d);
|
||||
cogl_material_set_layer_filters (material_2d, 0,
|
||||
COGL_MATERIAL_FILTER_NEAREST,
|
||||
COGL_MATERIAL_FILTER_NEAREST);
|
||||
|
||||
cogl_set_source (material_rect);
|
||||
|
||||
/* Render the texture repeated horizontally twice */
|
||||
cogl_rectangle_with_texture_coords (0.0f, 0.0f, 512.0f, 256.0f,
|
||||
0.0f, 0.0f, 2.0f, 1.0f);
|
||||
/* Render the top half of the texture to test without repeating */
|
||||
cogl_rectangle_with_texture_coords (0.0f, 256.0f, 256.0f, 384.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.5f);
|
||||
|
||||
cogl_set_source (material_2d);
|
||||
|
||||
/* Render the top half of a regular 2D texture */
|
||||
cogl_rectangle_with_texture_coords (256.0f, 256.0f, 512.0f, 384.0f,
|
||||
0.0f, 0.0f, 1.0f, 0.5f);
|
||||
|
||||
/* Flush the rendering now so we can safely delete the texture */
|
||||
cogl_flush ();
|
||||
|
||||
cogl_handle_unref (material_rect);
|
||||
|
||||
/* Cogl doesn't destroy foreign textures so we have to do it manually */
|
||||
cogl_texture_get_gl_texture (tex_rect, &gl_tex, NULL);
|
||||
gl_functions.glDeleteTextures (1, &gl_tex);
|
||||
cogl_handle_unref (tex_rect);
|
||||
}
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
guint8 *data, *p;
|
||||
int x, y;
|
||||
|
||||
p = data = g_malloc (512 * 384 * 4);
|
||||
|
||||
cogl_read_pixels (0, 0, 512, 384,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
data);
|
||||
|
||||
for (y = 0; y < 384; y++)
|
||||
for (x = 0; x < 512; x++)
|
||||
{
|
||||
if (x >= 256 && y >= 256)
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, 0);
|
||||
g_assert_cmpint (p[1], ==, x & 0xff);
|
||||
g_assert_cmpint (p[2], ==, y & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_assert_cmpint (p[0], ==, x & 0xff);
|
||||
g_assert_cmpint (p[1], ==, y & 0xff);
|
||||
g_assert_cmpint (p[2], ==, 0);
|
||||
}
|
||||
p += 4;
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
check_rectangle_extension (void)
|
||||
{
|
||||
static const char rect_extension[] = "GL_ARB_texture_rectangle";
|
||||
const char *extensions =
|
||||
(const char *) gl_functions.glGetString (GL_EXTENSIONS);
|
||||
const char *extensions_end;
|
||||
|
||||
extensions_end = extensions + strlen (extensions);
|
||||
|
||||
while (extensions < extensions_end)
|
||||
{
|
||||
const char *end = strchr (extensions, ' ');
|
||||
|
||||
if (end == NULL)
|
||||
end = extensions_end;
|
||||
|
||||
if (end - extensions == sizeof (rect_extension) - 1 &&
|
||||
!memcmp (extensions, rect_extension, sizeof (rect_extension) - 1))
|
||||
return TRUE;
|
||||
|
||||
extensions = end + 1;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_texture_rectangle (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
guint idle_source;
|
||||
guint paint_handler;
|
||||
|
||||
state.stage = clutter_stage_new ();
|
||||
|
||||
test_conform_get_gl_functions (&gl_functions);
|
||||
|
||||
/* Check whether GL supports the rectangle extension. If not we'll
|
||||
just assume the test passes */
|
||||
if (check_rectangle_extension ())
|
||||
{
|
||||
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");
|
||||
}
|
||||
else if (g_test_verbose ())
|
||||
g_print ("Skipping\n");
|
||||
}
|
||||
|
@ -1,258 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
/* This test verifies that the simplest usage of the vertex buffer API,
|
||||
* where we add contiguous (x,y) GLfloat vertices, and RGBA GLubyte color
|
||||
* attributes to a buffer, submit, and draw.
|
||||
*
|
||||
* It also tries to verify that the enable/disable attribute APIs are working
|
||||
* too.
|
||||
*
|
||||
* If you want visual feedback of what this test paints for debugging purposes,
|
||||
* then remove the call to clutter_main_quit() in validate_result.
|
||||
*/
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
CoglHandle buffer;
|
||||
CoglHandle texture;
|
||||
CoglHandle material;
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
guint8 pixel[4];
|
||||
int y_off = 90;
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("y_off = %d\n", y_off);
|
||||
|
||||
/* NB: We ignore the alpha, since we don't know if our render target is
|
||||
* RGB or RGBA */
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
|
||||
/* Should see a blue pixel */
|
||||
cogl_read_pixels (10, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
|
||||
|
||||
/* Should see a red pixel */
|
||||
cogl_read_pixels (110, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 1 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] != 0 && pixel[GREEN] == 0 && pixel[BLUE] == 0);
|
||||
|
||||
/* Should see a blue pixel */
|
||||
cogl_read_pixels (210, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 2 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
|
||||
|
||||
/* Should see a green pixel, at bottom of 4th triangle */
|
||||
cogl_read_pixels (310, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 3 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[GREEN] > pixel[RED] && pixel[GREEN] > pixel[BLUE]);
|
||||
|
||||
/* Should see a red pixel, at top of 4th triangle */
|
||||
cogl_read_pixels (310, y_off - 70, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 4 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] > pixel[GREEN] && pixel[RED] > pixel[BLUE]);
|
||||
|
||||
|
||||
#undef RED
|
||||
#undef GREEN
|
||||
#undef BLUE
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
/* Draw a faded blue triangle */
|
||||
cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue");
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
/* Draw a red triangle */
|
||||
/* Here we are testing that the disable attribute works; if it doesn't
|
||||
* the triangle will remain faded blue */
|
||||
cogl_translate (100, 0, 0);
|
||||
cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue");
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
/* Draw a faded blue triangle */
|
||||
/* Here we are testing that the re-enable works; if it doesn't
|
||||
* the triangle will remain red */
|
||||
cogl_translate (100, 0, 0);
|
||||
cogl_vertex_buffer_enable (state->buffer, "gl_Color::blue");
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
/* Draw a textured triangle */
|
||||
cogl_translate (100, 0, 0);
|
||||
cogl_vertex_buffer_disable (state->buffer, "gl_Color::blue");
|
||||
cogl_set_source (state->material);
|
||||
cogl_material_set_color4ub (state->material, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
validate_result (state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
test_cogl_vertex_buffer_contiguous (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff};
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
guchar tex_data[] = {
|
||||
0xff, 0x00, 0x00, 0xff,
|
||||
0xff, 0x00, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff
|
||||
};
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
|
||||
clutter_actor_get_geometry (stage, &state.stage_geom);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_actor_set_size (group,
|
||||
state.stage_geom.width,
|
||||
state.stage_geom.height);
|
||||
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 = g_idle_add (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
state.texture = cogl_texture_new_from_data (2, 2,
|
||||
COGL_TEXTURE_NO_SLICING,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
COGL_PIXEL_FORMAT_ANY,
|
||||
0, /* auto calc row stride */
|
||||
tex_data);
|
||||
|
||||
state.material = cogl_material_new ();
|
||||
cogl_material_set_color4ub (state.material, 0x00, 0xff, 0x00, 0xff);
|
||||
cogl_material_set_layer (state.material, 0, state.texture);
|
||||
|
||||
{
|
||||
float triangle_verts[3][2] =
|
||||
{
|
||||
{0.0, 0.0},
|
||||
{100.0, 100.0},
|
||||
{0.0, 100.0}
|
||||
};
|
||||
guint8 triangle_colors[3][4] =
|
||||
{
|
||||
{0x00, 0x00, 0xff, 0xff}, /* blue */
|
||||
{0x00, 0x00, 0xff, 0x00}, /* transparent blue */
|
||||
{0x00, 0x00, 0xff, 0x00} /* transparent blue */
|
||||
};
|
||||
float triangle_tex_coords[3][2] =
|
||||
{
|
||||
{0.0, 0.0},
|
||||
{1.0, 1.0},
|
||||
{0.0, 1.0}
|
||||
};
|
||||
state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Vertex",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_verts);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Color::blue",
|
||||
4, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_colors);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_MultiTexCoord0",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_tex_coords);
|
||||
|
||||
cogl_vertex_buffer_submit (state.buffer);
|
||||
}
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
cogl_handle_unref (state.buffer);
|
||||
cogl_handle_unref (state.material);
|
||||
cogl_handle_unref (state.texture);
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,158 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
/* This test verifies that interleved attributes work with the vertex buffer
|
||||
* API. We add (x,y) GLfloat vertices, interleved with RGBA GLubyte color
|
||||
* attributes to a buffer, submit and draw.
|
||||
*
|
||||
* If you want visual feedback of what this test paints for debugging purposes,
|
||||
* then remove the call to clutter_main_quit() in validate_result.
|
||||
*/
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
CoglHandle buffer;
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
typedef struct _InterlevedVertex
|
||||
{
|
||||
float x, y;
|
||||
guint8 r, g, b, a;
|
||||
} InterlevedVertex;
|
||||
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
guint8 pixel[4];
|
||||
int y_off = 90;
|
||||
|
||||
/* NB: We ignore the alpha, since we don't know if our render target is
|
||||
* RGB or RGBA */
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
|
||||
/* Should see a blue pixel */
|
||||
cogl_read_pixels (10, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);
|
||||
|
||||
#undef RED
|
||||
#undef GREEN
|
||||
#undef BLUE
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
/* Draw a faded blue triangle */
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
validate_result (state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_vertex_buffer_interleved (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff};
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
|
||||
clutter_actor_get_geometry (stage, &state.stage_geom);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_actor_set_size (group,
|
||||
state.stage_geom.width,
|
||||
state.stage_geom.height);
|
||||
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 = g_idle_add (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
{
|
||||
InterlevedVertex verts[3] =
|
||||
{
|
||||
{ /* .x = */ 0.0, /* .y = */ 0.0,
|
||||
/* blue */
|
||||
/* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0xff },
|
||||
|
||||
{ /* .x = */ 100.0, /* .y = */ 100.0,
|
||||
/* transparent blue */
|
||||
/* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 },
|
||||
|
||||
{ /* .x = */ 0.0, /* .y = */ 100.0,
|
||||
/* transparent blue */
|
||||
/* .r = */ 0x00, /* .g = */ 0x00, /* .b = */ 0xff, /* .a = */ 0x00 },
|
||||
};
|
||||
|
||||
/* We assume the compiler is doing no funny struct padding for this test:
|
||||
*/
|
||||
g_assert (sizeof (InterlevedVertex) == 12);
|
||||
|
||||
state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Vertex",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
12, /* stride */
|
||||
&verts[0].x);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Color",
|
||||
4, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
|
||||
FALSE, /* normalized */
|
||||
12, /* stride */
|
||||
&verts[0].r);
|
||||
cogl_vertex_buffer_submit (state.buffer);
|
||||
}
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
cogl_handle_unref (state.buffer);
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
|
||||
#include <clutter/clutter.h>
|
||||
#include <cogl/cogl.h>
|
||||
|
||||
#include "test-conform-common.h"
|
||||
|
||||
/* This test verifies that modifying a vertex buffer works, by updating
|
||||
* vertex positions, and deleting and re-adding different color attributes.
|
||||
*
|
||||
* If you want visual feedback of what this test paints for debugging purposes,
|
||||
* then remove the call to clutter_main_quit() in validate_result.
|
||||
*/
|
||||
|
||||
typedef struct _TestState
|
||||
{
|
||||
CoglHandle buffer;
|
||||
ClutterGeometry stage_geom;
|
||||
} TestState;
|
||||
|
||||
static void
|
||||
validate_result (TestState *state)
|
||||
{
|
||||
guint8 pixel[4];
|
||||
int y_off = 90;
|
||||
|
||||
/* NB: We ignore the alpha, since we don't know if our render target is
|
||||
* RGB or RGBA */
|
||||
|
||||
#define RED 0
|
||||
#define GREEN 1
|
||||
#define BLUE 2
|
||||
|
||||
/* Should see a red pixel */
|
||||
cogl_read_pixels (110, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] != 0 && pixel[GREEN] == 0 && pixel[BLUE] == 0);
|
||||
|
||||
/* Should see a green pixel */
|
||||
cogl_read_pixels (210, y_off, 1, 1,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
pixel);
|
||||
if (g_test_verbose ())
|
||||
g_print ("pixel 1 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
|
||||
g_assert (pixel[RED] == 0 && pixel[GREEN] != 0 && pixel[BLUE] == 0);
|
||||
|
||||
#undef RED
|
||||
#undef GREEN
|
||||
#undef BLUE
|
||||
|
||||
/* Comment this out if you want visual feedback of what this test
|
||||
* paints.
|
||||
*/
|
||||
clutter_main_quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
on_paint (ClutterActor *actor, TestState *state)
|
||||
{
|
||||
float triangle_verts[3][2] =
|
||||
{
|
||||
{100.0, 0.0},
|
||||
{200.0, 100.0},
|
||||
{100.0, 100.0}
|
||||
};
|
||||
guint8 triangle_colors[3][4] =
|
||||
{
|
||||
{0x00, 0xff, 0x00, 0xff}, /* blue */
|
||||
{0x00, 0xff, 0x00, 0x00}, /* transparent blue */
|
||||
{0x00, 0xff, 0x00, 0x00} /* transparent blue */
|
||||
};
|
||||
|
||||
/*
|
||||
* Draw a red triangle
|
||||
*/
|
||||
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
|
||||
cogl_vertex_buffer_add (state->buffer,
|
||||
"gl_Vertex",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_verts);
|
||||
cogl_vertex_buffer_delete (state->buffer, "gl_Color");
|
||||
cogl_vertex_buffer_submit (state->buffer);
|
||||
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
/*
|
||||
* Draw a faded green triangle
|
||||
*/
|
||||
|
||||
cogl_vertex_buffer_add (state->buffer,
|
||||
"gl_Color",
|
||||
4, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_colors);
|
||||
cogl_vertex_buffer_submit (state->buffer);
|
||||
|
||||
cogl_translate (100, 0, 0);
|
||||
cogl_vertex_buffer_draw (state->buffer,
|
||||
COGL_VERTICES_MODE_TRIANGLE_STRIP, /* mode */
|
||||
0, /* first */
|
||||
3); /* count */
|
||||
|
||||
validate_result (state);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
queue_redraw (gpointer stage)
|
||||
{
|
||||
clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_vertex_buffer_mutability (TestConformSimpleFixture *fixture,
|
||||
gconstpointer data)
|
||||
{
|
||||
TestState state;
|
||||
ClutterActor *stage;
|
||||
ClutterColor stage_clr = {0x0, 0x0, 0x0, 0xff};
|
||||
ClutterActor *group;
|
||||
guint idle_source;
|
||||
|
||||
stage = clutter_stage_new ();
|
||||
|
||||
clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_clr);
|
||||
clutter_actor_get_geometry (stage, &state.stage_geom);
|
||||
|
||||
group = clutter_group_new ();
|
||||
clutter_actor_set_size (group,
|
||||
state.stage_geom.width,
|
||||
state.stage_geom.height);
|
||||
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 = g_idle_add (queue_redraw, stage);
|
||||
|
||||
g_signal_connect (group, "paint", G_CALLBACK (on_paint), &state);
|
||||
|
||||
{
|
||||
float triangle_verts[3][2] =
|
||||
{
|
||||
{0.0, 0.0},
|
||||
{100.0, 100.0},
|
||||
{0.0, 100.0}
|
||||
};
|
||||
guint8 triangle_colors[3][4] =
|
||||
{
|
||||
{0x00, 0x00, 0xff, 0xff}, /* blue */
|
||||
{0x00, 0x00, 0xff, 0x00}, /* transparent blue */
|
||||
{0x00, 0x00, 0xff, 0x00} /* transparent blue */
|
||||
};
|
||||
state.buffer = cogl_vertex_buffer_new (3 /* n vertices */);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Vertex",
|
||||
2, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_FLOAT,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_verts);
|
||||
cogl_vertex_buffer_add (state.buffer,
|
||||
"gl_Color",
|
||||
4, /* n components */
|
||||
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE,
|
||||
FALSE, /* normalized */
|
||||
0, /* stride */
|
||||
triangle_colors);
|
||||
cogl_vertex_buffer_submit (state.buffer);
|
||||
}
|
||||
|
||||
clutter_actor_show_all (stage);
|
||||
|
||||
clutter_main ();
|
||||
|
||||
cogl_handle_unref (state.buffer);
|
||||
|
||||
g_source_remove (idle_source);
|
||||
|
||||
clutter_actor_destroy (stage);
|
||||
|
||||
if (g_test_verbose ())
|
||||
g_print ("OK\n");
|
||||
}
|
@ -1,412 +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 ALPHA 3
|
||||
|
||||
#define FRAMEBUFFER_WIDTH 640
|
||||
#define FRAMEBUFFER_HEIGHT 480
|
||||
|
||||
static const ClutterColor stage_color = { 0x0, 0x0, 0x0, 0xff };
|
||||
|
||||
static void
|
||||
assert_region_color (int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha)
|
||||
{
|
||||
guint8 *data = g_malloc0 (width * height * 4);
|
||||
cogl_read_pixels (x, y, width, height,
|
||||
COGL_READ_PIXELS_COLOR_BUFFER,
|
||||
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
|
||||
data);
|
||||
for (y = 0; y < height; y++)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
guint8 *pixel = &data[y*width*4 + x*4];
|
||||
#if 1
|
||||
g_assert (pixel[RED] == red &&
|
||||
pixel[GREEN] == green &&
|
||||
pixel[BLUE] == blue &&
|
||||
pixel[ALPHA] == alpha);
|
||||
#endif
|
||||
}
|
||||
g_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
assert_rectangle_color_and_black_border (int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue)
|
||||
{
|
||||
/* check the rectangle itself... */
|
||||
assert_region_color (x, y, width, height, red, green, blue, 0xff);
|
||||
/* black to left of the rectangle */
|
||||
assert_region_color (x-10, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
|
||||
/* black to right of the rectangle */
|
||||
assert_region_color (x+width, y-10, 10, height+20, 0x00, 0x00, 0x00, 0xff);
|
||||
/* black above the rectangle */
|
||||
assert_region_color (x-10, y-10, width+20, 10, 0x00, 0x00, 0x00, 0xff);
|
||||
/* and black below the rectangle */
|
||||
assert_region_color (x-10, y+height, width+20, 10, 0x00, 0x00, 0x00, 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;
|
||||
CoglColor black;
|
||||
float x0;
|
||||
float y0;
|
||||
float width;
|
||||
float height;
|
||||
|
||||
/* for clearing the offscreen framebuffer to black... */
|
||||
cogl_color_init_from_4ub (&black, 0x00, 0x00, 0x00, 0xff);
|
||||
|
||||
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);
|
||||
|
||||
/* - Create a 100x200 viewport (i.e. smaller than the onscreen framebuffer)
|
||||
* and position it a (20, 10) inside the framebuffer.
|
||||
* - Fill the whole viewport with a purple rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 purple rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
100, /* width */
|
||||
200); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* fill the viewport with purple.. */
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0xff, 0x00, 0xff);
|
||||
|
||||
|
||||
/* - Create a viewport twice the size of the onscreen framebuffer with
|
||||
* a negative offset positioning it at (-20, -10) relative to the
|
||||
* buffer itself.
|
||||
* - Draw a 100x200 green rectangle at (40, 20) within the viewport (which
|
||||
* is (20, 10) within the framebuffer)
|
||||
* - Verify that the framebuffer is black with a 100x200 green rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (-20, /* x */
|
||||
-10, /* y */
|
||||
FRAMEBUFFER_WIDTH * 2, /* width */
|
||||
FRAMEBUFFER_HEIGHT * 2); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* draw a 100x200 green rectangle offset into the viewport such that its
|
||||
* top left corner should be found at (20, 10) in the offscreen buffer */
|
||||
/* (offset 40 pixels right from the left of the viewport) */
|
||||
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
|
||||
/* (offset 20 pixels down from the top of the viewport) */
|
||||
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
|
||||
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
|
||||
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
|
||||
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
|
||||
cogl_rectangle (x0, y0, x0 + width, y0 - height);
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0x00, 0xff, 0x00);
|
||||
|
||||
|
||||
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
|
||||
* buffer.
|
||||
* - Push a 100x200 window space clip rectangle at (20, 10)
|
||||
* - Fill the whole viewport with a blue rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
200, /* width */
|
||||
400); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
cogl_clip_push_window_rectangle (20, 10, 100, 200);
|
||||
/* fill the viewport with blue.. */
|
||||
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
cogl_clip_pop ();
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0x00, 0x00, 0xff);
|
||||
|
||||
|
||||
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
|
||||
* buffer.
|
||||
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
|
||||
* (i.e. (40, 20) inside the framebuffer)
|
||||
* - Fill the whole viewport with a green rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 green rectangle at
|
||||
* (40, 20)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
200, /* width */
|
||||
400); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* figure out where to position our clip rectangle in model space
|
||||
* coordinates... */
|
||||
/* (offset 40 pixels right from the left of the viewport) */
|
||||
x0 = -1.0f + (2.0f / 200) * 20.f;
|
||||
/* (offset 20 pixels down from the top of the viewport) */
|
||||
y0 = 1.0f - (2.0f / 400) * 10.0f;
|
||||
width = (2.0f / 200) * 100;
|
||||
height = (2.0f / 400) * 200;
|
||||
/* add the clip rectangle... */
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
|
||||
/* XXX: Rotate just enough to stop Cogl from converting our model space
|
||||
* rectangle into a window space rectangle.. */
|
||||
cogl_rotate (0.1, 0, 0, 1);
|
||||
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
|
||||
width/2.0, height/2.0);
|
||||
cogl_pop_matrix ();
|
||||
/* fill the viewport with green.. */
|
||||
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
cogl_clip_pop ();
|
||||
assert_rectangle_color_and_black_border (40, 20, 100, 200,
|
||||
0x00, 0xff, 0x00);
|
||||
|
||||
|
||||
/* Set the viewport to something specific so we can verify that it gets
|
||||
* restored after we are done testing with an offscreen framebuffer... */
|
||||
cogl_set_viewport (20, 10, 100, 200);
|
||||
|
||||
/*
|
||||
* Next test offscreen drawing...
|
||||
*/
|
||||
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);
|
||||
|
||||
cogl_push_framebuffer (offscreen);
|
||||
|
||||
|
||||
/* - Create a 100x200 viewport (i.e. smaller than the offscreen framebuffer)
|
||||
* and position it a (20, 10) inside the framebuffer.
|
||||
* - Fill the whole viewport with a blue rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
100, /* width */
|
||||
200); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* fill the viewport with blue.. */
|
||||
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0x00, 0x00, 0xff);
|
||||
|
||||
|
||||
/* - Create a viewport twice the size of the offscreen framebuffer with
|
||||
* a negative offset positioning it at (-20, -10) relative to the
|
||||
* buffer itself.
|
||||
* - Draw a 100x200 red rectangle at (40, 20) within the viewport (which
|
||||
* is (20, 10) within the framebuffer)
|
||||
* - Verify that the framebuffer is black with a 100x200 red rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (-20, /* x */
|
||||
-10, /* y */
|
||||
FRAMEBUFFER_WIDTH * 2, /* width */
|
||||
FRAMEBUFFER_HEIGHT * 2); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* draw a 100x200 red rectangle offset into the viewport such that its
|
||||
* top left corner should be found at (20, 10) in the offscreen buffer */
|
||||
/* (offset 40 pixels right from the left of the viewport) */
|
||||
x0 = -1.0f + (1.0f / FRAMEBUFFER_WIDTH) * 40.f;
|
||||
/* (offset 20 pixels down from the top of the viewport) */
|
||||
y0 = 1.0f - (1.0f / FRAMEBUFFER_HEIGHT) * 20.0f;
|
||||
width = (1.0f / FRAMEBUFFER_WIDTH) * 100;
|
||||
height = (1.0f / FRAMEBUFFER_HEIGHT) * 200;
|
||||
cogl_set_source_color4ub (0xff, 0x00, 0x00, 0xff);
|
||||
cogl_rectangle (x0, y0, x0 + width, y0 - height);
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0xff, 0x00, 0x00);
|
||||
|
||||
|
||||
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
|
||||
* buffer.
|
||||
* - Push a 100x200 window space clip rectangle at (20, 10)
|
||||
* - Fill the whole viewport with a blue rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 blue rectangle at
|
||||
* (20, 10)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
200, /* width */
|
||||
400); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
cogl_clip_push_window_rectangle (20, 10, 100, 200);
|
||||
/* fill the viewport with blue.. */
|
||||
cogl_set_source_color4ub (0x00, 0x00, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
cogl_clip_pop ();
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0x00, 0x00, 0xff);
|
||||
|
||||
|
||||
/* - Create a 200x400 viewport and position it a (20, 10) inside the draw
|
||||
* buffer.
|
||||
* - Push a 100x200 model space clip rectangle at (20, 10) in the viewport
|
||||
* (i.e. (40, 20) inside the framebuffer)
|
||||
* - Fill the whole viewport with a green rectangle
|
||||
* - Verify that the framebuffer is black with a 100x200 green rectangle at
|
||||
* (40, 20)
|
||||
*/
|
||||
cogl_set_viewport (20, /* x */
|
||||
10, /* y */
|
||||
200, /* width */
|
||||
400); /* height */
|
||||
/* clear everything... */
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
/* figure out where to position our clip rectangle in model space
|
||||
* coordinates... */
|
||||
/* (offset 40 pixels right from the left of the viewport) */
|
||||
x0 = -1.0f + (2.0f / 200) * 20.f;
|
||||
/* (offset 20 pixels down from the top of the viewport) */
|
||||
y0 = 1.0f - (2.0f / 400) * 10.0f;
|
||||
width = (2.0f / 200) * 100;
|
||||
height = (2.0f / 400) * 200;
|
||||
/* add the clip rectangle... */
|
||||
cogl_push_matrix ();
|
||||
cogl_translate (x0 + (width/2.0), y0 - (height/2.0), 0);
|
||||
/* XXX: Rotate just enough to stop Cogl from converting our model space
|
||||
* rectangle into a window space rectangle.. */
|
||||
cogl_rotate (0.1, 0, 0, 1);
|
||||
cogl_clip_push_rectangle (-(width/2.0), -(height/2.0),
|
||||
width/2, height/2);
|
||||
cogl_pop_matrix ();
|
||||
/* fill the viewport with green.. */
|
||||
cogl_set_source_color4ub (0x00, 0xff, 0x00, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
cogl_clip_pop ();
|
||||
assert_rectangle_color_and_black_border (40, 20, 100, 200,
|
||||
0x00, 0xff, 0x00);
|
||||
|
||||
|
||||
/* Set the viewport to something obscure to verify that it gets
|
||||
* replace when we switch back to the onscreen framebuffer... */
|
||||
cogl_set_viewport (0, 0, 10, 10);
|
||||
|
||||
cogl_pop_framebuffer ();
|
||||
cogl_handle_unref (offscreen);
|
||||
|
||||
/*
|
||||
* Verify that the previous onscreen framebuffer's viewport was restored
|
||||
* by drawing a white rectangle across the whole viewport. This should
|
||||
* draw a 100x200 rectangle at (20,10) relative to the onscreen draw
|
||||
* buffer...
|
||||
*/
|
||||
cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
|
||||
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
assert_rectangle_color_and_black_border (20, 10, 100, 200,
|
||||
0xff, 0xff, 0xff);
|
||||
|
||||
|
||||
/* Uncomment to display the last contents of the offscreen framebuffer */
|
||||
#if 1
|
||||
cogl_matrix_init_identity (&projection);
|
||||
cogl_matrix_init_identity (&modelview);
|
||||
cogl_set_viewport (0, 0, FRAMEBUFFER_WIDTH, FRAMEBUFFER_HEIGHT);
|
||||
cogl_set_projection_matrix (&projection);
|
||||
cogl_set_modelview_matrix (&modelview);
|
||||
cogl_set_source_texture (tex);
|
||||
cogl_rectangle (-1, 1, 1, -1);
|
||||
#endif
|
||||
|
||||
cogl_handle_unref (tex);
|
||||
|
||||
/* Finally restore the stage's original state... */
|
||||
cogl_pop_matrix ();
|
||||
cogl_set_projection_matrix (&saved_projection);
|
||||
cogl_set_viewport (saved_viewport[0], saved_viewport[1],
|
||||
saved_viewport[2], saved_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 TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
test_cogl_viewport (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 = g_idle_add (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");
|
||||
}
|
@ -212,32 +212,5 @@ main (int argc, char **argv)
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/events", events_touch);
|
||||
|
||||
#if 0
|
||||
/* FIXME - see bug https://bugzilla.gnome.org/show_bug.cgi?id=655588 */
|
||||
TEST_CONFORM_TODO ("/cally", cally_text);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_object);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_fixed);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_materials);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_premult);
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_readpixels);
|
||||
|
||||
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_texture_rectangle);
|
||||
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);
|
||||
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_contiguous);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_interleved);
|
||||
TEST_CONFORM_SIMPLE ("/cogl/vertex-buffer", test_cogl_vertex_buffer_mutability);
|
||||
|
||||
/* left to the end because they aren't currently very orthogonal and tend to
|
||||
* break subsequent tests! */
|
||||
TEST_CONFORM_SIMPLE ("/cogl", test_cogl_viewport);
|
||||
#endif
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user