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 3d07e34cc5
commit 5985eef44c
30 changed files with 2235 additions and 1153 deletions

49
README
View File

@ -199,6 +199,55 @@ Release Notes for Clutter 1.0
API. The change removed the private (yet publicly exported) and
the already deprecated ClutterFixed API.
Cogl API changes for Clutter 1.0
--------------------------------
* All drawing functions now use a source material to determine how geometry is
filled. The source material is set via cogl_set_source. Or the convenience
functions cogl_set_source_color and cogl_set_source_texture.
"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 respectively.
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:
material = cogl_material_new ();
cogl_material_set_color4ub (r,g,b,a);
cogl_material_set_layer (material, 0, tex_handle));
cogl_set_source_material (material);
Code that uses the texture coordinates, 0, 0, 1, 1 don't need to use
cogl_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);
* A CoglMesh type and utility API has been added; this is currently used to
support describing texture matrices.
Release Notes for Clutter 0.8
-------------------------------

View File

@ -195,7 +195,7 @@ clutter_clone_texture_paint (ClutterActor *self)
#if USE_COGL_MATERIAL
cogl_material = clutter_texture_get_cogl_material (priv->parent_texture);
/* FIXME: This is a lazy way of extracting the cogl_texture for the
/* This is just a convenient way of extracting the cogl_texture for the
* the first layer of the above material... */
cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
#else
@ -221,23 +221,14 @@ clutter_clone_texture_paint (ClutterActor *self)
#if USE_COGL_MATERIAL
cogl_set_source (cogl_material);
tex_coords[0] = 0;
tex_coords[1] = 0;
tex_coords[2] = t_w;
tex_coords[3] = t_h;
cogl_material_rectangle (0, 0,
COGL_FIXED_FROM_INT (x_2 - x_1),
COGL_FIXED_FROM_INT (y_2 - y_1),
0,
tex_coords);
#else
cogl_set_source_texture (cogl_texture);
#endif
/* Parent paint translated us into position */
cogl_texture_rectangle (cogl_texture, 0, 0,
cogl_rectangle_with_texture_coords (0, 0,
(float) (x_2 - x_1),
(float) (y_2 - y_1),
0, 0, t_w, t_h);
#endif
}
static void

View File

@ -1157,18 +1157,6 @@ clutter_init_real (GError **error)
if (!_clutter_backend_post_parse (backend, error))
return CLUTTER_INIT_ERROR_BACKEND;
/*
* Resolution requires display to be open, so can only be queried after
* the post_parse hooks run.
*/
ctx->font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new ());
resolution = clutter_backend_get_resolution (ctx->backend);
cogl_pango_font_map_set_resolution (ctx->font_map, resolution);
cogl_pango_font_map_set_use_mipmapping (ctx->font_map, TRUE);
clutter_text_direction = clutter_get_text_direction ();
/* Stage will give us a GL Context etc */
stage = clutter_stage_get_default ();
if (!stage)
@ -1201,6 +1189,21 @@ clutter_init_real (GError **error)
* start issueing cogl commands
*/
/*
* Resolution requires display to be open, so can only be queried after
* the post_parse hooks run.
*
* NB: cogl_pango requires a Cogl context.
*/
ctx->font_map = COGL_PANGO_FONT_MAP (cogl_pango_font_map_new ());
resolution = clutter_backend_get_resolution (ctx->backend);
cogl_pango_font_map_set_resolution (ctx->font_map, resolution);
cogl_pango_font_map_set_use_mipmapping (ctx->font_map, TRUE);
clutter_text_direction = clutter_get_text_direction ();
/* Figure out framebuffer masks used for pick */
cogl_get_bitmasks (&ctx->fb_r_mask, &ctx->fb_g_mask, &ctx->fb_b_mask, NULL);

View File

