gboolean use_color);
/**
- * cogl_muti_texture_new:
- *
- * Creates a multi layered texture object. When first created it has
- * zero layers. You must use cogl_multi_texture_layer_set_texture to
- * define new layers.
- */
-CoglHandle cogl_multi_texture_new (void);
-
-/**
- * cogl_multi_texture_layer_set_texture:
- * @multi_texture_handle: a @CoglHandle
- * @layer: The index of the layer you want a handle for.
- *
- * A layer is implicitly created once you set a texture for a certain
- * layer_index. The texture layers are blended together starting with
- * the lowest index so the order is significant. It doesn't matter what
- * order you create the layers in and you may use sparsely generated index
- * values, it is only the relative index order that matters.
- */
-void cogl_multi_texture_layer_set_texture (CoglHandle multi_texture_handle,
- guint layer_index,
- CoglHandle texture_handle);
-
-/**
- * cogl_multi_texture_layer_remove:
- * @multi_texture_handle: a @CoglHandle
- * @index: The index of the layer you want to remove.
- *
- * Removes a single texture layer.
- */
-void cogl_multi_texture_layer_remove (CoglHandle multi_texture_handle,
- guint layer_index);
-
-/**
- * cogl_multi_texture_rectangle:
- * @handle: a @CoglHandle
+ * 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.
- * @texcoords: A multidimensional array containing sets of 4 texture
- * coordinates - one set for each texture layer that has been created.
- *
- * Draw a rectangle combining multiple texture layers together
- * where each layer can use different texture data and different texture
+ * @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 texture coordinates are supplied as a contiguous array of
- * CoglFixed items containing groups of [tx1, ty1, tx2, ty2] values
- * that are interpreted in the same way as the corresponding arguments
- * to cogl_texture_rectangle. The first group of coordinates are for the
- * first layer (with the smallest layer_index) you _must_ supply as many
- * groups of texture coordinates as you have layers.
+ * 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_multi_texture_rectangle (CoglHandle handle,
- CoglFixed x1,
- CoglFixed y1,
- CoglFixed x2,
- CoglFixed y2,
- CoglFixed *tex_coords);
+void cogl_material_rectangle (CoglFixed x1,
+ CoglFixed y1,
+ CoglFixed x2,
+ CoglFixed y2,
+ gint tex_coords_len,
+ CoglFixed *tex_coords);
G_END_DECLS
CoglFixed y1,
CoglFixed x2,
CoglFixed y2,
+ gint user_tex_coords_len,
CoglFixed *user_tex_coords)
{
CoglHandle material;
GLfloat *tex_coords_buff;
GLfloat quad_coords[8];
gulong enable_flags = 0;
- GLfloat values[4];
/* FIXME - currently cogl deals with enabling texturing via enable flags,
* but that can't scale to n texture units. Currently we have to be carefull
{
CoglHandle layer = tmp->data;
CoglHandle texture = cogl_material_layer_get_texture (layer);
-
+
if (cogl_material_layer_get_type (layer)
!= COGL_MATERIAL_LAYER_TYPE_TEXTURE)
continue;
if (n_valid_layers >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
break;
}
-
+
+ /* We at least support slicing as much as cogl_texture_rectangle... */
+ if (n_valid_layers == 1 && handle_slicing)
+ {
+ CoglHandle texture = cogl_material_layer_get_texture (valid_layers[0]);
+ cogl_texture_rectangle (texture,
+ x1, y1, x2, y2,
+ user_tex_coords[0], user_tex_coords[1],
+ user_tex_coords[2], user_tex_coords[3]);
+ return;
+ }
+
/* NB: It could be that no valid texture layers were found, but
* we will still submit a non-textured rectangle in that case. */
if (n_valid_layers)
{
CoglHandle layer = valid_layers[i];
CoglHandle texture = cogl_material_layer_get_texture (layer);
- CoglFixed *in_tex_coords = &user_tex_coords[i * 4];
+ CoglFixed *in_tex_coords;
GLfloat *out_tex_coords = &tex_coords_buff[i * 8];
GLuint gl_tex_handle;
#define CFX_F COGL_FIXED_TO_FLOAT
/* IN LAYOUT: [ tx1:0, ty1:1, tx2:2, ty2:3 ] */
- out_tex_coords[0] = CFX_F (in_tex_coords[0]); /* tx1 */
- out_tex_coords[1] = CFX_F (in_tex_coords[1]); /* ty1 */
- out_tex_coords[2] = CFX_F (in_tex_coords[2]); /* tx2 */
- out_tex_coords[3] = CFX_F (in_tex_coords[1]); /* ty1 */
- out_tex_coords[4] = CFX_F (in_tex_coords[0]); /* tx1 */
- out_tex_coords[5] = CFX_F (in_tex_coords[3]); /* ty2 */
- out_tex_coords[6] = CFX_F (in_tex_coords[2]); /* tx2 */
- out_tex_coords[7] = CFX_F (in_tex_coords[3]); /* ty2 */
+ if (i < (user_tex_coords_len / 4))
+ {
+ in_tex_coords = &user_tex_coords[i * 4];
+ /* FIXME: don't include waste in the texture coordinates */
+ out_tex_coords[0] = CFX_F (in_tex_coords[0]); /* tx1 */
+ out_tex_coords[1] = CFX_F (in_tex_coords[1]); /* ty1 */
+ out_tex_coords[2] = CFX_F (in_tex_coords[2]); /* tx2 */
+ out_tex_coords[3] = CFX_F (in_tex_coords[1]); /* ty1 */
+ out_tex_coords[4] = CFX_F (in_tex_coords[0]); /* tx1 */
+ out_tex_coords[5] = CFX_F (in_tex_coords[3]); /* ty2 */
+ out_tex_coords[6] = CFX_F (in_tex_coords[2]); /* tx2 */
+ out_tex_coords[7] = CFX_F (in_tex_coords[3]); /* ty2 */
+ }
+ else
+ {
+ out_tex_coords[0] = 0.0; /* tx1 */
+ out_tex_coords[1] = 0.0; /* ty1 */
+ out_tex_coords[2] = 1.0; /* tx2 */
+ out_tex_coords[3] = 0.0; /* ty1 */
+ out_tex_coords[4] = 0.0; /* tx1 */
+ out_tex_coords[5] = 1.0; /* ty2 */
+ out_tex_coords[6] = 1.0; /* tx2 */
+ out_tex_coords[7] = 1.0; /* ty2 */
+ }
#undef CFX_F
/* TODO - support sliced textures */
cogl_texture_get_gl_texture (texture, &gl_tex_handle, NULL);
- //gl_tex_handle = g_array_index (layer->tex->slice_gl_handles, GLuint, 0);
GE (glActiveTexture (GL_TEXTURE0 + i));
cogl_material_layer_flush_gl_sampler_state (layer);
- GE (glBindTexture (GL_TEXTURE_2D, gl_tex_handle));
- /* GE (glEnable (GL_TEXTURE_2D)); */
+ {
+ /* FIXME - we should avoid redundant calls to glBindTexture.
+ * Profiling test-actors, I've seen ~ 10% of the time spent in
+ * _mesa_UpdateTexEnvProgram, which the following simple test can
+ * show is as a result of these redundant glBindTexture calls.
+ */
+#if 0
+ static int debug = 0;
+ if (!debug)
+ GE (glBindTexture (GL_TEXTURE_2D, gl_tex_handle));
+ debug = 1;
+#else
+ GE (glBindTexture (GL_TEXTURE_2D, gl_tex_handle));
+#endif
+ }
GE (glClientActiveTexture (GL_TEXTURE0 + i));
GE (glTexCoordPointer (2, GL_FLOAT, 0, out_tex_coords));
- /* GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY)); */
/* FIXME - cogl only knows about one texture unit a.t.m
* (Also see cleanup note below) */
enable_flags |= cogl_material_get_cogl_enable_flags (material);
/* FIXME - cogl only knows about one texture unit so assumes that unit 0
- * is always active...*/
- GE (glActiveTexture (GL_TEXTURE0));
- GE (glClientActiveTexture (GL_TEXTURE0));
+ * is always active... */
+ if (n_valid_layers > 1)
+ {
+ GE (glActiveTexture (GL_TEXTURE0));
+ GE (glClientActiveTexture (GL_TEXTURE0));
+ }
cogl_enable (enable_flags);
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
for (i = 1; i < n_valid_layers; i++)
{
GE (glActiveTexture (GL_TEXTURE0 + i));
+ GE (glDisable (GL_TEXTURE_2D));
+ }
+
+ /* XXX: a bit over precautious. For one we don't support lighting yet
+ * so there's no real need to reset the material properties. */
+#if 0
+ /* FIXME - cogl doesn't currently have a way of caching the
+ * enable states for more than one texture unit so for now,
+ * we just disable anything relating to additional units once
+ * we are done with them. */
+ for (i = 1; i < n_valid_layers; i++)
+ {
+ GE (glActiveTexture (GL_TEXTURE0 + i));
GE (glClientActiveTexture (GL_TEXTURE0 + i));
GE (glDisable (GL_TEXTURE_2D));
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
}
-
+
/* FIXME - CoglMaterials aren't yet used pervasively throughout
* the cogl API, so we currently need to cleanup material state
* that will confuse other parts of the API.
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, values));
values[0] = 0;
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, values));
+#endif
}