2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com>

Bug 1049 - Clutter doesn't support most GLSL uniforms (patch
	by Chris Lord and Neil Roberts)

	* README: Update release notes.

	* clutter/Makefile.am:
	* clutter/clutter-shader-types.[ch]: Add GValue types for
	shader values.

	* clutter/clutter-actor.[ch]: Update the shader API to use
	the newly added GValue support for GLSL shader uniform
	setters.

	* clutter/clutter-shader.[ch]: Add float and integer convenience
	API for single value GLSL uniform setters.

	* clutter/cogl/cogl-shader.h: Add new uniform setters.

	* clutter/cogl/gl/cogl-context.c:
	* clutter/cogl/gl/cogl-context.h:
	* clutter/cogl/gl/cogl-defines.h.in:
	* clutter/cogl/gl/cogl-program.c:
	* clutter/cogl/gl/cogl.c: Update the GL implementation of COGL
	to handle the GLSL uniform setters.

	* clutter/cogl/gles/cogl-gles2-wrapper.c:
	* clutter/cogl/gles/cogl-gles2-wrapper.h:
	* clutter/cogl/gles/cogl-internal.h:
	* clutter/cogl/gles/cogl-program.c: Update the GLES 2.0 implementation
	of COGL to handle the GLSL uniform setters.

	* doc/reference/clutter/clutter-sections.txt:
	* doc/reference/cogl/cogl-sections.txt: Update the documentation.

	* tests/interactive/test-fbo.c:
	* tests/interactive/test-shader.c: Update the shader tests.
This commit is contained in:
Emmanuele Bassi 2008-11-18 15:08:40 +00:00
parent 25d9773e15
commit af0cb47570
23 changed files with 1595 additions and 100 deletions

View File

@ -1,3 +1,42 @@
2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com>
Bug 1049 - Clutter doesn't support most GLSL uniforms (patch
by Chris Lord and Neil Roberts)
* README: Update release notes.
* clutter/Makefile.am:
* clutter/clutter-shader-types.[ch]: Add GValue types for
shader values.
* clutter/clutter-actor.[ch]: Update the shader API to use
the newly added GValue support for GLSL shader uniform
setters.
* clutter/clutter-shader.[ch]: Add float and integer convenience
API for single value GLSL uniform setters.
* clutter/cogl/cogl-shader.h: Add new uniform setters.
* clutter/cogl/gl/cogl-context.c:
* clutter/cogl/gl/cogl-context.h:
* clutter/cogl/gl/cogl-defines.h.in:
* clutter/cogl/gl/cogl-program.c:
* clutter/cogl/gl/cogl.c: Update the GL implementation of COGL
to handle the GLSL uniform setters.
* clutter/cogl/gles/cogl-gles2-wrapper.c:
* clutter/cogl/gles/cogl-gles2-wrapper.h:
* clutter/cogl/gles/cogl-internal.h:
* clutter/cogl/gles/cogl-program.c: Update the GLES 2.0 implementation
of COGL to handle the GLSL uniform setters.
* doc/reference/clutter/clutter-sections.txt:
* doc/reference/cogl/cogl-sections.txt: Update the documentation.
* tests/interactive/test-fbo.c:
* tests/interactive/test-shader.c: Update the shader tests.
2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com> 2008-11-18 Emmanuele Bassi <ebassi@linux.intel.com>
* clutter/clutter-texture.c: * clutter/clutter-texture.c:

6
README
View File

@ -170,6 +170,12 @@ wanting to port to newer releases (See NEWS for general new feature info).
Release Notes for Clutter 1.0 Release Notes for Clutter 1.0
------------------------------- -------------------------------
* The clutter_actor_set_shader_param() function now takes a
GValue, which can be set using the clutter_value_set_shader()
family of functions. The floating point wrapper has been
rename clutter_actor_set_shader_param_float() to match the newly
added clutter_actor_set_shader_param_int().
* The Pango renderer API has been exposed as public API, after * The Pango renderer API has been exposed as public API, after
a full rename from PangoClutter to CoglPango, to avoid namespace a full rename from PangoClutter to CoglPango, to avoid namespace
collisions with upstream Pango. The Pango font map, renderer and collisions with upstream Pango. The Pango font map, renderer and

View File

@ -81,6 +81,7 @@ source_h = \
$(srcdir)/clutter-script.h \ $(srcdir)/clutter-script.h \
$(srcdir)/clutter-scriptable.h \ $(srcdir)/clutter-scriptable.h \
$(srcdir)/clutter-shader.h \ $(srcdir)/clutter-shader.h \
$(srcdir)/clutter-shader-types.h \
$(srcdir)/clutter-stage.h \ $(srcdir)/clutter-stage.h \
$(srcdir)/clutter-stage-manager.h \ $(srcdir)/clutter-stage-manager.h \
$(srcdir)/clutter-texture.h \ $(srcdir)/clutter-texture.h \
@ -171,6 +172,7 @@ source_c = \
clutter-script-parser.c \ clutter-script-parser.c \
clutter-scriptable.c \ clutter-scriptable.c \
clutter-shader.c \ clutter-shader.c \
clutter-shader-types.c \
clutter-stage.c \ clutter-stage.c \
clutter-stage-manager.c \ clutter-stage-manager.c \
clutter-stage-window.c \ clutter-stage-window.c \

View File

