1
0
Fork 0

Fully integrates CoglMaterial throughout the rest of Cogl

This glues CoglMaterial in as the fundamental way that Cogl describes how to
fill in geometry.

It adds cogl_set_source (), which is used to set the material which will be
used by all subsequent drawing functions

It adds cogl_set_source_texture as a convenience for setting up a default
material with a single texture layer, and cogl_set_source_color is now also
a convenience for setting up a material with a solid fill.

"drawing functions" include, cogl_rectangle, cogl_texture_rectangle,
cogl_texture_multiple_rectangles, cogl_texture_polygon (though the
cogl_texture_* funcs have been renamed; see below for details),
cogl_path_fill/stroke and cogl_vertex_buffer_draw*.

cogl_texture_rectangle, cogl_texture_multiple_rectangles and
cogl_texture_polygon no longer take a texture handle; instead the current
source material is referenced. The functions have also been renamed to:
cogl_rectangle_with_texture_coords, cogl_rectangles_with_texture_coords
and cogl_polygon respectivly.

Most code that previously did:
  cogl_texture_rectangle (tex_handle, x, y,...);
needs to be changed to now do:
  cogl_set_source_texture (tex_handle);
  cogl_rectangle_with_texture_coords (x, y,....);

In the less likely case where you were blending your source texture with a color
like:
  cogl_set_source_color4ub (r,g,b,a); /* where r,g,b,a isn't just white */
  cogl_texture_rectangle (tex_handle, x, y,...);
you will need your own material to do that:
  mat = cogl_material_new ();
  cogl_material_set_color4ub (r,g,b,a);
  cogl_material_set_layer (mat, 0, tex_handle));
  cogl_set_source_material (mat);

Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cog_rectangle_with_texure_coords since these are the coordinates that
cogl_rectangle will use.

For cogl_texture_polygon; as well as dropping the texture handle, the
n_vertices and vertices arguments were transposed for consistency. So
code previously written as:
  cogl_texture_polygon (tex_handle, 3, verts, TRUE);
need to be written as:
  cogl_set_source_texture (tex_handle);
  cogl_polygon (verts, 3, TRUE);

All of the unit tests have been updated to now use the material API and
test-cogl-material has been renamed to test-cogl-multitexture since any
textured quad is now technically a test of CoglMaterial but this test
specifically creates a material with multiple texture layers.

Note: The GLES backend has not been updated yet; that will be done in a
following commit.
This commit is contained in:
Robert Bragg 2009-01-23 16:15:40 +00:00
parent 0c8c273980
commit 2503f7b321
15 changed files with 1957 additions and 960 deletions

View file

@ -52,6 +52,8 @@ CoglHandle cogl_material_ref (CoglHandle handle);
*/
void cogl_material_unref (CoglHandle handle);
/**
* cogl_material_set_color:
* @material: A CoglMaterial object
@ -65,6 +67,37 @@ void cogl_material_unref (CoglHandle handle);
*/
void cogl_material_set_color (CoglHandle material, const CoglColor *color);
/**
* cogl_material_set_color:
* @material: A CoglMaterial object
* @red: The red component
* @green: The green component
* @blue: The blue component
* @alpha: The alpha component
*
* This is the basic color of the material, used when no lighting is enabled.
*
* The default value is (1.0, 1.0, 1.0, 1.0)
*
* Since 1.0
*/
void cogl_material_set_color4ub (CoglHandle handle,
guint8 red,
guint8 green,
guint8 blue,
guint8 alpha);
/**
* cogl_material_get_color:
* @material: A CoglMaterial object
* @color: The location to store the color
*
* This retrieves the current material color.
*
* Since 1.0
*/
void cogl_material_get_color (CoglHandle handle, CoglColor *color);
/**
* cogl_material_set_ambient:
* @material: A CoglMaterial object
@ -83,6 +116,17 @@ void cogl_material_set_color (CoglHandle material, const CoglColor *color);
void cogl_material_set_ambient (CoglHandle material,
const CoglColor *ambient);
/**
* cogl_material_get_ambient:
* @material: A CoglMaterial object
* @ambient: The location to store the ambient color
*
* This retrieves the materials current ambient color.
*
* Since 1.0
*/
void cogl_material_get_ambient (CoglHandle handle, CoglColor *ambient);
/**
* cogl_material_set_diffuse:
* @material: A CoglMaterial object
@ -100,6 +144,17 @@ void cogl_material_set_ambient (CoglHandle material,
void cogl_material_set_diffuse (CoglHandle material,
const CoglColor *diffuse);
/**
* cogl_material_get_diffuse:
* @material: A CoglMaterial object
* @diffuse: The location to store the diffuse color
*
* This retrieves the materials current diffuse color.
*
* Since 1.0
*/
void cogl_material_get_diffuse (CoglHandle handle, CoglColor *diffuse);
/**
* cogl_material_set_ambient_and_diffuse:
* @material: A CoglMaterial object
@ -133,6 +188,17 @@ void cogl_material_set_ambient_and_diffuse (CoglHandle material,
void cogl_material_set_specular (CoglHandle material,
const CoglColor *specular);
/**
* cogl_material_get_specular:
* @material: A CoglMaterial object
* @specular: The location to store the specular color
*
* This retrieves the materials current specular color.
*
* Since 1.0
*/
void cogl_material_get_specular (CoglHandle handle, CoglColor *specular);
/**
* cogl_material_set_shininess:
* @material: A CoglMaterial object
@ -148,6 +214,17 @@ void cogl_material_set_specular (CoglHandle material,
*/
void cogl_material_set_shininess (CoglHandle material,
float shininess);
/**
* cogl_material_get_shininess:
* @material: A CoglMaterial object
*
* This retrieves the materials current emission color.
*
* Return value: The materials current shininess value
*
* Since 1.0
*/
float cogl_material_get_shininess (CoglHandle handle);
/**
* cogl_material_set_emission:
@ -165,6 +242,17 @@ void cogl_material_set_shininess (CoglHandle material,
void cogl_material_set_emission (CoglHandle material,
const CoglColor *emission);
/**
* cogl_material_get_emission:
* @material: A CoglMaterial object
* @emission: The location to store the emission color
*
* This retrieves the materials current emission color.
*
* Since 1.0
*/
void cogl_material_get_emission (CoglHandle handle, CoglColor *emission);
/**
* CoglMaterialAlphaFunc:
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through.
@ -638,7 +726,7 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
/**
* cogl_material_layer_get_texture:
* @material: A CoglMaterial object
* @layer_handle: A CoglMaterial layer object
*
* This lets you extract a CoglTexture handle for a specific layer. Normally
* you shouldn't need to use this function directly since Cogl will do this
@ -653,18 +741,66 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
/**
* cogl_material_layer_flush_gl_sampler_state:
* @material: A CoglMaterial object
*
* This commits the sampler state for a single material layer to the OpenGL
* driver. Normally you shouldn't need to use this function directly since
* Cogl will do this internally, but if you are developing custom primitives
* directly with OpenGL you may want to use this.
*
* Note: It assumes you have already activated the appropriate sampler
* by calling glActiveTexture ();
* CoglMaterialLayerFlags:
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
* custom texture matrix.
*/
void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
typedef enum _CoglMaterialLayerFlags
{
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
} CoglMaterialLayerFlags;
/* XXX: NB: if you add flags here you will need to update
* CoglMaterialLayerPrivFlags!!! */
/**
* cogl_material_layer_get_flags:
* @layer_handle: A CoglMaterial layer object
*
* This lets you get a number of flag attributes about the layer. Normally
* you shouldn't need to use this function directly since Cogl will do this
* internally, but if you are developing custom primitives directly with
* OpenGL you may need this.
*/
gulong cogl_material_layer_get_flags (CoglHandle layer_handle);
/**
* CoglMaterialFlushOption:
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: Follow this by a guin32 mask
* of the layers that can't be supported with the user supplied texture
* and need to be replaced with fallback textures. (1 = fallback, and the
* least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: Follow this by a guint32 mask
* of the layers that you want to completly disable texturing for
* (1 = fallback, and the least significant bit = layer 0)
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: Follow this by a GLuint OpenGL texture
* name to override the texture used for layer 0 of the material. This is
* intended for dealing with sliced textures where you will need to point
* to each of the texture slices in turn when drawing your geometry.
* Passing a value of 0 is the same as not passing the option at all.
*/
typedef enum _CoglMaterialFlushOption
{
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
} CoglMaterialFlushOption;
/**
* cogl_material_flush_gl_state:
* @material: A CoglMaterial object
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
*
* This function commits the state of the specified CoglMaterial - including
* the texture state for all the layers - to the OpenGL[ES] driver.
*
* Normally you shouldn't need to use this function directly, but if you
* are developing a custom primitive using raw OpenGL that works with
* CoglMaterials, then you may want to use this function.
*
* Since 1.0
*/
void cogl_material_flush_gl_state (CoglHandle material,
...) G_GNUC_NULL_TERMINATED;
/**
* cogl_set_source:
@ -684,19 +820,16 @@ void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
void cogl_set_source (CoglHandle material);
/**
* cogl_flush_material_gl_state:
* cogl_set_source_texture:
* @texture_handle: The Cogl texture you want as your source
*
* This function commits all the state of the source CoglMaterial - not
* including the per-layer state - to the OpenGL[ES] driver.
*
* Normally you shouldn't need to use this function directly, but if you
* are developing a custom primitive using raw OpenGL that works with
* CoglMaterials, then you may want to use this function.
* This is a convenience function for creating a material with the first
* layer set to #texture_handle and setting that material as the source with
* cogl_set_source.
*
* Since 1.0
*/
/* XXX: This should be moved with cogl_set_source to cogl.h */
void cogl_flush_material_gl_state (void);
void cogl_set_source_texture (CoglHandle texture_handle);
G_END_DECLS

