/** * clutter_shader_set_is_enabled: * @shader: a #ClutterShader * @enabled: The new state of the shader. * * Enables a shader. This function will attempt to compile and link * the shader, if it isn't already. * * When @enabled is %FALSE the default state of the GL pipeline will be * used instead. * * Since: 0.6 */ void clutter_shader_set_is_enabled (ClutterShader *shader, gboolean enabled) { ClutterShaderPrivate *priv; g_return_if_fail (CLUTTER_IS_SHADER (shader)); priv = shader->priv; if (priv->is_enabled != enabled) { GError *error = NULL; gboolean res; res = clutter_shader_compile (shader, &error); if (!res) { g_warning ("Unable to bind the shader: %s", error ? error->message : "unknown error"); if (error) g_error_free (error); return; } priv->is_enabled = enabled; if (priv->is_enabled) cogl_program_use (priv->program); else cogl_program_use (COGL_INVALID_HANDLE); g_object_notify (G_OBJECT (shader), "enabled"); } }
G_MODULE_EXPORT gint test_shader_main (gint argc, gchar *argv[]) { ClutterActor *actor; ClutterActor *stage; ClutterColor stage_color = { 0x61, 0x64, 0x8c, 0xff }; ClutterShader *shader; GError *error; gchar *file; if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS) return 1; stage = clutter_stage_new (); clutter_stage_set_title (CLUTTER_STAGE (stage), "Shaders"); clutter_actor_set_size (stage, 512, 384); g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL); g_print ("applying shaders[%i] named '%s'\n", shader_no, shaders[shader_no].name); shader = clutter_shader_new (); error = NULL; clutter_shader_set_fragment_source (shader, shaders[shader_no].source, -1); clutter_shader_compile (shader, &error); if (error) { g_print ("unable to load shaders[%d] named '%s': %s\n", shader_no, shaders[shader_no].name, error->message); g_error_free (error); return EXIT_FAILURE; } clutter_stage_set_title (CLUTTER_STAGE (stage), "Shader Test"); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); file = g_build_filename (TESTS_DATADIR, "redhand.png", NULL); #ifndef TEST_GROUP actor = clutter_texture_new_from_file (file, &error); if (!actor) g_error("pixbuf load failed: %s", error ? error->message : "Unknown"); #else actor = clutter_group_new (); { ClutterActor *child1, *child2, *child3, *child4; ClutterColor color = { 0xff, 0x22, 0x66, 0x99 }; child1 = clutter_texture_new_from_file (file, &error); if (!child1) g_error("pixbuf load failed: %s", error ? error->message : "Unknown"); child2 = clutter_texture_new_from_file (file, &error); if (!child2) g_error("pixbuf load failed: %s", error ? error->message : "Unknown"); child3 = clutter_rectangle_new (); child4 = clutter_text_new_with_text ("Sans 20px", "Shady stuff"); clutter_rectangle_set_color (CLUTTER_RECTANGLE (child3), &color); clutter_actor_set_size (child3, 50, 50); clutter_actor_set_position (child1, 0, 0); clutter_actor_set_position (child2, 50, 100); clutter_actor_set_position (child3, 30, -30); clutter_actor_set_position (child4, -50, 20); clutter_container_add (CLUTTER_CONTAINER (actor), child1, child2, child3, child4, NULL); clutter_actor_show_all (actor); } #endif /* !TEST_GROUP */ g_free (file); clutter_actor_set_shader (actor, shader); clutter_actor_set_position (actor, 100, 100); g_object_unref (shader); clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); clutter_actor_set_shader_param_int (actor, "tex", 0); clutter_actor_set_shader_param_float (actor, "brightness", 0.4); clutter_actor_set_shader_param_float (actor, "contrast", -1.9); clutter_actor_set_reactive (actor, TRUE); g_signal_connect (actor, "button-release-event", G_CALLBACK (button_release_cb), NULL); #ifdef COGL_HAS_GLES2 /* On an embedded platform it is difficult to right click so we will cycle through the shaders automatically */ g_timeout_add_seconds (3, timeout_cb, actor); #endif /* Show everying ( and map window ) */ clutter_actor_show_all (stage); clutter_main (); return EXIT_SUCCESS; }
static void set_shader_num (ClutterActor *actor, gint new_no) { int tex_width; int tex_height; if (new_no >= 0 && shaders[new_no].name) { ClutterShader *shader; GError *error; shader_no = new_no; g_print ("setting shaders[%i] named '%s'\n", shader_no, shaders[shader_no].name); shader = clutter_shader_new (); error = NULL; g_object_set (G_OBJECT (shader), "fragment-source", shaders[shader_no].source, NULL); /* try to bind the shader, provoking an error we catch if there is issues * with the shader sources we've provided. At a later stage it should be * possible to iterate through a set of alternate shader sources (glsl -> * asm -> cg?) and the one that succesfully compiles is used. */ clutter_shader_compile (shader, &error); if (error) { g_print ("unable to set shaders[%i] named '%s': %s", shader_no, shaders[shader_no].name, error->message); g_error_free (error); clutter_actor_set_shader (actor, NULL); } else { clutter_actor_set_shader (actor, NULL); clutter_actor_set_shader (actor, shader); clutter_actor_set_shader_param_int (actor, "tex", 0); clutter_actor_set_shader_param_float (actor, "radius", 3.0); clutter_actor_set_shader_param_float (actor, "brightness", 0.4); clutter_actor_set_shader_param_float (actor, "contrast", -1.9); if (CLUTTER_IS_TEXTURE (actor)) { /* XXX - this assumes *a lot* about how things are done * internally on *some* hardware and driver */ tex_width = clutter_actor_get_width (actor); tex_width = next_p2 (tex_width); tex_height = clutter_actor_get_height (actor); tex_height = next_p2 (tex_height); clutter_actor_set_shader_param_float (actor, "x_step", 1.0f / tex_width); clutter_actor_set_shader_param_float (actor, "y_step", 1.0f / tex_height); } } g_object_unref (shader); } }