@ -7085,28 +7085,22 @@ clutter_actor_box_get_type (void)
/******************************************************************************/ /******************************************************************************/
typedef struct _BoxedFloat BoxedFloat;
struct _BoxedFloat
{
gfloat value;
};
static void
boxed_float_free (gpointer data)
{
if (G_LIKELY (data))
g_slice_free (BoxedFloat, data);
}
struct _ShaderData struct _ShaderData
{ {
ClutterShader *shader; ClutterShader *shader;
GHashTable *float1f_hash; /*< list of values that should be set GHashTable *value_hash; /*< list of GValue's that should be set
* on the shader before each paint cycle * on the shader before each paint cycle
*/ */
}; };
static void
shader_value_free (gpointer data)
{
GValue *var = data;
g_value_unset (var);
g_slice_free (GValue, var);
}
static void static void
destroy_shader_data (ClutterActor *self) destroy_shader_data (ClutterActor *self)
{ {
@ -7122,10 +7116,10 @@ destroy_shader_data (ClutterActor *self)
shader_data->shader = NULL; shader_data->shader = NULL;
} }
if (shader_data->float1f_hash) if (shader_data->value_hash)
{ {
g_hash_table_destroy (shader_data->float1f_hash); g_hash_table_destroy (shader_data->value_hash);
shader_data->float1f_hash = NULL; shader_data->value_hash = NULL;
} }
g_free (shader_data); g_free (shader_data);
@ -7196,10 +7190,10 @@ clutter_actor_set_shader (ClutterActor *self,
if (!shader_data) if (!shader_data)
{ {
actor_priv->shader_data = shader_data = g_new0 (ShaderData, 1); actor_priv->shader_data = shader_data = g_new0 (ShaderData, 1);
shader_data->float1f_hash = shader_data->value_hash =
g_hash_table_new_full (g_str_hash, g_str_equal, g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free,
boxed_float_free); shader_value_free);
} }
if (shader_data->shader) if (shader_data->shader)
{ {
@ -7224,10 +7218,10 @@ set_each_param (gpointer key,
gpointer value, gpointer value,
gpointer user_data) gpointer user_data)
{ {
ClutterShader *shader = CLUTTER_SHADER (user_data); ClutterShader *shader = user_data;
BoxedFloat *box = value; GValue *var = value;
clutter_shader_set_uniform_1f (shader, key, box->value); clutter_shader_set_uniform (shader, (const gchar *)key, var);
} }
static void static void
@ -7252,7 +7246,7 @@ clutter_actor_shader_pre_paint (ClutterActor *actor,
{ {
clutter_shader_set_is_enabled (shader, TRUE); clutter_shader_set_is_enabled (shader, TRUE);
g_hash_table_foreach (shader_data->float1f_hash, set_each_param, shader); g_hash_table_foreach (shader_data->value_hash, set_each_param, shader);
if (!repeat) if (!repeat)
context->shaders = g_slist_prepend (context->shaders, actor); context->shaders = g_slist_prepend (context->shaders, actor);
@ -7301,19 +7295,24 @@ clutter_actor_shader_post_paint (ClutterActor *actor)
* Sets the value for a named parameter of the shader applied * Sets the value for a named parameter of the shader applied
* to @actor. * to @actor.
* *
* Since: 0.6 * Since: 1.0
*/ */
void void
clutter_actor_set_shader_param (ClutterActor *self, clutter_actor_set_shader_param (ClutterActor *self,
const gchar *param, const gchar *param,
gfloat value) const GValue *value)
{ {
ClutterActorPrivate *priv; ClutterActorPrivate *priv;
ShaderData *shader_data; ShaderData *shader_data;
BoxedFloat *box; GValue *var;
g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (CLUTTER_IS_ACTOR (self));
g_return_if_fail (param != NULL); g_return_if_fail (param != NULL);
g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value) ||
CLUTTER_VALUE_HOLDS_SHADER_INT (value) ||
CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value) ||
G_VALUE_HOLDS_FLOAT (value) ||
G_VALUE_HOLDS_INT (value));
priv = self->priv; priv = self->priv;
shader_data = priv->shader_data; shader_data = priv->shader_data;
@ -7321,14 +7320,67 @@ clutter_actor_set_shader_param (ClutterActor *self,
if (!shader_data) if (!shader_data)
return; return;
box = g_slice_new (BoxedFloat); var = g_slice_new0 (GValue);
box->value = value; g_value_init (var, G_VALUE_TYPE (value));
g_hash_table_insert (shader_data->float1f_hash, g_strdup (param), box); g_value_copy (value, var);
g_hash_table_insert (shader_data->value_hash, g_strdup (param), var);
if (CLUTTER_ACTOR_IS_VISIBLE (self)) if (CLUTTER_ACTOR_IS_VISIBLE (self))
clutter_actor_queue_redraw (self); clutter_actor_queue_redraw (self);
} }
/**
* clutter_actor_set_shader_param_float:
* @self: a #ClutterActor
* @param: the name of the parameter
* @value: the value of the parameter
*
* Sets the value for a named float parameter of the shader applied
* to @actor.
*
* Since: 0.8
*/
void
clutter_actor_set_shader_param_float (ClutterActor *self,
const gchar *param,
gfloat value)
{
GValue var = { 0, };
g_value_init (&var, G_TYPE_FLOAT);
g_value_set_float (&var, value);
clutter_actor_set_shader_param (self, param, &var);
g_value_unset (&var);
}
/**
* clutter_actor_set_shader_param_int:
* @self: a #ClutterActor
* @param: the name of the parameter
* @value: the value of the parameter
*
* Sets the value for a named int parameter of the shader applied to
* @actor.
*
* Since: 0.8
*/
void
clutter_actor_set_shader_param_int (ClutterActor *self,
const gchar *param,
gint value)
{
GValue var = { 0, };
g_value_init (&var, G_TYPE_INT);
g_value_set_int (&var, value);
clutter_actor_set_shader_param (self, param, &var);
g_value_unset (&var);
}
/** /**
* clutter_actor_is_rotated: * clutter_actor_is_rotated:
* @self: a #ClutterActor * @self: a #ClutterActor

View File

@ -504,6 +504,12 @@ gboolean clutter_actor_set_shader (ClutterActor
ClutterShader *shader); ClutterShader *shader);
ClutterShader * clutter_actor_get_shader (ClutterActor *self); ClutterShader * clutter_actor_get_shader (ClutterActor *self);
void clutter_actor_set_shader_param (ClutterActor *self, void clutter_actor_set_shader_param (ClutterActor *self,
const gchar *param,
const GValue *value);
void clutter_actor_set_shader_param_int (ClutterActor *self,
const gchar *param,
gint value);
void clutter_actor_set_shader_param_float (ClutterActor *self,
const gchar *param, const gchar *param,
gfloat value); gfloat value);

View File

@ -0,0 +1,563 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
* Chris Lord <chris@openedhand.com>
*
* Copyright (C) 2008 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include "clutter-shader-types.h"
#include "clutter-private.h"
static GTypeInfo shader_float_info = {
0,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL,
};
static GTypeFundamentalInfo shader_float_finfo = { 0, };
static GTypeInfo shader_int_info = {
0,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL,
};
static GTypeFundamentalInfo shader_int_finfo = { 0, };
static GTypeInfo shader_matrix_info = {
0,
NULL,
NULL,
NULL,
NULL,
NULL,
0,
0,
NULL,
NULL,
};
static GTypeFundamentalInfo shader_matrix_finfo = { 0, };
struct _ClutterShaderFloat
{
gint size;
GLfloat value[4];
};
struct _ClutterShaderInt
{
gint size;
COGLint value[4];
};
struct _ClutterShaderMatrix
{
gint size;
GLfloat value[16];
};
static gpointer
clutter_value_peek_pointer (const GValue *value)
{
return value->data[0].v_pointer;
}
/* Float */
static void
clutter_value_init_shader_float (GValue *value)
{
value->data[0].v_pointer = g_slice_new0 (ClutterShaderFloat);
}
static void
clutter_value_free_shader_float (GValue *value)
{
g_slice_free (ClutterShaderFloat, value->data[0].v_pointer);
}
static void
clutter_value_copy_shader_float (const GValue *src,
GValue *dest)
{
dest->data[0].v_pointer =
g_slice_dup (ClutterShaderFloat, src->data[0].v_pointer);
}
static gchar *
clutter_value_collect_shader_float (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint float_count = collect_values[0].v_int;
const float *floats = collect_values[1].v_pointer;
if (!floats)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
clutter_value_init_shader_float (value);
clutter_value_set_shader_float (value, float_count, floats);
return NULL;
}
static gchar *
clutter_value_lcopy_shader_float (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint *float_count = collect_values[0].v_pointer;
float **floats = collect_values[1].v_pointer;
ClutterShaderFloat *shader_float = value->data[0].v_pointer;
if (!float_count || !floats)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
*float_count = shader_float->size;
*floats = g_memdup (shader_float->value, shader_float->size * sizeof (float));
return NULL;
}
static const GTypeValueTable _clutter_shader_float_value_table = {
clutter_value_init_shader_float,
clutter_value_free_shader_float,
clutter_value_copy_shader_float,
clutter_value_peek_pointer,
"ip",
clutter_value_collect_shader_float,
"pp",
clutter_value_lcopy_shader_float
};
GType
clutter_shader_float_get_type (void)
{
static GType _clutter_shader_float_type = 0;
if (G_UNLIKELY (_clutter_shader_float_type == 0))
{
shader_float_info.value_table = & _clutter_shader_float_value_table;
_clutter_shader_float_type =
g_type_register_fundamental (g_type_fundamental_next (),
I_("ClutterShaderFloat"),
&shader_float_info,
&shader_float_finfo, 0);
}
return _clutter_shader_float_type;
}
/* Integer */
static void
clutter_value_init_shader_int (GValue *value)
{
value->data[0].v_pointer = g_slice_new0 (ClutterShaderInt);
}
static void
clutter_value_free_shader_int (GValue *value)
{
g_slice_free (ClutterShaderInt, value->data[0].v_pointer);
}
static void
clutter_value_copy_shader_int (const GValue *src,
GValue *dest)
{
dest->data[0].v_pointer =
g_slice_dup (ClutterShaderInt, src->data[0].v_pointer);
}
static gchar *
clutter_value_collect_shader_int (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint int_count = collect_values[0].v_int;
const COGLint *ints = collect_values[1].v_pointer;
if (!ints)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
clutter_value_init_shader_int (value);
clutter_value_set_shader_int (value, int_count, ints);
return NULL;
}
static gchar *
clutter_value_lcopy_shader_int (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint *int_count = collect_values[0].v_pointer;
COGLint **ints = collect_values[1].v_pointer;
ClutterShaderInt *shader_int = value->data[0].v_pointer;
if (!int_count || !ints)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
*int_count = shader_int->size;
*ints = g_memdup (shader_int->value, shader_int->size * sizeof (COGLint));
return NULL;
}
static const GTypeValueTable _clutter_shader_int_value_table = {
clutter_value_init_shader_int,
clutter_value_free_shader_int,
clutter_value_copy_shader_int,
clutter_value_peek_pointer,
"ip",
clutter_value_collect_shader_int,
"pp",
clutter_value_lcopy_shader_int
};
GType
clutter_shader_int_get_type (void)
{
static GType _clutter_shader_int_type = 0;
if (G_UNLIKELY (_clutter_shader_int_type == 0))
{
shader_int_info.value_table = & _clutter_shader_int_value_table;
_clutter_shader_int_type =
g_type_register_fundamental (g_type_fundamental_next (),
I_("ClutterShaderInt"),
&shader_int_info,
&shader_int_finfo, 0);
}
return _clutter_shader_int_type;
}
/* Matrix */
static void
clutter_value_init_shader_matrix (GValue *value)
{
value->data[0].v_pointer = g_slice_new0 (ClutterShaderMatrix);
}
static void
clutter_value_free_shader_matrix (GValue *value)
{
g_slice_free (ClutterShaderMatrix, value->data[0].v_pointer);
}
static void
clutter_value_copy_shader_matrix (const GValue *src,
GValue *dest)
{
dest->data[0].v_pointer =
g_slice_dup (ClutterShaderMatrix, src->data[0].v_pointer);
}
static gchar *
clutter_value_collect_shader_matrix (GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint float_count = collect_values[0].v_int;
const float *floats = collect_values[1].v_pointer;
if (!floats)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
clutter_value_init_shader_matrix (value);
clutter_value_set_shader_matrix (value, float_count, floats);
return NULL;
}
static gchar *
clutter_value_lcopy_shader_matrix (const GValue *value,
guint n_collect_values,
GTypeCValue *collect_values,
guint collect_flags)
{
gint *float_count = collect_values[0].v_pointer;
float **floats = collect_values[1].v_pointer;
ClutterShaderFloat *shader_float = value->data[0].v_pointer;
if (!float_count || !floats)
return g_strdup_printf ("value location for `%s' passed as NULL",
G_VALUE_TYPE_NAME (value));
*float_count = shader_float->size;
*floats = g_memdup (shader_float->value,
shader_float->size * shader_float->size * sizeof (float));
return NULL;
}
static const GTypeValueTable _clutter_shader_matrix_value_table = {
clutter_value_init_shader_matrix,
clutter_value_free_shader_matrix,
clutter_value_copy_shader_matrix,
clutter_value_peek_pointer,
"ip",
clutter_value_collect_shader_matrix,
"pp",
clutter_value_lcopy_shader_matrix
};
GType
clutter_shader_matrix_get_type (void)
{
static GType _clutter_shader_matrix_type = 0;
if (G_UNLIKELY (_clutter_shader_matrix_type == 0))
{
shader_matrix_info.value_table = & _clutter_shader_matrix_value_table;
_clutter_shader_matrix_type =
g_type_register_fundamental (g_type_fundamental_next (),
I_("ClutterShaderMatrix"),
&shader_matrix_info,
&shader_matrix_finfo, 0);
}
return _clutter_shader_matrix_type;
}
/* Utility functions */
/**
* clutter_value_set_shader_float:
* @value: a #GValue
* @size: number of floating point values in @floats
* @floats: an array of floating point values
*
* Sets @floats as the contents of @value. The passed #GValue
* must have been initialized using %CLUTTER_TYPE_SHADER_FLOAT.
*
* Since: 0.8
*/
void
clutter_value_set_shader_float (GValue *value,
gint size,
const gfloat *floats)
{
ClutterShaderFloat *shader_float;
gint i;
g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value));
shader_float = value->data[0].v_pointer;
shader_float->size = size;
for (i = 0; i < size; i++)
shader_float->value[i] = floats[i];
}
/**
* clutter_value_set_shader_int:
* @value: a #GValue
* @size: number of integer values in @ints
* @ints: an array of integer values
*
* Sets @ints as the contents of @value. The passed #GValue
* must have been initialized using %CLUTTER_TYPE_SHADER_INT.
*
* Since: 0.8
*/
void
clutter_value_set_shader_int (GValue *value,
gint size,
const gint *ints)
{
ClutterShaderInt *shader_int;
gint i;
g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_INT (value));
shader_int = value->data[0].v_pointer;
shader_int->size = size;
for (i = 0; i < size; i++)
shader_int->value[i] = ints[i];
}
/**
* clutter_value_set_shader_matrix:
* @value: a #GValue
* @size: number of floating point values in @floats
* @matrix: a matrix of floating point values
*
* Sets @matrix as the contents of @value. The passed #GValue
* must have been initialized using %CLUTTER_TYPE_SHADER_MATRIX.
*
* Since: 0.8
*/
void
clutter_value_set_shader_matrix (GValue *value,
gint size,
const gfloat *matrix)
{
ClutterShaderMatrix *shader_matrix;
gint i;
g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value));
shader_matrix = value->data[0].v_pointer;
shader_matrix->size = size;
for (i = 0; i < size * size; i++)
shader_matrix->value[i] = matrix[i];
}
/**
* clutter_value_get_shader_float:
* @value: a #GValue
* @length: return location for the number of returned floating
* point values, or %NULL
*
* Retrieves the list of floating point values stored inside
* the passed #GValue. @value must have been initialized with
* %CLUTTER_TYPE_SHADER_FLOAT.
*
* Return value: the pointer to a list of floating point values.
* The returned value is owned by the #GValue and should never
* be modified or freed.
*
* Since: 0.8
*/
G_CONST_RETURN gfloat *
clutter_value_get_shader_float (const GValue *value,
gsize *length)
{
ClutterShaderFloat *shader_float;
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value), 0);
shader_float = value->data[0].v_pointer;
if (length)
*length = shader_float->size;
return shader_float->value;
}
/**
* clutter_value_get_shader_int:
* @value: a #GValue
* @length: return location for the number of returned integer
* values, or %NULL
*
* Retrieves the list of integer values stored inside the passed
* #GValue. @value must have been initialized with
* %CLUTTER_TYPE_SHADER_INT.
*
* Return value: the pointer to a list of integer values.
* The returned value is owned by the #GValue and should never
* be modified or freed.
*
* Since: 0.8
*/
G_CONST_RETURN COGLint *
clutter_value_get_shader_int (const GValue *value,
gsize *length)
{
ClutterShaderInt *shader_int;
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_INT (value), 0);
shader_int = value->data[0].v_pointer;
if (length)
*length = shader_int->size;
return shader_int->value;
}
/**
* clutter_value_get_shader_matrix:
* @value: a #GValue
* @length: return location for the number of returned floating
* point values, or %NULL
*
* Retrieves a matrix of floating point values stored inside
* the passed #GValue. @value must have been initialized with
* %CLUTTER_TYPE_SHADER_MATRIX.
*
* Return value: the pointer to a matrix of floating point values.
* The returned value is owned by the #GValue and should never
* be modified or freed.
*
* Since: 0.8
*/
G_CONST_RETURN gfloat *
clutter_value_get_shader_matrix (const GValue *value,
gsize *length)
{
ClutterShaderMatrix *shader_matrix;
g_return_val_if_fail (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value), 0);
shader_matrix = value->data[0].v_pointer;
if (length)
*length = shader_matrix->size;
return shader_matrix->value;
}

