diff --git a/clutter/clutter-clone-texture.c b/clutter/clutter-clone-texture.c index ba509ad22..c84b048af 100644 --- a/clutter/clutter-clone-texture.c +++ b/clutter/clutter-clone-texture.c @@ -229,6 +229,7 @@ clutter_clone_texture_paint (ClutterActor *self) 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 /* Parent paint translated us into position */ diff --git a/clutter/clutter-texture.c b/clutter/clutter-texture.c index 94541ff37..52a671b37 100644 --- a/clutter/clutter-texture.c +++ b/clutter/clutter-texture.c @@ -617,6 +617,7 @@ clutter_texture_paint (ClutterActor *self) cogl_material_rectangle (0, 0, COGL_FIXED_FROM_INT (x_2 - x_1), COGL_FIXED_FROM_INT (y_2 - y_1), + 4, tex_coords); #else cogl_texture_rectangle (priv->texture, 0, 0, diff --git a/clutter/cogl/cogl-texture.h b/clutter/cogl/cogl-texture.h index 475de2ac5..331407618 100644 --- a/clutter/cogl/cogl-texture.h +++ b/clutter/cogl/cogl-texture.h @@ -386,66 +386,35 @@ void cogl_texture_polygon (CoglHandle handle, 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. + * @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. * - * Draw a rectangle combining multiple texture layers together - * where each layer can use different texture data and different texture + * 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 diff --git a/clutter/cogl/common/cogl-material-private.h b/clutter/cogl/common/cogl-material-private.h index d64d8485b..935e0ae79 100644 --- a/clutter/cogl/common/cogl-material-private.h +++ b/clutter/cogl/common/cogl-material-private.h @@ -22,8 +22,8 @@ struct _CoglMaterialLayer gulong flags; CoglHandle texture; /*!< The texture for this layer, or COGL_INVALID_HANDLE for an empty layer */ - - /* Determines how the color of individual texture fragments + + /* Determines how the color of individual texture fragments * are calculated. */ CoglMaterialLayerCombineFunc texture_combine_rgb_func; CoglMaterialLayerCombineSrc texture_combine_rgb_src[3]; @@ -32,7 +32,7 @@ struct _CoglMaterialLayer CoglMaterialLayerCombineFunc texture_combine_alpha_func; CoglMaterialLayerCombineSrc texture_combine_alpha_src[3]; CoglMaterialLayerCombineOp texture_combine_alpha_op[3]; - + /* TODO: Support purely GLSL based material layers */ CoglMatrix matrix; @@ -41,7 +41,8 @@ struct _CoglMaterialLayer typedef enum _CoglMaterialFlags { 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 } CoglMaterialFlags; struct _CoglMaterial @@ -50,13 +51,16 @@ struct _CoglMaterial gulong flags; + /* If no lighting is enabled; this is the basic material color */ + GLfloat unlit[4]; + /* Standard OpenGL lighting model attributes */ GLfloat ambient[4]; GLfloat diffuse[4]; GLfloat specular[4]; GLfloat emission[4]; GLfloat shininess; - + /* Determines what fragments are discarded based on their alpha */ CoglMaterialAlphaFunc alpha_func; GLfloat alpha_func_reference; diff --git a/clutter/cogl/gl/cogl-texture.c b/clutter/cogl/gl/cogl-texture.c index ab84c9543..357fc2885 100644 --- a/clutter/cogl/gl/cogl-texture.c +++ b/clutter/cogl/gl/cogl-texture.c @@ -2411,6 +2411,7 @@ cogl_material_rectangle (CoglFixed x1, CoglFixed y1, CoglFixed x2, CoglFixed y2, + gint user_tex_coords_len, CoglFixed *user_tex_coords) { CoglHandle material; @@ -2424,7 +2425,6 @@ cogl_material_rectangle (CoglFixed x1, 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 @@ -2443,7 +2443,7 @@ cogl_material_rectangle (CoglFixed x1, { 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; @@ -2466,7 +2466,18 @@ cogl_material_rectangle (CoglFixed x1, 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) @@ -2476,34 +2487,61 @@ cogl_material_rectangle (CoglFixed x1, { 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) */ @@ -2538,12 +2576,28 @@ cogl_material_rectangle (CoglFixed x1, 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); + /* 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 (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 @@ -2556,7 +2610,7 @@ cogl_material_rectangle (CoglFixed x1, 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. @@ -2572,5 +2626,6 @@ cogl_material_rectangle (CoglFixed x1, GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, values)); values[0] = 0; GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, values)); +#endif } diff --git a/tests/interactive/test-cogl-material.c b/tests/interactive/test-cogl-material.c index e34082465..00084b568 100644 --- a/tests/interactive/test-cogl-material.c +++ b/tests/interactive/test-cogl-material.c @@ -49,6 +49,7 @@ material_rectangle_paint (ClutterActor *actor, gpointer data) CLUTTER_INT_TO_FIXED(0), CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT), CLUTTER_INT_TO_FIXED(TIMELINE_FRAME_COUNT), + 12, state->tex_coords); }