Clutter Reference Manual: ClutterShaderEffect

## ClutterShaderEffect ClutterShaderEffect — Base class for shader effects |

## Functions

ClutterEffect * | clutter_shader_effect_new ()
void | clutter_shader_effect_set_uniform ()
void | clutter_shader_effect_set_uniform_value ()
gboolean | clutter_shader_effect_set_shader_source ()
CoglHandle | clutter_shader_effect_get_program ()
CoglHandle | clutter_shader_effect_get_shader ()

## Properties

ClutterShaderType | shader-type | Write / Construct Only

## Types and Values

enum | ClutterShaderType
struct | ClutterShaderEffect
struct | ClutterShaderEffectClass

## Object Hierarchy

        GObject
        ╰── GInitiallyUnowned
            ╰── ClutterActorMeta
                ╰── ClutterEffect
                    ╰── ClutterOffscreenEffect
                        ╰── ClutterShaderEffect

## Description

ClutterShaderEffect is a class that implements all the plumbing for creating ClutterEffect<!-- -->s using GLSL shaders.

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

ClutterShaderEffect is available since Clutter 1.4

#### Implementing a ClutterShaderEffect

Creating a sub-class of ClutterShaderEffect requires the overriding of the `ClutterOffscreenEffectClass.paint_target()` virtual function from the ClutterOffscreenEffect class. It is also convenient to implement the `ClutterShaderEffectClass.get_static_shader_source()` virtual function in case you are planning to create more than one instance of the effect.

The `ClutterShaderEffectClass.get_static_shader_source()` function should return a copy of the shader source to use. This function is only called once per subclass of ClutterShaderEffect regardless of how many instances of the effect are created. The source for the shader is typically stored in a static const string which is returned from this function via `g_strdup()`.

The `ClutterOffscreenEffectClass.paint_target()` should set the shader's uniforms if any. This is done by calling `clutter_shader_effect_set_uniform_value()` or `clutter_shader_effect_set_uniform()`. The sub-class should then chain up to the ClutterShaderEffect implementation.

#### Setting uniforms on a ClutterShaderEffect

The example below shows a typical implementation of the `ClutterShaderEffectClass.get_static_shader_source()` and `ClutterOffscreenEffectClass.paint_target()` virtual functions for a ClutterShaderEffect subclass.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    static gchar *
    my_effect_get_static_shader_source (ClutterShaderEffect *effect)
    {
      // shader_source is set elsewhere
      return g_strdup (shader_source);
    }

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

      // 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_OFFSCREEN_EFFECT_CLASS (my_effect_parent_class);
      return parent_class->paint_target (effect);
    }

## Functions

### clutter_shader_effect_new ()

    ClutterEffect *
    clutter_shader_effect_new (ClutterShaderType shader_type);

Creates a new ClutterShaderEffect, to be applied to an actor using `clutter_actor_add_effect()`.

The effect will be empty until `clutter_shader_effect_set_shader_source()` is called.

#### Parameters

shader_type | the type of the shader, either `CLUTTER_FRAGMENT_SHADER`, or `CLUTTER_VERTEX_SHADER` |

#### Returns

the newly created ClutterShaderEffect. Use `g_object_unref()` when done.

Since 1.8

### 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));

#### Parameters

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. It also accepts `G_TYPE_DOUBLE` for compatibility with other languages than C.

#### Parameters

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.

#### Parameters

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

#### Parameters

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

#### Parameters

effect | a ClutterShaderEffect |

#### Returns

a pointer to the shader's handle, or `COGL_INVALID_HANDLE`.

[transfer none]

Since 1.4

## Types and Values

### enum ClutterShaderType

The type of GLSL shader program

#### Members

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 {
      gchar * (* get_static_shader_source) (ClutterShaderEffect *effect);
    };

The ClutterShaderEffectClass structure contains only private data

#### Members

`get_static_shader_source` () | Returns the GLSL source code to use for instances of this shader effect. Note that this function is only called once per subclass of ClutterShaderEffect regardless of how many instances are used. It is expected that subclasses will return a copy of a static string from this function. |

Since 1.4

## Property Details

### The `“shader-type”` property

      “shader-type”              ClutterShaderType

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

Flags: Write / Construct Only

Default value: CLUTTER_FRAGMENT_SHADER

Since 1.4

## See Also

ClutterEffect, ClutterOffscreenEffect