View File

@ -0,0 +1,96 @@
/*
* Clutter.
*
* An OpenGL based 'interactive canvas' library.
*
* Authored By Matthew Allum <mallum@openedhand.com>
*
* Copyright (C) 2008 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION)
#error "Only <clutter/clutter.h> can be included directly."
#endif
#ifndef __CLUTTER_SHADER_TYPES_H__
#define __CLUTTER_SHADER_TYPES_H__
#include <glib-object.h>
#include <cogl/cogl.h>
G_BEGIN_DECLS
#define CLUTTER_TYPE_SHADER_FLOAT (clutter_shader_float_get_type ())
#define CLUTTER_TYPE_SHADER_INT (clutter_shader_int_get_type ())
#define CLUTTER_TYPE_SHADER_MATRIX (clutter_shader_matrix_get_type ())
typedef struct _ClutterShaderFloat ClutterShaderFloat;
typedef struct _ClutterShaderInt ClutterShaderInt;
typedef struct _ClutterShaderMatrix ClutterShaderMatrix;
/**
* CLUTTER_VALUE_HOLDS_SHADER_FLOAT:
* @x: a #GValue
*
* Evaluates to %TRUE if @x holds a #ClutterShaderFloat.
*
* Since: 1.0
*/
#define CLUTTER_VALUE_HOLDS_SHADER_FLOAT(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_FLOAT))
/**
* CLUTTER_VALUE_HOLDS_SHADER_INT:
* @x: a #GValue
*
* Evaluates to %TRUE if @x holds a #ClutterShaderInt.
*
* Since: 1.0
*/
#define CLUTTER_VALUE_HOLDS_SHADER_INT(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_INT))
/**
* CLUTTER_VALUE_HOLDS_SHADER_MATRIX:
* @x: a #GValue
*
* Evaluates to %TRUE if @x holds a #ClutterShaderMatrix.
*
* Since: 1.0
*/
#define CLUTTER_VALUE_HOLDS_SHADER_MATRIX(x) (G_VALUE_HOLDS ((x), CLUTTER_TYPE_SHADER_MATRIX))
GType clutter_shader_float_get_type (void) G_GNUC_CONST;
GType clutter_shader_int_get_type (void) G_GNUC_CONST;
GType clutter_shader_matrix_get_type (void) G_GNUC_CONST;
void clutter_value_set_shader_float (GValue *value,
gint size,
const gfloat *floats);
void clutter_value_set_shader_int (GValue *value,
gint size,
const gint *ints);
void clutter_value_set_shader_matrix (GValue *value,
gint size,
const gfloat *matrix);
G_CONST_RETURN gfloat * clutter_value_get_shader_float (const GValue *value,
gsize *length);
G_CONST_RETURN COGLint *clutter_value_get_shader_int (const GValue *value,
gsize *length);
G_CONST_RETURN GLfloat *clutter_value_get_shader_matrix (const GValue *value,
gsize *length);
G_END_DECLS
#endif /* __CLUTTER_SHADER_TYPES_H__ */