View file

@ -57,8 +57,7 @@ G_BEGIN_DECLS
* @width: Width of the rectangle
* @height: Height of the rectangle
*
* Fills a rectangle at the given coordinates with the current
* drawing color in a highly optimizied fashion.
* Fills a rectangle at the given coordinates with the current source material
**/
void cogl_rectangle (float x,
float y,

View file

@ -359,90 +359,6 @@ CoglHandle cogl_texture_ref (CoglHandle handle);
*/
void cogl_texture_unref (CoglHandle handle);
/**
* cogl_texture_rectangle:
* @handle: a @CoglHandle.
* @x1: x coordinate upper left on screen.
* @y1: y coordinate upper left on screen.
* @x2: x coordinate lower right on screen.
* @y2: y coordinate lower right on screen.
* @tx1: x part of texture coordinate to use for upper left pixel
* @ty1: y part of texture coordinate to use for upper left pixel
* @tx2: x part of texture coordinate to use for lower right pixel
* @ty2: y part of texture coordinate to use for left pixel
*
* Draw a rectangle from a texture to the display, to draw the entire
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
*/
void cogl_texture_rectangle (CoglHandle handle,
float x1,
float y1,
float x2,
float y2,
float tx1,
float ty1,
float tx2,
float ty2);
/**
* cogl_texture_polygon:
* @handle: A CoglHandle for a texture
* @n_vertices: The length of the vertices array
* @vertices: An array of #CoglTextureVertex structs
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
*
* Draws a polygon from a texture with the given model and texture
* coordinates. This can be used to draw arbitrary shapes textured
* with a COGL texture. If @use_color is %TRUE then the current COGL
* color will be changed for each vertex using the value specified in
* the color member of #CoglTextureVertex. This can be used for
* example to make the texture fade out by setting the alpha value of
* the color.
*
* All of the texture coordinates must be in the range [0,1] and
* repeating the texture is not supported.
*
* Because of the way this function is implemented it will currently
* only work if either the texture is not sliced or the backend is not
* OpenGL ES and the minifying and magnifying functions are both set
* to CGL_NEAREST.
*/
void cogl_texture_polygon (CoglHandle handle,
guint n_vertices,
CoglTextureVertex *vertices,
gboolean use_color);
/**
* cogl_material_rectangle:
* @x1: x coordinate upper left on screen.
* @y1: y coordinate upper left on screen.
* @x2: x coordinate lower right on screen.
* @y2: y coordinate lower right on screen.
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
* and one group of texture coordinates, this would be 4)
* @tex_coords: An array containing groups of 4 CoglFixed values:
* [tx1, ty1, tx2, ty2] that are interpreted as two texture coordinates; one
* for the upper left texel, and one for the lower right texel. Each value
* should be between 0.0 and 1.0, where the coordinate (0.0, 0.0) represents
* the top left of the texture, and (1.0, 1.0) the bottom right.
*
* This function draws a rectangle using the current source material to
* texture or fill with. Since a material may contain multiple texture
* layers the interface lets you supply corresponding sets of texture
* coordinates.
*
* The first pair of coordinates are for the first layer (with the smallest
* layer index) and if you supply less texture coordinates than there are
* layers in the current source material then default texture coordinates
* [0.0, 0.0, 1.0, 1.0] are generated.
*/
void cogl_material_rectangle (CoglFixed x1,
CoglFixed y1,
CoglFixed x2,
CoglFixed y2,
gint tex_coords_len,
const CoglFixed *tex_coords);
/**
* cogl_bitmap_new_from_file:
* @filename: the file to load.
@ -483,27 +399,110 @@ gboolean cogl_bitmap_get_size_from_file (const gchar *filename,
void cogl_bitmap_free (CoglBitmap *bmp);
/**
* cogl_texture_multiple_rectangles:
* @handle: a @CoglHandle.
* cogl_rectangle_with_texture_coords:
* @x1: x coordinate upper left on screen.
* @y1: y coordinate upper left on screen.
* @x2: x coordinate lower right on screen.
* @y2: y coordinate lower right on screen.
* @tx1: x part of texture coordinate to use for upper left pixel
* @ty1: y part of texture coordinate to use for upper left pixel
* @tx2: x part of texture coordinate to use for lower right pixel
* @ty2: y part of texture coordinate to use for left pixel
*
* Draw a rectangle using the current material and supply texture coordinates
* to be used for the first texture layer of the material. To draw the entire
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
*
* Since 1.0
*/
void cogl_rectangle_with_texture_coords (float x1,
float y1,
float x2,
float y2,
float tx1,
float ty1,
float tx2,
float ty2);
/**
* cogl_rectangle_with_multitexture_coords:
* @x1: x coordinate upper left on screen.
* @y1: y coordinate upper left on screen.
* @x2: x coordinate lower right on screen.
* @y2: y coordinate lower right on screen.
* @tex_coords: An array containing groups of 4 float values:
* [tx1, ty1, tx2, ty2] that are interpreted as two texture coordinates; one
* for the upper left texel, and one for the lower right texel. Each value
* should be between 0.0 and 1.0, where the coordinate (0.0, 0.0) represents
* the top left of the texture, and (1.0, 1.0) the bottom right.
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
* and one group of texture coordinates, this would be 4)
*
* This function draws a rectangle using the current source material to
* texture or fill with. As a material may contain multiple texture layers
* this interface lets you supply texture coordinates for each layer of the
* material.
*
* The first pair of coordinates are for the first layer (with the smallest
* layer index) and if you supply less texture coordinates than there are
* layers in the current source material then default texture coordinates
* (0.0, 0.0, 1.0, 1.0) are generated.
*
* Since 1.0
*/
void cogl_rectangle_with_multitexture_coords (float x1,
float y1,
float x2,
float y2,
const float *tex_coords,
gint tex_coords_len);
/**
* cogl_rectangles_with_texture_coords:
* @verts: an array of vertices
* @n_rects: number of rectangles to draw
*
* Draws a series of rectangles in the same way that
* cogl_texture_rectangle() does. In some situations it can give a
* cogl_rectangle_with_texture_coords() does. In some situations it can give a
* significant performance boost to use this function rather than
* calling cogl_texture_rectangle() separately for each rectangle.
* calling cogl_rectangle_with_texture_coords() separately for each rectangle.
*
* @verts should point to an array of #float<!-- -->s with
* @n_rects * 8 elements. Each group of 8 values corresponds to the
* parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
* meaning as in cogl_texture_rectangle().
* meaning as in cogl_rectangle_with_texture_coords().
*
* Since: 0.8.6
*/
void cogl_texture_multiple_rectangles
(CoglHandle handle,
const float *verts,
guint n_rects);
void cogl_rectangles_with_texture_coords (const float *verts,
guint n_rects);
/**
* cogl_polygon:
* @vertices: An array of #CoglTextureVertex structs
* @n_vertices: The length of the vertices array
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
*
* Draws a convex polygon using the current source material to fill / texture
* with according to the texture coordinates passed.
*
* If @use_color is %TRUE then the color will be changed for each vertex using
* the value specified in the color member of #CoglTextureVertex. This can be
* used for example to make the texture fade out by setting the alpha value of
* the color.
*
* All of the texture coordinates must be in the range [0,1] and repeating the
* texture is not supported.
*
* Because of the way this function is implemented it will currently only work
* if either the texture is not sliced or the backend is not OpenGL ES and the
* minifying and magnifying functions are both set to CGL_NEAREST.
*
* Since 1.0
*/
void cogl_polygon (CoglTextureVertex *vertices,
guint n_vertices,
gboolean use_color);
G_END_DECLS

View file

@ -32,7 +32,7 @@
#include <cogl/cogl-defines-@CLUTTER_COGL@.h>
#include <cogl/cogl-mesh.h>
#include <cogl/cogl-vertex-buffer.h>
#include <cogl/cogl-matrix.h>
#include <cogl/cogl-vertex-buffer.h>
#include <cogl/cogl-fixed.h>

View file

@ -9,10 +9,28 @@
typedef struct _CoglMaterial CoglMaterial;
typedef struct _CoglMaterialLayer CoglMaterialLayer;
typedef enum _CoglMaterialLayerFlags
/* XXX: I don't think gtk-doc supports having private enums so these aren't
* bundled in with CoglMaterialLayerFlags */
typedef enum _CoglMaterialLayerPrivFlags
{
COGL_MATERIAL_LAYER_FLAG_USER_MATRIX = 1L<<0,
} CoglMaterialLayerFlags;
/* Ref: CoglMaterialLayerFlags
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
*/
COGL_MATERIAL_LAYER_FLAG_DIRTY = 1L<<1,
COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE = 1L<<2
} CoglMaterialLayerPrivFlags;
/* For tracking the state of a layer that's been flushed to OpenGL */
typedef struct _CoglLayerInfo
{
CoglHandle handle;
gulong flags;
GLenum gl_target;
GLuint gl_texture;
gboolean fallback;
gboolean disabled;
gboolean layer0_overridden;
} CoglLayerInfo;
struct _CoglMaterialLayer
{
@ -42,7 +60,12 @@ typedef enum _CoglMaterialFlags
{
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0,
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<1,
COGL_MATERIAL_FLAG_DIRTY = 1L<<2
COGL_MATERIAL_FLAG_DIRTY = 1L<<2,
COGL_MATERIAL_FLAG_LAYERS_DIRTY = 1L<<3,
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<4,
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<5,
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<6,
COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC = 1L<<7
} CoglMaterialFlags;
struct _CoglMaterial

View file

@ -37,20 +37,24 @@ cogl_material_new (void)
/* Use the same defaults as the GL spec... */
unlit[0] = 1.0; unlit[1] = 1.0; unlit[2] = 1.0; unlit[3] = 1.0;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
/* Use the same defaults as the GL spec... */
ambient[0] = 0.2; ambient[1] = 0.2; ambient[2] = 0.2; ambient[3] = 1.0;
diffuse[0] = 0.8; diffuse[1] = 0.8; diffuse[2] = 0.8; diffuse[3] = 1.0;
specular[0] = 0; specular[1] = 0; specular[2] = 0; specular[3] = 1.0;
emission[0] = 0; emission[1] = 0; emission[2] = 0; emission[3] = 1.0;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
/* Use the same defaults as the GL spec... */
material->alpha_func = COGL_MATERIAL_ALPHA_FUNC_ALWAYS;
material->alpha_func_reference = 0.0;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
/* Not the same as the GL default, but seems saner... */
material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA;
material->blend_dst_factor = COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
material->layers = NULL;
@ -69,7 +73,24 @@ _cogl_material_free (CoglMaterial *material)
}
void
cogl_material_set_color (CoglHandle handle,
cogl_material_get_color (CoglHandle handle,
CoglColor *color)
{
CoglMaterial *material;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
cogl_color_set_from_4f (color,
material->unlit[0],
material->unlit[1],
material->unlit[2],
material->unlit[3]);
}
void
cogl_material_set_color (CoglHandle handle,
const CoglColor *unlit_color)
{
CoglMaterial *material;
@ -88,7 +109,46 @@ cogl_material_set_color (CoglHandle handle,
memcpy (material->unlit, unlit, sizeof (unlit));
if (unlit[0] == 1.0 &&
unlit[1] == 1.0 &&
unlit[2] == 1.0 &&
unlit[3] == 1.0)
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
if (unlit[3] != 1.0)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_COLOR;
}
void
cogl_material_set_color4ub (CoglHandle handle,
guint8 red,
guint8 green,
guint8 blue,
guint8 alpha)
{
CoglColor color;
cogl_color_set_from_4ub (&color, red, green, blue, alpha);
cogl_material_set_color (handle, &color);
}
void
cogl_material_get_ambient (CoglHandle handle,
CoglColor *ambient)
{
CoglMaterial *material;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
cogl_color_set_from_4f (ambient,
material->ambient[0],
material->ambient[1],
material->ambient[2],
material->ambient[3]);
}
void
@ -109,6 +169,24 @@ cogl_material_set_ambient (CoglHandle handle,
ambient[3] = cogl_color_get_alpha_float (ambient_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
}
void
cogl_material_get_diffuse (CoglHandle handle,
CoglColor *diffuse)
{
CoglMaterial *material;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
cogl_color_set_from_4f (diffuse,
material->diffuse[0],
material->diffuse[1],
material->diffuse[2],
material->diffuse[3]);
}
void
@ -129,6 +207,7 @@ cogl_material_set_diffuse (CoglHandle handle,
diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
}
void
@ -139,6 +218,23 @@ cogl_material_set_ambient_and_diffuse (CoglHandle handle,
cogl_material_set_diffuse (handle, color);
}
void
cogl_material_get_specular (CoglHandle handle,
CoglColor *specular)
{
CoglMaterial *material;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
cogl_color_set_from_4f (specular,
material->specular[0],
material->specular[1],
material->specular[2],
material->specular[3]);
}
void
cogl_material_set_specular (CoglHandle handle,
const CoglColor *specular_color)
@ -157,6 +253,19 @@ cogl_material_set_specular (CoglHandle handle,
specular[3] = cogl_color_get_alpha_float (specular_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
}
float
cogl_material_get_shininess (CoglHandle handle)
{
CoglMaterial *material;
g_return_val_if_fail (cogl_is_material (handle), 0);
material = _cogl_material_pointer_from_handle (handle);
return material->shininess;
}
void
@ -176,6 +285,24 @@ cogl_material_set_shininess (CoglHandle handle,
material->shininess = (GLfloat)shininess * 128.0;
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
}
void
cogl_material_get_emission (CoglHandle handle,
CoglColor *emission)
{
CoglMaterial *material;
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
cogl_color_set_from_4f (emission,
material->emission[0],
material->emission[1],
material->emission[2],
material->emission[3]);
}
void
@ -196,6 +323,7 @@ cogl_material_set_emission (CoglHandle handle,
emission[3] = cogl_color_get_alpha_float (emission_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
}
void
@ -212,6 +340,7 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
material->alpha_func_reference = (GLfloat)alpha_reference;
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
}
void
@ -228,6 +357,7 @@ cogl_material_set_blend_factors (CoglHandle handle,
material->blend_dst_factor = dst_factor;
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
}
/* Asserts that a layer corresponding to the given index exists. If no
@ -264,6 +394,7 @@ _cogl_material_get_layer (CoglMaterial *material,
layer->ref_count = 1;
layer->index = index;
layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
layer->texture = COGL_INVALID_HANDLE;
/* Choose the same default combine mode as OpenGL:
@ -284,6 +415,8 @@ _cogl_material_get_layer (CoglMaterial *material,
layer->texture_combine_alpha_op[1] =
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA;
cogl_matrix_init_identity (&layer->matrix);
layer_handle = _cogl_material_layer_handle_new (layer);
/* Note: see comment after for() loop above */
material->layers =
@ -317,7 +450,7 @@ cogl_material_set_layer (CoglHandle material_handle,
{
if (!(material->flags & COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING))
{
g_warning ("Your hardware doesnot have enough texture samplers"
g_warning ("Your hardware does not have enough texture samplers"
"to handle this many texture layers");
material->flags |= COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING;
}
@ -328,11 +461,14 @@ cogl_material_set_layer (CoglHandle material_handle,
* MAX_COMBINED_TEXTURE_IMAGE_UNITS layers. */
}
cogl_texture_ref (texture_handle);
if (layer->texture)
cogl_texture_unref (layer->texture);
cogl_texture_ref (texture_handle);
layer->texture = texture_handle;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
}
void
@ -350,9 +486,7 @@ cogl_material_set_layer_combine_function (
g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE);
if (!layer)
return;
layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_alpha_func = set_rgb_func = TRUE;
@ -365,6 +499,10 @@ cogl_material_set_layer_combine_function (
layer->texture_combine_rgb_func = func;
if (set_alpha_func)
layer->texture_combine_alpha_func = func;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
void
@ -377,16 +515,14 @@ cogl_material_set_layer_combine_arg_src (
{
CoglMaterial *material;
CoglMaterialLayer *layer;
gboolean set_arg_alpha_src = FALSE;
gboolean set_arg_rgb_src = FALSE;
gboolean set_arg_alpha_src = FALSE;
gboolean set_arg_rgb_src = FALSE;
g_return_if_fail (cogl_is_material (handle));
g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE);
if (!layer)
return;
layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_src = set_arg_rgb_src = TRUE;
@ -399,6 +535,10 @@ cogl_material_set_layer_combine_arg_src (
layer->texture_combine_rgb_src[argument] = src;
if (set_arg_alpha_src)
layer->texture_combine_alpha_src[argument] = src;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
void
@ -418,9 +558,7 @@ cogl_material_set_layer_combine_arg_op (
g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE);
if (!layer)
return;
layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_op = set_arg_rgb_op = TRUE;
@ -433,6 +571,10 @@ cogl_material_set_layer_combine_arg_op (
layer->texture_combine_rgb_op[argument] = op;
if (set_arg_alpha_op)
layer->texture_combine_alpha_op[argument] = op;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
void
@ -446,12 +588,14 @@ cogl_material_set_layer_matrix (CoglHandle material_handle,
g_return_if_fail (cogl_is_material (material_handle));
material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE);
if (!layer)
return;
layer = _cogl_material_get_layer (material, layer_index, TRUE);
layer->matrix = *matrix;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_USER_MATRIX;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX;
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
}
static void
@ -490,6 +634,10 @@ cogl_material_remove_layer (CoglHandle material_handle,
if (cogl_texture_get_format (layer->texture) & COGL_A_BIT)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
}
if (material->unlit[3] != 1.0)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
}
/* XXX: This API is hopfully just a stop-gap solution. Ideally cogl_enable
@ -553,6 +701,18 @@ cogl_material_layer_get_texture (CoglHandle layer_handle)
return layer->texture;
}
gulong
cogl_material_layer_get_flags (CoglHandle layer_handle)
{
CoglMaterialLayer *layer;
g_return_val_if_fail (cogl_is_material_layer (layer_handle), 0);
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
return layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX;
}
static guint
get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
{
@ -573,89 +733,81 @@ get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
return 0;
}
void
cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
static void
_cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
CoglLayerInfo *gl_layer_info)
{
CoglMaterialLayer *layer;
int n_rgb_func_args;
int n_alpha_func_args;
g_return_if_fail (cogl_is_material_layer (layer_handle));
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
/* XXX: We really want some kind of cache/dirty flag mechanism
* somewhere here so we can avoid as much mucking about with
* the texture units per primitive as possible!
*
* E.g. some recent profiling of clutter-actor suggested that
* validating/updating the texture environment may currently
* be a significant bottleneck. Given that all the actors should
* have the same texture environment, that implies we could do a
* much better job of avoiding redundant glTexEnv calls.
*/
GE (glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
/* Set the combiner functions... */
GE (glTexEnvi (GL_TEXTURE_ENV,
GL_COMBINE_RGB,
layer->texture_combine_rgb_func));
GE (glTexEnvi (GL_TEXTURE_ENV,
GL_COMBINE_ALPHA,
layer->texture_combine_alpha_func));
/*
* Setup the function arguments...
*/
/* For the RGB components... */
n_rgb_func_args =
get_n_args_for_combine_func (layer->texture_combine_rgb_func);
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB,
layer->texture_combine_rgb_src[0]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB,
layer->texture_combine_rgb_op[0]));
if (n_rgb_func_args > 1)
if (!(gl_layer_info &&
gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE &&
layer->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE))
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB,
layer->texture_combine_rgb_src[1]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB,
layer->texture_combine_rgb_op[1]));
}
if (n_rgb_func_args > 2)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_RGB,
layer->texture_combine_rgb_src[2]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB,
layer->texture_combine_rgb_op[2]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
/* Set the combiner functions... */
GE (glTexEnvi (GL_TEXTURE_ENV,
GL_COMBINE_RGB,
layer->texture_combine_rgb_func));
GE (glTexEnvi (GL_TEXTURE_ENV,
GL_COMBINE_ALPHA,
layer->texture_combine_alpha_func));
/*
* Setup the function arguments...
*/
/* For the RGB components... */
n_rgb_func_args =
get_n_args_for_combine_func (layer->texture_combine_rgb_func);
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_RGB,
layer->texture_combine_rgb_src[0]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_RGB,
layer->texture_combine_rgb_op[0]));
if (n_rgb_func_args > 1)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB,
layer->texture_combine_rgb_src[1]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB,
layer->texture_combine_rgb_op[1]));
}
if (n_rgb_func_args > 2)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_RGB,
layer->texture_combine_rgb_src[2]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB,
layer->texture_combine_rgb_op[2]));
}
/* For the Alpha component */
n_alpha_func_args =
get_n_args_for_combine_func (layer->texture_combine_alpha_func);
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA,
layer->texture_combine_alpha_src[0]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
layer->texture_combine_alpha_op[0]));
if (n_alpha_func_args > 1)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA,
layer->texture_combine_alpha_src[1]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
layer->texture_combine_alpha_op[1]));
}
if (n_alpha_func_args > 2)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_ALPHA,
layer->texture_combine_alpha_src[2]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
layer->texture_combine_alpha_op[2]));
}
}
/* For the Alpha component */
n_alpha_func_args =
get_n_args_for_combine_func (layer->texture_combine_alpha_func);
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC0_ALPHA,
layer->texture_combine_alpha_src[0]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
layer->texture_combine_alpha_op[0]));
if (n_alpha_func_args > 1)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_ALPHA,
layer->texture_combine_alpha_src[1]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
layer->texture_combine_alpha_op[1]));
}
if (n_alpha_func_args > 2)
{
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_ALPHA,
layer->texture_combine_alpha_src[2]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
layer->texture_combine_alpha_op[2]));
}
if (layer->flags & COGL_MATERIAL_LAYER_FLAG_USER_MATRIX)
if (gl_layer_info &&
(gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX ||
layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX))
{
GE (glMatrixMode (GL_TEXTURE));
GE (glLoadMatrixf ((GLfloat *)&layer->matrix));
@ -663,6 +815,275 @@ cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
}
}
/**
* _cogl_material_flush_layers_gl_state:
* @fallback_mask: is a bitmask of the material layers that need to be
* replaced with the default, fallback textures. The fallback textures are
* fully transparent textures so they hopefully wont contribute to the
* texture combining.
*
* The intention of fallbacks is to try and preserve
* the number of layers the user is expecting so that texture coordinates
* they gave will mostly still correspond to the textures they intended, and
* have a fighting chance of looking close to their originally intended
* result.
*
* @disable_mask: is a bitmask of the material layers that will simply have
* texturing disabled. It's only really intended for disabling all layers
* > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB
* and at some point the remaining bits flip to 1. It might work to disable
* arbitrary layers; though I'm not sure a.t.m how OpenGL would take to
* that.
*
* The intention of the disable_mask is for emitting geometry when the user
* hasn't supplied enough texture coordinates for all the layers and it's
* not possible to auto generate default texture coordinates for those
* layers.
*
* @layer0_override_texture: forcibly tells us to bind this GL texture name for
* layer 0 instead of plucking the gl_texture from the CoglTexture of layer
* 0.
*
* The intention of this is for any geometry that supports sliced textures.
* The code will can iterate each of the slices and re-flush the material
* forcing the GL texture of each slice in turn.
*
* XXX: It might also help if we could specify a texture matrix for code
* dealing with slicing that would be multiplied with the users own matrix.
*
* Normaly texture coords in the range [0, 1] refer to the extents of the
* texture, but when your GL texture represents a slice of the real texture
* (from the users POV) then a texture matrix would be a neat way of
* transforming the mapping for each slice.
*
* Currently for textured rectangles we manually calculate the texture
* coords for each slice based on the users given coords, but this solution
* isn't ideal, and can't be used with CoglVertexBuffers.
*/
static void
_cogl_material_flush_layers_gl_state (CoglMaterial *material,
guint32 fallback_mask,
guint32 disable_mask,
GLuint layer0_override_texture)
{
GList *tmp;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
for (tmp = material->layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
{
CoglHandle layer_handle = (CoglHandle)tmp->data;
CoglMaterialLayer *layer =
_cogl_material_layer_pointer_from_handle (layer_handle);
CoglLayerInfo *gl_layer_info = NULL;
CoglLayerInfo new_gl_layer_info;
GLuint gl_texture;
GLenum gl_target;
new_gl_layer_info.layer0_overridden =
layer0_override_texture ? TRUE : FALSE;
new_gl_layer_info.fallback =
(fallback_mask & (1<<i)) ? TRUE : FALSE;
new_gl_layer_info.disabled =
(disable_mask & (1<<i)) ? TRUE : FALSE;
if (i < ctx->current_layers->len)
{
gl_layer_info =
&g_array_index (ctx->current_layers, CoglLayerInfo, i);
if (gl_layer_info->handle == layer_handle &&
!(layer->flags & COGL_MATERIAL_LAYER_FLAG_DIRTY) &&
(gl_layer_info->layer0_overridden
== new_gl_layer_info.layer0_overridden) &&
(gl_layer_info->fallback
== new_gl_layer_info.fallback) &&
(gl_layer_info->disabled
== new_gl_layer_info.disabled))
continue;
}
cogl_texture_get_gl_texture (layer->texture, &gl_texture, &gl_target);
if (new_gl_layer_info.layer0_overridden)
gl_texture = layer0_override_texture;
else if (new_gl_layer_info.fallback)
{
CoglHandle tex_handle;
if (gl_target == GL_TEXTURE_2D)
tex_handle = ctx->default_gl_texture_2d_tex;
else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
tex_handle = ctx->default_gl_texture_rect_tex;
else
{
g_warning ("We don't have a default texture we can use to fill "
"in for an invalid material layer, since it was "
"using an unsupported texture target ");
/* might get away with this... */
tex_handle = ctx->default_gl_texture_2d_tex;
}
cogl_texture_get_gl_texture (tex_handle, &gl_texture, NULL);
}
GE (glActiveTexture (GL_TEXTURE0 + i));
if (!gl_layer_info
|| gl_layer_info->gl_target != gl_target
|| gl_layer_info->gl_texture != gl_texture)
GE (glBindTexture (gl_target, gl_texture));
/* Disable the previous target if it was different */
if (gl_layer_info &&
gl_layer_info->gl_target != gl_target &&
!gl_layer_info->disabled)
GE (glDisable (gl_layer_info->gl_target));
/* Enable/Disable the new target */
if (!new_gl_layer_info.disabled)
{
if (!(gl_layer_info &&
gl_layer_info->gl_target == gl_target &&
!gl_layer_info->disabled))
GE (glEnable (gl_target));
}
else
{
if (!(gl_layer_info &&
gl_layer_info->gl_target == gl_target &&
gl_layer_info->disabled))
GE (glDisable (gl_target));
}
_cogl_material_layer_flush_gl_sampler_state (layer, gl_layer_info);
new_gl_layer_info.handle = layer_handle;
new_gl_layer_info.flags = layer->flags;
new_gl_layer_info.gl_target = gl_target;
new_gl_layer_info.gl_texture = gl_texture;
if (i < ctx->current_layers->len)
*gl_layer_info = new_gl_layer_info;
else
g_array_append_val (ctx->current_layers, new_gl_layer_info);
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DIRTY;
if ((i+1) >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
break;
}
/* Disable additional texture units that may have previously been in use.. */
for (; i < ctx->current_layers->len; i++)
{
CoglLayerInfo *gl_layer_info =
&g_array_index (ctx->current_layers, CoglLayerInfo, i);
if (!gl_layer_info->disabled)
{
GE (glActiveTexture (GL_TEXTURE0 + i));
GE (glDisable (gl_layer_info->gl_target));
gl_layer_info->disabled = TRUE;
}
}
material->flags &= ~COGL_MATERIAL_FLAG_DIRTY;
}
static void
_cogl_material_flush_base_gl_state (CoglMaterial *material)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR))
{
GE (glColor4fv (material->unlit));
}
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL))
{
/* FIXME - we only need to set these if lighting is enabled... */
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
}
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC))
{
/* NB: Currently the Cogl defines are compatible with the GL ones: */
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
}
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC))
{
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
}
}
void
cogl_material_flush_gl_state (CoglHandle handle, ...)
{
CoglMaterial *material;
va_list ap;
CoglMaterialFlushOption option;
guint32 fallback_layers = 0;
guint32 disable_layers = 0;
GLuint layer0_override_texture = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
material = _cogl_material_pointer_from_handle (handle);
if (ctx->current_material == material &&
!(material->flags & COGL_MATERIAL_FLAG_DIRTY) &&
!(material->flags & COGL_MATERIAL_FLAG_LAYERS_DIRTY))
return;
if (ctx->current_material != material ||
material->flags & COGL_MATERIAL_FLAG_DIRTY)
_cogl_material_flush_base_gl_state (material);
if (ctx->current_material != material ||
material->flags & COGL_MATERIAL_FLAG_LAYERS_DIRTY)
{
va_start (ap, handle);
while ((option = va_arg (ap, CoglMaterialFlushOption)))
{
if (option == COGL_MATERIAL_FLUSH_FALLBACK_MASK)
fallback_layers = va_arg (ap, guint32);
else if (option == COGL_MATERIAL_FLUSH_DISABLE_MASK)
disable_layers = va_arg (ap, guint32);
else if (option == COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE)
layer0_override_texture = va_arg (ap, GLuint);
}
va_end (ap);
_cogl_material_flush_layers_gl_state (material,
fallback_layers,
disable_layers,
layer0_override_texture);
}
/* NB: we have to take a reference so that next time
* cogl_material_flush_gl_state is called, we can compare the incomming
* material pointer with ctx->current_material
*/
cogl_material_ref (handle);
cogl_material_unref (ctx->current_material);
ctx->current_material = handle;
ctx->current_material_flags = material->flags;
}
/* TODO: Should go in cogl.c, but that implies duplication which is also
* not ideal. */
void
@ -675,40 +1096,24 @@ cogl_set_source (CoglHandle material_handle)
if (ctx->source_material == material_handle)
return;
cogl_material_ref (material_handle);
if (ctx->source_material)
cogl_material_unref (ctx->source_material);
cogl_material_ref (material_handle);
ctx->source_material = material_handle;
}
/* TODO: add cogl_set_front_source (), and cogl_set_back_source () */
void
cogl_flush_material_gl_state (void)
cogl_set_source_texture (CoglHandle texture_handle)
{
CoglMaterial *material;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
CoglColor white;
material = _cogl_material_pointer_from_handle (ctx->source_material);
if (ctx->source_material == ctx->current_material
&& !(material->flags & COGL_MATERIAL_FLAG_DIRTY))
return;
GE (glColor4fv (material->unlit));
/* FIXME - we only need to set these if lighting is enabled... */
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
/* NB: Currently the Cogl defines are compatible with the GL ones: */
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
ctx->current_material = ctx->source_material;
cogl_material_set_layer (ctx->default_material, 0, texture_handle);
cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
cogl_material_set_color (ctx->default_material, &white);
cogl_set_source (ctx->default_material);
}

