mirror of
https://github.com/brl/mutter.git
synced 2024-11-10 07:56:14 -05:00
cogl-shader: Prepend boilerplate for portable shaders
We now prepend a set of defines to any given GLSL shader so that we can define builtin uniforms/attributes within the "cogl" namespace that we can use to provide compatibility across a range of the earlier versions of GLSL. This updates test-cogl-shader-glsl.c and test-shader.c so they no longer needs to special case GLES vs GL when splicing together its shaders as well as the blur, colorize and desaturate effects. To get a feel for the new, portable uniform/attribute names here are the defines for OpenGL vertex shaders: #define cogl_position_in gl_Vertex #define cogl_color_in gl_Color #define cogl_tex_coord_in gl_MultiTexCoord0 #define cogl_tex_coord0_in gl_MultiTexCoord0 #define cogl_tex_coord1_in gl_MultiTexCoord1 #define cogl_tex_coord2_in gl_MultiTexCoord2 #define cogl_tex_coord3_in gl_MultiTexCoord3 #define cogl_tex_coord4_in gl_MultiTexCoord4 #define cogl_tex_coord5_in gl_MultiTexCoord5 #define cogl_tex_coord6_in gl_MultiTexCoord6 #define cogl_tex_coord7_in gl_MultiTexCoord7 #define cogl_normal_in gl_Normal #define cogl_position_out gl_Position #define cogl_point_size_out gl_PointSize #define cogl_color_out gl_FrontColor #define cogl_tex_coord_out gl_TexCoord #define cogl_modelview_matrix gl_ModelViewMatrix #define cogl_modelview_projection_matrix gl_ModelViewProjectionMatrix #define cogl_projection_matrix gl_ProjectionMatrix #define cogl_texture_matrix gl_TextureMatrix And for fragment shaders we have: #define cogl_color_in gl_Color #define cogl_tex_coord_in gl_TexCoord #define cogl_color_out gl_FragColor #define cogl_depth_out gl_FragDepth #define cogl_front_facing gl_FrontFacing
This commit is contained in:
parent
7a4c7b41c2
commit
353ea5299b
@ -239,7 +239,7 @@ cogl_create_context (void)
|
|||||||
default_texture_data);
|
default_texture_data);
|
||||||
|
|
||||||
cogl_push_source (_context->opaque_color_pipeline);
|
cogl_push_source (_context->opaque_color_pipeline);
|
||||||
_cogl_pipeline_flush_gl_state (_context->opaque_color_pipeline, FALSE);
|
_cogl_pipeline_flush_gl_state (_context->opaque_color_pipeline, FALSE, 0);
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
_cogl_flush_face_winding ();
|
_cogl_flush_face_winding ();
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ _cogl_path_stroke_nodes (void)
|
|||||||
|
|
||||||
cogl_push_source (source);
|
cogl_push_source (source);
|
||||||
|
|
||||||
_cogl_pipeline_flush_gl_state (source, FALSE);
|
_cogl_pipeline_flush_gl_state (source, FALSE, 0);
|
||||||
|
|
||||||
/* Disable all client texture coordinate arrays */
|
/* Disable all client texture coordinate arrays */
|
||||||
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
_cogl_bitmask_clear_all (&ctx->temp_bitmask);
|
||||||
@ -376,7 +376,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
|||||||
/* Just setup a simple pipeline that doesn't use texturing... */
|
/* Just setup a simple pipeline that doesn't use texturing... */
|
||||||
cogl_push_source (ctx->stencil_pipeline);
|
cogl_push_source (ctx->stencil_pipeline);
|
||||||
|
|
||||||
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE);
|
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0);
|
||||||
|
|
||||||
_cogl_enable (enable_flags);
|
_cogl_enable (enable_flags);
|
||||||
|
|
||||||
|
@ -327,7 +327,8 @@ get_arbfp_program_state (CoglPipeline *pipeline)
|
|||||||
static gboolean
|
static gboolean
|
||||||
_cogl_pipeline_backend_arbfp_start (CoglPipeline *pipeline,
|
_cogl_pipeline_backend_arbfp_start (CoglPipeline *pipeline,
|
||||||
int n_layers,
|
int n_layers,
|
||||||
unsigned long pipelines_difference)
|
unsigned long pipelines_difference,
|
||||||
|
int n_tex_coord_attribs)
|
||||||
{
|
{
|
||||||
CoglPipelineBackendARBfpPrivate *priv;
|
CoglPipelineBackendARBfpPrivate *priv;
|
||||||
CoglPipeline *authority;
|
CoglPipeline *authority;
|
||||||
|
@ -73,7 +73,8 @@ _cogl_pipeline_backend_fixed_get_max_texture_units (void)
|
|||||||
static gboolean
|
static gboolean
|
||||||
_cogl_pipeline_backend_fixed_start (CoglPipeline *pipeline,
|
_cogl_pipeline_backend_fixed_start (CoglPipeline *pipeline,
|
||||||
int n_layers,
|
int n_layers,
|
||||||
unsigned long pipelines_difference)
|
unsigned long pipelines_difference,
|
||||||
|
int n_tex_coord_attribs)
|
||||||
{
|
{
|
||||||
_cogl_use_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED);
|
_cogl_use_program (0, COGL_PIPELINE_PROGRAM_TYPE_FIXED);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -73,6 +73,17 @@ typedef struct _GlslProgramState
|
|||||||
unsigned int user_program_age;
|
unsigned int user_program_age;
|
||||||
GLuint gl_program;
|
GLuint gl_program;
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
/* To allow writing shaders that are portable between GLES 2 and
|
||||||
|
* OpenGL Cogl prepends a number of boilerplate #defines and
|
||||||
|
* declarations to user shaders. One of those declarations is an
|
||||||
|
* array of texture coordinate varyings, but to know how to emit the
|
||||||
|
* declaration we need to know how many texture coordinate
|
||||||
|
* attributes are in use. The boilerplate also needs to be changed
|
||||||
|
* if this increases. */
|
||||||
|
int n_tex_coord_attribs;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This is set to TRUE if the program has changed since we last
|
/* This is set to TRUE if the program has changed since we last
|
||||||
flushed the uniforms */
|
flushed the uniforms */
|
||||||
gboolean gl_program_changed;
|
gboolean gl_program_changed;
|
||||||
@ -252,7 +263,8 @@ link_program (GLint gl_program)
|
|||||||
static gboolean
|
static gboolean
|
||||||
_cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
|
_cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
|
||||||
int n_layers,
|
int n_layers,
|
||||||
unsigned long pipelines_difference)
|
unsigned long pipelines_difference,
|
||||||
|
int n_tex_coord_attribs)
|
||||||
{
|
{
|
||||||
CoglPipelineBackendGlslPrivate *priv;
|
CoglPipelineBackendGlslPrivate *priv;
|
||||||
CoglPipeline *authority;
|
CoglPipeline *authority;
|
||||||
@ -285,8 +297,17 @@ _cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
|
|||||||
if (priv->glsl_program_state)
|
if (priv->glsl_program_state)
|
||||||
{
|
{
|
||||||
/* However if the program has changed since the last link then we do
|
/* However if the program has changed since the last link then we do
|
||||||
need to relink */
|
* need to relink
|
||||||
if (priv->glsl_program_state->user_program_age == user_program->age)
|
*
|
||||||
|
* Also if the number of texture coordinate attributes in use has
|
||||||
|
* increased, then delete the program so we can prepend a new
|
||||||
|
* _cogl_tex_coord[] varying array declaration. */
|
||||||
|
if (priv->glsl_program_state->user_program_age == user_program->age
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
&& priv->glsl_program_state->n_tex_coord_attribs >=
|
||||||
|
n_tex_coord_attribs
|
||||||
|
#endif
|
||||||
|
)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
/* Destroy the existing program. We can't just dirty the whole
|
/* Destroy the existing program. We can't just dirty the whole
|
||||||
@ -340,6 +361,18 @@ _cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
GE_RET( gl_program, glCreateProgram () );
|
GE_RET( gl_program, glCreateProgram () );
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
/* Find the largest count of texture coordinate attributes
|
||||||
|
* associated with each of the shaders so we can ensure a consistent
|
||||||
|
* _cogl_tex_coord[] array declaration across all of the shaders.*/
|
||||||
|
for (l = user_program->attached_shaders; l; l = l->next)
|
||||||
|
{
|
||||||
|
CoglShader *shader = l->data;
|
||||||
|
n_tex_coord_attribs = MAX (shader->n_tex_coord_attribs,
|
||||||
|
n_tex_coord_attribs);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Add all of the shaders from the user program */
|
/* Add all of the shaders from the user program */
|
||||||
for (l = user_program->attached_shaders; l; l = l->next)
|
for (l = user_program->attached_shaders; l; l = l->next)
|
||||||
{
|
{
|
||||||
@ -347,11 +380,16 @@ _cogl_pipeline_backend_glsl_start (CoglPipeline *pipeline,
|
|||||||
|
|
||||||
g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL);
|
g_assert (shader->language == COGL_SHADER_LANGUAGE_GLSL);
|
||||||
|
|
||||||
|
_cogl_shader_compile_real (shader, n_tex_coord_attribs);
|
||||||
|
|
||||||
GE( glAttachShader (gl_program, shader->gl_handle) );
|
GE( glAttachShader (gl_program, shader->gl_handle) );
|
||||||
}
|
}
|
||||||
|
|
||||||
priv->glsl_program_state->gl_program = gl_program;
|
priv->glsl_program_state->gl_program = gl_program;
|
||||||
priv->glsl_program_state->user_program_age = user_program->age;
|
priv->glsl_program_state->user_program_age = user_program->age;
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
priv->glsl_program_state->n_tex_coord_attribs = n_tex_coord_attribs;
|
||||||
|
#endif
|
||||||
|
|
||||||
link_program (gl_program);
|
link_program (gl_program);
|
||||||
|
|
||||||
|
@ -150,7 +150,8 @@ _cogl_gl_use_program_wrapper (CoglHandle program);
|
|||||||
|
|
||||||
void
|
void
|
||||||
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
||||||
gboolean skip_gl_state);
|
gboolean skip_gl_state,
|
||||||
|
int n_tex_coord_attribs);
|
||||||
|
|
||||||
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
#endif /* __COGL_PIPELINE_OPENGL_PRIVATE_H */
|
||||||
|
|
||||||
|
@ -1036,7 +1036,8 @@ backend_add_layer_cb (CoglPipelineLayer *layer,
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
_cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
||||||
gboolean skip_gl_color)
|
gboolean skip_gl_color,
|
||||||
|
int n_tex_coord_attribs)
|
||||||
{
|
{
|
||||||
unsigned long pipelines_difference;
|
unsigned long pipelines_difference;
|
||||||
int n_layers;
|
int n_layers;
|
||||||
@ -1139,7 +1140,8 @@ _cogl_pipeline_flush_gl_state (CoglPipeline *pipeline,
|
|||||||
* scratch buffers here... */
|
* scratch buffers here... */
|
||||||
if (G_UNLIKELY (!backend->start (pipeline,
|
if (G_UNLIKELY (!backend->start (pipeline,
|
||||||
n_layers,
|
n_layers,
|
||||||
pipelines_difference)))
|
pipelines_difference,
|
||||||
|
n_tex_coord_attribs)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
state.backend = backend;
|
state.backend = backend;
|
||||||
|
@ -552,7 +552,8 @@ typedef struct _CoglPipelineBackend
|
|||||||
|
|
||||||
gboolean (*start) (CoglPipeline *pipeline,
|
gboolean (*start) (CoglPipeline *pipeline,
|
||||||
int n_layers,
|
int n_layers,
|
||||||
unsigned long pipelines_difference);
|
unsigned long pipelines_difference,
|
||||||
|
int n_tex_coord_attribs);
|
||||||
gboolean (*add_layer) (CoglPipeline *pipeline,
|
gboolean (*add_layer) (CoglPipeline *pipeline,
|
||||||
CoglPipelineLayer *layer,
|
CoglPipelineLayer *layer,
|
||||||
unsigned long layers_difference);
|
unsigned long layers_difference);
|
||||||
|
107
cogl/cogl-shader-boilerplate.h
Normal file
107
cogl/cogl-shader-boilerplate.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* Cogl
|
||||||
|
*
|
||||||
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||||
|
*
|
||||||
|
* Copyright (C) 2010 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/>.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* Robert Bragg <robert@linux.intel.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __COGL_SHADER_BOILERPLATE_H
|
||||||
|
#define __COGL_SHADER_BOILERPLATE_H
|
||||||
|
|
||||||
|
#include "cogl.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define _COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"#define COGL_VERSION 100\n" \
|
||||||
|
"\n"
|
||||||
|
|
||||||
|
#ifndef HAVE_COGL_GLES2
|
||||||
|
|
||||||
|
#define _COGL_VERTEX_SHADER_BOILERPLATE \
|
||||||
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"#define cogl_position_in gl_Vertex\n" \
|
||||||
|
"#define cogl_color_in gl_Color\n" \
|
||||||
|
"#define cogl_tex_coord_in gl_MultiTexCoord0\n" \
|
||||||
|
"#define cogl_tex_coord0_in gl_MultiTexCoord0\n" \
|
||||||
|
"#define cogl_tex_coord1_in gl_MultiTexCoord1\n" \
|
||||||
|
"#define cogl_tex_coord2_in gl_MultiTexCoord2\n" \
|
||||||
|
"#define cogl_tex_coord3_in gl_MultiTexCoord3\n" \
|
||||||
|
"#define cogl_tex_coord4_in gl_MultiTexCoord4\n" \
|
||||||
|
"#define cogl_tex_coord5_in gl_MultiTexCoord5\n" \
|
||||||
|
"#define cogl_tex_coord6_in gl_MultiTexCoord6\n" \
|
||||||
|
"#define cogl_tex_coord7_in gl_MultiTexCoord7\n" \
|
||||||
|
"#define cogl_normal_in gl_Normal\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_position_out gl_Position\n" \
|
||||||
|
"#define cogl_point_size_out gl_PointSize\n" \
|
||||||
|
"#define cogl_color_out gl_FrontColor\n" \
|
||||||
|
"#define cogl_tex_coord_out gl_TexCoord\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_modelview_matrix gl_ModelViewMatrix\n" \
|
||||||
|
"#define cogl_modelview_projection_matrix gl_ModelViewProjectionMatrix\n" \
|
||||||
|
"#define cogl_projection_matrix gl_ProjectionMatrix\n" \
|
||||||
|
"#define cogl_texture_matrix gl_TextureMatrix\n" \
|
||||||
|
|
||||||
|
#define _COGL_FRAGMENT_SHADER_BOILERPLATE \
|
||||||
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"#define cogl_color_in gl_Color\n" \
|
||||||
|
"#define cogl_tex_coord_in gl_TexCoord\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_color_out gl_FragColor\n" \
|
||||||
|
"#define cogl_depth_out gl_FragDepth\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_front_facing gl_FrontFacing\n"
|
||||||
|
#if 0
|
||||||
|
/* GLSL 1.2 has a bottom left origin, though later versions
|
||||||
|
* allow use of an origin_upper_left keyword which would be
|
||||||
|
* more appropriate for Cogl. */
|
||||||
|
"#define coglFragCoord gl_FragCoord\n"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* HAVE_COGL_GLES2 */
|
||||||
|
|
||||||
|
#define _COGL_VERTEX_SHADER_BOILERPLATE \
|
||||||
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"#define cogl_color_out _cogl_color\n" \
|
||||||
|
"#define cogl_point_coord_out _cogl_point_coord\n" \
|
||||||
|
"#define cogl_tex_coord_out _cogl_tex_coord\n"
|
||||||
|
|
||||||
|
#define _COGL_FRAGMENT_SHADER_BOILERPLATE \
|
||||||
|
_COGL_COMMON_SHADER_BOILERPLATE \
|
||||||
|
"#if __VERSION__ == 100\n" \
|
||||||
|
"precision highp float;\n" \
|
||||||
|
"#endif\n" \
|
||||||
|
"\n" \
|
||||||
|
"varying vec4 _cogl_color;\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_color_in _cogl_color\n" \
|
||||||
|
"#define cogl_tex_coord_in _cogl_tex_coord\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_color_out gl_FragColor\n" \
|
||||||
|
"#define cogl_depth_out gl_FragDepth\n" \
|
||||||
|
"\n" \
|
||||||
|
"#define cogl_front_facing gl_FrontFacing\n"
|
||||||
|
|
||||||
|
#endif /* HAVE_COGL_GLES2 */
|
||||||
|
|
||||||
|
#endif /* __COGL_SHADER_BOILERPLATE_H */
|
||||||
|
|
@ -40,12 +40,17 @@ struct _CoglShader
|
|||||||
{
|
{
|
||||||
CoglHandleObject _parent;
|
CoglHandleObject _parent;
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
|
int n_tex_coord_attribs;
|
||||||
CoglShaderType type;
|
CoglShaderType type;
|
||||||
CoglShaderLanguage language;
|
CoglShaderLanguage language;
|
||||||
|
char *source;
|
||||||
};
|
};
|
||||||
|
|
||||||
CoglShader *_cogl_shader_pointer_from_handle (CoglHandle handle);
|
CoglShader *_cogl_shader_pointer_from_handle (CoglHandle handle);
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_shader_compile_real (CoglHandle handle, int n_tex_coord_attribs);
|
||||||
|
|
||||||
CoglShaderLanguage
|
CoglShaderLanguage
|
||||||
_cogl_program_get_language (CoglHandle handle);
|
_cogl_program_get_language (CoglHandle handle);
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "cogl.h"
|
#include "cogl.h"
|
||||||
#include "cogl-shader-private.h"
|
#include "cogl-shader-private.h"
|
||||||
|
#include "cogl-shader-boilerplate.h"
|
||||||
#include "cogl-internal.h"
|
#include "cogl-internal.h"
|
||||||
#include "cogl-context.h"
|
#include "cogl-context.h"
|
||||||
#include "cogl-handle.h"
|
#include "cogl-handle.h"
|
||||||
@ -100,11 +101,35 @@ cogl_create_shader (CoglShaderType type)
|
|||||||
shader = g_slice_new (CoglShader);
|
shader = g_slice_new (CoglShader);
|
||||||
shader->language = COGL_SHADER_LANGUAGE_GLSL;
|
shader->language = COGL_SHADER_LANGUAGE_GLSL;
|
||||||
shader->gl_handle = 0;
|
shader->gl_handle = 0;
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
shader->n_tex_coord_attribs = 0;
|
||||||
|
#endif
|
||||||
shader->type = type;
|
shader->type = type;
|
||||||
|
|
||||||
return _cogl_shader_handle_new (shader);
|
return _cogl_shader_handle_new (shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
delete_shader (CoglShader *shader)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GL
|
||||||
|
if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
|
||||||
|
{
|
||||||
|
if (shader->gl_handle)
|
||||||
|
GE (glDeletePrograms (1, &shader->gl_handle));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (shader->gl_handle)
|
||||||
|
GE (glDeleteShader (shader->gl_handle));
|
||||||
|
}
|
||||||
|
|
||||||
|
shader->gl_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_shader_source (CoglHandle handle,
|
cogl_shader_source (CoglHandle handle,
|
||||||
const char *source)
|
const char *source)
|
||||||
@ -127,29 +152,55 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
language = COGL_SHADER_LANGUAGE_GLSL;
|
language = COGL_SHADER_LANGUAGE_GLSL;
|
||||||
|
|
||||||
/* Delete the old object if the language is changing... */
|
/* Delete the old object if the language is changing... */
|
||||||
if (G_UNLIKELY (language != shader->language))
|
if (G_UNLIKELY (language != shader->language) &&
|
||||||
{
|
shader->gl_handle)
|
||||||
#ifdef HAVE_COGL_GL
|
delete_shader (shader);
|
||||||
if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
|
|
||||||
{
|
shader->source = g_strdup (source);
|
||||||
if (shader->gl_handle)
|
|
||||||
GE (glDeletePrograms (1, &shader->gl_handle));
|
shader->language = language;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
void
|
||||||
{
|
cogl_shader_compile (CoglHandle handle)
|
||||||
if (shader->gl_handle)
|
{
|
||||||
GE (glDeleteShader (shader->gl_handle));
|
CoglShader *shader = handle;
|
||||||
}
|
|
||||||
}
|
if (!cogl_is_shader (handle))
|
||||||
|
return;
|
||||||
|
|
||||||
#ifdef HAVE_COGL_GL
|
#ifdef HAVE_COGL_GL
|
||||||
if (language == COGL_SHADER_LANGUAGE_ARBFP)
|
_cogl_shader_compile_real (shader, 0 /* ignored */);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* XXX: For GLES2 we don't actually compile anything until the
|
||||||
|
* shader gets used so we have an opportunity to add some
|
||||||
|
* boilerplate to the shader.
|
||||||
|
*
|
||||||
|
* At the end of the day this is obviously a badly designed API
|
||||||
|
* given that we are having to lie to the user. It was a mistake to
|
||||||
|
* so thinly wrap the OpenGL shader API and the current plan is to
|
||||||
|
* replace it with a pipeline snippets API. */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_cogl_shader_compile_real (CoglHandle handle,
|
||||||
|
int n_tex_coord_attribs)
|
||||||
|
{
|
||||||
|
CoglShader *shader = handle;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GL
|
||||||
|
if (shader->language == COGL_SHADER_LANGUAGE_ARBFP)
|
||||||
{
|
{
|
||||||
#ifdef COGL_GL_DEBUG
|
#ifdef COGL_GL_DEBUG
|
||||||
GLenum gl_error;
|
GLenum gl_error;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (shader->gl_handle)
|
||||||
|
return;
|
||||||
|
|
||||||
GE (glGenPrograms (1, &shader->gl_handle));
|
GE (glGenPrograms (1, &shader->gl_handle));
|
||||||
|
|
||||||
GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader->gl_handle));
|
GE (glBindProgram (GL_FRAGMENT_PROGRAM_ARB, shader->gl_handle));
|
||||||
@ -160,8 +211,8 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
#endif
|
#endif
|
||||||
glProgramString (GL_FRAGMENT_PROGRAM_ARB,
|
glProgramString (GL_FRAGMENT_PROGRAM_ARB,
|
||||||
GL_PROGRAM_FORMAT_ASCII_ARB,
|
GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||||
strlen (source),
|
strlen (shader->source),
|
||||||
source);
|
shader->source);
|
||||||
#ifdef COGL_GL_DEBUG
|
#ifdef COGL_GL_DEBUG
|
||||||
gl_error = glGetError ();
|
gl_error = glGetError ();
|
||||||
if (gl_error != GL_NO_ERROR)
|
if (gl_error != GL_NO_ERROR)
|
||||||
@ -169,7 +220,7 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s",
|
g_warning ("%s: GL error (%d): Failed to compile ARBfp:\n%s\n%s",
|
||||||
G_STRLOC,
|
G_STRLOC,
|
||||||
gl_error,
|
gl_error,
|
||||||
source,
|
shader->source,
|
||||||
glGetString (GL_PROGRAM_ERROR_STRING_ARB));
|
glGetString (GL_PROGRAM_ERROR_STRING_ARB));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -177,44 +228,70 @@ cogl_shader_source (CoglHandle handle,
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (!shader->gl_handle)
|
char *sourcev[4];
|
||||||
|
int count = 0;
|
||||||
|
GLenum gl_type;
|
||||||
|
|
||||||
|
if (shader->gl_handle
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
&& shader->n_tex_coord_attribs >= n_tex_coord_attribs
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (shader->gl_handle)
|
||||||
|
delete_shader (shader);
|
||||||
|
|
||||||
|
switch (shader->type)
|
||||||
{
|
{
|
||||||
GLenum gl_type;
|
case COGL_SHADER_TYPE_VERTEX:
|
||||||
|
gl_type = GL_VERTEX_SHADER;
|
||||||
switch (shader->type)
|
break;
|
||||||
{
|
case COGL_SHADER_TYPE_FRAGMENT:
|
||||||
case COGL_SHADER_TYPE_VERTEX:
|
gl_type = GL_FRAGMENT_SHADER;
|
||||||
gl_type = GL_VERTEX_SHADER;
|
break;
|
||||||
break;
|
default:
|
||||||
case COGL_SHADER_TYPE_FRAGMENT:
|
g_assert_not_reached ();
|
||||||
gl_type = GL_FRAGMENT_SHADER;
|
break;
|
||||||
break;
|
|
||||||
default:
|
|
||||||
g_assert_not_reached ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
shader->gl_handle = glCreateShader (gl_type);
|
|
||||||
}
|
}
|
||||||
glShaderSource (shader->gl_handle, 1, &source, NULL);
|
|
||||||
|
shader->gl_handle = glCreateShader (gl_type);
|
||||||
|
|
||||||
|
sourcev[count++] = _COGL_COMMON_SHADER_BOILERPLATE;
|
||||||
|
if (shader->type == COGL_SHADER_TYPE_VERTEX)
|
||||||
|
sourcev[count++] = _COGL_VERTEX_SHADER_BOILERPLATE;
|
||||||
|
else
|
||||||
|
sourcev[count++] = _COGL_FRAGMENT_SHADER_BOILERPLATE;
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
if (n_tex_coord_attribs)
|
||||||
|
sourcev[count++] =
|
||||||
|
g_strdup_printf ("varying vec2 _cogl_tex_coord[%d];\n",
|
||||||
|
n_tex_coord_attribs);
|
||||||
|
shader->n_tex_coord_attribs = n_tex_coord_attribs;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sourcev[count++] = shader->source;
|
||||||
|
|
||||||
|
glShaderSource (shader->gl_handle, count, (const char **)sourcev, NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_COGL_GLES2
|
||||||
|
if (count == 4)
|
||||||
|
g_free (sourcev[2]);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GE (glCompileShader (shader->gl_handle));
|
||||||
|
|
||||||
|
#ifdef COGL_GL_DEBUG
|
||||||
|
if (!cogl_shader_is_compiled (handle))
|
||||||
|
{
|
||||||
|
char *log = cogl_shader_get_info_log (handle);
|
||||||
|
g_warning ("Failed to compile GLSL program:\nsrc:\n%s\nerror:\n%s\n",
|
||||||
|
shader->source,
|
||||||
|
log);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
shader->language = language;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (shader->language == COGL_SHADER_LANGUAGE_GLSL)
|
|
||||||
GE (glCompileShader (shader->gl_handle));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -242,6 +319,21 @@ cogl_shader_get_info_log (CoglHandle handle)
|
|||||||
{
|
{
|
||||||
char buffer[512];
|
char buffer[512];
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
|
/* We don't normally compile the shader when the user calls
|
||||||
|
* cogl_shader_compile() because we want to be able to add
|
||||||
|
* boilerplate code that depends on how it ends up finally being
|
||||||
|
* used.
|
||||||
|
*
|
||||||
|
* Here we force an early compile if the user is interested in
|
||||||
|
* log information to increase the chance that the log will be
|
||||||
|
* useful! We have to guess the number of texture coordinate
|
||||||
|
* attributes that may be used (normally less than 4) since that
|
||||||
|
* affects the boilerplate.
|
||||||
|
*/
|
||||||
|
if (!shader->gl_handle)
|
||||||
|
_cogl_shader_compile_real (handle, 4);
|
||||||
|
|
||||||
glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||||
buffer[len] = '\0';
|
buffer[len] = '\0';
|
||||||
return g_strdup (buffer);
|
return g_strdup (buffer);
|
||||||
@ -284,6 +376,24 @@ cogl_shader_is_compiled (CoglHandle handle)
|
|||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/* FIXME: We currently have an arbitrary limit of 4 texture
|
||||||
|
* coordinate attributes since our API means we have to add
|
||||||
|
* some boilerplate to the users GLSL program (for GLES2)
|
||||||
|
* before we actually know how many attributes are in use.
|
||||||
|
*
|
||||||
|
* 4 will probably be enough (or at least that limitation should
|
||||||
|
* be enough until we can replace this API with the pipeline
|
||||||
|
* snippets API) but if it isn't then the shader won't compile,
|
||||||
|
* through no fault of the user.
|
||||||
|
*
|
||||||
|
* To some extent this is just a symptom of bad API design; it
|
||||||
|
* was a mistake for Cogl to so thinly wrap the OpenGL shader
|
||||||
|
* API. Eventually we plan for this whole API will be deprecated
|
||||||
|
* by the pipeline snippets framework.
|
||||||
|
*/
|
||||||
|
if (!shader->gl_handle)
|
||||||
|
_cogl_shader_compile_real (handle, 4);
|
||||||
|
|
||||||
GE (glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
GE (glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||||
if (status == GL_TRUE)
|
if (status == GL_TRUE)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -435,6 +435,7 @@ enable_gl_state (CoglVertexAttribute **attributes,
|
|||||||
gboolean skip_gl_color = FALSE;
|
gboolean skip_gl_color = FALSE;
|
||||||
CoglPipeline *source;
|
CoglPipeline *source;
|
||||||
CoglPipeline *copy = NULL;
|
CoglPipeline *copy = NULL;
|
||||||
|
int n_tex_coord_attribs = 0;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||||
|
|
||||||
@ -490,6 +491,7 @@ enable_gl_state (CoglVertexAttribute **attributes,
|
|||||||
base + attribute->offset));
|
base + attribute->offset));
|
||||||
_cogl_bitmask_set (&ctx->temp_bitmask,
|
_cogl_bitmask_set (&ctx->temp_bitmask,
|
||||||
attribute->texture_unit, TRUE);
|
attribute->texture_unit, TRUE);
|
||||||
|
n_tex_coord_attribs++;
|
||||||
break;
|
break;
|
||||||
case COGL_VERTEX_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
case COGL_VERTEX_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
|
||||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||||
@ -578,7 +580,7 @@ enable_gl_state (CoglVertexAttribute **attributes,
|
|||||||
_cogl_pipeline_apply_legacy_state (source);
|
_cogl_pipeline_apply_legacy_state (source);
|
||||||
}
|
}
|
||||||
|
|
||||||
_cogl_pipeline_flush_gl_state (source, skip_gl_color);
|
_cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs);
|
||||||
|
|
||||||
if (ctx->enable_backface_culling)
|
if (ctx->enable_backface_culling)
|
||||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||||
|
@ -218,6 +218,79 @@ validate_gl_attribute (const char *gl_attribute,
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* There are a number of standard OpenGL attributes that we deal with
|
||||||
|
* specially. These attributes are all namespaced with a "gl_" prefix
|
||||||
|
* so we should catch any typos instead of silently adding a custom
|
||||||
|
* attribute.
|
||||||
|
*/
|
||||||
|
static CoglVertexBufferAttribFlags
|
||||||
|
validate_cogl_attribute (const char *cogl_attribute,
|
||||||
|
guint8 n_components,
|
||||||
|
guint8 *texture_unit)
|
||||||
|
{
|
||||||
|
CoglVertexBufferAttribFlags type;
|
||||||
|
char *detail_seperator = NULL;
|
||||||
|
int name_len;
|
||||||
|
|
||||||
|
detail_seperator = strstr (cogl_attribute, "::");
|
||||||
|
if (detail_seperator)
|
||||||
|
name_len = detail_seperator - cogl_attribute;
|
||||||
|
else
|
||||||
|
name_len = strlen (cogl_attribute);
|
||||||
|
|
||||||
|
if (strncmp (cogl_attribute, "position_in", name_len) == 0)
|
||||||
|
{
|
||||||
|
if (G_UNLIKELY (n_components == 1))
|
||||||
|
g_critical ("glVertexPointer doesn't allow 1 component vertex "
|
||||||
|
"positions so we currently only support "
|
||||||
|
"\"cogl_position_in\" attributes where "
|
||||||
|
"n_components == 2, 3 or 4");
|
||||||
|
type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY;
|
||||||
|
}
|
||||||
|
else if (strncmp (cogl_attribute, "color_in", name_len) == 0)
|
||||||
|
{
|
||||||
|
if (G_UNLIKELY (n_components != 3 && n_components != 4))
|
||||||
|
g_critical ("glColorPointer expects 3 or 4 component colors so we "
|
||||||
|
"currently only support \"cogl_color_in\" attributes "
|
||||||
|
"where n_components == 3 or 4");
|
||||||
|
type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_COLOR_ARRAY;
|
||||||
|
}
|
||||||
|
else if (strncmp (cogl_attribute,
|
||||||
|
"cogl_tex_coord",
|
||||||
|
strlen ("cogl_tex_coord")) == 0)
|
||||||
|
{
|
||||||
|
unsigned int unit;
|
||||||
|
|
||||||
|
if (strcmp (cogl_attribute, "cogl_tex_coord_in") == 0)
|
||||||
|
unit = 0;
|
||||||
|
else if (sscanf (cogl_attribute, "cogl_tex_coord%u_in", &unit) != 1)
|
||||||
|
{
|
||||||
|
g_warning ("texture coordinate attributes should either be "
|
||||||
|
"referenced as \"cogl_tex_coord_in\" or with a"
|
||||||
|
"texture unit number like \"cogl_tex_coord1_in\"");
|
||||||
|
unit = 0;
|
||||||
|
}
|
||||||
|
/* FIXME: validate any '::' delimiter for this case */
|
||||||
|
*texture_unit = unit;
|
||||||
|
type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY;
|
||||||
|
}
|
||||||
|
else if (strncmp (cogl_attribute, "normal_in", name_len) == 0)
|
||||||
|
{
|
||||||
|
if (G_UNLIKELY (n_components != 3))
|
||||||
|
g_critical ("glNormalPointer expects 3 component normals so we "
|
||||||
|
"currently only support \"cogl_normal_in\" attributes "
|
||||||
|
"where n_components == 3");
|
||||||
|
type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_NORMAL_ARRAY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Unknown cogl_* attribute name cogl_%s\n", cogl_attribute);
|
||||||
|
type = COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
/* This validates that a custom attribute name is a valid GLSL variable name
|
/* This validates that a custom attribute name is a valid GLSL variable name
|
||||||
*
|
*
|
||||||
* NB: attribute names may have a detail component delimited using '::' E.g.
|
* NB: attribute names may have a detail component delimited using '::' E.g.
|
||||||
@ -402,8 +475,9 @@ cogl_vertex_buffer_add (CoglHandle handle,
|
|||||||
|
|
||||||
attribute = submitted_attribute;
|
attribute = submitted_attribute;
|
||||||
|
|
||||||
/* since we will skip validate_gl_attribute in this case, we need
|
/* since we will skip validate_gl/cogl_attribute in this case, we
|
||||||
* to pluck out the attribute type before overwriting the flags: */
|
* need to pluck out the attribute type before overwriting the
|
||||||
|
* flags: */
|
||||||
flags |=
|
flags |=
|
||||||
attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK;
|
attribute->flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_TYPE_MASK;
|
||||||
break;
|
break;
|
||||||
@ -424,6 +498,14 @@ cogl_vertex_buffer_add (CoglHandle handle,
|
|||||||
if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
|
if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (strncmp (attribute_name, "cogl_", 5) == 0)
|
||||||
|
{
|
||||||
|
flags |= validate_cogl_attribute (attribute_name + 5,
|
||||||
|
n_components,
|
||||||
|
&texture_unit);
|
||||||
|
if (flags & COGL_VERTEX_BUFFER_ATTRIB_FLAG_INVALID)
|
||||||
|
return;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY;
|
flags |= COGL_VERTEX_BUFFER_ATTRIB_FLAG_CUSTOM_ARRAY;
|
||||||
|
16
cogl/cogl.c
16
cogl/cogl.c
@ -745,6 +745,7 @@ void
|
|||||||
cogl_begin_gl (void)
|
cogl_begin_gl (void)
|
||||||
{
|
{
|
||||||
unsigned long enable_flags = 0;
|
unsigned long enable_flags = 0;
|
||||||
|
CoglPipeline *pipeline;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
@ -777,8 +778,21 @@ cogl_begin_gl (void)
|
|||||||
*
|
*
|
||||||
* A user should instead call cogl_set_source_color4ub() before
|
* A user should instead call cogl_set_source_color4ub() before
|
||||||
* cogl_begin_gl() to simplify the state flushed.
|
* cogl_begin_gl() to simplify the state flushed.
|
||||||
|
*
|
||||||
|
* XXX: note defining n_tex_coord_attribs using
|
||||||
|
* cogl_pipeline_get_n_layers is a hack, but the problem is that
|
||||||
|
* n_tex_coord_attribs is usually defined when drawing a primitive
|
||||||
|
* which isn't happening here.
|
||||||
|
*
|
||||||
|
* Maybe it would be more useful if this code did flush the
|
||||||
|
* opaque_color_pipeline and then call into cogl-pipeline-opengl.c to then
|
||||||
|
* restore all state for the material's backend back to default OpenGL
|
||||||
|
* values.
|
||||||
*/
|
*/
|
||||||
_cogl_pipeline_flush_gl_state (cogl_get_source (), FALSE);
|
pipeline = cogl_get_source ();
|
||||||
|
_cogl_pipeline_flush_gl_state (pipeline,
|
||||||
|
FALSE,
|
||||||
|
cogl_pipeline_get_n_layers (pipeline));
|
||||||
|
|
||||||
if (ctx->enable_backface_culling)
|
if (ctx->enable_backface_culling)
|
||||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||||
|
@ -7,8 +7,8 @@ precision highp float;
|
|||||||
/*** _cogl_fixed_fragment_shader_inputs ***/
|
/*** _cogl_fixed_fragment_shader_inputs ***/
|
||||||
|
|
||||||
/* Inputs from the vertex shader */
|
/* Inputs from the vertex shader */
|
||||||
varying vec4 frag_color;
|
varying vec4 _cogl_color;
|
||||||
varying float fog_amount;
|
varying float _cogl_fog_amount;
|
||||||
|
|
||||||
/*** _cogl_fixed_fragment_shader_texturing_options ***/
|
/*** _cogl_fixed_fragment_shader_texturing_options ***/
|
||||||
|
|
||||||
@ -17,10 +17,10 @@ varying float fog_amount;
|
|||||||
/*** _cogl_fixed_fragment_shader_fogging_options ***/
|
/*** _cogl_fixed_fragment_shader_fogging_options ***/
|
||||||
|
|
||||||
/* Fogging options */
|
/* Fogging options */
|
||||||
uniform vec4 fog_color;
|
uniform vec4 _cogl_fog_color;
|
||||||
|
|
||||||
/* Alpha test options */
|
/* Alpha test options */
|
||||||
uniform float alpha_test_ref;
|
uniform float _cogl_alpha_test_ref;
|
||||||
|
|
||||||
/*** _cogl_fixed_fragment_shader_main_declare ***/
|
/*** _cogl_fixed_fragment_shader_main_declare ***/
|
||||||
|
|
||||||
@ -33,30 +33,32 @@ main (void)
|
|||||||
/*** _cogl_fixed_fragment_shader_fog ***/
|
/*** _cogl_fixed_fragment_shader_fog ***/
|
||||||
|
|
||||||
/* Mix the calculated color with the fog color */
|
/* Mix the calculated color with the fog color */
|
||||||
gl_FragColor.rgb = mix (fog_color.rgb, gl_FragColor.rgb, fog_amount);
|
gl_FragColor.rgb = mix (_cogl_fog_color.rgb, gl_FragColor.rgb,
|
||||||
|
_cogl_fog_amount);
|
||||||
|
|
||||||
/* Alpha testing */
|
/* Alpha testing */
|
||||||
|
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_never ***/
|
/*** _cogl_fixed_fragment_shader_alpha_never ***/
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_less ***/
|
/*** _cogl_fixed_fragment_shader_alpha_less ***/
|
||||||
if (gl_FragColor.a >= alpha_test_ref)
|
if (gl_FragColor.a >= _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_equal ***/
|
/*** _cogl_fixed_fragment_shader_alpha_equal ***/
|
||||||
if (gl_FragColor.a != alpha_test_ref)
|
if (gl_FragColor.a != _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_lequal ***/
|
/*** _cogl_fixed_fragment_shader_alpha_lequal ***/
|
||||||
if (gl_FragColor.a > alpha_test_ref)
|
if (gl_FragColor.a > _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_greater ***/
|
/*** _cogl_fixed_fragment_shader_alpha_greater ***/
|
||||||
if (gl_FragColor.a <= alpha_test_ref)
|
if (gl_FragColor.a <= _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_notequal ***/
|
/*** _cogl_fixed_fragment_shader_alpha_notequal ***/
|
||||||
if (gl_FragColor.a == alpha_test_ref)
|
if (gl_FragColor.a == _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
/*** _cogl_fixed_fragment_shader_alpha_gequal ***/
|
/*** _cogl_fixed_fragment_shader_alpha_gequal ***/
|
||||||
if (gl_FragColor.a < alpha_test_ref)
|
if (gl_FragColor.a < _cogl_alpha_test_ref)
|
||||||
discard;
|
discard;
|
||||||
|
|
||||||
/*** _cogl_fixed_fragment_shader_end ***/
|
/*** _cogl_fixed_fragment_shader_end ***/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
/*** _cogl_fixed_vertex_shader_per_vertex_attribs ***/
|
/*** _cogl_fixed_vertex_shader_per_vertex_attribs ***/
|
||||||
|
|
||||||
/* Per vertex attributes */
|
/* Per vertex attributes */
|
||||||
attribute vec4 vertex_attrib;
|
attribute vec4 cogl_position_in;
|
||||||
attribute vec4 color_attrib;
|
attribute vec4 cogl_color_in;
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_transform_matrices ***/
|
/*** _cogl_fixed_vertex_shader_transform_matrices ***/
|
||||||
|
|
||||||
/* Transformation matrices */
|
/* Transformation matrices */
|
||||||
uniform mat4 modelview_matrix;
|
uniform mat4 cogl_modelview_matrix;
|
||||||
uniform mat4 mvp_matrix; /* combined modelview and projection matrix */
|
uniform mat4 cogl_modelview_projection_matrix; /* combined modelview and projection matrix */
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_output_variables ***/
|
/*** _cogl_fixed_vertex_shader_output_variables ***/
|
||||||
|
|
||||||
/* Outputs to the fragment shader */
|
/* Outputs to the fragment shader */
|
||||||
varying vec4 frag_color;
|
varying vec4 _cogl_color;
|
||||||
varying float fog_amount;
|
varying float _cogl_fog_amount;
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_fogging_options ***/
|
/*** _cogl_fixed_vertex_shader_fogging_options ***/
|
||||||
|
|
||||||
/* Fogging options */
|
/* Fogging options */
|
||||||
uniform float fog_density;
|
uniform float _cogl_fog_density;
|
||||||
uniform float fog_start;
|
uniform float _cogl_fog_start;
|
||||||
uniform float fog_end;
|
uniform float _cogl_fog_end;
|
||||||
|
|
||||||
/* Point options */
|
/* Point options */
|
||||||
uniform float point_size;
|
uniform float cogl_point_size_in;
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_main_start ***/
|
/*** _cogl_fixed_vertex_shader_main_start ***/
|
||||||
|
|
||||||
@ -34,38 +34,40 @@ main (void)
|
|||||||
vec4 transformed_tex_coord;
|
vec4 transformed_tex_coord;
|
||||||
|
|
||||||
/* Calculate the transformed position */
|
/* Calculate the transformed position */
|
||||||
gl_Position = mvp_matrix * vertex_attrib;
|
gl_Position = cogl_modelview_projection_matrix * cogl_position_in;
|
||||||
|
|
||||||
/* Copy across the point size from the uniform */
|
/* Copy across the point size from the uniform */
|
||||||
gl_PointSize = point_size;
|
gl_PointSize = cogl_point_size_in;
|
||||||
|
|
||||||
/* Calculate the transformed texture coordinate */
|
/* Calculate the transformed texture coordinate */
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_frag_color_start ***/
|
/*** _cogl_fixed_vertex_shader_frag_color_start ***/
|
||||||
|
|
||||||
/* Pass the interpolated vertex color on to the fragment shader */
|
/* Pass the interpolated vertex color on to the fragment shader */
|
||||||
frag_color = color_attrib;
|
_cogl_color = cogl_color_in;
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_fog_start ***/
|
/*** _cogl_fixed_vertex_shader_fog_start ***/
|
||||||
|
|
||||||
/* Estimate the distance from the eye using just the z-coordinate to
|
/* Estimate the distance from the eye using just the z-coordinate to
|
||||||
use as the fog coord */
|
use as the fog coord */
|
||||||
vec4 eye_coord = modelview_matrix * vertex_attrib;
|
vec4 eye_coord = cogl_modelview_matrix * cogl_position_in;
|
||||||
float fog_coord = abs (eye_coord.z / eye_coord.w);
|
float fog_coord = abs (eye_coord.z / eye_coord.w);
|
||||||
|
|
||||||
/* Calculate the fog amount per-vertex and interpolate it for the
|
/* Calculate the fog amount per-vertex and interpolate it for the
|
||||||
fragment shader */
|
fragment shader */
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_fog_exp ***/
|
/*** _cogl_fixed_vertex_shader_fog_exp ***/
|
||||||
fog_amount = exp (-fog_density * fog_coord);
|
_cogl_fog_amount = exp (-fog_density * fog_coord);
|
||||||
/*** _cogl_fixed_vertex_shader_fog_exp2 ***/
|
/*** _cogl_fixed_vertex_shader_fog_exp2 ***/
|
||||||
fog_amount = exp (-fog_density * fog_coord
|
_cogl_fog_amount = exp (-_cogl_fog_density * fog_coord
|
||||||
* fog_density * fog_coord);
|
* _cogl_fog_density * fog_coord);
|
||||||
/*** _cogl_fixed_vertex_shader_fog_linear ***/
|
/*** _cogl_fixed_vertex_shader_fog_linear ***/
|
||||||
fog_amount = (fog_end - fog_coord) / (fog_end - fog_start);
|
_cogl_fog_amount = (_cogl_fog_end - fog_coord) /
|
||||||
|
(_cogl_fog_end - _cogl_fog_start);
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_fog_end ***/
|
/*** _cogl_fixed_vertex_shader_fog_end ***/
|
||||||
fog_amount = clamp (fog_amount, 0.0, 1.0);
|
_cogl_fog_amount = clamp (_cogl_fog_amount, 0.0, 1.0);
|
||||||
|
|
||||||
/*** _cogl_fixed_vertex_shader_end ***/
|
/*** _cogl_fixed_vertex_shader_end ***/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
|||||||
for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
|
for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
|
||||||
if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
|
if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"attribute vec4 multi_tex_coord_attrib%d;\n",
|
"attribute vec4 cogl_tex_coord%d_in;\n",
|
||||||
i);
|
i);
|
||||||
|
|
||||||
/* Find the biggest enabled texture unit index */
|
/* Find the biggest enabled texture unit index */
|
||||||
@ -332,11 +332,11 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
|||||||
if (n_texture_units > 0)
|
if (n_texture_units > 0)
|
||||||
{
|
{
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"uniform mat4 texture_matrix[%d];\n",
|
"uniform mat4 cogl_texture_matrix[%d];\n",
|
||||||
n_texture_units);
|
n_texture_units);
|
||||||
|
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"varying vec2 tex_coord[%d];",
|
"varying vec2 _cogl_tex_coord[%d];",
|
||||||
n_texture_units);
|
n_texture_units);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,11 +349,11 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
|
|||||||
{
|
{
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"transformed_tex_coord = "
|
"transformed_tex_coord = "
|
||||||
"texture_matrix[%d] "
|
"cogl_texture_matrix[%d] "
|
||||||
" * multi_tex_coord_attrib%d;\n",
|
" * cogl_tex_coord%d_in;\n",
|
||||||
i, i);
|
i, i);
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"tex_coord[%d] = transformed_tex_coord.st "
|
"_cogl_tex_coord[%d] = transformed_tex_coord.st "
|
||||||
" / transformed_tex_coord.q;\n",
|
" / transformed_tex_coord.q;\n",
|
||||||
i);
|
i);
|
||||||
}
|
}
|
||||||
@ -410,19 +410,21 @@ cogl_gles2_add_texture_lookup (int unit,
|
|||||||
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
|
||||||
|
|
||||||
if (w->settings.tex_env[unit].texture_target == GL_TEXTURE_3D_OES)
|
if (w->settings.tex_env[unit].texture_target == GL_TEXTURE_3D_OES)
|
||||||
g_string_append_printf (shader_source, "texture3D (texture_unit[%d], ",
|
g_string_append_printf (shader_source,
|
||||||
|
"texture3D (_cogl_texture_unit[%d], ",
|
||||||
unit);
|
unit);
|
||||||
else
|
else
|
||||||
g_string_append_printf (shader_source, "texture2D (texture_unit[%d], ",
|
g_string_append_printf (shader_source,
|
||||||
|
"texture2D (_cogl_texture_unit[%d], ",
|
||||||
unit);
|
unit);
|
||||||
|
|
||||||
/* If point sprite coord generation is being used then divert to the
|
/* If point sprite coord generation is being used then divert to the
|
||||||
built-in varying var for that instead of the texture
|
built-in varying var for that instead of the texture
|
||||||
coordinates */
|
coordinates */
|
||||||
if (w->settings.tex_env[unit].point_sprite_coords)
|
if (w->settings.tex_env[unit].point_sprite_coords)
|
||||||
g_string_append (shader_source, "gl_PointCoord");
|
g_string_append (shader_source, "_cogl_point_coord");
|
||||||
else
|
else
|
||||||
g_string_append_printf (shader_source, "tex_coord[%d]", unit);
|
g_string_append_printf (shader_source, "_cogl_tex_coord[%d]", unit);
|
||||||
|
|
||||||
g_string_append_printf (shader_source, ").%s", swizzle);
|
g_string_append_printf (shader_source, ").%s", swizzle);
|
||||||
}
|
}
|
||||||
@ -458,7 +460,7 @@ cogl_gles2_add_arg (int unit,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case GL_CONSTANT:
|
case GL_CONSTANT:
|
||||||
g_string_append_printf (shader_source, "combine_constant[%d].%s",
|
g_string_append_printf (shader_source, "_cogl_combine_constant[%d].%s",
|
||||||
unit, swizzle);
|
unit, swizzle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -470,7 +472,7 @@ cogl_gles2_add_arg (int unit,
|
|||||||
}
|
}
|
||||||
/* flow through */
|
/* flow through */
|
||||||
case GL_PRIMARY_COLOR:
|
case GL_PRIMARY_COLOR:
|
||||||
g_string_append_printf (shader_source, "frag_color.%s", swizzle);
|
g_string_append_printf (shader_source, "_cogl_color.%s", swizzle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -635,13 +637,13 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
|||||||
if (n_texture_units > 0)
|
if (n_texture_units > 0)
|
||||||
{
|
{
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"varying vec2 tex_coord[%d];\n",
|
"varying vec2 _cogl_tex_coord[%d];\n",
|
||||||
n_texture_units);
|
n_texture_units);
|
||||||
|
|
||||||
g_string_append (shader_source,
|
g_string_append (shader_source,
|
||||||
_cogl_fixed_fragment_shader_texturing_options);
|
_cogl_fixed_fragment_shader_texturing_options);
|
||||||
g_string_append_printf (shader_source,
|
g_string_append_printf (shader_source,
|
||||||
"uniform sampler2D texture_unit[%d];\n",
|
"uniform sampler2D _cogl_texture_unit[%d];\n",
|
||||||
n_texture_units);
|
n_texture_units);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,12 +657,12 @@ cogl_gles2_get_fragment_shader (const CoglGles2WrapperSettings *settings)
|
|||||||
apparent bug in the PowerVR drivers. Without it the alpha
|
apparent bug in the PowerVR drivers. Without it the alpha
|
||||||
blending seems to stop working */
|
blending seems to stop working */
|
||||||
g_string_append (shader_source,
|
g_string_append (shader_source,
|
||||||
"vec4 frag_color_copy = frag_color;\n");
|
"vec4 frag_color_copy = _cogl_color;\n");
|
||||||
|
|
||||||
/* If there are no textures units enabled then we can just directly
|
/* If there are no textures units enabled then we can just directly
|
||||||
use the color from the vertex shader */
|
use the color from the vertex shader */
|
||||||
if (n_texture_units == 0)
|
if (n_texture_units == 0)
|
||||||
g_string_append (shader_source, "gl_FragColor = frag_color;\n");
|
g_string_append (shader_source, "gl_FragColor = _cogl_color;\n");
|
||||||
else
|
else
|
||||||
/* Otherwise we need to calculate the value based on the layer
|
/* Otherwise we need to calculate the value based on the layer
|
||||||
combine settings */
|
combine settings */
|
||||||
@ -769,17 +771,17 @@ cogl_gles2_wrapper_get_locations (GLuint program,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
uniforms->mvp_matrix_uniform
|
uniforms->mvp_matrix_uniform
|
||||||
= glGetUniformLocation (program, "mvp_matrix");
|
= glGetUniformLocation (program, "cogl_modelview_projection_matrix");
|
||||||
uniforms->modelview_matrix_uniform
|
uniforms->modelview_matrix_uniform
|
||||||
= glGetUniformLocation (program, "modelview_matrix");
|
= glGetUniformLocation (program, "cogl_modelview_matrix");
|
||||||
|
|
||||||
for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
|
for (i = 0; i < COGL_GLES2_MAX_TEXTURE_UNITS; i++)
|
||||||
if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
|
if (COGL_GLES2_TEXTURE_UNIT_IS_ENABLED (settings->texture_units, i))
|
||||||
{
|
{
|
||||||
char *matrix_var_name = g_strdup_printf ("texture_matrix[%d]", i);
|
char *matrix_var_name = g_strdup_printf ("cogl_texture_matrix[%d]", i);
|
||||||
char *sampler_var_name = g_strdup_printf ("texture_unit[%d]", i);
|
char *sampler_var_name = g_strdup_printf ("_cogl_texture_unit[%d]", i);
|
||||||
char *tex_coord_var_name =
|
char *tex_coord_var_name =
|
||||||
g_strdup_printf ("multi_tex_coord_attrib%d", i);
|
g_strdup_printf ("cogl_tex_coord%d_in", i);
|
||||||
|
|
||||||
uniforms->texture_matrix_uniforms[i]
|
uniforms->texture_matrix_uniforms[i]
|
||||||
= glGetUniformLocation (program, matrix_var_name);
|
= glGetUniformLocation (program, matrix_var_name);
|
||||||
@ -800,30 +802,30 @@ cogl_gles2_wrapper_get_locations (GLuint program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uniforms->fog_density_uniform
|
uniforms->fog_density_uniform
|
||||||
= glGetUniformLocation (program, "fog_density");
|
= glGetUniformLocation (program, "_cogl_fog_density");
|
||||||
uniforms->fog_start_uniform
|
uniforms->fog_start_uniform
|
||||||
= glGetUniformLocation (program, "fog_start");
|
= glGetUniformLocation (program, "_cogl_fog_start");
|
||||||
uniforms->fog_end_uniform
|
uniforms->fog_end_uniform
|
||||||
= glGetUniformLocation (program, "fog_end");
|
= glGetUniformLocation (program, "_cogl_fog_end");
|
||||||
uniforms->fog_color_uniform
|
uniforms->fog_color_uniform
|
||||||
= glGetUniformLocation (program, "fog_color");
|
= glGetUniformLocation (program, "_cogl_fog_color");
|
||||||
|
|
||||||
uniforms->alpha_test_ref_uniform
|
uniforms->alpha_test_ref_uniform
|
||||||
= glGetUniformLocation (program, "alpha_test_ref");
|
= glGetUniformLocation (program, "_cogl_alpha_test_ref");
|
||||||
|
|
||||||
uniforms->point_size_uniform
|
uniforms->point_size_uniform
|
||||||
= glGetUniformLocation (program, "point_size");
|
= glGetUniformLocation (program, "cogl_point_size_in");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cogl_gles2_wrapper_bind_attributes (GLuint program)
|
cogl_gles2_wrapper_bind_attributes (GLuint program)
|
||||||
{
|
{
|
||||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
|
glBindAttribLocation (program, COGL_GLES2_WRAPPER_VERTEX_ATTRIB,
|
||||||
"vertex_attrib");
|
"cogl_position_in");
|
||||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
|
glBindAttribLocation (program, COGL_GLES2_WRAPPER_COLOR_ATTRIB,
|
||||||
"color_attrib");
|
"cogl_color_in");
|
||||||
glBindAttribLocation (program, COGL_GLES2_WRAPPER_NORMAL_ATTRIB,
|
glBindAttribLocation (program, COGL_GLES2_WRAPPER_NORMAL_ATTRIB,
|
||||||
"normal_attrib");
|
"cogl_normal_in");
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglGles2WrapperProgram *
|
static CoglGles2WrapperProgram *
|
||||||
|
Loading…
Reference in New Issue
Block a user