diff --git a/tests/interactive/Makefile.am b/tests/interactive/Makefile.am index e5882ed32..190436feb 100644 --- a/tests/interactive/Makefile.am +++ b/tests/interactive/Makefile.am @@ -19,6 +19,7 @@ UNIT_TESTS = \ test-fullscreen.c \ test-shader.c \ test-cogl-shader-arbfp.c \ + test-cogl-shader-glsl.c \ test-animator.c \ test-state.c \ test-state-animator.c \ diff --git a/tests/interactive/test-cogl-shader-glsl.c b/tests/interactive/test-cogl-shader-glsl.c new file mode 100644 index 000000000..786a3ba5e --- /dev/null +++ b/tests/interactive/test-cogl-shader-glsl.c @@ -0,0 +1,382 @@ +#include + +#include +#include +#include +#include + +typedef struct +{ + char *name; + char *source; +} ShaderSource; + +/* These variables are used instead of the standard GLSL variables on + GLES 2 */ +#ifdef COGL_HAS_GLES2 + +#define GLES2_VARS \ + "precision mediump float;\n" \ + "varying vec2 tex_coord[1];\n" \ + "varying vec4 frag_color;\n" +#define TEX_COORD "tex_coord[0]" +#define COLOR_VAR "frag_color" + +#else /* COGL_HAS_GLES2 */ + +#define GLES2_VARS "" +#define TEX_COORD "gl_TexCoord[0]" +#define COLOR_VAR "gl_Color" + +#endif /* COGL_HAS_GLES2 */ + +/* a couple of boilerplate defines that are common amongst all the + * sample shaders + */ + +/* FRAGMENT_SHADER_BEGIN: generate boilerplate with a local vec4 color already + * initialized, from a sampler2D in a variable tex. + */ +#define FRAGMENT_SHADER_VARS \ + GLES2_VARS \ + "uniform sampler2D tex;" \ + "uniform float x_step, y_step;" \ + +#define FRAGMENT_SHADER_BEGIN \ + "void main (){" \ + " vec4 color = texture2D (tex, vec2(" TEX_COORD "));" + +/* FRAGMENT_SHADER_END: apply the changed color to the output buffer correctly + * blended with the gl specified color (makes the opacity of actors work + * correctly). + */ +#define FRAGMENT_SHADER_END \ + " gl_FragColor = color;" \ + " gl_FragColor = gl_FragColor * " COLOR_VAR ";" \ + "}" + +static ShaderSource shaders[]= + { + {"brightness-contrast", + FRAGMENT_SHADER_VARS + "uniform float brightness, contrast;" + FRAGMENT_SHADER_BEGIN + " color.rgb /= color.a;" + " color.rgb = (color.rgb - vec3(0.5, 0.5, 0.5)) * contrast + " + "vec3 (brightness + 0.5, brightness + 0.5, brightness + 0.5);" + " color.rgb *= color.a;" + FRAGMENT_SHADER_END + }, + + {"box-blur", + FRAGMENT_SHADER_VARS + +#if GPU_SUPPORTS_DYNAMIC_BRANCHING + "uniform float radius;" + FRAGMENT_SHADER_BEGIN + "float u, v;" + "int count = 1;" + "for (u=-radius;ubutton.button == 1) + { + new_no = shader_no - 1; + if (new_no < 0) + new_no = G_N_ELEMENTS (shaders) - 1; + } + else + { + new_no = shader_no + 1; + if (new_no >= G_N_ELEMENTS (shaders)) + new_no = 0; + } + + set_shader_num (new_no); + + return FALSE; +} + +static gboolean +key_release_cb (ClutterActor *actor, + ClutterEvent *event, + void *user_data) +{ + if (event->key.keyval == CLUTTER_Q || event->key.keyval == CLUTTER_q) + clutter_main_quit (); + + return FALSE; +} + +static gboolean +timeout_cb (void *user_data) +{ + shader_no++; + if (shader_no > (G_N_ELEMENTS (shaders) - 1)) + shader_no = 0; + + set_shader_num (shader_no); + + return TRUE; +} + +static gboolean +idle_cb (void *data) +{ + clutter_actor_queue_redraw (data); + + return TRUE; +} + +static gboolean +destroy_window_cb (ClutterStage *stage, + ClutterEvent *event, + void *user_data) +{ + clutter_main_quit (); + return TRUE; +} + +G_MODULE_EXPORT int +test_cogl_shader_glsl_main (int argc, char *argv[]) +{ + ClutterActor *stage; + char *file; + GError *error; + ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; + + clutter_init (&argc, &argv); + + stage = clutter_stage_new (); + + clutter_stage_set_title (CLUTTER_STAGE (stage), "Assembly Shader Test"); + clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); + + file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); + error = NULL; + redhand = cogl_texture_new_from_file (file, 0, COGL_PIXEL_FORMAT_ANY, + &error); + if (redhand == COGL_INVALID_HANDLE) + g_error ("image load failed: %s", error->message); + + material = cogl_material_new (); + cogl_material_set_layer (material, 0, redhand); + + set_shader_num (0); + g_signal_connect_after (stage, "paint", G_CALLBACK (paint_cb), NULL); + + clutter_actor_set_reactive (stage, TRUE); + g_signal_connect (stage, "button-release-event", + G_CALLBACK (button_release_cb), NULL); + g_signal_connect (stage, "key-release-event", + G_CALLBACK (key_release_cb), NULL); + + g_signal_connect (stage, "delete-event", + G_CALLBACK (destroy_window_cb), NULL); + + timeout_id = g_timeout_add (1000, timeout_cb, NULL); + + g_idle_add (idle_cb, stage); + + clutter_actor_show_all (stage); + + clutter_main (); + + return EXIT_SUCCESS; +} +