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 API. The change removed the private (yet publicly exported) and
the already deprecated ClutterFixed API. 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 Release Notes for Clutter 0.8
------------------------------- -------------------------------

View File

@ -195,7 +195,7 @@ clutter_clone_texture_paint (ClutterActor *self)
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
cogl_material = clutter_texture_get_cogl_material (priv->parent_texture); 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... */ * the first layer of the above material... */
cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture); cogl_texture = clutter_texture_get_cogl_texture (priv->parent_texture);
#else #else
@ -221,23 +221,14 @@ clutter_clone_texture_paint (ClutterActor *self)
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
cogl_set_source (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 #else
/* Parent paint translated us into position */ cogl_set_source_texture (cogl_texture);
cogl_texture_rectangle (cogl_texture, 0, 0,
(float)(x_2 - x_1),
(float)(y_2 - y_1),
0, 0, t_w, t_h);
#endif #endif
/* Parent paint translated us into position */
cogl_rectangle_with_texture_coords (0, 0,
(float) (x_2 - x_1),
(float) (y_2 - y_1),
0, 0, t_w, t_h);
} }
static void static void

View File

@ -1157,18 +1157,6 @@ clutter_init_real (GError **error)
if (!_clutter_backend_post_parse (backend, error)) if (!_clutter_backend_post_parse (backend, error))
return CLUTTER_INIT_ERROR_BACKEND; 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 will give us a GL Context etc */
stage = clutter_stage_get_default (); stage = clutter_stage_get_default ();
if (!stage) if (!stage)
@ -1201,6 +1189,21 @@ clutter_init_real (GError **error)
* start issueing cogl commands * 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 */ /* Figure out framebuffer masks used for pick */
cogl_get_bitmasks (&ctx->fb_r_mask, &ctx->fb_g_mask, &ctx->fb_b_mask, NULL); 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 */ /* Paint will have translated us */
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
cogl_set_source (priv->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 #else
cogl_texture_rectangle (priv->texture, 0, 0, cogl_set_source_texture (priv->texture);
(float)(x_2 - x_1),
(float)(y_2 - y_1),
0, 0, t_w, t_h);
#endif #endif
cogl_rectangle_with_texture_coords (0, 0,
(float) (x_2 - x_1),
(float) (y_2 - y_1),
0, 0, t_w, t_h);
} }
/* /*
@ -769,6 +760,7 @@ clutter_texture_set_property (GObject *object,
(texture, (CoglHandle) g_value_get_boxed (value)); (texture, (CoglHandle) g_value_get_boxed (value));
break; break;
#if USE_COGL_MATERIAL #if USE_COGL_MATERIAL
case PROP_COGL_MATERIAL:
clutter_texture_set_cogl_material clutter_texture_set_cogl_material
(texture, (CoglHandle) g_value_get_boxed (value)); (texture, (CoglHandle) g_value_get_boxed (value));
break; break;
@ -2188,7 +2180,7 @@ on_fbo_source_size_change (GObject *object,
if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH) if (priv->filter_quality == CLUTTER_TEXTURE_QUALITY_HIGH)
flags |= COGL_TEXTURE_AUTO_MIPMAP; flags |= COGL_TEXTURE_AUTO_MIPMAP;
priv->fdo_texture = priv->fbo_texture =
cogl_texture_new_with_size (MAX (priv->width, 1), cogl_texture_new_with_size (MAX (priv->width, 1),
MAX (priv->height, 1), MAX (priv->height, 1),
-1, -1,

View File

@ -52,6 +52,8 @@ CoglHandle cogl_material_ref (CoglHandle handle);
*/ */
void cogl_material_unref (CoglHandle handle); void cogl_material_unref (CoglHandle handle);
/** /**
* cogl_material_set_color: * cogl_material_set_color:
* @material: A CoglMaterial object * @material: A CoglMaterial object
@ -65,6 +67,37 @@ void cogl_material_unref (CoglHandle handle);
*/ */
void cogl_material_set_color (CoglHandle material, const CoglColor *color); 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: * cogl_material_set_ambient:
* @material: A CoglMaterial object * @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, void cogl_material_set_ambient (CoglHandle material,
const CoglColor *ambient); 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: * cogl_material_set_diffuse:
* @material: A CoglMaterial object * @material: A CoglMaterial object
@ -100,6 +144,17 @@ void cogl_material_set_ambient (CoglHandle material,
void cogl_material_set_diffuse (CoglHandle material, void cogl_material_set_diffuse (CoglHandle material,
const CoglColor *diffuse); 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: * cogl_material_set_ambient_and_diffuse:
* @material: A CoglMaterial object * @material: A CoglMaterial object
@ -133,6 +188,17 @@ void cogl_material_set_ambient_and_diffuse (CoglHandle material,
void cogl_material_set_specular (CoglHandle material, void cogl_material_set_specular (CoglHandle material,
const CoglColor *specular); 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: * cogl_material_set_shininess:
* @material: A CoglMaterial object * @material: A CoglMaterial object
@ -148,6 +214,17 @@ void cogl_material_set_specular (CoglHandle material,
*/ */
void cogl_material_set_shininess (CoglHandle material, void cogl_material_set_shininess (CoglHandle material,
float shininess); 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: * cogl_material_set_emission:
@ -165,6 +242,17 @@ void cogl_material_set_shininess (CoglHandle material,
void cogl_material_set_emission (CoglHandle material, void cogl_material_set_emission (CoglHandle material,
const CoglColor *emission); 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: * CoglMaterialAlphaFunc:
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through. * @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: * 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 * 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 * 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); CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
/** /**
* cogl_material_layer_flush_gl_sampler_state: * CoglMaterialLayerFlags:
* @material: A CoglMaterial object * @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
* * custom texture matrix.
* 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 ();
*/ */
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: * cogl_set_source:
@ -684,19 +820,16 @@ void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
void cogl_set_source (CoglHandle material); 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 * This is a convenience function for creating a material with the first
* including the per-layer state - to the OpenGL[ES] driver. * layer set to #texture_handle and setting that material as the source with
* * cogl_set_source.
* 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 * Since 1.0
*/ */
/* XXX: This should be moved with cogl_set_source to cogl.h */ void cogl_set_source_texture (CoglHandle texture_handle);
void cogl_flush_material_gl_state (void);
G_END_DECLS G_END_DECLS

View File

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

View File

@ -359,90 +359,6 @@ CoglHandle cogl_texture_ref (CoglHandle handle);
*/ */
void cogl_texture_unref (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: * cogl_bitmap_new_from_file:
* @filename: the file to load. * @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); void cogl_bitmap_free (CoglBitmap *bmp);
/** /**
* cogl_texture_multiple_rectangles: * cogl_rectangle_with_texture_coords:
* @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 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 * @verts: an array of vertices
* @n_rects: number of rectangles to draw * @n_rects: number of rectangles to draw
* *
* Draws a series of rectangles in the same way that * 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 * 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 * @verts should point to an array of #float<!-- -->s with
* @n_rects * 8 elements. Each group of 8 values corresponds to the * @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 * 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 * Since: 0.8.6
*/ */
void cogl_texture_multiple_rectangles void cogl_rectangles_with_texture_coords (const float *verts,
(CoglHandle handle, guint n_rects);
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 G_END_DECLS

View File

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

View File

@ -9,10 +9,28 @@
typedef struct _CoglMaterial CoglMaterial; typedef struct _CoglMaterial CoglMaterial;
typedef struct _CoglMaterialLayer CoglMaterialLayer; 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, /* Ref: CoglMaterialLayerFlags
} 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 struct _CoglMaterialLayer
{ {
@ -42,7 +60,12 @@ typedef enum _CoglMaterialFlags
{ {
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0, COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0,
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<1, 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; } CoglMaterialFlags;
struct _CoglMaterial struct _CoglMaterial

View File

@ -37,20 +37,24 @@ cogl_material_new (void)
/* Use the same defaults as the GL spec... */ /* Use the same defaults as the GL spec... */
unlit[0] = 1.0; unlit[1] = 1.0; unlit[2] = 1.0; unlit[3] = 1.0; 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... */ /* Use the same defaults as the GL spec... */
ambient[0] = 0.2; ambient[1] = 0.2; ambient[2] = 0.2; ambient[3] = 1.0; 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; 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; 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; 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... */ /* Use the same defaults as the GL spec... */
material->alpha_func = COGL_MATERIAL_ALPHA_FUNC_ALWAYS; material->alpha_func = COGL_MATERIAL_ALPHA_FUNC_ALWAYS;
material->alpha_func_reference = 0.0; material->alpha_func_reference = 0.0;
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
/* Not the same as the GL default, but seems saner... */ /* Not the same as the GL default, but seems saner... */
material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA; material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA;
material->blend_dst_factor = COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_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; material->layers = NULL;
@ -69,7 +73,24 @@ _cogl_material_free (CoglMaterial *material)
} }
void 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) const CoglColor *unlit_color)
{ {
CoglMaterial *material; CoglMaterial *material;
@ -88,7 +109,46 @@ cogl_material_set_color (CoglHandle handle,
memcpy (material->unlit, unlit, sizeof (unlit)); 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_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 void
@ -109,6 +169,24 @@ cogl_material_set_ambient (CoglHandle handle,
ambient[3] = cogl_color_get_alpha_float (ambient_color); ambient[3] = cogl_color_get_alpha_float (ambient_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY; 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 void
@ -129,6 +207,7 @@ cogl_material_set_diffuse (CoglHandle handle,
diffuse[3] = cogl_color_get_alpha_float (diffuse_color); diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY; material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
} }
void void
@ -139,6 +218,23 @@ cogl_material_set_ambient_and_diffuse (CoglHandle handle,
cogl_material_set_diffuse (handle, color); 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 void
cogl_material_set_specular (CoglHandle handle, cogl_material_set_specular (CoglHandle handle,
const CoglColor *specular_color) const CoglColor *specular_color)
@ -157,6 +253,19 @@ cogl_material_set_specular (CoglHandle handle,
specular[3] = cogl_color_get_alpha_float (specular_color); specular[3] = cogl_color_get_alpha_float (specular_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY; 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 void
@ -176,6 +285,24 @@ cogl_material_set_shininess (CoglHandle handle,
material->shininess = (GLfloat)shininess * 128.0; material->shininess = (GLfloat)shininess * 128.0;
material->flags |= COGL_MATERIAL_FLAG_DIRTY; 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 void
@ -196,6 +323,7 @@ cogl_material_set_emission (CoglHandle handle,
emission[3] = cogl_color_get_alpha_float (emission_color); emission[3] = cogl_color_get_alpha_float (emission_color);
material->flags |= COGL_MATERIAL_FLAG_DIRTY; material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
} }
void void
@ -212,6 +340,7 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
material->alpha_func_reference = (GLfloat)alpha_reference; material->alpha_func_reference = (GLfloat)alpha_reference;
material->flags |= COGL_MATERIAL_FLAG_DIRTY; material->flags |= COGL_MATERIAL_FLAG_DIRTY;
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
} }
void void
@ -228,6 +357,7 @@ cogl_material_set_blend_factors (CoglHandle handle,
material->blend_dst_factor = dst_factor; material->blend_dst_factor = dst_factor;
material->flags |= COGL_MATERIAL_FLAG_DIRTY; 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 /* 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->ref_count = 1;
layer->index = index; layer->index = index;
layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
layer->texture = COGL_INVALID_HANDLE; layer->texture = COGL_INVALID_HANDLE;
/* Choose the same default combine mode as OpenGL: /* Choose the same default combine mode as OpenGL:
@ -284,6 +415,8 @@ _cogl_material_get_layer (CoglMaterial *material,
layer->texture_combine_alpha_op[1] = layer->texture_combine_alpha_op[1] =
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA; COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA;
cogl_matrix_init_identity (&layer->matrix);
layer_handle = _cogl_material_layer_handle_new (layer); layer_handle = _cogl_material_layer_handle_new (layer);
/* Note: see comment after for() loop above */ /* Note: see comment after for() loop above */
material->layers = material->layers =
@ -317,7 +450,7 @@ cogl_material_set_layer (CoglHandle material_handle,
{ {
if (!(material->flags & COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING)) 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"); "to handle this many texture layers");
material->flags |= COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING; 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. */ * MAX_COMBINED_TEXTURE_IMAGE_UNITS layers. */
} }
cogl_texture_ref (texture_handle);
if (layer->texture) if (layer->texture)
cogl_texture_unref (layer->texture); cogl_texture_unref (layer->texture);
cogl_texture_ref (texture_handle);
layer->texture = texture_handle; layer->texture = texture_handle;
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
} }
void void
@ -350,9 +486,7 @@ cogl_material_set_layer_combine_function (
g_return_if_fail (cogl_is_material (handle)); g_return_if_fail (cogl_is_material (handle));
material = _cogl_material_pointer_from_handle (handle); material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE); layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (!layer)
return;
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA) if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_alpha_func = set_rgb_func = TRUE; set_alpha_func = set_rgb_func = TRUE;
@ -365,6 +499,10 @@ cogl_material_set_layer_combine_function (
layer->texture_combine_rgb_func = func; layer->texture_combine_rgb_func = func;
if (set_alpha_func) if (set_alpha_func)
layer->texture_combine_alpha_func = 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 void
@ -377,16 +515,14 @@ cogl_material_set_layer_combine_arg_src (
{ {
CoglMaterial *material; CoglMaterial *material;
CoglMaterialLayer *layer; CoglMaterialLayer *layer;
gboolean set_arg_alpha_src = FALSE; gboolean set_arg_alpha_src = FALSE;
gboolean set_arg_rgb_src = FALSE; gboolean set_arg_rgb_src = FALSE;
g_return_if_fail (cogl_is_material (handle)); g_return_if_fail (cogl_is_material (handle));
g_return_if_fail (argument >=0 && argument <= 3); g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (handle); material = _cogl_material_pointer_from_handle (handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE); layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (!layer)
return;
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA) if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_src = set_arg_rgb_src = TRUE; 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; layer->texture_combine_rgb_src[argument] = src;
if (set_arg_alpha_src) if (set_arg_alpha_src)
layer->texture_combine_alpha_src[argument] = 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 void
@ -418,9 +558,7 @@ cogl_material_set_layer_combine_arg_op (
g_return_if_fail (argument >=0 && argument <= 3); g_return_if_fail (argument >=0 && argument <= 3);
material = _cogl_material_pointer_from_handle (material_handle); material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE); layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (!layer)
return;
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA) if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
set_arg_alpha_op = set_arg_rgb_op = TRUE; 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; layer->texture_combine_rgb_op[argument] = op;
if (set_arg_alpha_op) if (set_arg_alpha_op)
layer->texture_combine_alpha_op[argument] = 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 void
@ -446,12 +588,14 @@ cogl_material_set_layer_matrix (CoglHandle material_handle,
g_return_if_fail (cogl_is_material (material_handle)); g_return_if_fail (cogl_is_material (material_handle));
material = _cogl_material_pointer_from_handle (material_handle); material = _cogl_material_pointer_from_handle (material_handle);
layer = _cogl_material_get_layer (material, layer_index, FALSE); layer = _cogl_material_get_layer (material, layer_index, TRUE);
if (!layer)
return;
layer->matrix = *matrix; 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 static void
@ -490,6 +634,10 @@ cogl_material_remove_layer (CoglHandle material_handle,
if (cogl_texture_get_format (layer->texture) & COGL_A_BIT) if (cogl_texture_get_format (layer->texture) & COGL_A_BIT)
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND; 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 /* 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; 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 static guint
get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func) get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
{ {
@ -573,89 +733,81 @@ get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
return 0; return 0;
} }
void static void
cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle) _cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
CoglLayerInfo *gl_layer_info)
{ {
CoglMaterialLayer *layer;
int n_rgb_func_args; int n_rgb_func_args;
int n_alpha_func_args; int n_alpha_func_args;
g_return_if_fail (cogl_is_material_layer (layer_handle)); if (!(gl_layer_info &&
gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE &&
layer = _cogl_material_layer_pointer_from_handle (layer_handle); layer->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE))
/* 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)
{ {
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC1_RGB, GE (glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE));
layer->texture_combine_rgb_src[1]));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND1_RGB, /* Set the combiner functions... */
layer->texture_combine_rgb_op[1])); GE (glTexEnvi (GL_TEXTURE_ENV,
} GL_COMBINE_RGB,
if (n_rgb_func_args > 2) layer->texture_combine_rgb_func));
{ GE (glTexEnvi (GL_TEXTURE_ENV,
GE (glTexEnvi (GL_TEXTURE_ENV, GL_SRC2_RGB, GL_COMBINE_ALPHA,
layer->texture_combine_rgb_src[2])); layer->texture_combine_alpha_func));
GE (glTexEnvi (GL_TEXTURE_ENV, GL_OPERAND2_RGB,
layer->texture_combine_rgb_op[2])); /*
* 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 */ if (gl_layer_info &&
n_alpha_func_args = (gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX ||
get_n_args_for_combine_func (layer->texture_combine_alpha_func); layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX))
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)
{ {
GE (glMatrixMode (GL_TEXTURE)); GE (glMatrixMode (GL_TEXTURE));
GE (glLoadMatrixf ((GLfloat *)&layer->matrix)); 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 /* TODO: Should go in cogl.c, but that implies duplication which is also
* not ideal. */ * not ideal. */
void void
@ -675,40 +1096,24 @@ cogl_set_source (CoglHandle material_handle)
if (ctx->source_material == material_handle) if (ctx->source_material == material_handle)
return; return;
cogl_material_ref (material_handle);
if (ctx->source_material) if (ctx->source_material)
cogl_material_unref (ctx->source_material); cogl_material_unref (ctx->source_material);
cogl_material_ref (material_handle);
ctx->source_material = material_handle; ctx->source_material = material_handle;
} }
/* TODO: add cogl_set_front_source (), and cogl_set_back_source () */ /* TODO: add cogl_set_front_source (), and cogl_set_back_source () */
void void
cogl_flush_material_gl_state (void) cogl_set_source_texture (CoglHandle texture_handle)
{ {
CoglMaterial *material;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
CoglColor white;
material = _cogl_material_pointer_from_handle (ctx->source_material); cogl_material_set_layer (ctx->default_material, 0, texture_handle);
cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
if (ctx->source_material == ctx->current_material cogl_material_set_color (ctx->default_material, &white);
&& !(material->flags & COGL_MATERIAL_FLAG_DIRTY)) cogl_set_source (ctx->default_material);
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;
} }

View File

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

View File

@ -134,6 +134,7 @@
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-handle.h" #include "cogl-handle.h"
#include "cogl-vertex-buffer-private.h" #include "cogl-vertex-buffer-private.h"
#include "cogl-texture-private.h"
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \ #define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1))) (VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
@ -1416,12 +1417,15 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
static void static void
enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer) enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
{ {
GList *tmp; GList *tmp;
GLenum gl_type; GLenum gl_type;
GLuint generic_index = 0; GLuint generic_index = 0;
gulong enable_flags = COGL_ENABLE_BLEND; gulong enable_flags = 0;
/* FIXME: I don't think it's appropriate to force enable guint max_texcoord_attrib_unit = 0;
* GL_BLEND here. */ const GList *layers;
guint32 fallback_mask = 0;
guint32 disable_mask = ~0;
int i;
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
@ -1460,17 +1464,16 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
(const GLvoid *)attribute->u.vbo_offset)); (const GLvoid *)attribute->u.vbo_offset));
break; break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
/* FIXME: set the active texture unit */ GE (glClientActiveTexture (GL_TEXTURE0 +
/* NB: Cogl currently manages unit 0 */ attribute->texture_unit));
enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY GE (glEnableClientState (GL_TEXTURE_COORD_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 (glTexCoordPointer (attribute->n_components, GE (glTexCoordPointer (attribute->n_components,
gl_type, gl_type,
attribute->stride, attribute->stride,
(const GLvoid *)attribute->u.vbo_offset)); (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; break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
enable_flags |= COGL_ENABLE_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 static void
@ -1550,9 +1596,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
GE (glDisableClientState (GL_NORMAL_ARRAY)); GE (glDisableClientState (GL_NORMAL_ARRAY));
break; break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY: case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
/* FIXME: set the active texture unit */ GE (glClientActiveTexture (GL_TEXTURE0 +
/* NB: Cogl currently manages unit 0 */ attribute->texture_unit));
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
break; break;
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY: case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */ /* GE (glDisableClientState (GL_VERTEX_ARRAY)); */

View File

@ -31,6 +31,8 @@
#include "cogl-internal.h" #include "cogl-internal.h"
#include "cogl-util.h" #include "cogl-util.h"
#include "cogl-context.h" #include "cogl-context.h"
#include "cogl-texture-private.h"
#include "cogl-material-private.h"
#include <string.h> #include <string.h>
@ -39,6 +41,9 @@ static CoglContext *_context = NULL;
gboolean gboolean
cogl_create_context () cogl_create_context ()
{ {
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
gulong enable_flags = 0;
if (_context != NULL) if (_context != NULL)
return FALSE; return FALSE;
@ -52,19 +57,26 @@ cogl_create_context ()
_context->enable_flags = 0; _context->enable_flags = 0;
_context->color_alpha = 255; _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_handles = NULL;
_context->material_layer_handles = NULL; _context->material_layer_handles = NULL;
_context->default_material = cogl_material_new ();
_context->source_material = NULL; _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 = 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->fbo_handles = NULL;
_context->draw_buffer = COGL_WINDOW_BUFFER; _context->draw_buffer = COGL_WINDOW_BUFFER;
@ -78,6 +90,10 @@ cogl_create_context ()
_context->vertex_buffer_handles = NULL; _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_glGenRenderbuffersEXT = NULL;
_context->pf_glBindRenderbufferEXT = NULL; _context->pf_glBindRenderbufferEXT = NULL;
_context->pf_glRenderbufferStorageEXT = NULL; _context->pf_glRenderbufferStorageEXT = NULL;
@ -123,15 +139,37 @@ cogl_create_context ()
_context->pf_glDrawRangeElements = NULL; _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 */ /* Initialise the clip stack */
_cogl_clip_stack_state_init (); _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; return TRUE;
} }
@ -155,10 +193,25 @@ cogl_destroy_context ()
if (_context->program_handles) if (_context->program_handles)
g_array_free (_context->program_handles, TRUE); g_array_free (_context->program_handles, TRUE);
if (_context->texture_vertices) if (_context->default_gl_texture_2d_tex)
g_array_free (_context->texture_vertices, TRUE); cogl_texture_unref (_context->default_gl_texture_2d_tex);
if (_context->texture_indices) if (_context->default_gl_texture_rect_tex)
g_array_free (_context->texture_indices, TRUE); 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); g_free (_context);
} }

View File

@ -50,33 +50,34 @@ typedef struct
gboolean enable_backface_culling; 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 */ /* Cache of inverse projection matrix */
GLfloat inverse_projection[16]; GLfloat inverse_projection[16];
/* Textures */ /* Textures */
GArray *texture_handles; GArray *texture_handles;
GArray *texture_vertices; CoglHandle default_gl_texture_2d_tex;
GArray *texture_indices; CoglHandle default_gl_texture_rect_tex;
/* 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;
/* Materials */ /* Materials */
GArray *material_handles; GArray *material_handles;
GArray *material_layer_handles; GArray *material_layer_handles;
CoglHandle default_material;
CoglHandle source_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; CoglHandle current_material;
gulong current_material_flags;
GArray *current_layers;
guint n_texcoord_arrays_enabled;
/* Framebuffer objects */ /* Framebuffer objects */
GArray *fbo_handles; GArray *fbo_handles;
@ -94,6 +95,15 @@ typedef struct
/* Vertex buffers */ /* Vertex buffers */
GArray *vertex_buffer_handles; 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 */ /* Relying on glext.h to define these */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT; COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT; COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;

View File

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

View File

@ -38,20 +38,6 @@
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16 #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 void
_cogl_path_add_node (gboolean new_sub_path, _cogl_path_add_node (gboolean new_sub_path,
float x, float x,
@ -89,13 +75,18 @@ _cogl_path_add_node (gboolean new_sub_path,
void void
_cogl_path_stroke_nodes () _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_GET_CONTEXT (ctx, NO_RETVAL);
cogl_enable (COGL_ENABLE_VERTEX_ARRAY enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material);
| (ctx->color_alpha < 255 cogl_enable (enable_flags);
? COGL_ENABLE_BLEND : 0));
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) 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_w;
float bounds_h; float bounds_h;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_path_get_bounds (nodes_min, nodes_max, _cogl_path_get_bounds (nodes_min, nodes_max,
&bounds_x, &bounds_y, &bounds_w, &bounds_h); &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) 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), GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
(guchar *) path (guchar *) path

View File

@ -28,11 +28,9 @@
#include "cogl-bitmap.h" #include "cogl-bitmap.h"
typedef struct _CoglTexture CoglTexture; typedef struct _CoglTexture CoglTexture;
typedef struct _CoglTexSliceSpan CoglTexSliceSpan; typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
typedef struct _CoglSpanIter CoglSpanIter; typedef struct _CoglSpanIter CoglSpanIter;
typedef struct _CoglCompositeTexture CoglCompositeTexture;
typedef struct _CoglCompositeTextureLayer CoglCompositeTextureLayer;
struct _CoglTexSliceSpan struct _CoglTexSliceSpan
{ {
@ -61,26 +59,23 @@ struct _CoglTexture
gboolean auto_mipmap; 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; CoglHandle material;
gint n_layers;
guint index; /*!< lowest index is blended first then others guint32 fallback_mask;
on top */ GLuint layer0_override_texture;
CoglTexture *tex; /*!< The texture for this layer, or NULL } CoglJournalEntry;
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;
};
CoglTexture* CoglTexture*
_cogl_texture_pointer_from_handle (CoglHandle handle); _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 */ #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, COGL_ENABLE_BLEND,
GL_BLEND); GL_BLEND);
cogl_toggle_flag (ctx, flags,
COGL_ENABLE_TEXTURE_2D,
GL_TEXTURE_2D);
cogl_toggle_flag (ctx, flags, cogl_toggle_flag (ctx, flags,
COGL_ENABLE_BACKFACE_CULLING, COGL_ENABLE_BACKFACE_CULLING,
GL_CULL_FACE); 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_toggle_client_flag (ctx, flags,
COGL_ENABLE_VERTEX_ARRAY, COGL_ENABLE_VERTEX_ARRAY,
GL_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_toggle_client_flag (ctx, flags,
COGL_ENABLE_COLOR_ARRAY, COGL_ENABLE_COLOR_ARRAY,
GL_COLOR_ARRAY); GL_COLOR_ARRAY);
@ -376,13 +362,11 @@ cogl_set_source_color (const CoglColor *color)
{ {
_COGL_GET_CONTEXT (ctx, NO_RETVAL); _COGL_GET_CONTEXT (ctx, NO_RETVAL);
glColor4ub (cogl_color_get_red_byte (color), /* In case cogl_set_source_texture was previously used... */
cogl_color_get_green_byte (color), cogl_material_remove_layer (ctx->default_material, 0);
cogl_color_get_blue_byte (color),
cogl_color_get_alpha_byte (color));
/* Store alpha for proper blending enables */ cogl_material_set_color (ctx->default_material, color);
ctx->color_alpha = cogl_color_get_alpha_byte (color); cogl_set_source (ctx->default_material);
} }
static void static void

View File

@ -42,8 +42,10 @@ struct _CoglPangoRenderer
{ {
PangoRenderer parent_instance; PangoRenderer parent_instance;
/* The color to draw the glyphs with */ /* The material used to texture from the glyph cache with */
CoglColor color; 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 /* Two caches of glyphs as textures, one with mipmapped textures and
one without */ one without */
@ -68,8 +70,10 @@ cogl_pango_renderer_glyphs_end (CoglPangoRenderer *priv)
if (priv->glyph_rectangles->len > 0) if (priv->glyph_rectangles->len > 0)
{ {
float *rectangles = (float *) priv->glyph_rectangles->data; 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);
priv->glyph_rectangles->len / 8); 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); g_array_set_size (priv->glyph_rectangles, 0);
} }
} }
@ -128,6 +132,38 @@ G_DEFINE_TYPE (CoglPangoRenderer, cogl_pango_renderer, PANGO_TYPE_RENDERER);
static void static void
cogl_pango_renderer_init (CoglPangoRenderer *priv) 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->glyph_cache = cogl_pango_glyph_cache_new (FALSE);
priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE); priv->mipmapped_glyph_cache = cogl_pango_glyph_cache_new (TRUE);
priv->use_mipmapping = FALSE; priv->use_mipmapping = FALSE;
@ -203,7 +239,8 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout,
if (G_UNLIKELY (!priv)) if (G_UNLIKELY (!priv))
return; 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); 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)) if (G_UNLIKELY (!priv))
return; 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); 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) if (pango_color)
{ {
cogl_set_source_color4ub (pango_color->red >> 8, CoglColor color;
pango_color->green >> 8, guint8 red = pango_color->red >> 8;
pango_color->blue >> 8, guint8 green = pango_color->green >> 8;
cogl_color_get_alpha_byte (&priv->color)); 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 static void
cogl_pango_renderer_draw_box (int x, int y, cogl_pango_renderer_draw_box (PangoRenderer *renderer,
int width, int height) 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), cogl_path_rectangle ((float)(x),
(float)(y - height), (float)(y - height),
(float)(width), (float)(width),
@ -450,6 +501,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
int width, int width,
int height) int height)
{ {
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
float x1, x2, y1, y2; float x1, x2, y1, y2;
cogl_pango_renderer_set_color_for_part (renderer, part); cogl_pango_renderer_set_color_for_part (renderer, part);
@ -461,6 +513,7 @@ cogl_pango_renderer_draw_rectangle (PangoRenderer *renderer,
x + width, y + height, x + width, y + height,
&x2, &y2); &x2, &y2);
cogl_set_source (priv->solid_material);
cogl_rectangle (x1, y1, x2 - x1, y2 - y1); cogl_rectangle (x1, y1, x2 - x1, y2 - y1);
} }
@ -474,6 +527,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
double x12, double x12,
double x22) double x22)
{ {
CoglPangoRenderer *priv = COGL_PANGO_RENDERER (renderer);
float points[8]; float points[8];
points[0] = (x11); points[0] = (x11);
@ -487,6 +541,7 @@ cogl_pango_renderer_draw_trapezoid (PangoRenderer *renderer,
cogl_pango_renderer_set_color_for_part (renderer, part); cogl_pango_renderer_set_color_for_part (renderer, part);
cogl_set_source (priv->solid_material);
cogl_path_polygon (points, 4); cogl_path_polygon (points, 4);
cogl_path_fill (); cogl_path_fill ();
} }
@ -524,15 +579,17 @@ cogl_pango_renderer_draw_glyphs (PangoRenderer *renderer,
if (font == NULL || if (font == NULL ||
(metrics = pango_font_get_metrics (font, NULL)) == NULL) (metrics = pango_font_get_metrics (font, NULL)) == NULL)
{ {
cogl_pango_renderer_draw_box ( (x), cogl_pango_renderer_draw_box (renderer,
(y), x,
y,
PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT); PANGO_UNKNOWN_GLYPH_HEIGHT);
} }
else else
{ {
cogl_pango_renderer_draw_box ( (x), cogl_pango_renderer_draw_box (renderer,
(y), x,
y,
metrics->approximate_char_width metrics->approximate_char_width
/ PANGO_SCALE, / PANGO_SCALE,
metrics->ascent / 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_glyphs_end (priv);
cogl_pango_renderer_draw_box ( (x), cogl_pango_renderer_draw_box (renderer,
(y), x,
y,
PANGO_UNKNOWN_GLYPH_WIDTH, PANGO_UNKNOWN_GLYPH_WIDTH,
PANGO_UNKNOWN_GLYPH_HEIGHT); PANGO_UNKNOWN_GLYPH_HEIGHT);
} }

View File

@ -127,47 +127,45 @@ on_paint (ClutterActor *actor, TestState *state)
x2 = x1 + (float)(TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a front-facing texture */ /* Draw a front-facing texture */
cogl_texture_rectangle (state->texture, cogl_set_source_texture (state->texture);
x1, y1, x2, y2, cogl_rectangle (x1, y1, x2, y2);
0, 0, 1.0, 1.0);
x1 = x2; x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a back-facing texture */ /* Draw a back-facing texture */
cogl_texture_rectangle (state->texture, cogl_set_source_texture (state->texture);
x2, y1, x1, y2, cogl_rectangle (x2, y1, x1, y2);
0, 0, 1.0, 1.0);
x1 = x2; x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a front-facing texture polygon */ /* Draw a front-facing texture polygon */
verts[0].x = x1; verts[0].y = y2; verts[0].x = x1; verts[0].y = y2;
verts[1].x = x2; verts[1].y = y2; verts[1].x = x2; verts[1].y = y2;
verts[2].x = x2; verts[2].y = y1; verts[2].x = x2; verts[2].y = y1;
verts[3].x = x1; verts[3].y = y1; verts[3].x = x1; verts[3].y = y1;
verts[0].tx = 0; verts[0].ty = 0; verts[0].tx = 0; verts[0].ty = 0;
verts[1].tx = 1.0; verts[1].ty = 0; verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = 1.0; verts[2].ty = 1.0; verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = 1.0; verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4, cogl_set_source_texture (state->texture);
verts, FALSE); cogl_polygon (verts, 4, FALSE);
x1 = x2; x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);
/* Draw a back-facing texture polygon */ /* Draw a back-facing texture polygon */
verts[0].x = x1; verts[0].y = y1; verts[0].x = x1; verts[0].y = y1;
verts[1].x = x2; verts[1].y = y1; verts[1].x = x2; verts[1].y = y1;
verts[2].x = x2; verts[2].y = y2; verts[2].x = x2; verts[2].y = y2;
verts[3].x = x1; verts[3].y = y2; verts[3].x = x1; verts[3].y = y2;
verts[0].tx = 0; verts[0].ty = 0; verts[0].tx = 0; verts[0].ty = 0;
verts[1].tx = 1.0; verts[1].ty = 0; verts[1].tx = 1.0; verts[1].ty = 0;
verts[2].tx = 1.0; verts[2].ty = 1.0; verts[2].tx = 1.0; verts[2].ty = 1.0;
verts[3].tx = 0; verts[3].ty = 1.0; verts[3].tx = 0; verts[3].ty = 1.0;
cogl_texture_polygon (state->texture, 4, cogl_set_source_texture (state->texture);
verts, FALSE); cogl_polygon (verts, 4, FALSE);
x1 = x2; x1 = x2;
x2 = x1 + (float)(TEXTURE_SIZE); x2 = x1 + (float)(TEXTURE_SIZE);

View File

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

View File

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

View File

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

View File

@ -87,20 +87,20 @@ test_coglbox_paint(ClutterActor *self)
CLUTTER_FLOAT_TO_FIXED (1.0f), CLUTTER_FLOAT_TO_FIXED (1.0f),
CLUTTER_FLOAT_TO_FIXED (1.0f) CLUTTER_FLOAT_TO_FIXED (1.0f)
}; };
CoglHandle material;
priv = TEST_COGLBOX_GET_PRIVATE (self); priv = TEST_COGLBOX_GET_PRIVATE (self);
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400); cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff); cogl_set_source_texture (priv->texhand_id);
cogl_texture_rectangle (priv->texhand_id, cogl_rectangle_with_texture_coords (0, 0,
0, 0, CLUTTER_INT_TO_FIXED (400),
CLUTTER_INT_TO_FIXED (400), CLUTTER_INT_TO_FIXED (400),
CLUTTER_INT_TO_FIXED (400), 0, 0,
0, 0, CLUTTER_INT_TO_FIXED (6),
CLUTTER_INT_TO_FIXED (6), CLUTTER_INT_TO_FIXED (6));
CLUTTER_INT_TO_FIXED (6));
cogl_draw_buffer (COGL_OFFSCREEN_BUFFER, priv->offscreen_id); cogl_draw_buffer (COGL_OFFSCREEN_BUFFER, priv->offscreen_id);
@ -112,16 +112,18 @@ test_coglbox_paint(ClutterActor *self)
cogl_draw_buffer (COGL_WINDOW_BUFFER, 0); cogl_draw_buffer (COGL_WINDOW_BUFFER, 0);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0x88); material = cogl_material_new ();
cogl_texture_rectangle (priv->texture_id, cogl_material_set_color4ub (material, 0xff, 0xff, 0xff, 0x88);
CLUTTER_INT_TO_FIXED (100), cogl_material_set_layer (material, 0, priv->texture_id);
CLUTTER_INT_TO_FIXED (100), cogl_set_source (material);
CLUTTER_INT_TO_FIXED (300), cogl_rectangle_with_texture_coords (CLUTTER_INT_TO_FIXED (100),
CLUTTER_INT_TO_FIXED (300), CLUTTER_INT_TO_FIXED (100),
texcoords[0], CLUTTER_INT_TO_FIXED (300),
texcoords[1], CLUTTER_INT_TO_FIXED (300),
texcoords[2], texcoords[0],
texcoords[3]); texcoords[1],
texcoords[2],
texcoords[3]);
} }
static void static void

