summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeil Roberts <neil@linux.intel.com>2011-11-28 13:46:30 +0000
committerNeil Roberts <neil@linux.intel.com>2011-11-28 18:18:51 +0000
commit561dd805b98c6548c01b6fcb97e6e9d58802bae4 (patch)
tree937ed86d41b3701bd3451ab2f96c868a46a114bc
parent46da7407ddeddf826bcf1285254584380d157257 (diff)
downloadclutter-wip/neil/effect-snippets.tar.gz
desaturate-effect: Use the new CoglSnippet APIwip/neil/effect-snippets
-rw-r--r--clutter/clutter-desaturate-effect.c160
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;
}