@ -635,22 +635,13 @@ clutter_texture_paint (ClutterActor *self)
/* Paint will have translated us */
#if USE_COGL_MATERIAL
cogl_set_source (priv->material);
tex_coords[0] = 0;
tex_coords[1] = 0;
tex_coords[2] = t_w;
tex_coords[3] = t_h;
cogl_material_rectangle (0, 0,
(float)(x_2 - x_1),
(float)(y_2 - y_1),
4,
tex_coords);
#else
cogl_texture_rectangle (priv->texture, 0, 0,
cogl_set_source_texture (priv->texture);
#endif
cogl_rectangle_with_texture_coords (0, 0,
(float) (x_2 - x_1),
(float) (y_2 - y_1),
0, 0, t_w, t_h);
#endif
}
/*
@ -769,6 +760,7 @@ clutter_texture_set_property (GObject *object,
(texture, (CoglHandle) g_value_get_boxed (value));
break;
#if USE_COGL_MATERIAL
case PROP_COGL_MATERIAL:
clutter_texture_set_cogl_material
(texture, (CoglHandle) g_value_get_boxed (value));
break;
@ -2188,7 +2180,7 @@ on_fbo_source_size_change (GObject *object,
if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH)
flags |= COGL_TEXTURE_AUTO_MIPMAP;
priv->fdo_texture =
priv->fbo_texture =
cogl_texture_new_with_size (MAX (priv->width, 1),
MAX (priv->height, 1),
-1,

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,28 +399,111 @@ 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,
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
#endif /* __COGL_TEXTURE_H__ */

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;
@ -68,6 +72,23 @@ _cogl_material_free (CoglMaterial *material)
g_free (material);
}
void
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)
@ -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 =
@ -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
@ -384,9 +522,7 @@ cogl_material_set_layer_combine_arg_src (
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,28 +733,17 @@ 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.
*/
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_TEXTURE_ENV_MODE, GL_COMBINE));
/* Set the combiner functions... */
@ -654,8 +803,11 @@ cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
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)))
@ -1419,9 +1420,12 @@ 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. */
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;
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,20 +38,6 @@
#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,
@ -90,12 +76,17 @@ void
_cogl_path_stroke_nodes ()
{
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)
{
@ -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);
@ -162,7 +155,14 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
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

View File

@ -31,8 +31,6 @@
typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglCompositeTexture CoglCompositeTexture;
typedef struct _CoglCompositeTextureLayer CoglCompositeTextureLayer;
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

View File

@ -294,28 +294,14 @@ cogl_enable (gulong 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);
@ -376,13 +362,11 @@ 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));
/* In case cogl_set_source_texture was previously used... */
cogl_material_remove_layer (ctx->default_material, 0);
/* Store alpha for proper blending enables */
ctx->color_alpha = cogl_color_get_alpha_byte (color);
cogl_material_set_color (ctx->default_material, color);
cogl_set_source (ctx->default_material);
}
static void

View File