View file

@ -43,19 +43,18 @@ void _cogl_path_add_node (gboolean new_sub_path,
float y);
void _cogl_path_fill_nodes ();
void _cogl_path_stroke_nodes ();
void _cogl_rectangle (float x,
float y,
float width,
float height);
void
cogl_rectangle (float x,
float y,
float width,
float height)
{
cogl_clip_ensure ();
_cogl_rectangle (x, y, width, height);
cogl_rectangle_with_multitexture_coords (x, y,
x+width,
y+height,
NULL,
0);
}
void

View file

@ -134,6 +134,7 @@
#include "cogl-context.h"
#include "cogl-handle.h"
#include "cogl-vertex-buffer-private.h"
#include "cogl-texture-private.h"
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
@ -1416,12 +1417,15 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
static void
enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
{
GList *tmp;
GLenum gl_type;
GLuint generic_index = 0;
gulong enable_flags = COGL_ENABLE_BLEND;
/* FIXME: I don't think it's appropriate to force enable
* GL_BLEND here. */
GList *tmp;
GLenum gl_type;
GLuint generic_index = 0;
gulong enable_flags = 0;
guint max_texcoord_attrib_unit = 0;
const GList *layers;
guint32 fallback_mask = 0;
guint32 disable_mask = ~0;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1460,17 +1464,16 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
(const GLvoid *)attribute->u.vbo_offset));
break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
/* FIXME: set the active texture unit */
/* NB: Cogl currently manages unit 0 */
enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY
| COGL_ENABLE_TEXTURE_2D);
/* FIXME: I don't think it's appropriate to force enable
* GL_TEXTURE_2D here. */
/* GE (glEnableClientState (GL_VERTEX_ARRAY)); */
GE (glClientActiveTexture (GL_TEXTURE0 +
attribute->texture_unit));
GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
GE (glTexCoordPointer (attribute->n_components,
gl_type,
attribute->stride,
(const GLvoid *)attribute->u.vbo_offset));
if (attribute->texture_unit > max_texcoord_attrib_unit)
max_texcoord_attrib_unit = attribute->texture_unit;
disable_mask &= ~(1 << attribute->texture_unit);
break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
@ -1505,8 +1508,51 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
}
}
cogl_enable (enable_flags);
layers = cogl_material_get_layers (ctx->source_material);
for (tmp = (GList *)layers, i = 0;
tmp != NULL && i <= max_texcoord_attrib_unit;
tmp = tmp->next, i++)
{
CoglHandle layer = (CoglHandle)tmp->data;
CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
CoglTexture *texture =
_cogl_texture_pointer_from_handle (tex_handle);
if (cogl_texture_is_sliced (tex_handle)
|| _cogl_texture_span_has_waste (texture, 0, 0))
{
g_warning ("Disabling layer %d of the current source material, "
"because texturing with the vertex buffer API is not "
"currently supported using sliced textures, or textures "
"with waste\n", i);
/* XXX: maybe we can add a mechanism for users to forcibly use
* textures with waste where it would be their responsability to use
* texture coords in the range [0,1] such that sampling outside isn't
* required. We can then use a texture matrix (or a modification of
* the users own matrix) to map 1 to the edge of the texture data.
*
* Potentially, given the same guarantee as above we could also
* support a single sliced layer too. We would have to redraw the
* vertices once for each layer, each time with a fiddled texture
* matrix.
*/
fallback_mask |= (1 << i);
}
else if (!(disable_mask & (1 << i)))
fallback_mask |= (1 << i);
}
cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
disable_mask,
NULL);
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags);
}
static void
@ -1550,9 +1596,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
GE (glDisableClientState (GL_NORMAL_ARRAY));
break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
/* FIXME: set the active texture unit */
/* NB: Cogl currently manages unit 0 */
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */
GE (glClientActiveTexture (GL_TEXTURE0 +
attribute->texture_unit));
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */

View file

@ -31,6 +31,8 @@
#include "cogl-internal.h"
#include "cogl-util.h"
#include "cogl-context.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#include <string.h>
@ -39,6 +41,9 @@ static CoglContext *_context = NULL;
gboolean
cogl_create_context ()
{
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
gulong enable_flags = 0;
if (_context != NULL)
return FALSE;
@ -52,19 +57,26 @@ cogl_create_context ()
_context->enable_flags = 0;
_context->color_alpha = 255;
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
_context->last_path = 0;
_context->texture_handles = NULL;
_context->texture_vertices = g_array_new (FALSE, FALSE,
sizeof (CoglTextureGLVertex));
_context->texture_indices = g_array_new (FALSE, FALSE,
sizeof (GLushort));
_context->material_handles = NULL;
_context->material_layer_handles = NULL;
_context->default_material = cogl_material_new ();
_context->source_material = NULL;
_context->texture_handles = NULL;
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
_context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
_context->static_indices = g_array_new (FALSE, FALSE, sizeof (GLushort));
_context->polygon_vertices = g_array_new (FALSE, FALSE,
sizeof (CoglTextureGLVertex));
_context->current_material = NULL;
_context->current_material_flags = 0;
_context->current_layers = g_array_new (FALSE, FALSE,
sizeof (CoglLayerInfo));
_context->n_texcoord_arrays_enabled = 0;
_context->fbo_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER;
@ -78,6 +90,10 @@ cogl_create_context ()
_context->vertex_buffer_handles = NULL;
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
_context->last_path = 0;
_context->stencil_material = cogl_material_new ();
_context->pf_glGenRenderbuffersEXT = NULL;
_context->pf_glBindRenderbufferEXT = NULL;
_context->pf_glRenderbufferStorageEXT = NULL;
@ -123,15 +139,37 @@ cogl_create_context ()
_context->pf_glDrawRangeElements = NULL;
/* Init OpenGL state */
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
cogl_enable (0);
/* Initialise the clip stack */
_cogl_clip_stack_state_init ();
/* Create default textures used for fall backs */
_context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
FALSE, /* auto mipmap */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
0, /* auto calc row stride */
&default_texture_data);
_context->default_gl_texture_rect_tex =
cogl_texture_new_from_data (1, /* width */
1, /* height */
-1, /* max waste */
FALSE, /* auto mipmap */
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
/* internal format */
COGL_PIXEL_FORMAT_RGBA_8888,
0, /* auto calc row stride */
&default_texture_data);
cogl_set_source (_context->default_material);
cogl_material_flush_gl_state (_context->source_material, NULL);
enable_flags =
cogl_material_get_cogl_enable_flags (_context->source_material);
cogl_enable (enable_flags);
return TRUE;
}
@ -155,10 +193,25 @@ cogl_destroy_context ()
if (_context->program_handles)
g_array_free (_context->program_handles, TRUE);
if (_context->texture_vertices)
g_array_free (_context->texture_vertices, TRUE);
if (_context->texture_indices)
g_array_free (_context->texture_indices, TRUE);
if (_context->default_gl_texture_2d_tex)
cogl_texture_unref (_context->default_gl_texture_2d_tex);
if (_context->default_gl_texture_rect_tex)
cogl_texture_unref (_context->default_gl_texture_rect_tex);
if (_context->default_material)
cogl_material_unref (_context->default_material);
if (_context->journal)
g_array_free (_context->journal, TRUE);
if (_context->logged_vertices)
g_array_free (_context->logged_vertices, TRUE);
if (_context->static_indices)
g_array_free (_context->static_indices, TRUE);
if (_context->polygon_vertices)
g_array_free (_context->polygon_vertices, TRUE);
if (_context->current_layers)
g_array_free (_context->current_layers, TRUE);
g_free (_context);
}

