* clutter/cogl/gles/cogl-gles2-wrapper.h: The uniform numbers are

now stored in a separate struct so they can be stored for
	application program objects as well.

	* clutter/cogl/gles/cogl.c: Moved stub shader functions into
	separate files.
	(_cogl_features_init): Report support for the shaders feature on
	GLES 2

	* clutter/cogl/gles/cogl-shader.h:
	* clutter/cogl/gles/cogl-shader.c:
	* clutter/cogl/gles/cogl-program.h:
	* clutter/cogl/gles/cogl-program.c: Separate files to handle
	shaders on programs on GLES. If version 1.1 is being used then the
	stub functions which all fail are still used.

	* clutter/cogl/gles/cogl-gles2-wrapper.c
	(cogl_gles2_wrapper_init, cogl_gles2_wrapper_bind_attributes),
	(cogl_gles2_wrapper_get_uniforms): Move the uniforms and attribute
	bindings into a separate function so they can be used to bind on
	application shaders as well.
	(cogl_gles2_wrapper_update_matrix): Now takes a parameter and is
	no longer static so that it can be used to update all of the
	matrices when a new shader is bound.

	* clutter/cogl/gles/cogl-defines.h.in: Use GL_COMPILE_STATUS for
	CGL_OBJECT_COMPILE_STATUS if the latter isn't available (for
	example on GLES 2).

	* clutter/cogl/gles/cogl-context.h (CoglContext): Added handle
	arrays for programs and shaders.

	* clutter/cogl/gles/cogl-context.c (cogl_create_context)
	(cogl_destroy_context): Initialize and destroy program and shader
	handle array.

	* clutter/cogl/gles/Makefile.am (libclutter_cogl_la_SOURCES): Add
	cogl-{shader,program}.{c,h}
This commit is contained in:
Neil Roberts 2008-06-02 10:58:57 +00:00
parent 46be48f8f6
commit 165531074b
11 changed files with 661 additions and 175 deletions

View File

@ -30,7 +30,11 @@ libclutter_cogl_la_SOURCES = \
cogl-texture.c \
cogl-fbo.c \
cogl-context.c \
cogl-gles2-wrapper.h
cogl-gles2-wrapper.h \
cogl-program.h \
cogl-program.c \
cogl-shader.h \
cogl-shader.c
if USE_GLES2_WRAPPER
libclutter_cogl_la_SOURCES += \

View File

@ -64,6 +64,8 @@ cogl_create_context ()
_context->texture_vertices = NULL;
_context->fbo_handles = NULL;
_context->program_handles = NULL;
_context->shader_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER;
_context->blend_src_factor = CGL_SRC_ALPHA;
@ -96,6 +98,15 @@ cogl_destroy_context ()
if (_context->texture_vertices)
g_free (_context->texture_vertices);
if (_context->texture_handles)
g_array_free (_context->texture_handles, TRUE);
if (_context->fbo_handles)
g_array_free (_context->fbo_handles, TRUE);
if (_context->shader_handles)
g_array_free (_context->shader_handles, TRUE);
if (_context->program_handles)
g_array_free (_context->program_handles, TRUE);
g_free (_context);
}

View File

@ -67,6 +67,10 @@ typedef struct
GArray *fbo_handles;
CoglBufferTarget draw_buffer;
/* Shaders */
GArray *program_handles;
GArray *shader_handles;
#ifdef HAVE_COGL_GLES2
CoglGles2Wrapper gles2;
#endif

View File

@ -460,8 +460,10 @@ typedef GLuint COGLuint;
#define CGL_VERTEX_SHADER 0
#endif
#ifdef GL_OBJECT_COMPILE_STATUS
#define CGL_OBJECT_COMPILE_STATUS GL_OBJECT_COMPILE_STATUS
#if defined(GL_OBJECT_COMPILE_STATUS)
#define CGL_OBJECT_COMPILE_STATUS GL_OBJECT_COMPILE_STATUS
#elif defined(GL_COMPILE_STATUS)
#define CGL_OBJECT_COMPILE_STATUS GL_COMPILE_STATUS
#else
#define CGL_OBJECT_COMPILE_STATUS 0
#endif

View File

