cogl-material: Add support for point sprites

This adds a new API call to enable point sprite coordinate generation
for a material layer:

void
cogl_material_set_layer_point_sprite_coords_enabled (CoglHandle material,
                                                     int layer_index,
                                                     gboolean enable);

There is also a corresponding get function.

Enabling point sprite coords simply sets the GL_COORD_REPLACE of the
GL_POINT_SPRITE glTexEnv when flusing the material. There is no
separate application control for glEnable(GL_POINT_SPRITE). Instead it
is left permanently enabled under the assumption that it has no affect
unless GL_COORD_REPLACE is enabled for a texture unit.

http://bugzilla.openedhand.com/show_bug.cgi?id=2047
This commit is contained in:
Neil Roberts 2010-03-22 13:33:55 +00:00 committed by Robert Bragg
parent 06b58baa10
commit da3be3df6b
10 changed files with 306 additions and 31 deletions

View File

@ -41,6 +41,11 @@
#define glActiveTexture _context->drv.pf_glActiveTexture #define glActiveTexture _context->drv.pf_glActiveTexture
#endif #endif
/* This isn't defined in the GLES headers */
#ifndef GL_POINT_SPRITE
#define GL_POINT_SPRITE 0x8861
#endif
extern void extern void
_cogl_create_context_driver (CoglContext *context); _cogl_create_context_driver (CoglContext *context);
extern void extern void
@ -211,6 +216,15 @@ cogl_create_context (void)
_context->atlas = NULL; _context->atlas = NULL;
_context->atlas_texture = COGL_INVALID_HANDLE; _context->atlas_texture = COGL_INVALID_HANDLE;
/* As far as I can tell, GL_POINT_SPRITE doesn't have any effect
unless GL_COORD_REPLACE is enabled for an individual
layer. Therefore it seems like it should be ok to just leave it
enabled all the time instead of having to have a set property on
each material to track whether any layers have point sprite
coords enabled */
if (cogl_features_available (COGL_FEATURE_POINT_SPRITE))
GE (glEnable (GL_POINT_SPRITE));
return TRUE; return TRUE;
} }

View File

@ -184,7 +184,9 @@ typedef enum
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT = 1L<<5, COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
COGL_MATERIAL_LAYER_STATE_USER_MATRIX = 1L<<6, COGL_MATERIAL_LAYER_STATE_USER_MATRIX = 1L<<6,
/* COGL_MATERIAL_LAYER_STATE_TEXTURE_INTERN = 1L<<7, */ COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS = 1L<<7,
/* COGL_MATERIAL_LAYER_STATE_TEXTURE_INTERN = 1L<<8, */
COGL_MATERIAL_LAYER_STATE_ALL_SPARSE = COGL_MATERIAL_LAYER_STATE_ALL_SPARSE =
COGL_MATERIAL_LAYER_STATE_UNIT | COGL_MATERIAL_LAYER_STATE_UNIT |
@ -193,12 +195,14 @@ typedef enum
COGL_MATERIAL_LAYER_STATE_WRAP_MODES | COGL_MATERIAL_LAYER_STATE_WRAP_MODES |
COGL_MATERIAL_LAYER_STATE_COMBINE | COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT | COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX, COGL_MATERIAL_LAYER_STATE_USER_MATRIX |
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS,
COGL_MATERIAL_LAYER_STATE_NEEDS_BIG_STATE = COGL_MATERIAL_LAYER_STATE_NEEDS_BIG_STATE =
COGL_MATERIAL_LAYER_STATE_COMBINE | COGL_MATERIAL_LAYER_STATE_COMBINE |
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT | COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
COGL_MATERIAL_LAYER_STATE_USER_MATRIX COGL_MATERIAL_LAYER_STATE_USER_MATRIX |
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS,
} CoglMaterialLayerState; } CoglMaterialLayerState;
@ -219,6 +223,8 @@ typedef struct
/* The texture matrix dscribes how to transform texture coordinates */ /* The texture matrix dscribes how to transform texture coordinates */
CoglMatrix matrix; CoglMatrix matrix;
gboolean point_sprite_coords;
} CoglMaterialLayerBigState; } CoglMaterialLayerBigState;
struct _CoglMaterialLayer struct _CoglMaterialLayer

View File