View File

@ -70,7 +70,6 @@ struct _ClutterShaderPrivate
{ {
guint compiled : 1; /* Shader is bound to the GL context */ guint compiled : 1; /* Shader is bound to the GL context */
guint is_enabled : 1; guint is_enabled : 1;
guint vertex_is_glsl : 1; guint vertex_is_glsl : 1;
guint fragment_is_glsl : 1; guint fragment_is_glsl : 1;
@ -95,9 +94,6 @@ enum
G_DEFINE_TYPE (ClutterShader, clutter_shader, G_TYPE_OBJECT); G_DEFINE_TYPE (ClutterShader, clutter_shader, G_TYPE_OBJECT);
G_CONST_RETURN gchar *clutter_shader_get_source (ClutterShader *shader,
ClutterShaderType type);
static void static void
clutter_shader_finalize (GObject *object) clutter_shader_finalize (GObject *object)
{ {
@ -193,7 +189,6 @@ clutter_shader_constructor (GType type,
return object; return object;
} }
static void static void
clutter_shader_class_init (ClutterShaderClass *klass) clutter_shader_class_init (ClutterShaderClass *klass)
{ {
@ -341,8 +336,8 @@ clutter_shader_set_fragment_source (ClutterShader *shader,
g_free (priv->fragment_source); g_free (priv->fragment_source);
CLUTTER_NOTE (SHADER, "setting fragment shader (GLSL:%s, len:%" CLUTTER_NOTE (SHADER,
G_GSSIZE_FORMAT ")", "setting fragment shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
is_glsl ? "yes" : "no", is_glsl ? "yes" : "no",
length); length);
@ -387,8 +382,8 @@ clutter_shader_set_vertex_source (ClutterShader *shader,
g_free (priv->vertex_source); g_free (priv->vertex_source);
CLUTTER_NOTE (SHADER, "setting vertex shader (GLSL:%s, len:%" CLUTTER_NOTE (SHADER,
G_GSSIZE_FORMAT ")", "setting vertex shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
is_glsl ? "yes" : "no", is_glsl ? "yes" : "no",
length); length);
@ -668,6 +663,7 @@ clutter_shader_set_uniform_1f (ClutterShader *shader,
GLfloat foo = value; GLfloat foo = value;
g_return_if_fail (CLUTTER_IS_SHADER (shader)); g_return_if_fail (CLUTTER_IS_SHADER (shader));
g_return_if_fail (name != NULL);
priv = shader->priv; priv = shader->priv;
@ -675,13 +671,83 @@ clutter_shader_set_uniform_1f (ClutterShader *shader,
cogl_program_uniform_1f (location, foo); cogl_program_uniform_1f (location, foo);
} }
/**
* clutter_shader_set_uniform:
* @shader: a #ClutterShader.
* @name: name of uniform in GLSL shader program to set.
* @value: a #ClutterShaderFloat, #ClutterShaderInt or #ClutterShaderMatrix
* #GValue.
*
* Sets a user configurable variable in the GLSL shader programs attached to
* a #ClutterShader.
*
* Since: 1.0
*/
void
clutter_shader_set_uniform (ClutterShader *shader,
const gchar *name,
const GValue *value)
{
ClutterShaderPrivate *priv;
GLint location = 0;
gsize size;
g_return_if_fail (CLUTTER_IS_SHADER (shader));
g_return_if_fail (name != NULL);
g_return_if_fail (value != NULL);
g_return_if_fail (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value) ||
CLUTTER_VALUE_HOLDS_SHADER_INT (value) ||
CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value) ||
G_VALUE_HOLDS_FLOAT (value) ||
G_VALUE_HOLDS_INT (value));
priv = shader->priv;
g_return_if_fail (priv->program != COGL_INVALID_HANDLE);
location = cogl_program_get_uniform_location (priv->program, name);
if (CLUTTER_VALUE_HOLDS_SHADER_FLOAT (value))
{
const GLfloat *floats;
floats = clutter_value_get_shader_float (value, &size);
cogl_program_uniform_float (location, size, 1, floats);
}
else if (CLUTTER_VALUE_HOLDS_SHADER_INT (value))
{
const COGLint *ints;
ints = clutter_value_get_shader_int (value, &size);
cogl_program_uniform_int (location, size, 1, ints);
}
else if (CLUTTER_VALUE_HOLDS_SHADER_MATRIX (value))
{
const GLfloat *matrix;
matrix = clutter_value_get_shader_matrix (value, &size);
cogl_program_uniform_matrix (location, size, 1, FALSE, matrix);
}
else if (G_VALUE_HOLDS_FLOAT (value))
{
GLfloat float_val = g_value_get_float (value);
cogl_program_uniform_float (location, 1, 1, &float_val);
}
else if (G_VALUE_HOLDS_INT (value))
{
COGLint int_val = g_value_get_int (value);
cogl_program_uniform_int (location, 1, 1, &int_val);
}
else
g_assert_not_reached ();
}
/* /*
* _clutter_shader_release_all: * _clutter_shader_release_all:
* *
* Iterate through all #ClutterShaders and tell them to release GL context * Iterate through all #ClutterShaders and tell them to release GL context
* related sources. * related sources.
*
* Since: 0.6
*/ */
void void
_clutter_shader_release_all (void) _clutter_shader_release_all (void)
@ -730,6 +796,57 @@ clutter_shader_get_vertex_source (ClutterShader *shader)
return shader->priv->vertex_source; return shader->priv->vertex_source;
} }
/**
* clutter_shader_get_cogl_program:
* @shader: a #ClutterShader
*
* Retrieves the underlying #CoglHandle for the shader program.
*
* Return value: A #CoglHandle for the shader program, or %NULL
*
* Since: 1.0
*/
CoglHandle
clutter_shader_get_cogl_program (ClutterShader *shader)
{
g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);
return shader->priv->program;
}
/**
* clutter_shader_get_cogl_fragment_shader:
* @shader: a #ClutterShader
*
* Retrieves the underlying #CoglHandle for the fragment shader.
*
* Return value: A #CoglHandle for the fragment shader, or %NULL
*
* Since: 1.0
*/
CoglHandle
clutter_shader_get_cogl_fragment_shader (ClutterShader *shader)
{
g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);
return shader->priv->fragment_shader;
}
/**
* clutter_shader_get_cogl_vertex_shader:
* @shader: a #ClutterShader
*
* Retrieves the underlying #CoglHandle for the vertex shader.
*
* Return value: A #CoglHandle for the vertex shader, or %NULL
*
* Since: 1.0
*/
CoglHandle
clutter_shader_get_cogl_vertex_shader (ClutterShader *shader)
{
g_return_val_if_fail (CLUTTER_IS_SHADER (shader), NULL);
return shader->priv->vertex_shader;
}
GQuark GQuark
clutter_shader_error_quark (void) clutter_shader_error_quark (void)
{ {

View File

@ -29,7 +29,7 @@
#ifndef __CLUTTER_SHADER_H__ #ifndef __CLUTTER_SHADER_H__
#define __CLUTTER_SHADER_H__ #define __CLUTTER_SHADER_H__
#include <glib-object.h> #include <clutter/clutter-shader-types.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -75,34 +75,45 @@ struct _ClutterShaderClass
GObjectClass parent_class; GObjectClass parent_class;
}; };
GQuark clutter_shader_error_quark (void); GQuark clutter_shader_error_quark (void);
GType clutter_shader_get_type (void) G_GNUC_CONST; GType clutter_shader_get_type (void) G_GNUC_CONST;
ClutterShader * clutter_shader_new (void); ClutterShader * clutter_shader_new (void);
void clutter_shader_set_is_enabled (ClutterShader *shader, void clutter_shader_set_is_enabled (ClutterShader *shader,
gboolean enabled); gboolean enabled);
gboolean clutter_shader_get_is_enabled (ClutterShader *shader); gboolean clutter_shader_get_is_enabled (ClutterShader *shader);
gboolean clutter_shader_compile (ClutterShader *shader, gboolean clutter_shader_compile (ClutterShader *shader,
GError **error); GError **error);
void clutter_shader_release (ClutterShader *shader); void clutter_shader_release (ClutterShader *shader);
gboolean clutter_shader_is_compiled (ClutterShader *shader); gboolean clutter_shader_is_compiled (ClutterShader *shader);
void clutter_shader_set_vertex_source (ClutterShader *shader, void clutter_shader_set_vertex_source (ClutterShader *shader,
const gchar *data, const gchar *data,
gssize length); gssize length);
void clutter_shader_set_fragment_source (ClutterShader *shader, void clutter_shader_set_fragment_source (ClutterShader *shader,
const gchar *data, const gchar *data,
gssize length); gssize length);
G_CONST_RETURN gchar *clutter_shader_get_vertex_source (ClutterShader *shader); G_CONST_RETURN gchar *clutter_shader_get_vertex_source (ClutterShader *shader);
G_CONST_RETURN gchar *clutter_shader_get_fragment_source (ClutterShader *shader); G_CONST_RETURN gchar *clutter_shader_get_fragment_source (ClutterShader *shader);
void clutter_shader_set_uniform_1f (ClutterShader *shader, void clutter_shader_set_uniform (ClutterShader *shader,
const gchar *name, const gchar *name,
gfloat value); const GValue *value);
/* should be private and internal */
CoglHandle clutter_shader_get_cogl_program (ClutterShader *shader);
CoglHandle clutter_shader_get_cogl_fragment_shader (ClutterShader *shader);
CoglHandle clutter_shader_get_cogl_vertex_shader (ClutterShader *shader);
#ifndef CLUTTER_DISABLE_DEPRECATED
void clutter_shader_set_uniform_1f (ClutterShader *shader,
const gchar *name,
gfloat value);
#endif
/* private */
void _clutter_shader_release_all (void); void _clutter_shader_release_all (void);
G_END_DECLS G_END_DECLS

View File

@ -188,10 +188,10 @@ void cogl_program_link (CoglHandle handle);
/** /**
* cogl_program_use: * cogl_program_use:
* @handle: a #CoglHandle for a shader program or COGL_INVALID_HANDLE. * @handle: a #CoglHandle for a shader program or %COGL_INVALID_HANDLE.
* *
* Activate a specific shader program replacing that part of the GL * Activate a specific shader program replacing that part of the GL
* rendering pipeline, if passed in COGL_INVALID_HANDLE the default * rendering pipeline, if passed in %COGL_INVALID_HANDLE the default
* behavior of GL is reinstated. * behavior of GL is reinstated.
*/ */
void cogl_program_use (CoglHandle handle); void cogl_program_use (CoglHandle handle);
@ -201,29 +201,77 @@ void cogl_program_use (CoglHandle handle);
* @handle: a #CoglHandle for a shader program. * @handle: a #CoglHandle for a shader program.
* @uniform_name: the name of a uniform. * @uniform_name: the name of a uniform.
* *
* Retrieve the location (offset) of a uniform variable in a shader program, a * Retrieve the location (offset) of a uniform variable in a shader program,
* uniform is a variable that is constant for all vertices/fragments for a * a uniform is a variable that is constant for all vertices/fragments for a
* shader object and is possible to modify as an external parameter. * shader object and is possible to modify as an external parameter.
* *
* Returns: the offset of a uniform in a specified program, this uniform can be * Return value: the offset of a uniform in a specified program.
* set using #cogl_program_uniform_1f when the program is in use. * This uniform can be set using cogl_program_uniform_1f() when the
* program is in use.
*/ */
COGLint cogl_program_get_uniform_location COGLint cogl_program_get_uniform_location
(CoglHandle handle, (CoglHandle handle,
const gchar *uniform_name); const gchar *uniform_name);
/** /**
* cogl_program_uniform_1f: * cogl_program_uniform_1f:
* @uniform_no: the unform to set. * @uniform_no: the unform to set.
* @value: the new value of the uniform. * @value: the new value of the uniform.
* *
* Changes the value of a uniform in the currently used (see #cogl_program_use) * Changes the value of a uniform in the currently used (see
* shader program. * cogl_program_use()) shader program.
*/ */
void cogl_program_uniform_1f (COGLint uniform_no, void cogl_program_uniform_1f (COGLint uniform_no,
gfloat value); gfloat value);
/**
* cogl_program_uniform_float:
* @uniform_no: the uniform to set.
* @size: Size of float vector.
* @count: Size of array of uniforms.
* @value: the new value of the uniform.
*
* Changes the value of a float vector uniform, or uniform array in the
* currently used (see #cogl_program_use) shader program.
*/
void cogl_program_uniform_float (COGLint uniform_no,
gint size,
gint count,
const GLfloat *value);
/**
* cogl_program_uniform_int:
* @uniform_no: the uniform to set.
* @size: Size of int vector.
* @count: Size of array of uniforms.
* @value: the new value of the uniform.
*
* Changes the value of a int vector uniform, or uniform array in the
* currently used (see cogl_program_use()) shader program.
*/
void cogl_program_uniform_int (COGLint uniform_no,
gint size,
gint count,
const COGLint *value);
/**
* cogl_program_uniform_matrix:
* @uniform_no: the uniform to set.
* @size: Size of matrix.
* @count: Size of array of uniforms.
* @transpose: Whether to transpose the matrix when setting the uniform.
* @value: the new value of the uniform.
*
* Changes the value of a matrix uniform, or uniform array in the
* currently used (see cogl_program_use()) shader program. The @size
* parameter is used to determine the square size of the matrix.
*/
void cogl_program_uniform_matrix (COGLint uniform_no,
gint size,
gint count,
gboolean transpose,
const GLfloat *value);
G_END_DECLS G_END_DECLS
#endif /* __COGL_SHADER_H__ */ #endif /* __COGL_SHADER_H__ */

View File

@ -94,6 +94,24 @@ cogl_create_context ()
_context->pf_glGetInfoLogARB = NULL; _context->pf_glGetInfoLogARB = NULL;
_context->pf_glGetObjectParameterivARB = NULL; _context->pf_glGetObjectParameterivARB = NULL;
_context->pf_glUniform1fARB = NULL; _context->pf_glUniform1fARB = NULL;
_context->pf_glUniform2fARB = NULL;
_context->pf_glUniform3fARB = NULL;
_context->pf_glUniform4fARB = NULL;
_context->pf_glUniform1fvARB = NULL;
_context->pf_glUniform2fvARB = NULL;
_context->pf_glUniform3fvARB = NULL;
_context->pf_glUniform4fvARB = NULL;
_context->pf_glUniform1iARB = NULL;
_context->pf_glUniform2iARB = NULL;
_context->pf_glUniform3iARB = NULL;
_context->pf_glUniform4iARB = NULL;
_context->pf_glUniform1ivARB = NULL;
_context->pf_glUniform2ivARB = NULL;
_context->pf_glUniform3ivARB = NULL;
_context->pf_glUniform4ivARB = NULL;
_context->pf_glUniformMatrix2fvARB = NULL;
_context->pf_glUniformMatrix3fvARB = NULL;
_context->pf_glUniformMatrix4fvARB = NULL;
/* Init OpenGL state */ /* Init OpenGL state */
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) ); GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );

View File

@ -96,7 +96,7 @@ typedef struct
COGL_PFNGLDELETEOBJECTARBPROC pf_glDeleteObjectARB; COGL_PFNGLDELETEOBJECTARBPROC pf_glDeleteObjectARB;
COGL_PFNGLGETINFOLOGARBPROC pf_glGetInfoLogARB; COGL_PFNGLGETINFOLOGARBPROC pf_glGetInfoLogARB;
COGL_PFNGLGETOBJECTPARAMETERIVARBPROC pf_glGetObjectParameterivARB; COGL_PFNGLGETOBJECTPARAMETERIVARBPROC pf_glGetObjectParameterivARB;
COGL_PFNGLUNIFORM1FARBPROC pf_glUniform1fARB;
COGL_PFNGLVERTEXATTRIBPOINTERARBPROC pf_glVertexAttribPointerARB; COGL_PFNGLVERTEXATTRIBPOINTERARBPROC pf_glVertexAttribPointerARB;
COGL_PFNGLENABLEVERTEXATTRIBARRAYARBPROC pf_glEnableVertexAttribArrayARB; COGL_PFNGLENABLEVERTEXATTRIBARRAYARBPROC pf_glEnableVertexAttribArrayARB;
COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC pf_glDisableVertexAttribArrayARB; COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC pf_glDisableVertexAttribArrayARB;
@ -109,6 +109,25 @@ typedef struct
COGL_PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB; COGL_PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB;
COGL_PFNGLDELETEBUFFERSARBPROC pf_glDeleteBuffersARB; COGL_PFNGLDELETEBUFFERSARBPROC pf_glDeleteBuffersARB;
COGL_PFNGLUNIFORM1FARBPROC pf_glUniform1fARB;
COGL_PFNGLUNIFORM2FARBPROC pf_glUniform2fARB;
COGL_PFNGLUNIFORM3FARBPROC pf_glUniform3fARB;
COGL_PFNGLUNIFORM4FARBPROC pf_glUniform4fARB;
COGL_PFNGLUNIFORM1FVARBPROC pf_glUniform1fvARB;
COGL_PFNGLUNIFORM2FVARBPROC pf_glUniform2fvARB;
COGL_PFNGLUNIFORM3FVARBPROC pf_glUniform3fvARB;
COGL_PFNGLUNIFORM4FVARBPROC pf_glUniform4fvARB;
COGL_PFNGLUNIFORM1IARBPROC pf_glUniform1iARB;
COGL_PFNGLUNIFORM2IARBPROC pf_glUniform2iARB;
COGL_PFNGLUNIFORM3IARBPROC pf_glUniform3iARB;
COGL_PFNGLUNIFORM4IARBPROC pf_glUniform4iARB;
COGL_PFNGLUNIFORM1IVARBPROC pf_glUniform1ivARB;
COGL_PFNGLUNIFORM2IVARBPROC pf_glUniform2ivARB;
COGL_PFNGLUNIFORM3IVARBPROC pf_glUniform3ivARB;
COGL_PFNGLUNIFORM4IVARBPROC pf_glUniform4ivARB;
COGL_PFNGLUNIFORMMATRIX2FVARBPROC pf_glUniformMatrix2fvARB;
COGL_PFNGLUNIFORMMATRIX3FVARBPROC pf_glUniformMatrix3fvARB;
COGL_PFNGLUNIFORMMATRIX4FVARBPROC pf_glUniformMatrix4fvARB;
} CoglContext; } CoglContext;
CoglContext * CoglContext *