@ -109,12 +109,7 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
wrapper->program = glCreateProgram ();
glAttachShader (wrapper->program, wrapper->fragment_shader);
glAttachShader (wrapper->program, wrapper->vertex_shader);
glBindAttribLocation (wrapper->program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
"vertex_attrib");
glBindAttribLocation (wrapper->program, COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB,
"tex_coord_attrib");
glBindAttribLocation (wrapper->program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
"color_attrib");
cogl_gles2_wrapper_bind_attributes (wrapper->program);
glLinkProgram (wrapper->program);
glGetProgramiv (wrapper->program, GL_LINK_STATUS, &status);
@ -138,41 +133,11 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
glUseProgram (wrapper->program);
wrapper->mvp_matrix_uniform
= glGetUniformLocation (wrapper->program, "mvp_matrix");
wrapper->modelview_matrix_uniform
= glGetUniformLocation (wrapper->program, "modelview_matrix");
wrapper->texture_matrix_uniform
= glGetUniformLocation (wrapper->program, "texture_matrix");
wrapper->texture_2d_enabled_uniform
= glGetUniformLocation (wrapper->program, "texture_2d_enabled");
wrapper->bound_texture_uniform
= glGetUniformLocation (wrapper->program, "texture_unit");
wrapper->alpha_only_uniform
= glGetUniformLocation (wrapper->program, "alpha_only");
wrapper->fog_enabled_uniform
= glGetUniformLocation (wrapper->program, "fog_enabled");
wrapper->fog_mode_uniform
= glGetUniformLocation (wrapper->program, "fog_mode");
wrapper->fog_density_uniform
= glGetUniformLocation (wrapper->program, "fog_density");
wrapper->fog_start_uniform
= glGetUniformLocation (wrapper->program, "fog_start");
wrapper->fog_end_uniform
= glGetUniformLocation (wrapper->program, "fog_end");
wrapper->fog_color_uniform
= glGetUniformLocation (wrapper->program, "fog_color");
wrapper->alpha_test_enabled_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_enabled");
wrapper->alpha_test_func_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_func");
wrapper->alpha_test_ref_uniform
= glGetUniformLocation (wrapper->program, "alpha_test_ref");
wrapper->uniforms = &wrapper->fixed_uniforms;
cogl_gles2_wrapper_get_uniforms (wrapper->program, wrapper->uniforms);
/* Always use the first texture unit */
glUniform1i (wrapper->bound_texture_uniform, 0);
glUniform1i (wrapper->uniforms->bound_texture_uniform, 0);
/* Initialize the stacks */
cogl_wrap_glMatrixMode (GL_TEXTURE);
@ -197,6 +162,55 @@ cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper)
cogl_wrap_glAlphaFunc (GL_ALWAYS, 0.0f);
}
void
cogl_gles2_wrapper_bind_attributes (GLuint program)
{
glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
"vertex_attrib");
glBindAttribLocation (program, COGL_GLES2_WRAPPER_TEX_COORD_ATTRIB,
"tex_coord_attrib");
glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
"color_attrib");
}
void
cogl_gles2_wrapper_get_uniforms (GLuint program,
CoglGles2WrapperUniforms *uniforms)
{
uniforms->mvp_matrix_uniform
= glGetUniformLocation (program, "mvp_matrix");
uniforms->modelview_matrix_uniform
= glGetUniformLocation (program, "modelview_matrix");
uniforms->texture_matrix_uniform
= glGetUniformLocation (program, "texture_matrix");
uniforms->texture_2d_enabled_uniform
= glGetUniformLocation (program, "texture_2d_enabled");
uniforms->bound_texture_uniform
= glGetUniformLocation (program, "texture_unit");
uniforms->alpha_only_uniform
= glGetUniformLocation (program, "alpha_only");
uniforms->fog_enabled_uniform
= glGetUniformLocation (program, "fog_enabled");
uniforms->fog_mode_uniform
= glGetUniformLocation (program, "fog_mode");
uniforms->fog_density_uniform
= glGetUniformLocation (program, "fog_density");
uniforms->fog_start_uniform
= glGetUniformLocation (program, "fog_start");
uniforms->fog_end_uniform
= glGetUniformLocation (program, "fog_end");
uniforms->fog_color_uniform
= glGetUniformLocation (program, "fog_color");
uniforms->alpha_test_enabled_uniform
= glGetUniformLocation (program, "alpha_test_enabled");
uniforms->alpha_test_func_uniform
= glGetUniformLocation (program, "alpha_test_func");
uniforms->alpha_test_ref_uniform
= glGetUniformLocation (program, "alpha_test_ref");
}
void
cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
{
@ -217,12 +231,12 @@ cogl_gles2_wrapper_deinit (CoglGles2Wrapper *wrapper)
}
}
static void
cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper)
void
cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper, GLenum matrix_num)
{
const float *matrix;
switch (wrapper->matrix_mode)
switch (matrix_num)
{
default:
case GL_MODELVIEW:
@ -234,10 +248,10 @@ cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper)
case GL_TEXTURE:
matrix = wrapper->texture_stack + wrapper->texture_stack_pos * 16;
glUniformMatrix4fv (wrapper->texture_matrix_uniform, 1, GL_FALSE, matrix);
glUniformMatrix4fv (wrapper->uniforms->texture_matrix_uniform,
1, GL_FALSE, matrix);
break;
}
}
void
@ -314,7 +328,7 @@ cogl_wrap_glPopMatrix ()
}
/* Update the matrix in the program object */
cogl_gles2_wrapper_update_matrix (w);
cogl_gles2_wrapper_update_matrix (w, w->matrix_mode);
}
void
@ -356,7 +370,7 @@ cogl_wrap_glLoadIdentity ()
matrix[10] = 1.0f;
matrix[15] = 1.0f;
cogl_gles2_wrapper_update_matrix (w);
cogl_gles2_wrapper_update_matrix (w, w->matrix_mode);
}
static void
@ -388,7 +402,7 @@ cogl_wrap_glMultMatrix (const float *m)
memcpy (old_matrix, new_matrix, sizeof (float) * 16);
cogl_gles2_wrapper_update_matrix (w);
cogl_gles2_wrapper_update_matrix (w, w->matrix_mode);
}
void
@ -530,8 +544,9 @@ cogl_wrap_glDrawArrays (GLenum mode, GLint first, GLsizei count)
+ w->projection_stack_pos * 16,
modelview_matrix);
glUniformMatrix4fv (w->mvp_matrix_uniform, 1, GL_FALSE, mvp_matrix);
glUniformMatrix4fv (w->modelview_matrix_uniform, 1, GL_FALSE,
glUniformMatrix4fv (w->uniforms->mvp_matrix_uniform, 1,
GL_FALSE, mvp_matrix);
glUniformMatrix4fv (w->uniforms->modelview_matrix_uniform, 1, GL_FALSE,
modelview_matrix);
w->mvp_uptodate = GL_TRUE;
@ -551,7 +566,7 @@ cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
/* We need to keep track of whether the texture is alpha-only
because the emulation of GL_MODULATE needs to work differently in
that case */
glUniform1i (w->alpha_only_uniform,
glUniform1i (w->uniforms->alpha_only_uniform,
internal_format == GL_ALPHA ? GL_TRUE : GL_FALSE);
}
@ -571,15 +586,15 @@ cogl_wrap_glEnable (GLenum cap)
switch (cap)
{
case GL_TEXTURE_2D:
glUniform1i (w->texture_2d_enabled_uniform, GL_TRUE);
glUniform1i (w->uniforms->texture_2d_enabled_uniform, GL_TRUE);
break;
case GL_FOG:
glUniform1i (w->fog_enabled_uniform, GL_TRUE);
glUniform1i (w->uniforms->fog_enabled_uniform, GL_TRUE);
break;
case GL_ALPHA_TEST:
glUniform1i (w->alpha_test_enabled_uniform, GL_TRUE);
glUniform1i (w->uniforms->alpha_test_enabled_uniform, GL_TRUE);
break;
default:
@ -595,15 +610,15 @@ cogl_wrap_glDisable (GLenum cap)
switch (cap)
{
case GL_TEXTURE_2D:
glUniform1i (w->texture_2d_enabled_uniform, GL_FALSE);
glUniform1i (w->uniforms->texture_2d_enabled_uniform, GL_FALSE);
break;
case GL_FOG:
glUniform1i (w->fog_enabled_uniform, GL_FALSE);
glUniform1i (w->uniforms->fog_enabled_uniform, GL_FALSE);
break;
case GL_ALPHA_TEST:
glUniform1i (w->alpha_test_enabled_uniform, GL_FALSE);
glUniform1i (w->uniforms->alpha_test_enabled_uniform, GL_FALSE);
break;
default:
@ -655,8 +670,8 @@ cogl_wrap_glAlphaFunc (GLenum func, GLclampf ref)
else if (ref > 1.0f)
ref = 1.0f;
glUniform1i (w->alpha_test_func_uniform, func);
glUniform1f (w->alpha_test_ref_uniform, ref);
glUniform1i (w->uniforms->alpha_test_func_uniform, func);
glUniform1f (w->uniforms->alpha_test_ref_uniform, ref);
}
void
@ -738,19 +753,22 @@ cogl_wrap_glFogx (GLenum pname, GLfixed param)
switch (pname)
{
case GL_FOG_MODE:
glUniform1i (w->fog_mode_uniform, param);
glUniform1i (w->uniforms->fog_mode_uniform, param);
break;
case GL_FOG_DENSITY:
glUniform1f (w->fog_density_uniform, CLUTTER_FIXED_TO_FLOAT (param));
glUniform1f (w->uniforms->fog_density_uniform,
CLUTTER_FIXED_TO_FLOAT (param));
break;
case GL_FOG_START:
glUniform1f (w->fog_start_uniform, CLUTTER_FIXED_TO_FLOAT (param));
glUniform1f (w->uniforms->fog_start_uniform,
CLUTTER_FIXED_TO_FLOAT (param));
break;
case GL_FOG_END:
glUniform1f (w->fog_end_uniform, CLUTTER_FIXED_TO_FLOAT (param));
glUniform1f (w->uniforms->fog_end_uniform,
CLUTTER_FIXED_TO_FLOAT (param));
break;
}
}
@ -761,7 +779,7 @@ cogl_wrap_glFogxv (GLenum pname, const GLfixed *params)
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
if (pname == GL_FOG_COLOR)
glUniform4f (w->fog_color_uniform,
glUniform4f (w->uniforms->fog_color_uniform,
CLUTTER_FIXED_TO_FLOAT (params[0]),
CLUTTER_FIXED_TO_FLOAT (params[1]),
CLUTTER_FIXED_TO_FLOAT (params[2]),

View File

@ -30,19 +30,16 @@ G_BEGIN_DECLS
#ifdef HAVE_COGL_GLES2
typedef struct _CoglGles2Wrapper CoglGles2Wrapper;
typedef struct _CoglGles2Wrapper CoglGles2Wrapper;
typedef struct _CoglGles2WrapperUniforms CoglGles2WrapperUniforms;
/* Must be a power of two */
#define COGL_GLES2_MODELVIEW_STACK_SIZE 32
#define COGL_GLES2_PROJECTION_STACK_SIZE 2
#define COGL_GLES2_TEXTURE_STACK_SIZE 2
struct _CoglGles2Wrapper
struct _CoglGles2WrapperUniforms
{
GLuint program;
GLuint vertex_shader;
GLuint fragment_shader;
GLint mvp_matrix_uniform;
GLint modelview_matrix_uniform;
GLint texture_matrix_uniform;
@ -60,6 +57,13 @@ struct _CoglGles2Wrapper
GLint alpha_test_enabled_uniform;
GLint alpha_test_func_uniform;
GLint alpha_test_ref_uniform;
};
struct _CoglGles2Wrapper
{
GLuint program;
GLuint vertex_shader;
GLuint fragment_shader;
GLuint matrix_mode;
GLfloat modelview_stack[COGL_GLES2_MODELVIEW_STACK_SIZE * 16];
@ -69,6 +73,11 @@ struct _CoglGles2Wrapper
GLfloat texture_stack[COGL_GLES2_TEXTURE_STACK_SIZE * 16];
GLuint texture_stack_pos;
/* The uniforms for the fixed-functionality emulation program */
CoglGles2WrapperUniforms fixed_uniforms;
/* The uniforms for the currently bound program */
CoglGles2WrapperUniforms *uniforms;
/* The combined modelview and projection matrix is only updated at
the last minute in glDrawArrays to avoid recalculating it for
every change to the modelview matrix */
@ -169,6 +178,12 @@ void cogl_gles2_wrapper_bind_texture (GLenum target, GLuint texture,
/* This function is only available on GLES 2 */
#define cogl_wrap_glGenerateMipmap glGenerateMipmap
void cogl_gles2_wrapper_bind_attributes (GLuint program);
void cogl_gles2_wrapper_get_uniforms (GLuint program,
CoglGles2WrapperUniforms *uniforms);
void cogl_gles2_wrapper_update_matrix (CoglGles2Wrapper *wrapper,
GLenum matrix_num);
#else /* HAVE_COGL_GLES2 */
/* If we're not using GL ES 2 then just use the GL functions

257
gles/cogl-program.c Normal file
View File

@ -0,0 +1,257 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Matthew Allum <mallum@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 "cogl.h"
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#ifdef HAVE_COGL_GLES2
#include "cogl-shader.h"
#include "cogl-program.h"
static void _cogl_program_free (CoglProgram *program);
COGL_HANDLE_DEFINE (Program, program, program_handles);
static void
_cogl_program_free (CoglProgram *program)
{
/* Frees program resources but its handle is not
released! Do that separately before this! */
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glDeleteProgram (program->gl_handle);
}
CoglHandle
cogl_create_program (void)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, 0);
program = g_slice_new (CoglProgram);
program->ref_count = 1;
program->gl_handle = glCreateProgram ();
program->attached_vertex_shader = FALSE;
program->attached_fragment_shader = FALSE;
program->attached_fixed_vertex_shader = FALSE;
program->attached_fixed_fragment_shader = FALSE;
COGL_HANDLE_DEBUG_NEW (program, program);
return _cogl_program_handle_new (program);
}
void
cogl_program_attach_shader (CoglHandle program_handle,
CoglHandle shader_handle)
{
CoglProgram *program;
CoglShader *shader;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_program (program_handle) || !cogl_is_shader (shader_handle))
return;
program = _cogl_program_pointer_from_handle (program_handle);
shader = _cogl_shader_pointer_from_handle (shader_handle);
if (shader->type == GL_VERTEX_SHADER)
{
if (program->attached_fixed_vertex_shader)
{
glDetachShader (program->gl_handle, ctx->gles2.vertex_shader);
program->attached_fixed_vertex_shader = FALSE;
}
program->attached_vertex_shader = TRUE;
}
else if (shader->type == GL_FRAGMENT_SHADER)
{
if (program->attached_fixed_fragment_shader)
{
glDetachShader (program->gl_handle, ctx->gles2.fragment_shader);
program->attached_fixed_fragment_shader = FALSE;
}
program->attached_fragment_shader = TRUE;
}
glAttachShader (program->gl_handle, shader->gl_handle);
}
void
cogl_program_link (CoglHandle handle)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_program (handle))
return;
program = _cogl_program_pointer_from_handle (handle);
if (!program->attached_vertex_shader
&& !program->attached_fixed_vertex_shader)
{
glAttachShader (program->gl_handle, ctx->gles2.vertex_shader);
program->attached_fixed_vertex_shader = TRUE;
}
if (!program->attached_fragment_shader
&& !program->attached_fixed_fragment_shader)
{
glAttachShader (program->gl_handle, ctx->gles2.fragment_shader);
program->attached_fixed_fragment_shader = TRUE;
}
/* Set the attributes so that the wrapper functions will still work */
cogl_gles2_wrapper_bind_attributes (program->gl_handle);
glLinkProgram (program->gl_handle);
/* Retrieve the uniforms */
cogl_gles2_wrapper_get_uniforms (program->gl_handle,
&program->uniforms);
}
void
cogl_program_use (CoglHandle handle)
{
CoglProgram *program;
GLuint gl_handle;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
return;
if (handle == COGL_INVALID_HANDLE)
{
/* Go back to the fixed-functionality emulator program */
gl_handle = ctx->gles2.program;
ctx->gles2.uniforms = &ctx->gles2.fixed_uniforms;
}
else
{
program = _cogl_program_pointer_from_handle (handle);
gl_handle = program->gl_handle;
/* Use the uniforms in the program */
ctx->gles2.uniforms = &program->uniforms;
}
glUseProgram (gl_handle);
/* Update all of the matrix attributes */
cogl_gles2_wrapper_update_matrix (&ctx->gles2, GL_MODELVIEW);
cogl_gles2_wrapper_update_matrix (&ctx->gles2, GL_PROJECTION);
cogl_gles2_wrapper_update_matrix (&ctx->gles2, GL_TEXTURE);
}
COGLint
cogl_program_get_uniform_location (CoglHandle handle,
const gchar *uniform_name)
{
CoglProgram *program;
_COGL_GET_CONTEXT (ctx, 0);
if (!cogl_is_program (handle))
return 0;
program = _cogl_program_pointer_from_handle (handle);
return glGetUniformLocation (program->gl_handle, uniform_name);
}
void
cogl_program_uniform_1f (COGLint uniform_no,
gfloat value)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glUniform1f (uniform_no, value);
}
#else /* HAVE_COGL_GLES2 */
/* No support on regular OpenGL 1.1 */
CoglHandle
cogl_create_program (void)
{
return COGL_INVALID_HANDLE;
}
gboolean
cogl_is_program (CoglHandle handle)
{
return FALSE;
}
CoglHandle
cogl_program_ref (CoglHandle handle)
{
return COGL_INVALID_HANDLE;
}
void
cogl_program_unref (CoglHandle handle)
{
}
void
cogl_program_attach_shader (CoglHandle program_handle,
CoglHandle shader_handle)
{
}
void
cogl_program_link (CoglHandle program_handle)
{
}
void
cogl_program_use (CoglHandle program_handle)
{
}
COGLint
cogl_program_get_uniform_location (CoglHandle program_handle,
const gchar *uniform_name)
{
return 0;
}
void
cogl_program_uniform_1f (COGLint uniform_no,
gfloat value)
{
}
#endif /* HAVE_COGL_GLES2 */