View file

@ -50,33 +50,34 @@ typedef struct
gboolean enable_backface_culling;
/* Primitives */
floatVec2 path_start;
floatVec2 path_pen;
GArray *path_nodes;
guint last_path;
floatVec2 path_nodes_min;
floatVec2 path_nodes_max;
/* Cache of inverse projection matrix */
GLfloat inverse_projection[16];
/* Textures */
GArray *texture_handles;
GArray *texture_vertices;
GArray *texture_indices;
/* The gl texture number that the above vertices apply to. This to
detect when a different slice is encountered so that the vertices
can be flushed */
GLuint texture_current;
GLenum texture_target;
GLenum texture_wrap_mode;
GArray *texture_handles;
CoglHandle default_gl_texture_2d_tex;
CoglHandle default_gl_texture_rect_tex;
/* Materials */
GArray *material_handles;
GArray *material_layer_handles;
CoglHandle default_material;
CoglHandle source_material;
/* Batching geometry... */
/* We journal the texture rectangles we want to submit to OpenGL so
* we have an oppertunity to optimise the final order so that we
* can batch things together. */
GArray *journal;
GArray *logged_vertices;
GArray *static_indices;
GArray *polygon_vertices;
/* Some simple caching, to minimize state changes... */
CoglHandle current_material;
gulong current_material_flags;
GArray *current_layers;
guint n_texcoord_arrays_enabled;
/* Framebuffer objects */
GArray *fbo_handles;
@ -94,6 +95,15 @@ typedef struct
/* Vertex buffers */
GArray *vertex_buffer_handles;
/* Primitives */
floatVec2 path_start;
floatVec2 path_pen;
GArray *path_nodes;
guint last_path;
floatVec2 path_nodes_min;
floatVec2 path_nodes_max;
CoglHandle stencil_material;
/* Relying on glext.h to define these */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;