View File

@ -92,45 +92,43 @@ test_coglbox_paint(ClutterActor *self)
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff); cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
cogl_rectangle (0, 0, 400, 400); cogl_rectangle (0, 0, 400, 400);
cogl_set_source_color4ub (0xff, 0xff, 0xff, 0xff);
cogl_push_matrix (); cogl_push_matrix ();
cogl_texture_rectangle (priv->cogl_tex_id[0], cogl_set_source_texture (priv->cogl_tex_id[0]);
0, 0, cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200), CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213), CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1], texcoords[0], texcoords[1],
texcoords[2], texcoords[3]); texcoords[2], texcoords[3]);
cogl_pop_matrix (); cogl_pop_matrix ();
cogl_push_matrix (); cogl_push_matrix ();
cogl_translate (200, 0, 0); cogl_translate (200, 0, 0);
cogl_texture_rectangle (priv->cogl_tex_id[1], cogl_set_source_texture (priv->cogl_tex_id[1]);
0, 0, cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200), CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213), CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1], texcoords[0], texcoords[1],
texcoords[2], texcoords[3]); texcoords[2], texcoords[3]);
cogl_pop_matrix (); cogl_pop_matrix ();
cogl_push_matrix (); cogl_push_matrix ();
cogl_translate (0, 200, 0); cogl_translate (0, 200, 0);
cogl_texture_rectangle (priv->cogl_tex_id[2], cogl_set_source_texture (priv->cogl_tex_id[2]);
0, 0, cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200), CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213), CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1], texcoords[0], texcoords[1],
texcoords[2], texcoords[3]); texcoords[2], texcoords[3]);
cogl_pop_matrix (); cogl_pop_matrix ();
cogl_push_matrix (); cogl_push_matrix ();
cogl_translate (200, 200, 0); cogl_translate (200, 200, 0);
cogl_texture_rectangle (priv->cogl_tex_id[3], cogl_set_source_texture (priv->cogl_tex_id[3]);
0, 0, cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (200), CLUTTER_INT_TO_FIXED (200),
CLUTTER_INT_TO_FIXED (213), CLUTTER_INT_TO_FIXED (213),
texcoords[0], texcoords[1], texcoords[0], texcoords[1],
texcoords[2], texcoords[3]); texcoords[2], texcoords[3]);
cogl_pop_matrix(); cogl_pop_matrix();
} }