50
gles/cogl-program.h Normal file
View File

@ -0,0 +1,50 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Matthew Allum <mallum@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.
*/
#ifndef __COGL_PROGRAM_H
#define __COGL_PROGRAM_H
#include "cogl-gles2-wrapper.h"
typedef struct _CoglProgram CoglProgram;
struct _CoglProgram
{
guint ref_count;
GLuint gl_handle;
/* Keep track of which types of shader we've attached so we can link
in our replacement fixed functionality shader */
gboolean attached_vertex_shader;
gboolean attached_fragment_shader;
gboolean attached_fixed_vertex_shader;
gboolean attached_fixed_fragment_shader;
CoglGles2WrapperUniforms uniforms;
};
CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle);
#endif /* __COGL_PROGRAM_H */

184
gles/cogl-shader.c Normal file
View File

@ -0,0 +1,184 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Matthew Allum <mallum@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 "cogl.h"
#include "cogl-shader.h"
#include "cogl-internal.h"
#include "cogl-context.h"
#include "cogl-handle.h"
#ifdef HAVE_COGL_GLES2
static void _cogl_shader_free (CoglShader *shader);
COGL_HANDLE_DEFINE (Shader, shader, shader_handles);
static void
_cogl_shader_free (CoglShader *shader)
{
/* Frees shader resources but its handle is not
released! Do that separately before this! */
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glDeleteShader (shader->gl_handle);
}
CoglHandle
cogl_create_shader (COGLenum shaderType)
{
CoglShader *shader;
_COGL_GET_CONTEXT (ctx, 0);
shader = g_slice_new (CoglShader);
shader->ref_count = 1;
shader->gl_handle = glCreateShader (shaderType);
shader->type = shaderType;
COGL_HANDLE_DEBUG_NEW (shader, shader);
return _cogl_shader_handle_new (shader);
}
void
cogl_shader_source (CoglHandle handle,
const gchar *source)
{
CoglShader *shader;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_shader (handle))
return;
shader = _cogl_shader_pointer_from_handle (handle);
glShaderSource (shader->gl_handle, 1, &source, NULL);
}
void
cogl_shader_compile (CoglHandle handle)
{
CoglShader *shader;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_shader (handle))
return;
shader = _cogl_shader_pointer_from_handle (handle);
glCompileShader (shader->gl_handle);
}
void
cogl_shader_get_info_log (CoglHandle handle,
guint size,
gchar *buffer)
{
CoglShader *shader;
COGLint len = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_shader (handle))
return;
shader = _cogl_shader_pointer_from_handle (handle);
glGetShaderInfoLog (shader->gl_handle, size - 1, &len, buffer);
buffer[len] = '\0';
}
void
cogl_shader_get_parameteriv (CoglHandle handle,
COGLenum pname,
COGLint *dest)
{
CoglShader *shader;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!cogl_is_shader (handle))
return;
shader = _cogl_shader_pointer_from_handle (handle);
glGetShaderiv (shader->gl_handle, pname, dest);
}
#else /* HAVE_COGL_GLES2 */
/* No support on regular OpenGL 1.1 */
CoglHandle
cogl_create_shader (COGLenum shaderType)
{
return COGL_INVALID_HANDLE;
}
gboolean
cogl_is_shader (CoglHandle handle)
{
return FALSE;
}
CoglHandle
cogl_shader_ref (CoglHandle handle)
{
return COGL_INVALID_HANDLE;
}
void
cogl_shader_unref (CoglHandle handle)
{
}
void
cogl_shader_source (CoglHandle shader,
const gchar *source)
{
}
void
cogl_shader_compile (CoglHandle shader_handle)
{
}
void
cogl_shader_get_info_log (CoglHandle handle,
guint size,
gchar *buffer)
{
}
void
cogl_shader_get_parameteriv (CoglHandle handle,
COGLenum pname,
COGLint *dest)
{
}
#endif /* HAVE_COGL_GLES2 */

