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:
parent
25d9773e15
commit
af0cb47570
23 changed files with 1595 additions and 100 deletions
39
ChangeLog
39
ChangeLog
|
@ -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>
|
||||
|
||||
* clutter/clutter-texture.c:
|
||||
|
|
6
README
6
README
|
@ -170,6 +170,12 @@ wanting to port to newer releases (See NEWS for general new feature info).
|
|||
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
|
||||
a full rename from PangoClutter to CoglPango, to avoid namespace
|
||||
collisions with upstream Pango. The Pango font map, renderer and
|
||||
|
|
|
@ -81,6 +81,7 @@ source_h = \
|
|||
$(srcdir)/clutter-script.h \
|
||||
$(srcdir)/clutter-scriptable.h \
|
||||
$(srcdir)/clutter-shader.h \
|
||||
$(srcdir)/clutter-shader-types.h \
|
||||
$(srcdir)/clutter-stage.h \
|
||||
$(srcdir)/clutter-stage-manager.h \
|
||||
$(srcdir)/clutter-texture.h \
|
||||
|
@ -171,6 +172,7 @@ source_c = \
|
|||
clutter-script-parser.c \
|
||||
clutter-scriptable.c \
|
||||
clutter-shader.c \
|
||||
clutter-shader-types.c \
|
||||
clutter-stage.c \
|
||||
clutter-stage-manager.c \
|
||||
clutter-stage-window.c \
|
||||
|
|
|
@ -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
|
||||
{
|
||||
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
|
||||
*/
|
||||
};
|
||||
|
||||
static void
|
||||
shader_value_free (gpointer data)
|
||||
{
|
||||
GValue *var = data;
|
||||
g_value_unset (var);
|
||||
g_slice_free (GValue, var);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_shader_data (ClutterActor *self)
|
||||
{
|
||||
|
@ -7122,10 +7116,10 @@ destroy_shader_data (ClutterActor *self)
|
|||
shader_data->shader = NULL;
|
||||
}
|
||||
|
||||
if (shader_data->float1f_hash)
|
||||
if (shader_data->value_hash)
|
||||
{
|
||||
g_hash_table_destroy (shader_data->float1f_hash);
|
||||
shader_data->float1f_hash = NULL;
|
||||
g_hash_table_destroy (shader_data->value_hash);
|
||||
shader_data->value_hash = NULL;
|
||||
}
|
||||
|
||||
g_free (shader_data);
|
||||
|
@ -7196,10 +7190,10 @@ clutter_actor_set_shader (ClutterActor *self,
|
|||
if (!shader_data)
|
||||
{
|
||||
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_free,
|
||||
boxed_float_free);
|
||||
shader_value_free);
|
||||
}
|
||||
if (shader_data->shader)
|
||||
{
|
||||
|
@ -7224,10 +7218,10 @@ set_each_param (gpointer key,
|
|||
gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
ClutterShader *shader = CLUTTER_SHADER (user_data);
|
||||
BoxedFloat *box = value;
|
||||
ClutterShader *shader = user_data;
|
||||
GValue *var = value;
|
||||
|
||||
clutter_shader_set_uniform_1f (shader, key, box->value);
|
||||
clutter_shader_set_uniform (shader, (const gchar *)key, var);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -7252,7 +7246,7 @@ clutter_actor_shader_pre_paint (ClutterActor *actor,
|
|||
{
|
||||
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)
|
||||
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
|
||||
* to @actor.
|
||||
*
|
||||
* Since: 0.6
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
clutter_actor_set_shader_param (ClutterActor *self,
|
||||
const gchar *param,
|
||||
gfloat value)
|
||||
const GValue *value)
|
||||
{
|
||||
ClutterActorPrivate *priv;
|
||||
ShaderData *shader_data;
|
||||
BoxedFloat *box;
|
||||
GValue *var;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_ACTOR (self));
|
||||
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;
|
||||
shader_data = priv->shader_data;
|
||||
|
@ -7321,14 +7320,67 @@ clutter_actor_set_shader_param (ClutterActor *self,
|
|||
if (!shader_data)
|
||||
return;
|
||||
|
||||
box = g_slice_new (BoxedFloat);
|
||||
box->value = value;
|
||||
g_hash_table_insert (shader_data->float1f_hash, g_strdup (param), box);
|
||||
var = g_slice_new0 (GValue);
|
||||
g_value_init (var, G_VALUE_TYPE (value));
|
||||
g_value_copy (value, var);
|
||||
g_hash_table_insert (shader_data->value_hash, g_strdup (param), var);
|
||||
|
||||
if (CLUTTER_ACTOR_IS_VISIBLE (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:
|
||||
* @self: a #ClutterActor
|
||||
|
|
|
@ -504,6 +504,12 @@ gboolean clutter_actor_set_shader (ClutterActor
|
|||
ClutterShader *shader);
|
||||
ClutterShader * clutter_actor_get_shader (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,
|
||||
gfloat value);
|
||||
|
||||
|
|
563
clutter/clutter-shader-types.c
Normal file
563
clutter/clutter-shader-types.c
Normal 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;
|
||||
}
|
96
clutter/clutter-shader-types.h
Normal file
96
clutter/clutter-shader-types.h
Normal 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__ */
|
|
@ -70,7 +70,6 @@ struct _ClutterShaderPrivate
|
|||
{
|
||||
guint compiled : 1; /* Shader is bound to the GL context */
|
||||
guint is_enabled : 1;
|
||||
|
||||
guint vertex_is_glsl : 1;
|
||||
guint fragment_is_glsl : 1;
|
||||
|
||||
|
@ -95,9 +94,6 @@ enum
|
|||
|
||||
G_DEFINE_TYPE (ClutterShader, clutter_shader, G_TYPE_OBJECT);
|
||||
|
||||
G_CONST_RETURN gchar *clutter_shader_get_source (ClutterShader *shader,
|
||||
ClutterShaderType type);
|
||||
|
||||
static void
|
||||
clutter_shader_finalize (GObject *object)
|
||||
{
|
||||
|
@ -193,7 +189,6 @@ clutter_shader_constructor (GType type,
|
|||
return object;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
clutter_shader_class_init (ClutterShaderClass *klass)
|
||||
{
|
||||
|
@ -341,8 +336,8 @@ clutter_shader_set_fragment_source (ClutterShader *shader,
|
|||
|
||||
g_free (priv->fragment_source);
|
||||
|
||||
CLUTTER_NOTE (SHADER, "setting fragment shader (GLSL:%s, len:%"
|
||||
G_GSSIZE_FORMAT ")",
|
||||
CLUTTER_NOTE (SHADER,
|
||||
"setting fragment shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
|
||||
is_glsl ? "yes" : "no",
|
||||
length);
|
||||
|
||||
|
@ -387,8 +382,8 @@ clutter_shader_set_vertex_source (ClutterShader *shader,
|
|||
|
||||
g_free (priv->vertex_source);
|
||||
|
||||
CLUTTER_NOTE (SHADER, "setting vertex shader (GLSL:%s, len:%"
|
||||
G_GSSIZE_FORMAT ")",
|
||||
CLUTTER_NOTE (SHADER,
|
||||
"setting vertex shader (GLSL:%s, len:%" G_GSSIZE_FORMAT ")",
|
||||
is_glsl ? "yes" : "no",
|
||||
length);
|
||||
|
||||
|
@ -668,6 +663,7 @@ clutter_shader_set_uniform_1f (ClutterShader *shader,
|
|||
GLfloat foo = value;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_SHADER (shader));
|
||||
g_return_if_fail (name != NULL);
|
||||
|
||||
priv = shader->priv;
|
||||
|
||||
|
@ -675,13 +671,83 @@ clutter_shader_set_uniform_1f (ClutterShader *shader,
|
|||
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:
|
||||
*
|
||||
* Iterate through all #ClutterShaders and tell them to release GL context
|
||||
* related sources.
|
||||
*
|
||||
* Since: 0.6
|
||||
*/
|
||||
void
|
||||
_clutter_shader_release_all (void)
|
||||
|
@ -730,6 +796,57 @@ clutter_shader_get_vertex_source (ClutterShader *shader)
|
|||
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
|
||||
clutter_shader_error_quark (void)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#ifndef __CLUTTER_SHADER_H__
|
||||
#define __CLUTTER_SHADER_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <clutter/clutter-shader-types.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@ -75,34 +75,45 @@ struct _ClutterShaderClass
|
|||
GObjectClass parent_class;
|
||||
};
|
||||
|
||||
GQuark clutter_shader_error_quark (void);
|
||||
GType clutter_shader_get_type (void) G_GNUC_CONST;
|
||||
GQuark clutter_shader_error_quark (void);
|
||||
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,
|
||||
gboolean enabled);
|
||||
gboolean clutter_shader_get_is_enabled (ClutterShader *shader);
|
||||
void clutter_shader_set_is_enabled (ClutterShader *shader,
|
||||
gboolean enabled);
|
||||
gboolean clutter_shader_get_is_enabled (ClutterShader *shader);
|
||||
|
||||
gboolean clutter_shader_compile (ClutterShader *shader,
|
||||
GError **error);
|
||||
void clutter_shader_release (ClutterShader *shader);
|
||||
gboolean clutter_shader_is_compiled (ClutterShader *shader);
|
||||
gboolean clutter_shader_compile (ClutterShader *shader,
|
||||
GError **error);
|
||||
void clutter_shader_release (ClutterShader *shader);
|
||||
gboolean clutter_shader_is_compiled (ClutterShader *shader);
|
||||
|
||||
void clutter_shader_set_vertex_source (ClutterShader *shader,
|
||||
const gchar *data,
|
||||
gssize length);
|
||||
void clutter_shader_set_fragment_source (ClutterShader *shader,
|
||||
const gchar *data,
|
||||
gssize length);
|
||||
void clutter_shader_set_vertex_source (ClutterShader *shader,
|
||||
const gchar *data,
|
||||
gssize length);
|
||||
void clutter_shader_set_fragment_source (ClutterShader *shader,
|
||||
const gchar *data,
|
||||
gssize length);
|
||||
|
||||
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_vertex_source (ClutterShader *shader);
|
||||
G_CONST_RETURN gchar *clutter_shader_get_fragment_source (ClutterShader *shader);
|
||||
|
||||
void clutter_shader_set_uniform_1f (ClutterShader *shader,
|
||||
const gchar *name,
|
||||
gfloat value);
|
||||
/* should be private and internal */
|
||||
void clutter_shader_set_uniform (ClutterShader *shader,
|
||||
const gchar *name,
|
||||
const GValue *value);
|
||||
|
||||
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);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
@ -188,10 +188,10 @@ void cogl_program_link (CoglHandle handle);
|
|||
|
||||
/**
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void cogl_program_use (CoglHandle handle);
|
||||
|
@ -201,29 +201,77 @@ void cogl_program_use (CoglHandle handle);
|
|||
* @handle: a #CoglHandle for a shader program.
|
||||
* @uniform_name: the name of a uniform.
|
||||
*
|
||||
* Retrieve the location (offset) of a uniform variable in a shader program, a
|
||||
* uniform is a variable that is constant for all vertices/fragments for a
|
||||
* Retrieve the location (offset) of a uniform variable in a shader program,
|
||||
* 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.
|
||||
*
|
||||
* Returns: the offset of a uniform in a specified program, this uniform can be
|
||||
* set using #cogl_program_uniform_1f when the program is in use.
|
||||
* Return value: the offset of a uniform in a specified program.
|
||||
* This uniform can be set using cogl_program_uniform_1f() when the
|
||||
* program is in use.
|
||||
*/
|
||||
COGLint cogl_program_get_uniform_location
|
||||
(CoglHandle handle,
|
||||
const gchar *uniform_name);
|
||||
|
||||
|
||||
/**
|
||||
* cogl_program_uniform_1f:
|
||||
* @uniform_no: the unform to set.
|
||||
* @value: the new value of the uniform.
|
||||
*
|
||||
* Changes the value of a uniform in the currently used (see #cogl_program_use)
|
||||
* shader program.
|
||||
* Changes the value of a uniform in the currently used (see
|
||||
* cogl_program_use()) shader program.
|
||||
*/
|
||||
void cogl_program_uniform_1f (COGLint uniform_no,
|
||||
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
|
||||
|
||||
#endif /* __COGL_SHADER_H__ */
|
||||
|
|
|
@ -94,6 +94,24 @@ cogl_create_context ()
|
|||
_context->pf_glGetInfoLogARB = NULL;
|
||||
_context->pf_glGetObjectParameterivARB = 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 */
|
||||
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
|
||||
|
|
|
@ -96,7 +96,7 @@ typedef struct
|
|||
COGL_PFNGLDELETEOBJECTARBPROC pf_glDeleteObjectARB;
|
||||
COGL_PFNGLGETINFOLOGARBPROC pf_glGetInfoLogARB;
|
||||
COGL_PFNGLGETOBJECTPARAMETERIVARBPROC pf_glGetObjectParameterivARB;
|
||||
COGL_PFNGLUNIFORM1FARBPROC pf_glUniform1fARB;
|
||||
|
||||
COGL_PFNGLVERTEXATTRIBPOINTERARBPROC pf_glVertexAttribPointerARB;
|
||||
COGL_PFNGLENABLEVERTEXATTRIBARRAYARBPROC pf_glEnableVertexAttribArrayARB;
|
||||
COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC pf_glDisableVertexAttribArrayARB;
|
||||
|
@ -109,6 +109,25 @@ typedef struct
|
|||
COGL_PFNGLUNMAPBUFFERARBPROC pf_glUnmapBufferARB;
|
||||
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 *
|
||||
|
|
|
@ -837,11 +837,6 @@ typedef void
|
|||
GLenum pname,
|
||||
GLint *params);
|
||||
|
||||
typedef void
|
||||
(APIENTRYP COGL_PFNGLUNIFORM1FARBPROC)
|
||||
(GLint location,
|
||||
GLfloat v0);
|
||||
|
||||
typedef void
|
||||
(APIENTRYP COGL_PFNGLVERTEXATTRIBPOINTERARBPROC)
|
||||
(GLuint index,
|
||||
|
@ -897,6 +892,127 @@ typedef void
|
|||
(GLsizei n,
|
||||
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
|
||||
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,24 @@
|
|||
#define glLinkProgramARB ctx->pf_glLinkProgramARB
|
||||
#define glGetUniformLocationARB ctx->pf_glGetUniformLocationARB
|
||||
#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
|
||||
|
||||
static void _cogl_program_free (CoglProgram *program);
|
||||
|
@ -121,7 +139,7 @@ cogl_program_use (CoglHandle handle)
|
|||
{
|
||||
program = _cogl_program_pointer_from_handle (handle);
|
||||
gl_handle = program->gl_handle;
|
||||
}
|
||||
}
|
||||
|
||||
glUseProgramObjectARB (gl_handle);
|
||||
}
|
||||
|
@ -148,3 +166,82 @@ cogl_program_uniform_1f (COGLint uniform_no,
|
|||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1028,6 +1028,78 @@ _cogl_features_init ()
|
|||
(COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)
|
||||
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 &&
|
||||
ctx->pf_glCreateShaderObjectARB &&
|
||||
ctx->pf_glShaderSourceARB &&
|
||||
|
@ -1039,14 +1111,31 @@ _cogl_features_init ()
|
|||
ctx->pf_glDeleteObjectARB &&
|
||||
ctx->pf_glGetInfoLogARB &&
|
||||
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_glEnableVertexAttribArrayARB &&
|
||||
ctx->pf_glDisableVertexAttribArrayARB)
|
||||
flags |= COGL_FEATURE_SHADERS_GLSL;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) ||
|
||||
cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions))
|
||||
{
|
||||
|
|
|
@ -462,6 +462,7 @@ void
|
|||
cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
|
||||
{
|
||||
GSList *node, *next;
|
||||
int i;
|
||||
|
||||
for (node = wrapper->compiled_programs; node; node = next)
|
||||
{
|
||||
|
@ -486,6 +487,10 @@ cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
|
|||
g_slist_free1 (node);
|
||||
}
|
||||
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
|
||||
|
@ -814,6 +819,78 @@ cogl_wrap_glNormalPointer (GLenum type, GLsizei stride, const GLvoid *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
|
||||
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]
|
||||
= glGetUniformLocation (program->program, uniform_name);
|
||||
if (program->custom_uniforms[i] >= 0)
|
||||
glUniform1f (program->custom_uniforms[i],
|
||||
w->custom_uniforms[i]);
|
||||
cogl_gles2_do_set_uniform (program->custom_uniforms[i],
|
||||
&w->custom_uniforms[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#ifndef __COGL_GLES2_WRAPPER_H__
|
||||
#define __COGL_GLES2_WRAPPER_H__
|
||||
|
||||
#include "cogl-internal.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#ifdef HAVE_COGL_GLES2
|
||||
|
@ -131,7 +133,7 @@ struct _CoglGles2Wrapper
|
|||
GLfloat fog_start;
|
||||
GLfloat fog_end;
|
||||
GLfloat fog_color[4];
|
||||
GLfloat custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
|
||||
CoglBoxedValue custom_uniforms[COGL_GLES2_NUM_CUSTOM_UNIFORMS];
|
||||
};
|
||||
|
||||
struct _CoglGles2WrapperProgram
|
||||
|
|
|
@ -26,6 +26,30 @@
|
|||
#ifndef __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
|
||||
|
||||
#if COGL_DEBUG
|
||||
|
|
|
@ -162,16 +162,95 @@ cogl_program_get_uniform_location (CoglHandle handle,
|
|||
void
|
||||
cogl_program_uniform_1f (COGLint uniform_no,
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
/* 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 */
|
||||
|
|
|
@ -1503,6 +1503,10 @@ clutter_shader_is_compiled
|
|||
clutter_shader_set_is_enabled
|
||||
clutter_shader_get_is_enabled
|
||||
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>
|
||||
CLUTTER_IS_SHADER
|
||||
|
|
|
@ -138,6 +138,9 @@ cogl_program_link
|
|||
cogl_program_use
|
||||
cogl_program_get_uniform_location
|
||||
cogl_program_uniform_1f
|
||||
cogl_program_uniform_float
|
||||
cogl_program_uniform_int
|
||||
cogl_program_uniform_matrix
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
|
|
@ -142,10 +142,10 @@ test_fbo_main (gint argc, gchar *argv[])
|
|||
/* apply a shader to it */
|
||||
shader = make_shader();
|
||||
clutter_actor_set_shader (fbo, shader);
|
||||
clutter_actor_set_shader_param (fbo, "radius", 2.0);
|
||||
clutter_actor_set_shader_param (fbo, "x_step",
|
||||
clutter_actor_set_shader_param_float (fbo, "radius", 2.0);
|
||||
clutter_actor_set_shader_param_float (fbo, "x_step",
|
||||
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));
|
||||
|
||||
/* Third from cloning the fbo texture */
|
||||
|
|
|
@ -238,9 +238,10 @@ set_shader_num (ClutterActor *actor, gint new_no)
|
|||
{
|
||||
clutter_actor_set_shader (actor, NULL);
|
||||
clutter_actor_set_shader (actor, shader);
|
||||
clutter_actor_set_shader_param (actor, "radius", 3.0);
|
||||
clutter_actor_set_shader_param (actor, "brightness", 0.4);
|
||||
clutter_actor_set_shader_param (actor, "contrast", -1.9);
|
||||
clutter_actor_set_shader_param_int (actor, "tex", 0);
|
||||
clutter_actor_set_shader_param_float (actor, "radius", 3.0);
|
||||
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))
|
||||
{
|
||||
|
@ -249,10 +250,10 @@ set_shader_num (ClutterActor *actor, gint new_no)
|
|||
tex_height = clutter_actor_get_height (actor);
|
||||
tex_height = clutter_util_next_p2 (tex_height);
|
||||
|
||||
clutter_actor_set_shader_param (actor, "x_step",
|
||||
1.0f / tex_width);
|
||||
clutter_actor_set_shader_param (actor, "y_step",
|
||||
1.0f / tex_height);
|
||||
clutter_actor_set_shader_param_float (actor, "x_step",
|
||||
1.0f / tex_width);
|
||||
clutter_actor_set_shader_param_float (actor, "y_step",
|
||||
1.0f / tex_height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,10 +377,10 @@ test_shader_main (gint argc, gchar *argv[])
|
|||
|
||||
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);
|
||||
g_signal_connect (actor, "button-release-event",
|
||||
G_CALLBACK (button_release_cb), NULL);
|
||||
|
|
Loading…
Reference in a new issue