mutter/tests/conform/test-depth-test.c
Robert Bragg 6c0dd4aab1 tests: avoid redundant setting of projection/modelview
This removes some redundant initializing of the modelview matrix since
we can assume the initial state is already the identity matrix. The
explicit initialization was only really necessary when running as a
clutter test because there the default matrix isn't the identity matrix.

Also some calls to cogl_orth to change the projection matrix have been
moved into the test entry point functions instead of calling this in the
paint function. Again the previous style probably came about because
with clutter we always had to re-assert the projection but now we are in
full control of the projection and can assume it doesn't need
re-asserting once set.

Acked-by: Luca Bruno <lucabru@src.gnome.org>
2011-10-01 15:53:48 +01:00

281 lines
7.7 KiB
C

#include <cogl/cogl.h>
#include <string.h>
#include "test-utils.h"
#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
{
int dummy;
} TestState;
typedef struct
{
guint32 color;
float depth;
gboolean test_enable;
CoglDepthTestFunction test_function;
gboolean write_enable;
float range_near;
float range_far;
} TestDepthState;
static void
check_pixel (GLubyte *pixel, guint32 color)
{
guint8 r = MASK_RED (color);
guint8 g = MASK_GREEN (color);
guint8 b = MASK_BLUE (color);
guint8 a = MASK_ALPHA (color);
if (g_test_verbose ())
g_print (" expected = %x, %x, %x, %x\n",
r, g, b, a);
/* FIXME - allow for hardware in-precision */
g_assert_cmpint (pixel[RED], ==, r);
g_assert_cmpint (pixel[GREEN], ==, g);
g_assert_cmpint (pixel[BLUE], ==, b);
/* FIXME
* We ignore the alpha, since we don't know if our render target is
* RGB or RGBA */
/* g_assert (pixel[ALPHA] == a); */
}
static gboolean
draw_rectangle (TestState *state,
int x,
int y,
TestDepthState *rect_state)
{
guint8 Cr = MASK_RED (rect_state->color);
guint8 Cg = MASK_GREEN (rect_state->color);
guint8 Cb = MASK_BLUE (rect_state->color);
guint8 Ca = MASK_ALPHA (rect_state->color);
CoglHandle pipeline;
CoglDepthState depth_state;
cogl_depth_state_init (&depth_state);
cogl_depth_state_set_test_enabled (&depth_state, rect_state->test_enable);
cogl_depth_state_set_test_function (&depth_state, rect_state->test_function);
cogl_depth_state_set_write_enabled (&depth_state, rect_state->write_enable);
cogl_depth_state_set_range (&depth_state,
rect_state->range_near,
rect_state->range_far);
pipeline = cogl_pipeline_new ();
if (!cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL))
{
cogl_object_unref (pipeline);
return FALSE;
}
cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);
cogl_set_source (pipeline);
cogl_push_matrix ();
cogl_translate (0, 0, rect_state->depth);
cogl_rectangle (x * QUAD_WIDTH,
y * QUAD_WIDTH,
x * QUAD_WIDTH + QUAD_WIDTH,
y * QUAD_WIDTH + QUAD_WIDTH);
cogl_pop_matrix ();
cogl_object_unref (pipeline);
return TRUE;
}
static void
test_depth (TestState *state,
int x,
int y,
TestDepthState *rect0_state,
TestDepthState *rect1_state,
TestDepthState *rect2_state,
guint32 expected_result)
{
GLubyte pixel[4];
int y_off;
int x_off;
gboolean missing_feature = FALSE;
if (rect0_state)
missing_feature |= !draw_rectangle (state, x, y, rect0_state);
if (rect1_state)
missing_feature |= !draw_rectangle (state, x, y, rect1_state);
if (rect2_state)
missing_feature |= !draw_rectangle (state, x, y, rect2_state);
/* We don't consider it an error that we can't test something
* the driver doesn't support. */
if (missing_feature)
return;
/* See what we got... */
y_off = y * QUAD_WIDTH + (QUAD_WIDTH / 2);
x_off = x * QUAD_WIDTH + (QUAD_WIDTH / 2);
cogl_read_pixels (x_off, y_off, 1, 1,
COGL_READ_PIXELS_COLOR_BUFFER,
COGL_PIXEL_FORMAT_RGBA_8888_PRE,
pixel);
check_pixel (pixel, expected_result);
}
static void
paint (TestState *state)
{
/* Sanity check a few of the different depth test functions
* and that depth writing can be disabled... */
{
/* Closest */
TestDepthState rect0_state = {
0xff0000ff, /* rgba color */
-10, /* depth */
FALSE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
0, 1 /* depth range */
};
/* Furthest */
TestDepthState rect1_state = {
0x00ff00ff, /* rgba color */
-70, /* depth */
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
0, 1 /* depth range */
};
/* In the middle */
TestDepthState rect2_state = {
0x0000ffff, /* rgba color */
-20, /* depth */
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_NEVER,
TRUE, /* depth write enable */
0, 1 /* depth range */
};
test_depth (state, 0, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x00ff00ff); /* expected */
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_ALWAYS;
test_depth (state, 1, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x0000ffff); /* expected */
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_LESS;
test_depth (state, 2, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x0000ffff); /* expected */
rect2_state.test_function = COGL_DEPTH_TEST_FUNCTION_GREATER;
test_depth (state, 3, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x00ff00ff); /* expected */
rect0_state.test_enable = TRUE;
rect1_state.write_enable = FALSE;
test_depth (state, 4, 0, /* position */
&rect0_state, &rect1_state, &rect2_state,
0x0000ffff); /* expected */
}
/* Check that the depth buffer values can be mapped into different
* ranges... */
{
/* Closest by depth, furthest by depth range */
TestDepthState rect0_state = {
0xff0000ff, /* rgba color */
-10, /* depth */
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_ALWAYS,
TRUE, /* depth write enable */
0.5, 1 /* depth range */
};
/* Furthest by depth, nearest by depth range */
TestDepthState rect1_state = {
0x00ff00ff, /* rgba color */
-70, /* depth */
TRUE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_GREATER,
TRUE, /* depth write enable */
0, 0.5 /* depth range */
};
test_depth (state, 0, 1, /* position */
&rect0_state, &rect1_state, NULL,
0xff0000ff); /* expected */
}
/* Test that the legacy cogl_set_depth_test_enabled() API still
* works... */
{
/* Nearest */
TestDepthState rect0_state = {
0xff0000ff, /* rgba color */
-10, /* depth */
FALSE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_LESS,
TRUE, /* depth write enable */
0, 1 /* depth range */
};
/* Furthest */
TestDepthState rect1_state = {
0x00ff00ff, /* rgba color */
-70, /* depth */
FALSE, /* depth test enable */
COGL_DEPTH_TEST_FUNCTION_LESS,
TRUE, /* depth write enable */
0, 1 /* depth range */
};
cogl_set_depth_test_enabled (TRUE);
test_depth (state, 0, 2, /* position */
&rect0_state, &rect1_state, NULL,
0xff0000ff); /* expected */
cogl_set_depth_test_enabled (FALSE);
test_depth (state, 1, 2, /* position */
&rect0_state, &rect1_state, NULL,
0x00ff00ff); /* expected */
}
}
void
test_cogl_depth_test (TestUtilsGTestFixture *fixture,
void *data)
{
TestUtilsSharedState *shared_state = data;
TestState state;
cogl_ortho (0, cogl_framebuffer_get_width (shared_state->fb), /* left, right */
cogl_framebuffer_get_height (shared_state->fb), 0, /* bottom, top */
-1, 100 /* z near, far */);
paint (&state);
if (g_test_verbose ())
g_print ("OK\n");
}