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.
This commit is contained in:
Emmanuele Bassi 2010-06-11 14:47:48 +01:00
parent 0f41948c82
commit d816acd834
4 changed files with 82 additions and 8 deletions

View File

@ -112,6 +112,7 @@
#include "cogl/cogl.h" #include "cogl/cogl.h"
#include "clutter-debug.h" #include "clutter-debug.h"
#include "clutter-enum-types.h"
#include "clutter-feature.h" #include "clutter-feature.h"
#include "clutter-private.h" #include "clutter-private.h"
#include "clutter-shader-types.h" #include "clutter-shader-types.h"
@ -128,6 +129,8 @@ struct _ClutterShaderEffectPrivate
{ {
ClutterActor *actor; ClutterActor *actor;
ClutterShaderType shader_type;
CoglHandle program; CoglHandle program;
CoglHandle shader; CoglHandle shader;
@ -137,6 +140,13 @@ struct _ClutterShaderEffectPrivate
guint source_set : 1; guint source_set : 1;
}; };
enum
{
PROP_0,
PROP_SHADER_TYPE
};
G_DEFINE_ABSTRACT_TYPE (ClutterShaderEffect, G_DEFINE_ABSTRACT_TYPE (ClutterShaderEffect,
clutter_shader_effect, clutter_shader_effect,
CLUTTER_TYPE_OFFSCREEN_EFFECT); CLUTTER_TYPE_OFFSCREEN_EFFECT);
@ -287,7 +297,21 @@ clutter_shader_effect_set_actor (ClutterActorMeta *meta,
priv->program = cogl_create_program (); 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); g_assert (priv->shader != COGL_INVALID_HANDLE);
} }
@ -350,6 +374,26 @@ clutter_shader_effect_paint_target (ClutterOffscreenEffect *effect)
cogl_program_use (COGL_INVALID_HANDLE); 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 static void
clutter_shader_effect_finalize (GObject *gobject) 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); ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass);
GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
ClutterOffscreenEffectClass *offscreen_class; ClutterOffscreenEffectClass *offscreen_class;
GParamSpec *pspec;
g_type_class_add_private (klass, sizeof (ClutterShaderEffectPrivate));
offscreen_class = CLUTTER_OFFSCREEN_EFFECT_CLASS (klass); 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; 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; meta_class->set_actor = clutter_shader_effect_set_actor;
offscreen_class->paint_target = clutter_shader_effect_paint_target; offscreen_class->paint_target = clutter_shader_effect_paint_target;

View File

@ -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)) #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 struct _ClutterShaderPrivate
{ {
guint compiled : 1; /* Shader is bound to the GL context */ guint compiled : 1; /* Shader is bound to the GL context */

View File

@ -417,6 +417,20 @@ typedef enum {
CLUTTER_TEXT_DIRECTION_RTL CLUTTER_TEXT_DIRECTION_RTL
} ClutterTextDirection; } 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 G_END_DECLS
#endif /* __CLUTTER_TYPES_H__ */ #endif /* __CLUTTER_TYPES_H__ */

View File

@ -2339,6 +2339,7 @@ clutter_offscreen_effect_get_type
<SECTION> <SECTION>
<TITLE>ClutterShaderEffect</TITLE> <TITLE>ClutterShaderEffect</TITLE>
<FILE>clutter-shader-effect</FILE> <FILE>clutter-shader-effect</FILE>
ClutterShaderType
ClutterShaderEffect ClutterShaderEffect
ClutterShaderEffectClass ClutterShaderEffectClass
clutter_shader_effect_set_uniform clutter_shader_effect_set_uniform