View File

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

View File

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

View File

@ -122,7 +122,8 @@ test_coglbox_fade_texture (CoglHandle tex_id,
((i ^ (i >> 1)) & 1) ? 0 : 128); ((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); 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].tx = tx3;
vertices[2].ty = ty3; 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 static void
@ -172,8 +174,6 @@ test_coglbox_paint (ClutterActor *self)
int tex_width = cogl_texture_get_width (tex_handle); int tex_width = cogl_texture_get_width (tex_handle);
int tex_height = cogl_texture_get_height (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, cogl_texture_set_filters (tex_handle,
priv->use_linear_filtering priv->use_linear_filtering
? CGL_LINEAR : CGL_NEAREST, ? CGL_LINEAR : CGL_NEAREST,
@ -186,11 +186,11 @@ test_coglbox_paint (ClutterActor *self)
cogl_translate (-tex_width / 2, 0, 0); cogl_translate (-tex_width / 2, 0, 0);
/* Draw a hand and refect it */ /* Draw a hand and refect it */
cogl_texture_rectangle (tex_handle, cogl_set_source_texture (tex_handle);
0, 0, cogl_rectangle_with_texture_coords (0, 0,
CLUTTER_INT_TO_FIXED (tex_width), CLUTTER_INT_TO_FIXED (tex_width),
CLUTTER_INT_TO_FIXED (tex_height), CLUTTER_INT_TO_FIXED (tex_height),
0, 0, CFX_ONE, CFX_ONE); 0, 0, CFX_ONE, CFX_ONE);
test_coglbox_fade_texture (tex_handle, test_coglbox_fade_texture (tex_handle,
0, CLUTTER_INT_TO_FIXED (tex_height), 0, CLUTTER_INT_TO_FIXED (tex_height),
CLUTTER_INT_TO_FIXED (tex_width), CLUTTER_INT_TO_FIXED (tex_width),

View File

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