## ClutterShaderEffect

ClutterShaderEffect — Base class for fragment shader effects

## Synopsis

    enum                ClutterShaderType;
    struct              ClutterShaderEffect;
    struct              ClutterShaderEffectClass;
    void                clutter_shader_effect_set_uniform   (ClutterShaderEffect *effect,
                                                             const gchar *name,
                                                             GType gtype,
                                                             gsize n_values,
                                                             ...);
    void                clutter_shader_effect_set_uniform_value
                                                            (ClutterShaderEffect *effect,
                                                             const gchar *name,
                                                             const GValue *value);

    gboolean            clutter_shader_effect_set_shader_source
                                                            (ClutterShaderEffect *effect,
                                                             const gchar *source);
    CoglHandle          clutter_shader_effect_get_program   (ClutterShaderEffect *effect);
    CoglHandle          clutter_shader_effect_get_shader    (ClutterShaderEffect *effect);

## Object Hierarchy

      GObject
       +----GInitiallyUnowned
             +----ClutterActorMeta
                   +----ClutterEffect
                         +----ClutterOffscreenEffect
                               +----ClutterShaderEffect

## Properties

      "shader-type"              ClutterShaderType     : Write / Construct Only

## Description

ClutterShaderEffect is an abstract class that implements all the plumbing for creating ClutterEffects using GLSL fragment shaders.

ClutterShaderEffect creates an offscreen buffer and then applies the GLSL fragment shader (after checking whether the compilation and linking were successfull) to the buffer before painting it on screen.

### Implementing a ClutterShaderEffect

Creating a sub-class of ClutterShaderEffect requires the overriding of the ``pre_paint()`` virtual function from the ClutterEffect class.

The ``pre_paint()`` should set the shader's source and eventually set the uniforms. The sub-class should call `clutter_shader_effect_set_shader_source()` to set the shader source code, and `clutter_shader_effect_set_uniform_value()` or `clutter_shader_effect_set_uniform()` to set the values of the shader uniforms, if any; the sub-class should then chain up to the ClutterShaderEffect implementation.

Example 6. Setting uniforms on a ClutterShaderEffect

The example below shows a typical implementation of the ``pre_paint()`` phase of a ClutterShaderEffect sub-class.

     static gboolean
     my_effect_pre_paint (ClutterEffect *effect)
     {
       MyEffect *self = MY_EFFECT (effect);
       ClutterShaderEffect *shader = CLUTTER_SHADER_EFFECT (effect);
       ClutterEffectClass *parent_class;
       gfloat component_r, component_g, component_b;

       /* if the effect is not enabled we can bail out now */
       if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
         return FALSE;

       /* this function is a no-op after the first call */
       clutter_shader_effect_set_shader_source (shader, shader_source);

       /* the "tex" uniform is declared in the shader as:
        *
        *   uniform int tex;
        *
        * and it is passed a constant value of 0
        */
       clutter_shader_effect_set_uniform (shader, "tex", G_TYPE_INT, 1, 0);

       /* the "component" uniform is declared in the shader as:
        *
        *   uniform vec3 component;
        *
        * and it's defined to contain the normalized components
        * of a ClutterColor
        */
       component_r = self->color.red   / 255.0f;
       component_g = self->color.green / 255.0f;
       component_b = self->color.blue  / 255.0f;
       clutter_shader_effect_set_uniform (shader, "component",
                                          G_TYPE_FLOAT, 3,
                                          component_r,
                                          component_g,
                                          component_b);

       /* chain up to the parent's implementation */
       parent_class = CLUTTER_EFFECT_CLASS (my_effect_parent_class);
       return parent_class->pre_paint (effect);
     }

ClutterShaderEffect is available since Clutter 1.4

## Details

### enum ClutterShaderType

    typedef enum {
      CLUTTER_VERTEX_SHADER,
      CLUTTER_FRAGMENT_SHADER
    } ClutterShaderType;

The type of GLSL shader program

`CLUTTER_VERTEX_SHADER` | a vertex shader
`CLUTTER_FRAGMENT_SHADER` | a fragment shader

Since 1.4

### struct ClutterShaderEffect

    struct ClutterShaderEffect;

The ClutterShaderEffect structure contains only private data and should be accessed using the provided API

Since 1.4

### struct ClutterShaderEffectClass

    struct ClutterShaderEffectClass {
    };

The ClutterShaderEffectClass structure contains only private data

Since 1.4