@ -42,8 +42,10 @@ struct _CoglPangoRenderer
{
PangoRenderer parent_instance;
/* The color to draw the glyphs with */
CoglColor color;
/* The material used to texture from the glyph cache with */
CoglHandle glyph_material;
/* The material used for solid fills. (boxes, rectangles + trapezoids) */
CoglHandle solid_material;
/* Two caches of glyphs as textures, one with mipmapped textures and
one without */
@ -68,7 +70,9 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv)
if (priv->glyph_rectangles->len > 0)
{
float *rectangles = (float *) priv->glyph_rectangles->data;
cogl_texture_multiple_rectangles (priv->glyph_texture, rectangles,
cogl_material_set_layer (priv->glyph_material, 0, priv->glyph_texture);
cogl_set_source (priv->glyph_material);
cogl_rectangles_with_texture_coords (rectangles,
priv->glyph_rectangles->len / 8);
g_array_set_size (priv->glyph_rectangles, 0);
}
@ -128,6 +132,38 @@ G_DEFINE_TYPE (CoglPangoRenderer, cogl_pango_renderer, PANGO_TYPE_RENDERER);
static void
cogl_pango_renderer_init (CoglPangoRenderer *priv)
{
priv->glyph_material = cogl_material_new ();
/* The default combine mode of materials is to modulate (A x B) the texture
* RGBA channels with the RGBA channels of the previous layer (which in our
* case is just the solid font color)
*
* Since our glyph cache textures are component alpha textures, and so the
* RGB channels are defined as (0, 0, 0) we don't want to modulate the RGB
* channels, instead we want to simply replace them with our solid font
* color...
*
* XXX: we could really do with a neat string based way for describing
* combine modes, like: "REPLACE(PREVIOUS[RGB])"
* XXX: potentially materials could have a fuzzy default combine mode
* such that they default to this for component alpha textures? This would
* give the same semantics as the old-style GL_MODULATE mode but sounds a
* bit hacky.
*/
cogl_material_set_layer_combine_function (
priv->glyph_material,
0, /* layer */
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_FUNC_REPLACE);
cogl_material_set_layer_combine_arg_src (
priv->glyph_material,
0, /* layer */
0, /* arg */
COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGB,
COGL_MATERIAL_LAYER_COMBINE_SRC_PREVIOUS);
priv->solid_material = cogl_material_new ();
priv->glyph_cache = cogl_pango_glyph_cache_new (FALSE);
priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE);
priv->use_mipmapping = FALSE;
@ -203,7 +239,8 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout,
if (G_UNLIKELY (!priv))
return;
priv->color = *color;
cogl_material_set_color (priv->glyph_material, color);
cogl_material_set_color (priv->solid_material, color);
pango_renderer_draw_layout (PANGO_RENDERER (priv), layout, x, y);
}
@ -259,7 +296,8 @@ cogl_pango_render_layout_line (PangoLayoutLine *line,
if (G_UNLIKELY (!priv))
return;
priv->color = *color;
cogl_material_set_color (priv->glyph_material, color);
cogl_material_set_color (priv->solid_material, color);
pango_renderer_draw_layout_line (PANGO_RENDERER (priv), line, x, y);
}
@ -398,19 +436,32 @@ cogl_pango_renderer_set_color_for_part (PangoRenderer *renderer,
if (pango_color)
{
cogl_set_source_color4ub (pango_color->red >> 8,
pango_color->green >> 8,
pango_color->blue >> 8,
cogl_color_get_alpha_byte (&priv->color));
CoglColor color;
guint8 red = pango_color->red >> 8;
guint8 green = pango_color->green >> 8;
guint8 blue = pango_color->blue >> 8;
guint8 alpha;
cogl_material_get_color (priv->solid_material, &color);
alpha = cogl_color_get_alpha_byte (&color);
cogl_material_set_color4ub (priv->solid_material,
red, green, blue, alpha);
cogl_material_set_color4ub (priv->glyph_material,
red, green, blue, alpha);
}
else
cogl_set_source_color (&priv->color);
}
static void
cogl_pango_renderer_draw_box (int x, int y,
int width, int height)
cogl_pango_renderer_draw_box (PangoRenderer *renderer,
int x,
int y,
int width,
int height)
{
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
cogl_set_source (priv->solid_material);
cogl_path_rectangle ((float)(x),
(float)(y - height),
(float)(width),
@ -450,6 +501,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
int width,
int height)
{
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
float x1, x2, y1, y2;
cogl_pango_renderer_set_color_for_part (renderer, part);
@ -461,6 +513,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
x + width, y + height,
&x2, &y2);
cogl_set_source (priv->solid_material);
cogl_rectangle (x1, y1, x2 - x1, y2 - y1);
}
@ -474,6 +527,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
double x12,
double x22)
{
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
float points[8];
points[0] = (x11);
@ -487,6 +541,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
cogl_pango_renderer_set_color_for_part (renderer, part);
cogl_set_source (priv->solid_material);
cogl_path_polygon (points, 4);
cogl_path_fill ();
}
@ -524,15 +579,17 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
if (font == NULL ||
(metrics = pango_font_get_metrics (font, NULL)) == NULL)
{
cogl_pango_renderer_draw_box ( (x),
(y),
cogl_pango_renderer_draw_box (renderer,
x,
y,
PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT);
}
else
{
cogl_pango_renderer_draw_box ( (x),
(y),
cogl_pango_renderer_draw_box (renderer,
x,
y,
metrics->approximate_char_width
/ PANGO_SCALE,
metrics->ascent / PANGO_SCALE);
@ -553,8 +610,9 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
{
cogl_pango_renderer_glyphs_end (priv);
cogl_pango_renderer_draw_box ( (x),
(y),
cogl_pango_renderer_draw_box (renderer,
x,
y,
PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT);
}

View File

@ -127,17 +127,15 @@ on_paint (ClutterActor *actor, TestState *state)
x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a front-facing texture */
cogl_texture_rectangle (state->texture,
x1, y1, x2, y2,
0, 0, 1.0, 1.0);
cogl_set_source_texture (state->texture);
cogl_rectangle (x1, y1, x2, y2);
x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a back-facing texture */
cogl_texture_rectangle (state->texture,
x2, y1, x1, y2,
0, 0, 1.0, 1.0);
cogl_set_source_texture (state->texture);
cogl_rectangle (x2, y1, x1, y2);
x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE);
@ -151,8 +149,8 @@ on_paint (ClutterActor *actor, TestState *state)
verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4,
verts, FALSE);
cogl_set_source_texture (state->texture);
cogl_polygon (verts, 4, FALSE);
x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE);
@ -166,8 +164,8 @@ on_paint (ClutterActor *actor, TestState *state)
verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4,
verts, FALSE);
cogl_set_source_texture (state->texture);
cogl_polygon (verts, 4, FALSE);
x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE);

