From 72097ac01d3b6626ca128b7df055352b556c46a1 Mon Sep 17 00:00:00 2001 From: Neil Roberts <neil@linux.intel.com> Date: Fri, 2 Dec 2011 10:55:41 +0000 Subject: [PATCH] Add a conformance test for custom attributes The test creates some pipelines with snippets with custom attributes and uses CoglAttribute to define values for them. Reviewed-by: Robert Bragg <robert@linux.intel.com> --- tests/conform/Makefile.am | 1 + tests/conform/test-conform-main.c | 1 + tests/conform/test-custom-attributes.c | 304 +++++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 tests/conform/test-custom-attributes.c diff --git a/tests/conform/Makefile.am b/tests/conform/Makefile.am index 92e1ef4da..a8c23286a 100644 --- a/tests/conform/Makefile.am +++ b/tests/conform/Makefile.am @@ -46,6 +46,7 @@ test_sources = \ test-snippets.c \ test-wrap-modes.c \ test-sub-texture.c \ + test-custom-attributes.c \ $(NULL) test_conformance_SOURCES = $(common_sources) $(test_sources) diff --git a/tests/conform/test-conform-main.c b/tests/conform/test-conform-main.c index 700238c1b..0f924b514 100644 --- a/tests/conform/test-conform-main.c +++ b/tests/conform/test-conform-main.c @@ -163,6 +163,7 @@ main (int argc, char **argv) ADD_TEST ("/cogl/shaders", test_cogl_just_vertex_shader); ADD_TEST ("/cogl/shaders", test_cogl_pipeline_uniforms); ADD_TEST ("/cogl/shaders", test_cogl_snippets); + ADD_TEST ("/cogl/shaders", test_cogl_custom_attributes); ADD_TEST ("/cogl/internal/bitmask", test_cogl_bitmask); diff --git a/tests/conform/test-custom-attributes.c b/tests/conform/test-custom-attributes.c new file mode 100644 index 000000000..bc3d09fae --- /dev/null +++ b/tests/conform/test-custom-attributes.c @@ -0,0 +1,304 @@ +#include <cogl/cogl.h> + +#include <string.h> + +#include "test-utils.h" + +typedef struct _TestState +{ + CoglPipeline *pipeline; +} TestState; + +typedef struct +{ + gint16 x, y; + float r, g, b, a; +} FloatVert; + +typedef struct +{ + gint16 x, y; + guint8 r, g, b, a; +} ByteVert; + +typedef struct +{ + gint16 x, y; +} ShortVert; + +static void +test_float_verts (TestState *state, int offset_x, int offset_y) +{ + CoglAttribute *attributes[2]; + CoglAttributeBuffer *buffer; + + static const FloatVert float_verts[] = + { + { 0, 10, /**/ 1, 0, 0, 1 }, + { 10, 10, /**/ 1, 0, 0, 1 }, + { 5, 0, /**/ 1, 0, 0, 1 }, + + { 10, 10, /**/ 0, 1, 0, 1 }, + { 20, 10, /**/ 0, 1, 0, 1 }, + { 15, 0, /**/ 0, 1, 0, 1 } + }; + + buffer = cogl_attribute_buffer_new (sizeof (float_verts), float_verts); + attributes[0] = cogl_attribute_new (buffer, + "cogl_position_in", + sizeof (FloatVert), + G_STRUCT_OFFSET (FloatVert, x), + 2, /* n_components */ + COGL_ATTRIBUTE_TYPE_SHORT); + attributes[1] = cogl_attribute_new (buffer, + "color", + sizeof (FloatVert), + G_STRUCT_OFFSET (FloatVert, r), + 4, /* n_components */ + COGL_ATTRIBUTE_TYPE_FLOAT); + + cogl_push_source (state->pipeline); + + cogl_push_matrix (); + cogl_translate (offset_x, offset_y, 0.0f); + + cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES, + 0, /* first_vertex */ + 6, /* n_vertices */ + attributes, + 2 /* n_attributes */); + + cogl_pop_matrix (); + + cogl_pop_source (); + + cogl_object_unref (attributes[1]); + cogl_object_unref (attributes[0]); + cogl_object_unref (buffer); + + test_utils_check_pixel (offset_x + 5, offset_y + 5, 0xff0000ff); + test_utils_check_pixel (offset_x + 15, offset_y + 5, 0x00ff00ff); +} + +static void +test_byte_verts (TestState *state, int offset_x, int offset_y) +{ + CoglAttribute *attributes[2]; + CoglAttributeBuffer *buffer, *unnorm_buffer; + + static const ByteVert norm_verts[] = + { + { 0, 10, /**/ 255, 0, 0, 255 }, + { 10, 10, /**/ 255, 0, 0, 255 }, + { 5, 0, /**/ 255, 0, 0, 255 }, + + { 10, 10, /**/ 0, 255, 0, 255 }, + { 20, 10, /**/ 0, 255, 0, 255 }, + { 15, 0, /**/ 0, 255, 0, 255 } + }; + + static const ByteVert unnorm_verts[] = + { + { 0, 0, /**/ 0, 0, 1, 1 }, + { 0, 0, /**/ 0, 0, 1, 1 }, + { 0, 0, /**/ 0, 0, 1, 1 }, + }; + + buffer = cogl_attribute_buffer_new (sizeof (norm_verts), norm_verts); + attributes[0] = cogl_attribute_new (buffer, + "cogl_position_in", + sizeof (ByteVert), + G_STRUCT_OFFSET (ByteVert, x), + 2, /* n_components */ + COGL_ATTRIBUTE_TYPE_SHORT); + attributes[1] = cogl_attribute_new (buffer, + "color", + sizeof (ByteVert), + G_STRUCT_OFFSET (ByteVert, r), + 4, /* n_components */ + COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE); + cogl_attribute_set_normalized (attributes[1], TRUE); + + cogl_push_source (state->pipeline); + + cogl_push_matrix (); + cogl_translate (offset_x, offset_y, 0.0f); + + cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES, + 0, /* first_vertex */ + 6, /* n_vertices */ + attributes, + 2 /* n_attributes */); + + cogl_object_unref (attributes[1]); + + /* Test again with unnormalized attributes */ + unnorm_buffer = cogl_attribute_buffer_new (sizeof (unnorm_verts), + unnorm_verts); + attributes[1] = cogl_attribute_new (unnorm_buffer, + "color", + sizeof (ByteVert), + G_STRUCT_OFFSET (ByteVert, r), + 4, /* n_components */ + COGL_ATTRIBUTE_TYPE_BYTE); + + cogl_translate (20, 0, 0); + + cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES, + 0, /* first_vertex */ + 3, /* n_vertices */ + attributes, + 2 /* n_attributes */); + + cogl_pop_matrix (); + + cogl_pop_source (); + + cogl_object_unref (attributes[0]); + cogl_object_unref (attributes[1]); + cogl_object_unref (buffer); + cogl_object_unref (unnorm_buffer); + + test_utils_check_pixel (offset_x + 5, offset_y + 5, 0xff0000ff); + test_utils_check_pixel (offset_x + 15, offset_y + 5, 0x00ff00ff); + test_utils_check_pixel (offset_x + 25, offset_y + 5, 0x0000ffff); +} + +static void +test_short_verts (TestState *state, int offset_x, int offset_y) +{ + CoglAttribute *attributes[1]; + CoglAttributeBuffer *buffer; + CoglPipeline *pipeline, *pipeline2; + CoglSnippet *snippet; + + static const ShortVert short_verts[] = + { + { -10, -10 }, + { -1, -10 }, + { -5, -1 } + }; + + pipeline = cogl_pipeline_new (); + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX_TRANSFORM, + "attribute vec2 pos;", + NULL); + cogl_snippet_set_replace (snippet, + "cogl_position_out = " + "cogl_modelview_projection_matrix * " + "vec4 (pos, 0.0, 1.0);"); + cogl_pipeline_add_snippet (pipeline, snippet); + cogl_object_unref (snippet); + + cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255); + + buffer = cogl_attribute_buffer_new (sizeof (short_verts), short_verts); + attributes[0] = cogl_attribute_new (buffer, + "pos", + sizeof (ShortVert), + G_STRUCT_OFFSET (ShortVert, x), + 2, /* n_components */ + COGL_ATTRIBUTE_TYPE_SHORT); + + cogl_push_source (pipeline); + + cogl_push_matrix (); + cogl_translate (offset_x + 10.0f, offset_y + 10.0f, 0.0f); + + cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES, + 0, /* first_vertex */ + 3, /* n_vertices */ + attributes, + 1 /* n_attributes */); + + cogl_pop_matrix (); + + cogl_pop_source (); + + cogl_object_unref (attributes[0]); + + /* Test again treating the attribute as unsigned */ + attributes[0] = cogl_attribute_new (buffer, + "pos", + sizeof (ShortVert), + G_STRUCT_OFFSET (ShortVert, x), + 2, /* n_components */ + COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT); + + pipeline2 = cogl_pipeline_copy (pipeline); + cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255); + + cogl_push_source (pipeline2); + + cogl_push_matrix (); + cogl_translate (offset_x + 10.0f - 65525.0f, offset_y - 65525, 0.0f); + + cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES, + 0, /* first_vertex */ + 3, /* n_vertices */ + attributes, + 1 /* n_attributes */); + + cogl_pop_matrix (); + + cogl_pop_source (); + + cogl_object_unref (attributes[0]); + + cogl_object_unref (pipeline2); + cogl_object_unref (pipeline); + cogl_object_unref (buffer); + + test_utils_check_pixel (offset_x + 5, offset_y + 5, 0xff0000ff); + test_utils_check_pixel (offset_x + 15, offset_y + 5, 0x00ff00ff); +} + +static void +paint (TestState *state) +{ + CoglColor color; + + cogl_color_init_from_4ub (&color, 0, 0, 0, 255); + cogl_clear (&color, COGL_BUFFER_BIT_COLOR); + + test_float_verts (state, 0, 0); + test_byte_verts (state, 0, 10); + test_short_verts (state, 0, 20); +} + +void +test_cogl_custom_attributes (TestUtilsGTestFixture *fixture, + void *user_data) +{ + TestUtilsSharedState *shared_state = user_data; + + /* If shaders aren't supported then we can't run the test */ + if (cogl_features_available (COGL_FEATURE_SHADERS_GLSL)) + { + CoglSnippet *snippet; + TestState state; + + cogl_ortho (/* left, right */ + 0, cogl_framebuffer_get_width (shared_state->fb), + /* bottom, top */ + cogl_framebuffer_get_height (shared_state->fb), 0, + /* z near, far */ + -1, 100); + + state.pipeline = cogl_pipeline_new (); + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX, + "attribute vec4 color;", + "cogl_color_out = color;"); + cogl_pipeline_add_snippet (state.pipeline, snippet); + + paint (&state); + + cogl_object_unref (state.pipeline); + cogl_object_unref (snippet); + + if (g_test_verbose ()) + g_print ("OK\n"); + } + else if (g_test_verbose ()) + g_print ("Skipping\n"); +}