### clutter_shader_effect_set_uniform ()

    void                clutter_shader_effect_set_uniform   (ClutterShaderEffect *effect,
                                                             const gchar *name,
                                                             GType gtype,
                                                             gsize n_values,
                                                             ...);

Sets a list of values as the payload for the uniform `name` inside the shader effect

The `gtype` must be one of: `G_TYPE_INT`, for 1 or more integer values; `G_TYPE_FLOAT`, for 1 or more floating point values; `CLUTTER_TYPE_SHADER_INT`, for a pointer to an array of integer values; `CLUTTER_TYPE_SHADER_FLOAT`, for a pointer to an array of floating point values; and `CLUTTER_TYPE_SHADER_MATRIX`, for a pointer to an array of floating point values mapping a matrix

The number of values interepreted is defined by the `n_value` argument, and by the `gtype` argument. For instance, a uniform named "sampler0" and containing a single integer value is set using:

    1
    2
    3

    clutter_shader_effect_set_uniform (effect, "sampler0",
                                       G_TYPE_INT, 1,
                                       0);

While a uniform named "components" and containing a 3-elements vector of floating point values (a "vec3") can be set using:

    1
    2
    3
    4
    5
    6
    7

    gfloat component_r, component_g, component_b;

    clutter_shader_effect_set_uniform (effect, "components",
                                       G_TYPE_FLOAT, 3,
                                       component_r,
                                       component_g,
                                       component_b);

or can be set using:

    1
    2
    3
    4
    5

    gfloat component_vec[3];

    clutter_shader_effect_set_uniform (effect, "components",
                                       CLUTTER_TYPE_SHADER_FLOAT, 3,
                                       component_vec);

Finally, a uniform named "map" and containing a matrix can be set using:

    1
    2
    3

    clutter_shader_effect_set_uniform (effect, "map",
                                       CLUTTER_TYPE_SHADER_MATRIX, 1,
                                       cogl_matrix_get_array (&matrix));

`effect` : | a ClutterShaderEffect
`name` : | the name of the uniform to set
`gtype` : | the type of the uniform to set
`n_values` : | the number of values
`...` : | a list of values

Since 1.4

### clutter_shader_effect_set_uniform_value ()

    void                clutter_shader_effect_set_uniform_value
                                                            (ClutterShaderEffect *effect,
                                                             const gchar *name,
                                                             const GValue *value);

Sets `value` as the payload for the uniform `name` inside the shader effect

The GType of the `value` must be one of: `G_TYPE_INT`, for a single integer value; `G_TYPE_FLOAT`, for a single floating point value; `CLUTTER_TYPE_SHADER_INT`, for an array of integer values; `CLUTTER_TYPE_SHADER_FLOAT`, for an array of floating point values; and `CLUTTER_TYPE_SHADER_MATRIX`, for a matrix of floating point values

`effect` : | a ClutterShaderEffect
`name` : | the name of the uniform to set
`value` : | a GValue with the value of the uniform to set

Since 1.4

### clutter_shader_effect_set_shader_source ()

    gboolean            clutter_shader_effect_set_shader_source
                                                            (ClutterShaderEffect *effect,
                                                             const gchar *source);

Sets the source of the GLSL shader used by `effect`

This function should only be called by implementations of the ClutterShaderEffect class, and not by application code.

This function can only be called once; subsequent calls will yield no result.

`effect` : | a ClutterShaderEffect
`source` : | the source of a GLSL shader
Returns : | `TRUE` if the source was set

Since 1.4

### clutter_shader_effect_get_program ()

    CoglHandle          clutter_shader_effect_get_program   (ClutterShaderEffect *effect);

Retrieves a pointer to the program's handle

`effect` : | a ClutterShaderEffect
Returns : | a pointer to the program's handle, or `COGL_INVALID_HANDLE`. [transfer none]

Since 1.4

### clutter_shader_effect_get_shader ()

    CoglHandle          clutter_shader_effect_get_shader    (ClutterShaderEffect *effect);

Retrieves a pointer to the shader's handle

`effect` : | a ClutterShaderEffect
Returns : | a pointer to the shader's handle, or `COGL_INVALID_HANDLE`. [transfer none]

Since 1.4

## Property Details

### The `"shader-type"` property

      "shader-type"              ClutterShaderType     : Write / Construct Only

The type of shader that is used by the effect. This property should be set by the constructor of ClutterShaderEffect sub-classes.

Default value: CLUTTER_FRAGMENT_SHADER

Since 1.4

## See Also

ClutterEffect, ClutterOffscreenEffect