From d816acd8348a84bf3f0e9f065fab80688a76350d Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Fri, 11 Jun 2010 14:47:48 +0100 Subject: [PATCH] shader-effect: Allow creating vertex shaders By default, ShaderEffect creates a fragment shader; in order to be able to deprecate ClutterShader we need a way for ShaderEffect sub-classes to create a vertex shader if needed - By using a write-only, constructor only property. ClutterShader has, internally, a ClutterShaderType enumeration that can be used exactly for this. We just need to expose it and create a GObject property for ClutterShaderEffect. --- clutter/clutter-shader-effect.c | 70 +++++++++++++++++++++- clutter/clutter-shader.c | 5 -- clutter/clutter-types.h | 14 +++++ doc/reference/clutter/clutter-sections.txt | 1 + 4 files changed, 82 insertions(+), 8 deletions(-) diff --git a/clutter/clutter-shader-effect.c b/clutter/clutter-shader-effect.c index 900653658..0ec465e51 100644 --- a/clutter/clutter-shader-effect.c +++ b/clutter/clutter-shader-effect.c @@ -112,6 +112,7 @@ #include "cogl/cogl.h" #include "clutter-debug.h" +#include "clutter-enum-types.h" #include "clutter-feature.h" #include "clutter-private.h" #include "clutter-shader-types.h" @@ -128,6 +129,8 @@ struct _ClutterShaderEffectPrivate { ClutterActor *actor; + ClutterShaderType shader_type; + CoglHandle program; CoglHandle shader; @@ -137,6 +140,13 @@ struct _ClutterShaderEffectPrivate guint source_set : 1; }; +enum +{ + PROP_0, + + PROP_SHADER_TYPE +}; + G_DEFINE_ABSTRACT_TYPE (ClutterShaderEffect, clutter_shader_effect, CLUTTER_TYPE_OFFSCREEN_EFFECT); @@ -287,7 +297,21 @@ clutter_shader_effect_set_actor (ClutterActorMeta *meta, priv->program = cogl_create_program (); - priv->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); + switch (priv->shader_type) + { + case CLUTTER_FRAGMENT_SHADER: + priv->shader = cogl_create_shader (COGL_SHADER_TYPE_FRAGMENT); + break; + + case CLUTTER_VERTEX_SHADER: + priv->shader = cogl_create_shader (COGL_SHADER_TYPE_VERTEX); + break; + + default: + priv->shader = COGL_INVALID_HANDLE; + break; + } + g_assert (priv->shader != COGL_INVALID_HANDLE); } @@ -350,6 +374,26 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect) cogl_program_use (COGL_INVALID_HANDLE); } +static void +clutter_shader_effect_set_property (GObject *gobject, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + ClutterShaderEffectPrivate *priv = CLUTTER_SHADER_EFFECT (gobject)->priv; + + switch (prop_id) + { + case PROP_SHADER_TYPE: + priv->shader_type = g_value_get_enum (value); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); + break; + } +} + static void clutter_shader_effect_finalize (GObject *gobject) { @@ -366,13 +410,33 @@ clutter_shader_effect_class_init (ClutterShaderEffectClass *klass) ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass); ClutterOffscreenEffectClass *offscreen_class; - - g_type_class_add_private (klass, sizeof (ClutterShaderEffectPrivate)); + GParamSpec *pspec; offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); + g_type_class_add_private (klass, sizeof (ClutterShaderEffectPrivate)); + + gobject_class->set_property = clutter_shader_effect_set_property; gobject_class->finalize = clutter_shader_effect_finalize; + /** + * ClutterShaderEffect:shader-type: + * + * The type of shader that is used by the effect. This property + * should be set by the constructor of #ClutterShaderEffect + * sub-classes. + * + * Since: 1.4 + */ + pspec = g_param_spec_enum ("shader-type", + "Shader Type", + "The type of shader used", + CLUTTER_TYPE_SHADER_TYPE, + CLUTTER_FRAGMENT_SHADER, + CLUTTER_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (gobject_class, PROP_SHADER_TYPE, pspec); + meta_class->set_actor = clutter_shader_effect_set_actor; offscreen_class->paint_target = clutter_shader_effect_paint_target; diff --git a/clutter/clutter-shader.c b/clutter/clutter-shader.c index 42fab2dff..9e2e84529 100644 --- a/clutter/clutter-shader.c +++ b/clutter/clutter-shader.c @@ -63,11 +63,6 @@ static GList *clutter_shaders_list = NULL; #define CLUTTER_SHADER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CLUTTER_TYPE_SHADER, ClutterShaderPrivate)) -typedef enum { - CLUTTER_VERTEX_SHADER, - CLUTTER_FRAGMENT_SHADER -} ClutterShaderType; - struct _ClutterShaderPrivate { guint compiled : 1; /* Shader is bound to the GL context */ diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h index 9d53ea9a0..fa11bc901 100644 --- a/clutter/clutter-types.h +++ b/clutter/clutter-types.h @@ -417,6 +417,20 @@ typedef enum { CLUTTER_TEXT_DIRECTION_RTL } ClutterTextDirection; +/** + * ClutterShaderType: + * @CLUTTER_VERTEX_SHADER: a vertex shader + * @CLUTTER_FRAGMENT_SHADER: a fragment shader + * + * The type of GLSL shader program + * + * Since: 1.4 + */ +typedef enum { + CLUTTER_VERTEX_SHADER, + CLUTTER_FRAGMENT_SHADER +} ClutterShaderType; + G_END_DECLS #endif /* __CLUTTER_TYPES_H__ */ diff --git a/doc/reference/clutter/clutter-sections.txt b/doc/reference/clutter/clutter-sections.txt index 9f1b7436f..660f55b4d 100644 --- a/doc/reference/clutter/clutter-sections.txt +++ b/doc/reference/clutter/clutter-sections.txt @@ -2339,6 +2339,7 @@ clutter_offscreen_effect_get_type
ClutterShaderEffect clutter-shader-effect +ClutterShaderType ClutterShaderEffect ClutterShaderEffectClass clutter_shader_effect_set_uniform