View file

@ -51,13 +51,10 @@ const char *_cogl_error_string(GLenum errorCode);
#endif /* COGL_DEBUG */
#define COGL_ENABLE_BLEND (1<<1)
#define COGL_ENABLE_TEXTURE_2D (1<<2)
#define COGL_ENABLE_ALPHA_TEST (1<<3)
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
#define COGL_ENABLE_COLOR_ARRAY (1<<7)
#define COGL_ENABLE_BACKFACE_CULLING (1<<8)
#define COGL_ENABLE_ALPHA_TEST (1<<2)
#define COGL_ENABLE_VERTEX_ARRAY (1<<3)
#define COGL_ENABLE_COLOR_ARRAY (1<<4)
#define COGL_ENABLE_BACKFACE_CULLING (1<<5)
gint
_cogl_get_format_bpp (CoglPixelFormat format);

View file

@ -38,27 +38,13 @@
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16
void
_cogl_rectangle (float x,
float y,
float width,
float height)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_enable (ctx->color_alpha < 255
? COGL_ENABLE_BLEND : 0);
GE( glRectf (x, y, x + width, y + height) );
}
void
_cogl_path_add_node (gboolean new_sub_path,
float x,
float y)
{
CoglPathNode new_node;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
new_node.x = (x);
@ -89,13 +75,18 @@ _cogl_path_add_node (gboolean new_sub_path,
void
_cogl_path_stroke_nodes ()
{
guint path_start = 0;
guint path_start = 0;
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_enable (COGL_ENABLE_VERTEX_ARRAY
| (ctx->color_alpha < 255
? COGL_ENABLE_BLEND : 0));
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags);
cogl_material_flush_gl_state (ctx->source_material,
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */
NULL);
while (path_start < ctx->path_nodes->len)
{
@ -106,7 +97,7 @@ _cogl_path_stroke_nodes ()
(guchar *) path
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
GE( glDrawArrays (GL_LINE_STRIP, 0, path->path_size) );
path_start += path->path_size;
}
}
@ -139,6 +130,8 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
float bounds_w;
float bounds_h;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_path_get_bounds (nodes_min, nodes_max,
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
@ -159,10 +152,17 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
GE( glDepthMask (FALSE) );
while (path_start < path_size)
{
cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
/* Just setup a simple material that doesn't use texturing... */
cogl_material_flush_gl_state (ctx->stencil_material, NULL);
enable_flags |=
cogl_material_get_cogl_enable_flags (ctx->source_material);
cogl_enable (enable_flags);
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
(guchar *) path
@ -207,11 +207,11 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
}
GE( glStencilMask (~(GLuint) 0) );
GE( glDepthMask (TRUE) );
GE( glColorMask (TRUE, TRUE, TRUE, TRUE) );
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
}

View file

@ -28,11 +28,9 @@
#include "cogl-bitmap.h"
typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglCompositeTexture CoglCompositeTexture;
typedef struct _CoglCompositeTextureLayer CoglCompositeTextureLayer;
typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter;
struct _CoglTexSliceSpan
{
@ -61,26 +59,23 @@ struct _CoglTexture
gboolean auto_mipmap;
};
struct _CoglCompositeTextureLayer
/* To improve batching of geometry when submitting vertices to OpenGL we
* log the texture rectangles we want to draw to a journal, so when we
* later flush the journal we aim to batch data, and gl draw calls. */
typedef struct _CoglJournalEntry
{
guint ref_count;
guint index; /*!< lowest index is blended first then others
on top */
CoglTexture *tex; /*!< The texture for this layer, or NULL
for an empty layer */
/* TODO: Add more control over the texture environment for each texture
* unit. For example we should support dot3 normal mapping. */
};
struct _CoglCompositeTexture
{
guint ref_count;
GList *layers;
};
CoglHandle material;
gint n_layers;
guint32 fallback_mask;
GLuint layer0_override_texture;
} CoglJournalEntry;
CoglTexture*
_cogl_texture_pointer_from_handle (CoglHandle handle);
gboolean
_cogl_texture_span_has_waste (CoglTexture *tex,
gint x_span_index,
gint y_span_index);
#endif /* __COGL_TEXTURE_H */