View File

@ -837,11 +837,6 @@ typedef void
GLenum pname, GLenum pname,
GLint *params); GLint *params);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM1FARBPROC)
(GLint location,
GLfloat v0);
typedef void typedef void
(APIENTRYP COGL_PFNGLVERTEXATTRIBPOINTERARBPROC) (APIENTRYP COGL_PFNGLVERTEXATTRIBPOINTERARBPROC)
(GLuint index, (GLuint index,
@ -897,6 +892,127 @@ typedef void
(GLsizei n, (GLsizei n,
const GLuint *buffers); const GLuint *buffers);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM1FARBPROC)
(GLint location,
GLfloat v0);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM2FARBPROC)
(GLint location,
GLfloat v0,
GLfloat v1);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM3FARBPROC)
(GLint location,
GLfloat v0,
GLfloat v1,
GLfloat v2);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM4FARBPROC)
(GLint location,
GLfloat v0,
GLfloat v1,
GLfloat v2,
GLfloat v3);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM1FVARBPROC)
(GLint location,
GLsizei count,
const GLfloat * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM2FVARBPROC)
(GLint location,
GLsizei count,
const GLfloat * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM3FVARBPROC)
(GLint location,
GLsizei count,
const GLfloat * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM4FVARBPROC)
(GLint location,
GLsizei count,
const GLfloat * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM1IARBPROC)
(GLint location,
GLint v0);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM2IARBPROC)
(GLint location,
GLint v0,
GLint v1);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM3IARBPROC)
(GLint location,
GLint v0,
GLint v1,
GLint v2);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM4IARBPROC)
(GLint location,
GLint v0,
GLint v1,
GLint v2,
GLint v3);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM1IVARBPROC)
(GLint location,
GLsizei count,
const GLint * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM2IVARBPROC)
(GLint location,
GLsizei count,
const GLint * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM3IVARBPROC)
(GLint location,
GLsizei count,
const GLint * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORM4IVARBPROC)
(GLint location,
GLsizei count,
const GLint * value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORMMATRIX2FVARBPROC)
(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORMMATRIX3FVARBPROC)
(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value);
typedef void
(APIENTRYP COGL_PFNGLUNIFORMMATRIX4FVARBPROC)
(GLint location,
GLsizei count,
GLboolean transpose,
const GLfloat *value);
G_END_DECLS G_END_DECLS
#endif #endif

View File

@ -43,6 +43,24 @@
#define glLinkProgramARB ctx->pf_glLinkProgramARB #define glLinkProgramARB ctx->pf_glLinkProgramARB
#define glGetUniformLocationARB ctx->pf_glGetUniformLocationARB #define glGetUniformLocationARB ctx->pf_glGetUniformLocationARB
#define glUniform1fARB ctx->pf_glUniform1fARB #define glUniform1fARB ctx->pf_glUniform1fARB
#define glUniform2fARB ctx->pf_glUniform2fARB
#define glUniform3fARB ctx->pf_glUniform3fARB
#define glUniform4fARB ctx->pf_glUniform4fARB
#define glUniform1fvARB ctx->pf_glUniform1fvARB
#define glUniform2fvARB ctx->pf_glUniform2fvARB
#define glUniform3fvARB ctx->pf_glUniform3fvARB
#define glUniform4fvARB ctx->pf_glUniform4fvARB
#define glUniform1iARB ctx->pf_glUniform1iARB
#define glUniform2iARB ctx->pf_glUniform2iARB
#define glUniform3iARB ctx->pf_glUniform3iARB
#define glUniform4iARB ctx->pf_glUniform4iARB
#define glUniform1ivARB ctx->pf_glUniform1ivARB
#define glUniform2ivARB ctx->pf_glUniform2ivARB
#define glUniform3ivARB ctx->pf_glUniform3ivARB
#define glUniform4ivARB ctx->pf_glUniform4ivARB
#define glUniformMatrix2fvARB ctx->pf_glUniformMatrix2fvARB
#define glUniformMatrix3fvARB ctx->pf_glUniformMatrix3fvARB
#define glUniformMatrix4fvARB ctx->pf_glUniformMatrix4fvARB
#define glDeleteObjectARB ctx->pf_glDeleteObjectARB #define glDeleteObjectARB ctx->pf_glDeleteObjectARB
static void _cogl_program_free (CoglProgram *program); static void _cogl_program_free (CoglProgram *program);
@ -121,7 +139,7 @@ cogl_program_use (CoglHandle handle)
{ {
program = _cogl_program_pointer_from_handle (handle); program = _cogl_program_pointer_from_handle (handle);
gl_handle = program->gl_handle; gl_handle = program->gl_handle;
} }
glUseProgramObjectARB (gl_handle); glUseProgramObjectARB (gl_handle);
} }
@ -148,3 +166,82 @@ cogl_program_uniform_1f (COGLint uniform_no,
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
glUniform1fARB (uniform_no, value); glUniform1fARB (uniform_no, value);
} }
void
cogl_program_uniform_float (COGLint uniform_no,
gint size,
gint count,
const GLfloat *value)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
switch (size)
{
case 1:
glUniform1fvARB (uniform_no, count, value);
break;
case 2:
glUniform2fvARB (uniform_no, count, value);
break;
case 3:
glUniform3fvARB (uniform_no, count, value);
break;
case 4:
glUniform4fvARB (uniform_no, count, value);
break;
default:
g_warning ("%s called with invalid size parameter", G_STRFUNC);
}
}
void
cogl_program_uniform_int (COGLint uniform_no,
gint size,
gint count,
const COGLint *value)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
switch (size)
{
case 1:
glUniform1ivARB (uniform_no, count, value);
break;
case 2:
glUniform2ivARB (uniform_no, count, value);
break;
case 3:
glUniform3ivARB (uniform_no, count, value);
break;
case 4:
glUniform4ivARB (uniform_no, count, value);
break;
default:
g_warning ("%s called with invalid size parameter", G_STRFUNC);
}
}
void
cogl_program_uniform_matrix (COGLint uniform_no,
gint size,
gint count,
gboolean transpose,
const GLfloat *value)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
switch (size)
{
case 2 :
glUniformMatrix2fvARB (uniform_no, count, transpose, value);
break;
case 3 :
glUniformMatrix3fvARB (uniform_no, count, transpose, value);
break;
case 4 :
glUniformMatrix4fvARB (uniform_no, count, transpose, value);
break;
default :
g_warning ("%s called with invalid size parameter", G_STRFUNC);
}
}

View File