40
gles/cogl-shader.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Matthew Allum <mallum@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.
*/
#ifndef __COGL_SHADER_H
#define __COGL_SHADER_H
typedef struct _CoglShader CoglShader;
struct _CoglShader
{
guint ref_count;
GLuint gl_handle;
GLenum type;
};
CoglShader *_cogl_shader_pointer_from_handle (CoglHandle handle);
#endif /* __COGL_SHADER_H */

View File

@ -490,6 +490,10 @@ _cogl_features_init ()
if (max_clip_planes >= 4)
flags |= COGL_FEATURE_FOUR_CLIP_PLANES;
#ifdef HAVE_COGL_GLES2
flags |= COGL_FEATURE_SHADERS_GLSL;
#endif
ctx->feature_flags = flags;
ctx->features_cached = TRUE;
}
@ -571,106 +575,3 @@ cogl_fog_set (const ClutterColor *fog_color,
cogl_wrap_glFogx (GL_FOG_START, (GLfixed) z_near);
cogl_wrap_glFogx (GL_FOG_END, (GLfixed) z_far);
}
/* Shaders, no support on regular OpenGL 1.1 */
CoglHandle
cogl_create_program (void)
{
return COGL_INVALID_HANDLE;
}
gboolean
cogl_is_program (CoglHandle handle)
{
return FALSE;
}
CoglHandle
cogl_program_ref (CoglHandle handle)
{
return COGL_INVALID_HANDLE;
}
void
cogl_program_unref (CoglHandle handle)
{
}
CoglHandle
cogl_create_shader (COGLenum shaderType)
{
return COGL_INVALID_HANDLE;
}
gboolean
cogl_is_shader (CoglHandle handle)
{
return FALSE;
}
CoglHandle
cogl_shader_ref (CoglHandle handle)
{
return COGL_INVALID_HANDLE;
}
void
cogl_shader_unref (CoglHandle handle)
{
}
void
cogl_shader_source (CoglHandle shader,
const gchar *source)
{
}
void
cogl_shader_compile (CoglHandle shader_handle)
{
}
void
cogl_program_attach_shader (CoglHandle program_handle,
CoglHandle shader_handle)
{
}
void
cogl_program_link (CoglHandle program_handle)
{
}
void
cogl_program_use (CoglHandle program_handle)
{
}
COGLint
cogl_program_get_uniform_location (CoglHandle program_handle,
const gchar *uniform_name)
{
return 0;
}
void
cogl_shader_get_info_log (CoglHandle handle,
guint size,
gchar *buffer)
{
}
void
cogl_shader_get_parameteriv (CoglHandle handle,
COGLenum pname,
COGLint *dest)
{
}
void
cogl_program_uniform_1f (COGLint uniform_no,
gfloat value)
{
}