File diff suppressed because it is too large Load diff

128
gl/cogl.c
View file

@ -180,16 +180,16 @@ cogl_paint_init (const CoglColor *color)
glDisable (GL_LIGHTING);
glDisable (GL_FOG);
/*
/*
* Disable the depth test for now as has some strange side effects,
* mainly on x/y axis rotation with multiple layers at same depth
* (eg rotating text on a bg has very strange effect). Seems no clean
* 100% effective way to fix without other odd issues.. So for now
* mainly on x/y axis rotation with multiple layers at same depth
* (eg rotating text on a bg has very strange effect). Seems no clean
* 100% effective way to fix without other odd issues.. So for now
* move to application to handle and add cogl_enable_depth_test()
* as for custom actors (i.e groups) to enable if need be.
*
* glEnable (GL_DEPTH_TEST);
* glEnable (GL_ALPHA_TEST)
* glEnable (GL_DEPTH_TEST);
* glEnable (GL_ALPHA_TEST)
* glDepthFunc (GL_LEQUAL);
* glAlphaFunc (GL_GREATER, 0.1);
*/
@ -251,7 +251,7 @@ cogl_toggle_flag (CoglContext *ctx,
GE( glDisable (gl_flag) );
ctx->enable_flags &= ~flag;
}
return FALSE;
}
@ -278,7 +278,7 @@ cogl_toggle_client_flag (CoglContext *ctx,
GE( glDisableClientState (gl_flag) );
ctx->enable_flags &= ~flag;
}
return FALSE;
}
@ -289,33 +289,19 @@ cogl_enable (gulong flags)
* hope of lessening number GL traffic.
*/
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_BLEND,
GL_BLEND);
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_TEXTURE_2D,
GL_TEXTURE_2D);
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_BACKFACE_CULLING,
GL_CULL_FACE);
#ifdef GL_TEXTURE_RECTANGLE_ARB
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_TEXTURE_RECT,
GL_TEXTURE_RECTANGLE_ARB);
#endif
cogl_toggle_client_flag (ctx, flags,
COGL_ENABLE_VERTEX_ARRAY,
GL_VERTEX_ARRAY);
cogl_toggle_client_flag (ctx, flags,
COGL_ENABLE_TEXCOORD_ARRAY,
GL_TEXTURE_COORD_ARRAY);
cogl_toggle_client_flag (ctx, flags,
COGL_ENABLE_COLOR_ARRAY,
GL_COLOR_ARRAY);
@ -325,7 +311,7 @@ gulong
cogl_get_enable ()
{
_COGL_GET_CONTEXT (ctx, 0);
return ctx->enable_flags;
}
@ -336,7 +322,7 @@ cogl_blend_func (COGLenum src_factor, COGLenum dst_factor)
* hope of lessening GL traffic.
*/
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->blend_src_factor != src_factor ||
ctx->blend_dst_factor != dst_factor)
{
@ -351,14 +337,14 @@ cogl_enable_depth_test (gboolean setting)
{
if (setting)
{
glEnable (GL_DEPTH_TEST);
glEnable (GL_DEPTH_TEST);
glEnable (GL_ALPHA_TEST);
glDepthFunc (GL_LEQUAL);
glAlphaFunc (GL_GREATER, 0.1);
}
else
{
glDisable (GL_DEPTH_TEST);
glDisable (GL_DEPTH_TEST);
glDisable (GL_ALPHA_TEST);
}
}
@ -375,14 +361,12 @@ void
cogl_set_source_color (const CoglColor *color)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
glColor4ub (cogl_color_get_red_byte (color),
cogl_color_get_green_byte (color),
cogl_color_get_blue_byte (color),
cogl_color_get_alpha_byte (color));
/* Store alpha for proper blending enables */
ctx->color_alpha = cogl_color_get_alpha_byte (color);
/* In case cogl_set_source_texture was previously used... */
cogl_material_remove_layer (ctx->default_material, 0);
cogl_material_set_color (ctx->default_material, color);
cogl_set_source (ctx->default_material);
}
static void
@ -512,7 +496,7 @@ _cogl_add_stencil_clip (float x_offset,
if (first)
{
GE( glEnable (GL_STENCIL_TEST) );
/* Initially disallow everything */
GE( glClearStencil (0) );
GE( glClear (GL_STENCIL_BUFFER_BIT) );
@ -815,7 +799,7 @@ _cogl_features_init ()
GLint num_stencil_bits = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
@ -827,7 +811,7 @@ _cogl_features_init ()
#endif
flags |= COGL_FEATURE_TEXTURE_NPOT;
}
#ifdef GL_YCBCR_MESA
if (cogl_check_extension ("GL_MESA_ycbcr_texture", gl_extensions))
{
@ -842,47 +826,47 @@ _cogl_features_init ()
ctx->pf_glCreateProgramObjectARB =
(COGL_PFNGLCREATEPROGRAMOBJECTARBPROC)
cogl_get_proc_address ("glCreateProgramObjectARB");
ctx->pf_glCreateShaderObjectARB =
(COGL_PFNGLCREATESHADEROBJECTARBPROC)
cogl_get_proc_address ("glCreateShaderObjectARB");
ctx->pf_glShaderSourceARB =
(COGL_PFNGLSHADERSOURCEARBPROC)
cogl_get_proc_address ("glShaderSourceARB");
ctx->pf_glCompileShaderARB =
(COGL_PFNGLCOMPILESHADERARBPROC)
cogl_get_proc_address ("glCompileShaderARB");
ctx->pf_glAttachObjectARB =
(COGL_PFNGLATTACHOBJECTARBPROC)
cogl_get_proc_address ("glAttachObjectARB");
ctx->pf_glLinkProgramARB =
(COGL_PFNGLLINKPROGRAMARBPROC)
cogl_get_proc_address ("glLinkProgramARB");
ctx->pf_glUseProgramObjectARB =
(COGL_PFNGLUSEPROGRAMOBJECTARBPROC)
cogl_get_proc_address ("glUseProgramObjectARB");
ctx->pf_glGetUniformLocationARB =
(COGL_PFNGLGETUNIFORMLOCATIONARBPROC)
cogl_get_proc_address ("glGetUniformLocationARB");
ctx->pf_glDeleteObjectARB =
(COGL_PFNGLDELETEOBJECTARBPROC)
cogl_get_proc_address ("glDeleteObjectARB");
ctx->pf_glGetInfoLogARB =
(COGL_PFNGLGETINFOLOGARBPROC)
cogl_get_proc_address ("glGetInfoLogARB");
ctx->pf_glGetObjectParameterivARB =
(COGL_PFNGLGETOBJECTPARAMETERIVARBPROC)
cogl_get_proc_address ("glGetObjectParameterivARB");
ctx->pf_glUniform1fARB =
(COGL_PFNGLUNIFORM1FARBPROC)
cogl_get_proc_address ("glUniform1fARB");
@ -898,7 +882,7 @@ _cogl_features_init ()
ctx->pf_glDisableVertexAttribArrayARB =
(COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)
cogl_get_proc_address ("glDisableVertexAttribArrayARB");
ctx->pf_glUniform2fARB =
(COGL_PFNGLUNIFORM2FARBPROC)
cogl_get_proc_address ("glUniform2fARB");
@ -962,7 +946,7 @@ _cogl_features_init ()
ctx->pf_glUniformMatrix2fvARB =
(COGL_PFNGLUNIFORMMATRIX2FVARBPROC)
cogl_get_proc_address ("glUniformMatrix2fvARB");
ctx->pf_glUniformMatrix3fvARB =
(COGL_PFNGLUNIFORMMATRIX3FVARBPROC)
cogl_get_proc_address ("glUniformMatrix3fvARB");
@ -1006,50 +990,50 @@ _cogl_features_init ()
ctx->pf_glDisableVertexAttribArrayARB)
flags |= COGL_FEATURE_SHADERS_GLSL;
}
if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) ||
cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions))
{
{
ctx->pf_glGenRenderbuffersEXT =
(COGL_PFNGLGENRENDERBUFFERSEXTPROC)
cogl_get_proc_address ("glGenRenderbuffersEXT");
ctx->pf_glDeleteRenderbuffersEXT =
(COGL_PFNGLDELETERENDERBUFFERSEXTPROC)
cogl_get_proc_address ("glDeleteRenderbuffersEXT");
ctx->pf_glBindRenderbufferEXT =
(COGL_PFNGLBINDRENDERBUFFEREXTPROC)
cogl_get_proc_address ("glBindRenderbufferEXT");
ctx->pf_glRenderbufferStorageEXT =
(COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC)
cogl_get_proc_address ("glRenderbufferStorageEXT");
ctx->pf_glGenFramebuffersEXT =
(COGL_PFNGLGENFRAMEBUFFERSEXTPROC)
cogl_get_proc_address ("glGenFramebuffersEXT");
ctx->pf_glBindFramebufferEXT =
(COGL_PFNGLBINDFRAMEBUFFEREXTPROC)
cogl_get_proc_address ("glBindFramebufferEXT");
ctx->pf_glFramebufferTexture2DEXT =
(COGL_PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
cogl_get_proc_address ("glFramebufferTexture2DEXT");
ctx->pf_glFramebufferRenderbufferEXT =
(COGL_PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
cogl_get_proc_address ("glFramebufferRenderbufferEXT");
ctx->pf_glCheckFramebufferStatusEXT =
(COGL_PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
cogl_get_proc_address ("glCheckFramebufferStatusEXT");
ctx->pf_glDeleteFramebuffersEXT =
(COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC)
cogl_get_proc_address ("glDeleteFramebuffersEXT");
if (ctx->pf_glGenRenderbuffersEXT &&
ctx->pf_glBindRenderbufferEXT &&
ctx->pf_glRenderbufferStorageEXT &&
@ -1061,23 +1045,23 @@ _cogl_features_init ()
ctx->pf_glDeleteFramebuffersEXT)
flags |= COGL_FEATURE_OFFSCREEN;
}
if (cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
{
ctx->pf_glBlitFramebufferEXT =
(COGL_PFNGLBLITFRAMEBUFFEREXTPROC)
cogl_get_proc_address ("glBlitFramebufferEXT");
if (ctx->pf_glBlitFramebufferEXT)
flags |= COGL_FEATURE_OFFSCREEN_BLIT;
}
if (cogl_check_extension ("GL_EXT_framebuffer_multisample", gl_extensions))
{
ctx->pf_glRenderbufferStorageMultisampleEXT =
(COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
cogl_get_proc_address ("glRenderbufferStorageMultisampleEXT");
if (ctx->pf_glRenderbufferStorageMultisampleEXT)
flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
}
@ -1140,10 +1124,10 @@ CoglFeatureFlags
cogl_get_features ()
{
_COGL_GET_CONTEXT (ctx, 0);
if (!ctx->features_cached)
_cogl_features_init ();
return ctx->feature_flags;
}
@ -1151,10 +1135,10 @@ gboolean
cogl_features_available (CoglFeatureFlags features)
{
_COGL_GET_CONTEXT (ctx, 0);
if (!ctx->features_cached)
_cogl_features_init ();
return (ctx->feature_flags & features) == features;
}