View File

@ -28,7 +28,7 @@ UNIT_TESTS = \
test-cogl-tex-getset.c \
test-cogl-offscreen.c \
test-cogl-tex-polygon.c \
test-cogl-material.c \
test-cogl-multitexture.c \
test-stage-read-pixels.c \
test-random-text.c \
test-clip.c \
@ -40,7 +40,8 @@ UNIT_TESTS = \
test-binding-pool.c \
test-text.c \
test-text-field.c \
test-clutter-cairo-flowers.c
test-clutter-cairo-flowers.c \
test-simple.c
if X11_TESTS
UNIT_TESTS += test-pixmap.c

View File

@ -165,8 +165,8 @@ on_paint (ClutterActor *actor, CallbackData *data)
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_texture_rectangle (data->hand,
CLUTTER_INT_TO_FIXED (-hand_width / 2),
cogl_set_source_texture (data->hand);
cogl_rectangle_with_texture_coords (CLUTTER_INT_TO_FIXED (-hand_width / 2),
CLUTTER_INT_TO_FIXED (-hand_height / 2),
CLUTTER_INT_TO_FIXED (hand_width / 2),
CLUTTER_INT_TO_FIXED (hand_height / 2),

View File

@ -45,16 +45,17 @@ material_rectangle_paint (ClutterActor *actor, gpointer data)
TestMultiLayerMaterialState *state = data;
cogl_set_source (state->material);
cogl_material_rectangle (CLUTTER_INT_TO_FIXED(0),
cogl_rectangle_with_multitexture_coords (
CLUTTER_INT_TO_FIXED(0),
CLUTTER_INT_TO_FIXED(0),
CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT),
CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT),
12,
state->tex_coords);
state->tex_coords,
12);
}
G_MODULE_EXPORT int
test_cogl_material_main (int argc, char *argv[])
test_cogl_multitexture_main (int argc, char *argv[])
{
ClutterTimeline *timeline;
ClutterAlpha *alpha;
@ -130,12 +131,9 @@ test_cogl_material_main (int argc, char *argv[])
g_signal_connect (timeline, "new-frame", G_CALLBACK (frame_cb), state);
/* Set an alpha func to power behaviour - ramp is constant rise/fall */
alpha = clutter_alpha_new_for_mode (CLUTTER_LINEAR);
clutter_alpha_set_timeline (alpha, timeline);
/* Create a behaviour for that alpha */
r_behave = clutter_behaviour_rotate_new (alpha,
r_behave =
clutter_behaviour_rotate_new (clutter_alpha_new_full (timeline,
CLUTTER_LINEAR),
CLUTTER_Y_AXIS,
CLUTTER_ROTATE_CW,
0.0, 360.0);

View File

@ -87,15 +87,15 @@ test_coglbox_paint(ClutterActor *self)
CLUTTER_FLOAT_TO_FIXED (1.0f),
CLUTTER_FLOAT_TO_FIXED (1.0f)
};
CoglHandle material;
priv = TEST_COGLBOX_GET_PRIVATE (self);
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_texture_rectangle (priv->texhand_id,
0, 0,
cogl_set_source_texture (priv->texhand_id);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (400),
CLUTTER_INT_TO_FIXED (400),
0, 0,
@ -112,9 +112,11 @@ test_coglbox_paint(ClutterActor *self)
cogl_draw_buffer (COGL_WINDOW_BUFFER, 0);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0x88);
cogl_texture_rectangle (priv->texture_id,
CLUTTER_INT_TO_FIXED (100),
material = cogl_material_new ();
cogl_material_set_color4ub (material, 0xff, 0xff, 0xff, 0x88);
cogl_material_set_layer (material, 0, priv->texture_id);
cogl_set_source (material);
cogl_rectangle_with_texture_coords (CLUTTER_INT_TO_FIXED (100),
CLUTTER_INT_TO_FIXED (100),
CLUTTER_INT_TO_FIXED (300),
CLUTTER_INT_TO_FIXED (300),

View File

@ -92,11 +92,9 @@ test_coglbox_paint(ClutterActor *self)
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_push_matrix ();
cogl_texture_rectangle (priv->cogl_tex_id[0],
0, 0,
cogl_set_source_texture (priv->cogl_tex_id[0]);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],
@ -105,8 +103,8 @@ test_coglbox_paint(ClutterActor *self)
cogl_pop_matrix ();
cogl_push_matrix ();
cogl_translate (200, 0, 0);
cogl_texture_rectangle (priv->cogl_tex_id[1],
0, 0,
cogl_set_source_texture (priv->cogl_tex_id[1]);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],
@ -115,8 +113,8 @@ test_coglbox_paint(ClutterActor *self)
cogl_pop_matrix ();
cogl_push_matrix ();
cogl_translate (0, 200, 0);
cogl_texture_rectangle (priv->cogl_tex_id[2],
0, 0,
cogl_set_source_texture (priv->cogl_tex_id[2]);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],
@ -125,8 +123,8 @@ test_coglbox_paint(ClutterActor *self)
cogl_pop_matrix ();
cogl_push_matrix ();
cogl_translate (200, 200, 0);
cogl_texture_rectangle (priv->cogl_tex_id[3],
0, 0,
cogl_set_source_texture (priv->cogl_tex_id[3]);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],

View File

@ -92,13 +92,11 @@ test_coglbox_paint(ClutterActor *self)
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0,0,400,400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_push_matrix ();
cogl_translate (100,100,0);
cogl_texture_rectangle (priv->cogl_handle,
0, 0,
cogl_set_source_texture (priv->cogl_handle);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (200),
texcoords[0], texcoords[1],

View File

@ -91,13 +91,11 @@ test_coglbox_paint(ClutterActor *self)
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_push_matrix ();
cogl_translate (100, 100, 0);
cogl_texture_rectangle (priv->cogl_tex_id[1],
0, 0,
cogl_set_source_texture (priv->cogl_tex_id[1]);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],

View File

@ -122,7 +122,8 @@ test_coglbox_fade_texture (CoglHandle tex_id,
((i ^ (i >> 1)) & 1) ? 0 : 128);
}
cogl_texture_polygon (tex_id, 4, vertices, TRUE);
cogl_set_source_texture (tex_id);
cogl_polygon (vertices, 4, TRUE);
cogl_set_source_color4ub (255, 255, 255, 255);
}
@ -160,7 +161,8 @@ test_coglbox_triangle_texture (CoglHandle tex_id,
vertices[2].tx = tx3;
vertices[2].ty = ty3;
cogl_texture_polygon (tex_id, 3, vertices, FALSE);
cogl_set_source_texture (tex_id);
cogl_polygon (vertices, 3, FALSE);
}
static void
@ -172,8 +174,6 @@ test_coglbox_paint (ClutterActor *self)
int tex_width = cogl_texture_get_width (tex_handle);
int tex_height = cogl_texture_get_height (tex_handle);
cogl_set_source_color4ub (255, 255, 255, 255);
cogl_texture_set_filters (tex_handle,
priv->use_linear_filtering
? CGL_LINEAR : CGL_NEAREST,
@ -186,8 +186,8 @@ test_coglbox_paint (ClutterActor *self)
cogl_translate (-tex_width / 2, 0, 0);
/* Draw a hand and refect it */
cogl_texture_rectangle (tex_handle,
0, 0,
cogl_set_source_texture (tex_handle);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (tex_width),
CLUTTER_INT_TO_FIXED (tex_height),
0, 0, CFX_ONE, CFX_ONE);

View File

@ -115,10 +115,9 @@ test_coglbox_paint(ClutterActor *self)
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_translate (100, 100, 0);
cogl_texture_rectangle (priv->cogl_tex_id,
0, 0,
cogl_set_source_texture (priv->cogl_tex_id);
cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1],