diff options
author | Neil Roberts <neil@linux.intel.com> | 2011-11-28 13:46:30 +0000 |
---|---|---|
committer | Neil Roberts <neil@linux.intel.com> | 2011-11-28 18:18:51 +0000 |
commit | 561dd805b98c6548c01b6fcb97e6e9d58802bae4 (patch) | |
tree | 937ed86d41b3701bd3451ab2f96c868a46a114bc | |
parent | 46da7407ddeddf826bcf1285254584380d157257 (diff) | |
download | clutter-wip/neil/effect-snippets.tar.gz |
desaturate-effect: Use the new CoglSnippet APIwip/neil/effect-snippets
-rw-r--r-- | clutter/clutter-desaturate-effect.c | 160 |
1 files changed, 69 insertions, 91 deletions
diff --git a/clutter/clutter-desaturate-effect.c b/clutter/clutter-desaturate-effect.c index 8f00630fe..e845e2fa6 100644 --- a/clutter/clutter-desaturate-effect.c +++ b/clutter/clutter-desaturate-effect.c @@ -64,13 +64,9 @@ struct _ClutterDesaturateEffect /* the desaturation factor, also known as "strength" */ gdouble factor; - CoglHandle shader; - CoglHandle program; - - gint tex_uniform; gint factor_uniform; - guint is_compiled : 1; + CoglPipeline *pipeline; }; struct _ClutterDesaturateEffectClass @@ -78,6 +74,8 @@ struct _ClutterDesaturateEffectClass ClutterOffscreenEffectClass parent_class; }; +static CoglPipeline *base_pipeline = NULL; + /* the magic gray vec3 has been taken from the NTSC conversion weights * as defined by: * @@ -85,23 +83,18 @@ struct _ClutterDesaturateEffectClass * -- Richard S. Wright Jr, Benjamin Lipchak, Nicholas Haemel * Addison-Wesley */ -static const gchar *desaturate_glsl_shader = -"uniform sampler2D tex;\n" -"uniform float factor;\n" -"\n" -"vec3 desaturate (const vec3 color, const float desaturation)\n" -"{\n" -" const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n" -" vec3 gray = vec3 (dot (gray_conv, color));\n" -" return vec3 (mix (color.rgb, gray, desaturation));\n" -"}\n" -"\n" -"void main ()\n" -"{\n" -" vec4 color = cogl_color_in * texture2D (tex, vec2 (cogl_tex_coord_in[0].xy));\n" -" color.rgb = desaturate (color.rgb, factor);\n" -" cogl_color_out = color;\n" -"}\n"; +static const gchar *desaturate_glsl_declarations = + "uniform float factor;\n" + "\n" + "vec3 desaturate (const vec3 color, const float desaturation)\n" + "{\n" + " const vec3 gray_conv = vec3 (0.299, 0.587, 0.114);\n" + " vec3 gray = vec3 (dot (gray_conv, color));\n" + " return vec3 (mix (color.rgb, gray, desaturation));\n" + "}\n"; + +static const gchar *desaturate_glsl_source = + " cogl_color_out.rgb = desaturate (cogl_color_out.rgb, factor);\n"; enum { @@ -143,55 +136,6 @@ clutter_desaturate_effect_pre_paint (ClutterEffect *effect) return FALSE; } - if (self->shader == COGL_INVALID_HANDLE) - { - self->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); - cogl_shader_source (self->shader, desaturate_glsl_shader); - - self->is_compiled = FALSE; - self->tex_uniform = -1; - self->factor_uniform = -1; - } - - if (self->program == COGL_INVALID_HANDLE) - self->program = cogl_create_program (); - - if (!self->is_compiled) - { - g_assert (self->shader != COGL_INVALID_HANDLE); - g_assert (self->program != COGL_INVALID_HANDLE); - - cogl_shader_compile (self->shader); - if (!cogl_shader_is_compiled (self->shader)) - { - gchar *log_buf = cogl_shader_get_info_log (self->shader); - - g_warning (G_STRLOC ": Unable to compile the desaturate shader: %s", - log_buf); - g_free (log_buf); - - cogl_handle_unref (self->shader); - cogl_handle_unref (self->program); - - self->shader = COGL_INVALID_HANDLE; - self->program = COGL_INVALID_HANDLE; - } - else - { - cogl_program_attach_shader (self->program, self->shader); - cogl_program_link (self->program); - - cogl_handle_unref (self->shader); - - self->is_compiled = TRUE; - - self->tex_uniform = - cogl_program_get_uniform_location (self->program, "tex"); - self->factor_uniform = - cogl_program_get_uniform_location (self->program, "factor"); - } - } - parent_class = CLUTTER_EFFECT_CLASS (clutter_desaturate_effect_parent_class); return parent_class->pre_paint (effect); } @@ -200,26 +144,33 @@ static void clutter_desaturate_effect_paint_target (ClutterOffscreenEffect *effect) { ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (effect); - ClutterOffscreenEffectClass *parent; - CoglHandle material; + ClutterActor *actor; + CoglHandle texture; + guint8 paint_opacity; - if (self->program == COGL_INVALID_HANDLE) - goto out; + if (self->factor_uniform > -1) + cogl_pipeline_set_uniform_1f (self->pipeline, + self->factor_uniform, + self->factor); - if (self->tex_uniform > -1) - cogl_program_set_uniform_1i (self->program, self->tex_uniform, 0); + texture = clutter_offscreen_effect_get_texture (effect); + cogl_pipeline_set_layer_texture (self->pipeline, 0, texture); - if (self->factor_uniform > -1) - cogl_program_set_uniform_1f (self->program, - self->factor_uniform, - self->factor); + actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect)); + paint_opacity = clutter_actor_get_paint_opacity (actor); - material = clutter_offscreen_effect_get_target (effect); - cogl_material_set_user_program (material, self->program); + cogl_pipeline_set_color4ub (self->pipeline, + paint_opacity, + paint_opacity, + paint_opacity, + paint_opacity); + cogl_push_source (self->pipeline); -out: - parent = CLUTTER_OFFSCREEN_EFFECT_CLASS (clutter_desaturate_effect_parent_class); - parent->paint_target (effect); + cogl_rectangle (0, 0, + cogl_texture_get_width (texture), + cogl_texture_get_height (texture)); + + cogl_pop_source (); } static void @@ -227,12 +178,10 @@ clutter_desaturate_effect_dispose (GObject *gobject) { ClutterDesaturateEffect *self = CLUTTER_DESATURATE_EFFECT (gobject); - if (self->program != COGL_INVALID_HANDLE) + if (self->pipeline != NULL) { - cogl_handle_unref (self->program); - - self->program = COGL_INVALID_HANDLE; - self->shader = COGL_INVALID_HANDLE; + cogl_object_unref (self->pipeline); + self->pipeline = NULL; } G_OBJECT_CLASS (clutter_desaturate_effect_parent_class)->dispose (gobject); @@ -319,6 +268,35 @@ clutter_desaturate_effect_class_init (ClutterDesaturateEffectClass *klass) static void clutter_desaturate_effect_init (ClutterDesaturateEffect *self) { + if (base_pipeline == NULL) + { + CoglHandle dummy_texture; + + base_pipeline = cogl_pipeline_new (); + + if (clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL)) + { + CoglSnippet *snippet; + + snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_FRAGMENT, + desaturate_glsl_declarations, + desaturate_glsl_source); + cogl_pipeline_add_snippet (base_pipeline, snippet); + cogl_object_unref (snippet); + } + + dummy_texture = cogl_texture_new_with_size (1, 1, + COGL_TEXTURE_NONE, + COGL_PIXEL_FORMAT_RGB_888); + cogl_pipeline_set_layer_texture (base_pipeline, 0, dummy_texture); + cogl_handle_unref (dummy_texture); + } + + self->pipeline = cogl_pipeline_copy (base_pipeline); + + self->factor_uniform = + cogl_pipeline_get_uniform_location (self->pipeline, "factor"); + self->factor = 1.0; } |