@ -72,7 +72,13 @@
#define glUseProgram ctx->drv.pf_glUseProgram #define glUseProgram ctx->drv.pf_glUseProgram
#endif #endif
/* This isn't defined in the GLES headers */ /* These aren't defined in the GLES headers */
#ifndef GL_POINT_SPRITE
#define GL_POINT_SPRITE 0x8861
#endif
#ifndef GL_COORD_REPLACE
#define GL_COORD_REPLACE 0x8862
#endif
#ifndef GL_CLAMP_TO_BORDER #ifndef GL_CLAMP_TO_BORDER
#define GL_CLAMP_TO_BORDER 0x812d #define GL_CLAMP_TO_BORDER 0x812d
#endif #endif
@ -1549,6 +1555,9 @@ _cogl_material_layer_initialize_state (CoglMaterialLayer *dest,
if (differences & COGL_MATERIAL_LAYER_STATE_USER_MATRIX) if (differences & COGL_MATERIAL_LAYER_STATE_USER_MATRIX)
dest->big_state->matrix = src->big_state->matrix; dest->big_state->matrix = src->big_state->matrix;
if (differences & COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS)
dest->big_state->point_sprite_coords = src->big_state->point_sprite_coords;
} }
/* NB: This function will allocate a new derived layer if you are /* NB: This function will allocate a new derived layer if you are
@ -2466,6 +2475,123 @@ _cogl_material_layer_get_wrap_modes (CoglMaterialLayer *layer,
*wrap_mode_r = authority->wrap_mode_r; *wrap_mode_r = authority->wrap_mode_r;
} }
gboolean
cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index,
gboolean enable,
GError **error)
{
CoglMaterialLayerState change =
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS;
CoglMaterialLayer *layer;
CoglMaterialLayer *new;
CoglMaterialLayer *authority;
g_return_val_if_fail (cogl_is_material (material), FALSE);
/* Don't allow point sprite coordinates to be enabled if the driver
doesn't support it */
if (enable && !cogl_features_available (COGL_FEATURE_POINT_SPRITE))
{
if (error)
{
g_set_error (error, COGL_ERROR, COGL_ERROR_MISSING_FEATURE,
"Point sprite texture coordinates are enabled "
"for a layer but the GL driver does not support it.");
}
else
{
static gboolean warning_seen = FALSE;
if (!warning_seen)
g_warning ("Point sprite texture coordinates are enabled "
"for a layer but the GL driver does not support it.");
warning_seen = TRUE;
}
return FALSE;
}
/* Note: this will ensure that the layer exists, creating one if it
* doesn't already.
*
* Note: If the layer already existed it's possibly owned by another
* material. If the layer is created then it will be owned by
* material. */
layer = _cogl_material_get_layer (material, layer_index);
/* Now find the ancestor of the layer that is the authority for the
* state we want to change */
authority = _cogl_material_layer_get_authority (layer, change);
if (authority->big_state->point_sprite_coords == enable)
return TRUE;
new = _cogl_material_layer_pre_change_notify (material, layer, change);
if (new != layer)
layer = new;
else
{
/* If the original layer we found is currently the authority on
* the state we are changing see if we can revert to one of our
* ancestors being the authority. */
if (layer == authority && authority->parent != NULL)
{
CoglMaterialLayer *old_authority =
_cogl_material_layer_get_authority (authority->parent, change);
if (old_authority->big_state->point_sprite_coords == enable)
{
layer->differences &= ~change;
g_assert (layer->owner == material);
if (layer->differences == 0)
_cogl_material_prune_empty_layer_difference (material,
layer);
return TRUE;
}
}
}
layer->big_state->point_sprite_coords = enable;
/* If we weren't previously the authority on this state then we need
* to extended our differences mask and so it's possible that some
* of our ancestry will now become redundant, so we aim to reparent
* ourselves if that's true... */
if (layer != authority)
{
layer->differences |= change;
_cogl_material_layer_prune_redundant_ancestry (layer);
}
return TRUE;
}
gboolean
cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index)
{
CoglMaterialLayerState change =
COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS;
CoglMaterialLayer *layer;
CoglMaterialLayer *authority;
g_return_val_if_fail (cogl_is_material (material), FALSE);
/* Note: this will ensure that the layer exists, creating one if it
* doesn't already.
*
* Note: If the layer already existed it's possibly owned by another
* material. If the layer is created then it will be owned by
* material. */
layer = _cogl_material_get_layer (material, layer_index);
/* FIXME: we shouldn't ever construct a layer in a getter function */
authority = _cogl_material_layer_get_authority (layer, change);
return authority->big_state->point_sprite_coords;
}
typedef struct typedef struct
{ {
CoglMaterial *material; CoglMaterial *material;
@ -2793,6 +2919,16 @@ _cogl_material_layer_user_matrix_equal (CoglMaterialLayer *authority0,
return TRUE; return TRUE;
} }
static gboolean
_cogl_material_layer_point_sprite_coords_equal (CoglMaterialLayer *authority0,
CoglMaterialLayer *authority1)
{
CoglMaterialLayerBigState *big_state0 = authority0->big_state;
CoglMaterialLayerBigState *big_state1 = authority1->big_state;
return big_state0->point_sprite_coords == big_state1->point_sprite_coords;
}
typedef gboolean typedef gboolean
(*CoglMaterialLayerStateComparitor) (CoglMaterialLayer *authority0, (*CoglMaterialLayerStateComparitor) (CoglMaterialLayer *authority0,
CoglMaterialLayer *authority1); CoglMaterialLayer *authority1);
@ -2859,6 +2995,12 @@ _cogl_material_layer_equal (CoglMaterialLayer *layer0,
_cogl_material_layer_user_matrix_equal)) _cogl_material_layer_user_matrix_equal))
return FALSE; return FALSE;
if (layers_difference & COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS &&
!layer_state_equal (COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS,
layer0, layer1,
_cogl_material_layer_point_sprite_coords_equal))
return FALSE;
return TRUE; return TRUE;
} }
@ -4357,6 +4499,8 @@ _cogl_material_init_default_layers (void)
big_state->texture_combine_alpha_op[0] = GL_SRC_ALPHA; big_state->texture_combine_alpha_op[0] = GL_SRC_ALPHA;
big_state->texture_combine_alpha_op[1] = GL_SRC_ALPHA; big_state->texture_combine_alpha_op[1] = GL_SRC_ALPHA;
big_state->point_sprite_coords = FALSE;
cogl_matrix_init_identity (&big_state->matrix); cogl_matrix_init_identity (&big_state->matrix);
ctx->default_layer_0 = _cogl_material_layer_object_new (layer); ctx->default_layer_0 = _cogl_material_layer_object_new (layer);
@ -5575,9 +5719,23 @@ flush_layers_common_gl_state_cb (CoglMaterialLayer *layer, void *user_data)
_cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE); _cogl_matrix_stack_flush_to_gl (unit->matrix_stack, COGL_MATRIX_TEXTURE);
} }
cogl_object_ref (layer); if (layers_difference & COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS)
if (unit->layer != NULL) {
cogl_object_unref (unit->layer); CoglMaterialState change = COGL_MATERIAL_LAYER_STATE_POINT_SPRITE_COORDS;
CoglMaterialLayer *authority =
_cogl_material_layer_get_authority (layer, change);
CoglMaterialLayerBigState *big_state = authority->big_state;
_cogl_set_active_texture_unit (unit_index);
GE (glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE,
big_state->point_sprite_coords));
}
cogl_handle_ref (layer);
if (unit->layer != COGL_INVALID_HANDLE)
cogl_handle_unref (unit->layer);
unit->layer = layer; unit->layer = layer;
unit->layer_changes_since_flush = 0; unit->layer_changes_since_flush = 0;