@ -1028,6 +1028,78 @@ _cogl_features_init ()
(COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)
cogl_get_proc_address ("glDisableVertexAttribArrayARB"); cogl_get_proc_address ("glDisableVertexAttribArrayARB");
ctx->pf_glUniform2fARB =
(COGL_PFNGLUNIFORM2FARBPROC)
cogl_get_proc_address ("glUniform2fARB");
ctx->pf_glUniform3fARB =
(COGL_PFNGLUNIFORM3FARBPROC)
cogl_get_proc_address ("glUniform3fARB");
ctx->pf_glUniform4fARB =
(COGL_PFNGLUNIFORM4FARBPROC)
cogl_get_proc_address ("glUniform4fARB");
ctx->pf_glUniform1fvARB =
(COGL_PFNGLUNIFORM1FVARBPROC)
cogl_get_proc_address ("glUniform1fvARB");
ctx->pf_glUniform2fvARB =
(COGL_PFNGLUNIFORM2FVARBPROC)
cogl_get_proc_address ("glUniform2fvARB");
ctx->pf_glUniform3fvARB =
(COGL_PFNGLUNIFORM3FVARBPROC)
cogl_get_proc_address ("glUniform3fvARB");
ctx->pf_glUniform4fvARB =
(COGL_PFNGLUNIFORM4FVARBPROC)
cogl_get_proc_address ("glUniform4fvARB");
ctx->pf_glUniform1iARB =
(COGL_PFNGLUNIFORM1IARBPROC)
cogl_get_proc_address ("glUniform1iARB");
ctx->pf_glUniform2iARB =
(COGL_PFNGLUNIFORM2IARBPROC)
cogl_get_proc_address ("glUniform2iARB");
ctx->pf_glUniform3iARB =
(COGL_PFNGLUNIFORM3IARBPROC)
cogl_get_proc_address ("glUniform3iARB");
ctx->pf_glUniform4iARB =
(COGL_PFNGLUNIFORM4IARBPROC)
cogl_get_proc_address ("glUniform4iARB");
ctx->pf_glUniform1ivARB =
(COGL_PFNGLUNIFORM1IVARBPROC)
cogl_get_proc_address ("glUniform1ivARB");
ctx->pf_glUniform2ivARB =
(COGL_PFNGLUNIFORM2IVARBPROC)
cogl_get_proc_address ("glUniform2ivARB");
ctx->pf_glUniform3ivARB =
(COGL_PFNGLUNIFORM3IVARBPROC)
cogl_get_proc_address ("glUniform3ivARB");
ctx->pf_glUniform4ivARB =
(COGL_PFNGLUNIFORM4IVARBPROC)
cogl_get_proc_address ("glUniform4ivARB");
ctx->pf_glUniformMatrix2fvARB =
(COGL_PFNGLUNIFORMMATRIX2FVARBPROC)
cogl_get_proc_address ("glUniformMatrix2fvARB");
ctx->pf_glUniformMatrix3fvARB =
(COGL_PFNGLUNIFORMMATRIX3FVARBPROC)
cogl_get_proc_address ("glUniformMatrix3fvARB");
ctx->pf_glUniformMatrix4fvARB =
(COGL_PFNGLUNIFORMMATRIX4FVARBPROC)
cogl_get_proc_address ("glUniformMatrix4fvARB");
if (ctx->pf_glCreateProgramObjectARB && if (ctx->pf_glCreateProgramObjectARB &&
ctx->pf_glCreateShaderObjectARB && ctx->pf_glCreateShaderObjectARB &&
ctx->pf_glShaderSourceARB && ctx->pf_glShaderSourceARB &&
@ -1039,14 +1111,31 @@ _cogl_features_init ()
ctx->pf_glDeleteObjectARB && ctx->pf_glDeleteObjectARB &&
ctx->pf_glGetInfoLogARB && ctx->pf_glGetInfoLogARB &&
ctx->pf_glGetObjectParameterivARB && ctx->pf_glGetObjectParameterivARB &&
ctx->pf_glUniform1fARB && ctx->pf_glUniform1fARB &&
ctx->pf_glUniform2fARB &&
ctx->pf_glUniform3fARB &&
ctx->pf_glUniform4fARB &&
ctx->pf_glUniform1fvARB &&
ctx->pf_glUniform2fvARB &&
ctx->pf_glUniform3fvARB &&
ctx->pf_glUniform4fvARB &&
ctx->pf_glUniform1iARB &&
ctx->pf_glUniform2iARB &&
ctx->pf_glUniform3iARB &&
ctx->pf_glUniform4iARB &&
ctx->pf_glUniform1ivARB &&
ctx->pf_glUniform2ivARB &&
ctx->pf_glUniform3ivARB &&
ctx->pf_glUniform4ivARB &&
ctx->pf_glUniformMatrix2fvARB &&
ctx->pf_glUniformMatrix3fvARB &&
ctx->pf_glUniformMatrix4fvARB &&
ctx->pf_glVertexAttribPointerARB && ctx->pf_glVertexAttribPointerARB &&
ctx->pf_glEnableVertexAttribArrayARB && ctx->pf_glEnableVertexAttribArrayARB &&
ctx->pf_glDisableVertexAttribArrayARB) ctx->pf_glDisableVertexAttribArrayARB)
flags |= COGL_FEATURE_SHADERS_GLSL; flags |= COGL_FEATURE_SHADERS_GLSL;
} }
if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) || if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) ||
cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions)) cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions))
{ {

View File

@ -462,6 +462,7 @@ void
cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper) cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
{ {
GSList *node, *next; GSList *node, *next;
int i;
for (node = wrapper->compiled_programs; node; node = next) for (node = wrapper->compiled_programs; node; node = next)
{ {
@ -486,6 +487,10 @@ cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
g_slist_free1 (node); g_slist_free1 (node);
} }
wrapper->compiled_fragment_shaders = NULL; wrapper->compiled_fragment_shaders = NULL;
for (i = 0; i < COGL_GLES2_NUM_CUSTOM_UNIFORMS; i++)
if (wrapper->custom_uniforms[i].count > 1)
g_free (wrapper->custom_uniforms[i].v.array);
} }
void void
@ -814,6 +819,78 @@ cogl_wrap_glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
GL_FALSE, stride, pointer); GL_FALSE, stride, pointer);
} }
static void
cogl_gles2_do_set_uniform (GLint location, CoglBoxedValue *value)
{
switch (value->type)
{
case COGL_BOXED_NONE:
break;
case COGL_BOXED_INT:
{
gint *ptr;
if (value->count == 1)
ptr = value->v.int_value;
else
ptr = value->v.int_array;
switch (value->size)
{
case 1: glUniform1iv (location, value->count, ptr); break;
case 2: glUniform2iv (location, value->count, ptr); break;
case 3: glUniform3iv (location, value->count, ptr); break;
case 4: glUniform4iv (location, value->count, ptr); break;
}
}
break;
case COGL_BOXED_FLOAT:
{
gfloat *ptr;
if (value->count == 1)
ptr = value->v.float_value;
else
ptr = value->v.float_array;
switch (value->size)
{
case 1: glUniform1fv (location, value->count, ptr); break;
case 2: glUniform2fv (location, value->count, ptr); break;
case 3: glUniform3fv (location, value->count, ptr); break;
case 4: glUniform4fv (location, value->count, ptr); break;
}
}
break;
case COGL_BOXED_MATRIX:
{
gfloat *ptr;
if (value->count == 1)
ptr = value->v.matrix;
else
ptr = value->v.float_array;
switch (value->size)
{
case 2:
glUniformMatrix2fv (location, value->count, value->transpose, ptr);
break;
case 3:
glUniformMatrix3fv (location, value->count, value->transpose, ptr);
break;
case 4:
glUniformMatrix4fv (location, value->count, value->transpose, ptr);
break;
}
}
break;
}
}
void void
cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count) cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
{ {
@ -914,8 +991,8 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
program->custom_uniforms[i] program->custom_uniforms[i]
= glGetUniformLocation (program->program, uniform_name); = glGetUniformLocation (program->program, uniform_name);
if (program->custom_uniforms[i] >= 0) if (program->custom_uniforms[i] >= 0)
glUniform1f (program->custom_uniforms[i], cogl_gles2_do_set_uniform (program->custom_uniforms[i],
w->custom_uniforms[i]); &w->custom_uniforms[i]);
} }
} }

View File

@ -26,6 +26,8 @@
#ifndef __COGL_GLES2_WRAPPER_H__ #ifndef __COGL_GLES2_WRAPPER_H__
#define __COGL_GLES2_WRAPPER_H__ #define __COGL_GLES2_WRAPPER_H__
#include "cogl-internal.h"
G_BEGIN_DECLS G_BEGIN_DECLS
#ifdef HAVE_COGL_GLES2 #ifdef HAVE_COGL_GLES2
@ -131,7 +133,7 @@ struct _CoglGles2Wrapper
GLfloat fog_start; GLfloat fog_start;
GLfloat fog_end; GLfloat fog_end;
GLfloat fog_color[4]; GLfloat fog_color[4];
GLfloat custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS]; CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
}; };
struct _CoglGles2WrapperProgram struct _CoglGles2WrapperProgram

