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 fe7aa83f86
commit 2142062ba1
11 changed files with 621 additions and 23 deletions

View File

@ -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__ */

View File

@ -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>

View File

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

View File

@ -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 *

View File

@ -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

View File

@ -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);
@ -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);
}
}

View File

@ -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 &&
@ -1040,13 +1112,30 @@ _cogl_features_init ()
ctx->pf_glGetInfoLogARB &&
ctx->pf_glGetObjectParameterivARB &&
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))
{

View File

@ -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]);
}
}

View File

@ -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

View File

@ -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

View File

@ -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 */