View File

@ -921,6 +921,50 @@ cogl_material_set_layer_filters (CoglMaterial *material,
CoglMaterialFilter min_filter, CoglMaterialFilter min_filter,
CoglMaterialFilter mag_filter); CoglMaterialFilter mag_filter);
/**
* cogl_material_set_layer_point_sprite_coords_enabled:
* @material: a #CoglHandle to a material.
* @layer_index: the layer number to change.
* @enable: whether to enable point sprite coord generation.
* @error: A return location for a GError, or NULL to ignore errors.
*
* When rendering points, if @enable is %TRUE then the texture
* coordinates for this layer will be replaced with coordinates that
* vary from 0.0 to 1.0 across the primitive. The top left of the
* point will have the coordinates 0.0,0.0 and the bottom right will
* have 1.0,1.0. If @enable is %FALSE then the coordinates will be
* fixed for the entire point.
*
* This function will only work if %COGL_FEATURE_POINT_SPRITE is
* available. If the feature is not available then the function will
* return %FALSE and set @error.
*
* Return value: %TRUE if the function succeeds, %FALSE otherwise.
* Since: 1.4
*/
gboolean
cogl_material_set_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index,
gboolean enable,
GError **error);
/**
* cogl_material_get_layer_point_sprite_coords_enabled:
* @material: a #CoglHandle to a material.
* @layer_index: the layer number to check.
*
* Gets whether point sprite coordinate generation is enabled for this
* texture layer.
*
* Return value: whether the texture coordinates will be replaced with
* point sprite coordinates.
*
* Since: 1.4
*/
gboolean
cogl_material_get_layer_point_sprite_coords_enabled (CoglMaterial *material,
int layer_index);
/** /**
* cogl_material_set_layer_wrap_mode_s: * cogl_material_set_layer_wrap_mode_s:
* @material: A #CoglMaterial object * @material: A #CoglMaterial object

View File

@ -248,6 +248,8 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
* @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than * @COGL_FEATURE_TEXTURE_NPOT_REPEAT: Repeat modes other than
* %COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE are supported by the * %COGL_MATERIAL_WRAP_MODE_CLAMP_TO_EDGE are supported by the
* hardware. * hardware.
* @COGL_FEATURE_POINT_SPRITE: Whether
* cogl_material_set_layer_point_sprite_coords_enabled() is supported.
* *
* Flags for the supported features. * Flags for the supported features.
* *
@ -271,7 +273,8 @@ typedef enum
COGL_FEATURE_DEPTH_RANGE = (1 << 14), COGL_FEATURE_DEPTH_RANGE = (1 << 14),
COGL_FEATURE_TEXTURE_NPOT_BASIC = (1 << 15), COGL_FEATURE_TEXTURE_NPOT_BASIC = (1 << 15),
COGL_FEATURE_TEXTURE_NPOT_MIPMAP = (1 << 16), COGL_FEATURE_TEXTURE_NPOT_MIPMAP = (1 << 16),
COGL_FEATURE_TEXTURE_NPOT_REPEAT = (1 << 17) COGL_FEATURE_TEXTURE_NPOT_REPEAT = (1 << 17),
COGL_FEATURE_POINT_SPRITE = (1 << 18)
} CoglFeatureFlags; } CoglFeatureFlags;
/** /**

View File

@ -380,3 +380,10 @@ COGL_FEATURE_FUNCTION (void, glBlendEquationSeparate,
(GLenum modeRGB, (GLenum modeRGB,
GLenum modeAlpha)) GLenum modeAlpha))
COGL_FEATURE_END () COGL_FEATURE_END ()
COGL_FEATURE_BEGIN (point_sprites, 2, 0,
"ARB\0",
"point_sprite\0",
COGL_FEATURE_POINT_SPRITE,
0)
COGL_FEATURE_END ()

View File

@ -155,6 +155,9 @@ initialize_texture_units (CoglGles2Wrapper *w)
GL_SRC_COLOR) ); GL_SRC_COLOR) );
GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GE( _cogl_wrap_glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
GL_SRC_COLOR) ); GL_SRC_COLOR) );
GE( _cogl_wrap_glTexEnvi (GL_POINT_SPRITE, GL_COORD_REPLACE,
GL_FALSE) );
} }
GE( _cogl_wrap_glMatrixMode ((GLenum) prev_mode)); GE( _cogl_wrap_glMatrixMode ((GLenum) prev_mode));
@ -256,6 +259,10 @@ cogl_gles2_settings_equal (const CoglGles2WrapperSettings *a,
int arg, n_args; int arg, n_args;
GLenum func; GLenum func;
if (tex_env_a->point_sprite_coords !=
tex_env_b->point_sprite_coords)
return FALSE;
func = tex_env_a->texture_combine_rgb_func; func = tex_env_a->texture_combine_rgb_func;
if (func != tex_env_b->texture_combine_rgb_func) if (func != tex_env_b->texture_combine_rgb_func)
@ -329,7 +336,8 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
g_string_append (shader_source, _cogl_fixed_vertex_shader_main_start); g_string_append (shader_source, _cogl_fixed_vertex_shader_main_start);
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) &&
!settings->tex_env[i].point_sprite_coords)
{ {
g_string_append_printf (shader_source, g_string_append_printf (shader_source,
"transformed_tex_coord = " "transformed_tex_coord = "
@ -386,6 +394,26 @@ cogl_gles2_get_vertex_shader (const CoglGles2WrapperSettings *settings)
return shader; return shader;
} }
static void
cogl_gles2_add_texture_lookup (int unit,
const char *swizzle,
GString *shader_source)
{
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
g_string_append_printf (shader_source, "texture2D (texture_unit[%d], ", unit);
/* If point sprite coord generation is being used then divert to the
built-in varying var for that instead of the texture
coordinates */
if (w->settings.tex_env[unit].point_sprite_coords)
g_string_append (shader_source, "gl_PointCoord");
else
g_string_append_printf (shader_source, "tex_coord[%d]", unit);
g_string_append_printf (shader_source, ").%s", swizzle);
}
static void static void
cogl_gles2_add_arg (int unit, cogl_gles2_add_arg (int unit,
GLenum src, GLenum src,
@ -413,9 +441,7 @@ cogl_gles2_add_arg (int unit,
switch (src) switch (src)
{ {
case GL_TEXTURE: case GL_TEXTURE:
g_string_append_printf (shader_source, cogl_gles2_add_texture_lookup (unit, swizzle, shader_source);
"texture2D (texture_unit[%d], tex_coord[%d]).%s",
unit, unit, swizzle);
break; break;
case GL_CONSTANT: case GL_CONSTANT:
@ -437,12 +463,8 @@ cogl_gles2_add_arg (int unit,
default: default:
if (src >= GL_TEXTURE0 && if (src >= GL_TEXTURE0 &&
src < GL_TEXTURE0 + COGL_GLES2_MAX_TEXTURE_UNITS) src < GL_TEXTURE0 + COGL_GLES2_MAX_TEXTURE_UNITS)
g_string_append_printf (shader_source, cogl_gles2_add_texture_lookup (src - GL_TEXTURE0,
"texture2D (texture_unit[%d], " swizzle, shader_source);
"tex_coord[%d]).%s",
src - GL_TEXTURE0,
src - GL_TEXTURE0,
swizzle);
break; break;
} }
@ -1350,14 +1372,14 @@ _cogl_wrap_glDrawElements (GLenum mode, GLsizei count, GLenum type,
void void
_cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param) _cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param)
{ {
CoglGles2WrapperTexEnv *tex_env;
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
tex_env = w->settings.tex_env + w->active_texture_unit;
if (target == GL_TEXTURE_ENV) if (target == GL_TEXTURE_ENV)
{ {
CoglGles2WrapperTexEnv *tex_env;
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
tex_env = w->settings.tex_env + w->active_texture_unit;
switch (pname) switch (pname)
{ {
case GL_COMBINE_RGB: case GL_COMBINE_RGB:
@ -1388,6 +1410,17 @@ _cogl_wrap_glTexEnvi (GLenum target, GLenum pname, GLint param)
break; break;
} }
w->settings_dirty = TRUE;
}
else if (target == GL_POINT_SPRITE)
{
switch (pname)
{
case GL_COORD_REPLACE:
tex_env->point_sprite_coords = param;
break;
}
w->settings_dirty = TRUE; w->settings_dirty = TRUE;
} }
} }

View File

@ -117,15 +117,17 @@ struct _CoglGles2WrapperUniforms
struct _CoglGles2WrapperTexEnv struct _CoglGles2WrapperTexEnv
{ {
GLenum texture_combine_rgb_func; GLenum texture_combine_rgb_func;
GLenum texture_combine_rgb_src[3]; GLenum texture_combine_rgb_src[3];
GLenum texture_combine_rgb_op[3]; GLenum texture_combine_rgb_op[3];
GLenum texture_combine_alpha_func; GLenum texture_combine_alpha_func;
GLenum texture_combine_alpha_src[3]; GLenum texture_combine_alpha_src[3];
GLenum texture_combine_alpha_op[3]; GLenum texture_combine_alpha_op[3];
GLfloat texture_combine_constant[4]; GLfloat texture_combine_constant[4];
GLboolean point_sprite_coords;
}; };
/* NB: We get a copy of this for each fragment/vertex /* NB: We get a copy of this for each fragment/vertex
@ -319,6 +321,9 @@ struct _CoglGles2WrapperShader
#define GL_MAX_TEXTURE_UNITS 0x84e2 #define GL_MAX_TEXTURE_UNITS 0x84e2
#define GL_POINT_SPRITE 0x8861
#define GL_COORD_REPLACE 0x8862
#endif /* GL_MODELVIEW */ #endif /* GL_MODELVIEW */
void _cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper); void _cogl_gles2_wrapper_init (CoglGles2Wrapper *wrapper);

View File

@ -107,6 +107,9 @@ _cogl_features_init (void)
flags |= COGL_FEATURE_VBOS; flags |= COGL_FEATURE_VBOS;
/* Both GLES 1.1 and GLES 2.0 support point sprites in core */
flags |= COGL_FEATURE_POINT_SPRITE;
/* Cache features */ /* Cache features */
ctx->feature_flags = flags; ctx->feature_flags = flags;
ctx->features_cached = TRUE; ctx->features_cached = TRUE;

View File

@ -491,6 +491,8 @@ cogl_material_remove_layer
cogl_material_set_layer_combine cogl_material_set_layer_combine
cogl_material_set_layer_combine_constant cogl_material_set_layer_combine_constant
cogl_material_set_layer_matrix cogl_material_set_layer_matrix
cogl_material_set_layer_point_sprite_coords_enabled
cogl_material_get_layer_point_sprite_coords_enabled
cogl_material_get_layers cogl_material_get_layers
cogl_material_get_n_layers cogl_material_get_n_layers
CoglMaterialFilter CoglMaterialFilter