View File

@ -26,6 +26,30 @@
#ifndef __COGL_INTERNAL_H #ifndef __COGL_INTERNAL_H
#define __COGL_INTERNAL_H #define __COGL_INTERNAL_H
typedef enum {
COGL_BOXED_NONE,
COGL_BOXED_INT,
COGL_BOXED_FLOAT,
COGL_BOXED_MATRIX
} CoglBoxedType;
typedef struct _CoglBoxedValue
{
CoglBoxedType type;
int size, count;
gboolean transpose;
union {
gfloat float_value[4];
gint int_value[4];
gfloat matrix[16];
gfloat *float_array;
gint *int_array;
gpointer array;
} v;
} CoglBoxedValue;
#define COGL_DEBUG 0 #define COGL_DEBUG 0
#if COGL_DEBUG #if COGL_DEBUG

View File

@ -162,16 +162,95 @@ cogl_program_get_uniform_location (CoglHandle handle,
void void
cogl_program_uniform_1f (COGLint uniform_no, cogl_program_uniform_1f (COGLint uniform_no,
gfloat value) gfloat value)
{
cogl_program_uniform_float (uniform_no, 1, 1, &value);
}
static void
cogl_program_uniform_x (COGLint uniform_no,
gint size,
gint count,
CoglBoxedType type,
size_t value_size,
gconstpointer value)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (uniform_no >= 0 && uniform_no < COGL_GLES2_NUM_CUSTOM_UNIFORMS) if (uniform_no >= 0 && uniform_no < COGL_GLES2_NUM_CUSTOM_UNIFORMS
&& size >= 1 && size <= 4 && count >= 1)
{ {
ctx->gles2.custom_uniforms[uniform_no] = value; CoglBoxedValue *bv = ctx->gles2.custom_uniforms + uniform_no;
if (count == 1)
{
if (bv->count > 1)
g_free (bv->v.array);
memcpy (bv->v.float_value, value, value_size);
}
else
{
if (bv->count > 1)
{
if (bv->count != count || bv->size != size || bv->type != type)
{
g_free (bv->v.array);
bv->v.array = g_malloc (count * value_size);
}
}
else
bv->v.array = g_malloc (count * value_size);
memcpy (bv->v.array, value, count * value_size);
}
bv->type = type;
bv->size = size;
bv->count = count;
ctx->gles2.dirty_custom_uniforms |= 1 << uniform_no; ctx->gles2.dirty_custom_uniforms |= 1 << uniform_no;
} }
} }
void
cogl_program_uniform_float (COGLint uniform_no,
gint size,
gint count,
const GLfloat *value)
{
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_FLOAT,
sizeof (float) * size, value);
}
void
cogl_program_uniform_int (COGLint uniform_no,
gint size,
gint count,
const GLint *value)
{
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_INT,
sizeof (gint) * size, value);
}
void
cogl_program_uniform_matrix (COGLint uniform_no,
gint size,
gint count,
gboolean transpose,
const GLfloat *value)
{
CoglBoxedValue *bv;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
bv = ctx->gles2.custom_uniforms + uniform_no;
cogl_program_uniform_x (uniform_no, size, count, COGL_BOXED_MATRIX,
sizeof (float) * size * size, value);
bv->transpose = transpose;
}
#else /* HAVE_COGL_GLES2 */ #else /* HAVE_COGL_GLES2 */
/* No support on regular OpenGL 1.1 */ /* No support on regular OpenGL 1.1 */
@ -228,4 +307,30 @@ cogl_program_uniform_1f (COGLint uniform_no,
{ {
} }
void
cogl_program_uniform_float (COGLint uniform_no,
gint size,
gint count,
const GLfloat *value)
{
}
void
cogl_program_uniform_int (COGLint uniform_no,
gint size,
gint count,
const COGLint *value)
{
}
void
cogl_program_uniform_matrix (COGLint uniform_no,
gint size,
gint count,
gboolean transpose,
const GLfloat *value)
{
}
#endif /* HAVE_COGL_GLES2 */ #endif /* HAVE_COGL_GLES2 */

View File

@ -1503,6 +1503,10 @@ clutter_shader_is_compiled
clutter_shader_set_is_enabled clutter_shader_set_is_enabled
clutter_shader_get_is_enabled clutter_shader_get_is_enabled
clutter_shader_set_uniform_1f clutter_shader_set_uniform_1f
clutter_shader_set_uniform
clutter_shader_get_cogl_program
clutter_shader_get_cogl_fragment_shader
clutter_shader_get_cogl_vertex_shader
<SUBSECTION Standard> <SUBSECTION Standard>
CLUTTER_IS_SHADER CLUTTER_IS_SHADER

View File

@ -138,6 +138,9 @@ cogl_program_link
cogl_program_use cogl_program_use
cogl_program_get_uniform_location cogl_program_get_uniform_location
cogl_program_uniform_1f cogl_program_uniform_1f
cogl_program_uniform_float
cogl_program_uniform_int
cogl_program_uniform_matrix
</SECTION> </SECTION>
<SECTION> <SECTION>

View File

@ -142,10 +142,10 @@ test_fbo_main (gint argc, gchar *argv[])
/* apply a shader to it */ /* apply a shader to it */
shader = make_shader(); shader = make_shader();
clutter_actor_set_shader (fbo, shader); clutter_actor_set_shader (fbo, shader);
clutter_actor_set_shader_param (fbo, "radius", 2.0); clutter_actor_set_shader_param_float (fbo, "radius", 2.0);
clutter_actor_set_shader_param (fbo, "x_step", clutter_actor_set_shader_param_float (fbo, "x_step",
1.0f / clutter_util_next_p2 (fbo_width)); 1.0f / clutter_util_next_p2 (fbo_width));
clutter_actor_set_shader_param (fbo, "y_step", clutter_actor_set_shader_param_float (fbo, "y_step",
1.0f / clutter_util_next_p2 (fbo_height)); 1.0f / clutter_util_next_p2 (fbo_height));
/* Third from cloning the fbo texture */ /* Third from cloning the fbo texture */

View File

@ -238,9 +238,10 @@ set_shader_num (ClutterActor *actor, gint new_no)
{ {
clutter_actor_set_shader (actor, NULL); clutter_actor_set_shader (actor, NULL);
clutter_actor_set_shader (actor, shader); clutter_actor_set_shader (actor, shader);
clutter_actor_set_shader_param (actor, "radius", 3.0); clutter_actor_set_shader_param_int (actor, "tex", 0);
clutter_actor_set_shader_param (actor, "brightness", 0.4); clutter_actor_set_shader_param_float (actor, "radius", 3.0);
clutter_actor_set_shader_param (actor, "contrast", -1.9); clutter_actor_set_shader_param_float (actor, "brightness", 0.4);
clutter_actor_set_shader_param_float (actor, "contrast", -1.9);
if (CLUTTER_IS_TEXTURE (actor)) if (CLUTTER_IS_TEXTURE (actor))
{ {
@ -249,10 +250,10 @@ set_shader_num (ClutterActor *actor, gint new_no)
tex_height = clutter_actor_get_height (actor); tex_height = clutter_actor_get_height (actor);
tex_height = clutter_util_next_p2 (tex_height); tex_height = clutter_util_next_p2 (tex_height);
clutter_actor_set_shader_param (actor, "x_step", clutter_actor_set_shader_param_float (actor, "x_step",
1.0f / tex_width); 1.0f / tex_width);
clutter_actor_set_shader_param (actor, "y_step", clutter_actor_set_shader_param_float (actor, "y_step",
1.0f / tex_height); 1.0f / tex_height);
} }
} }
} }
@ -376,10 +377,10 @@ test_shader_main (gint argc, gchar *argv[])
clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor); clutter_container_add_actor (CLUTTER_CONTAINER (stage), actor);
clutter_actor_set_shader_param_int (actor, "tex", 0);
clutter_actor_set_shader_param_float (actor, "brightness", 0.4);
clutter_actor_set_shader_param_float (actor, "contrast", -1.9);
clutter_actor_set_shader_param (actor, "brightness", 0.4);
clutter_actor_set_shader_param (actor, "contrast", -1.9);
clutter_actor_set_reactive (actor, TRUE); clutter_actor_set_reactive (actor, TRUE);
g_signal_connect (actor, "button-release-event", g_signal_connect (actor, "button-release-event",
G_CALLBACK (button_release_cb), NULL); G_CALLBACK (button_release_cb), NULL);