mirror of
https://github.com/brl/mutter.git
synced 2024-11-23 00:20:42 -05:00
[cogl-material] improvements for cogl_material_rectangle
The API has been changed to take an explicit length for the number of texture coordinates passed, and it's now documented that if there are more layers to the current material than the number of texture coords passed, then default coordinates will be generated for the other layers. cogl_material_rectangle should now handle the case where a single sliced texture is supplied as a material layer by falling back to cogl_texture_rectangle. We are nearly at the point that cogl_texture_rectangle could be deprecated. A few issues remain though, such as not considering waste in cogl_material_rectangle.
This commit is contained in:
parent
98bd85afaa
commit
0408a5d2c5
@ -386,65 +386,34 @@ void cogl_texture_polygon (CoglHandle handle,
|
|||||||
gboolean use_color);
|
gboolean use_color);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_muti_texture_new:
|
* cogl_material_rectangle:
|
||||||
*
|
|
||||||
* 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
|
|
||||||
* @x1: x coordinate upper left on screen.
|
* @x1: x coordinate upper left on screen.
|
||||||
* @y1: y coordinate upper left on screen.
|
* @y1: y coordinate upper left on screen.
|
||||||
* @x2: x coordinate lower right on screen.
|
* @x2: x coordinate lower right on screen.
|
||||||
* @y2: y coordinate lower right on screen.
|
* @y2: y coordinate lower right on screen.
|
||||||
* @texcoords: A multidimensional array containing sets of 4 texture
|
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
|
||||||
* coordinates - one set for each texture layer that has been created.
|
* 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
|
* This function draws a rectangle using the current source material to
|
||||||
* where each layer can use different texture data and different texture
|
* texture or fill with. Since a material may contain multiple texture
|
||||||
|
* layers the interface lets you supply corresponding sets of texture
|
||||||
* coordinates.
|
* coordinates.
|
||||||
*
|
*
|
||||||
* The texture coordinates are supplied as a contiguous array of
|
* The first pair of coordinates are for the first layer (with the smallest
|
||||||
* CoglFixed items containing groups of [tx1, ty1, tx2, ty2] values
|
* layer index) and if you supply less texture coordinates than there are
|
||||||
* that are interpreted in the same way as the corresponding arguments
|
* layers in the current source material then default texture coordinates
|
||||||
* to cogl_texture_rectangle. The first group of coordinates are for the
|
* [0.0, 0.0, 1.0, 1.0] are generated.
|
||||||
* first layer (with the smallest layer_index) you _must_ supply as many
|
|
||||||
* groups of texture coordinates as you have layers.
|
|
||||||
*/
|
*/
|
||||||
void cogl_multi_texture_rectangle (CoglHandle handle,
|
void cogl_material_rectangle (CoglFixed x1,
|
||||||
CoglFixed x1,
|
|
||||||
CoglFixed y1,
|
CoglFixed y1,
|
||||||
CoglFixed x2,
|
CoglFixed x2,
|
||||||
CoglFixed y2,
|
CoglFixed y2,
|
||||||
|
gint tex_coords_len,
|
||||||
CoglFixed *tex_coords);
|
CoglFixed *tex_coords);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
@ -41,7 +41,8 @@ struct _CoglMaterialLayer
|
|||||||
typedef enum _CoglMaterialFlags
|
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
|
||||||
} CoglMaterialFlags;
|
} CoglMaterialFlags;
|
||||||
|
|
||||||
struct _CoglMaterial
|
struct _CoglMaterial
|
||||||
@ -50,6 +51,9 @@ struct _CoglMaterial
|
|||||||
|
|
||||||
gulong flags;
|
gulong flags;
|
||||||
|
|
||||||
|
/* If no lighting is enabled; this is the basic material color */
|
||||||
|
GLfloat unlit[4];
|
||||||
|
|
||||||
/* Standard OpenGL lighting model attributes */
|
/* Standard OpenGL lighting model attributes */
|
||||||
GLfloat ambient[4];
|
GLfloat ambient[4];
|
||||||
GLfloat diffuse[4];
|
GLfloat diffuse[4];
|
||||||
|
@ -2411,6 +2411,7 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
CoglFixed y1,
|
CoglFixed y1,
|
||||||
CoglFixed x2,
|
CoglFixed x2,
|
||||||
CoglFixed y2,
|
CoglFixed y2,
|
||||||
|
gint user_tex_coords_len,
|
||||||
CoglFixed *user_tex_coords)
|
CoglFixed *user_tex_coords)
|
||||||
{
|
{
|
||||||
CoglHandle material;
|
CoglHandle material;
|
||||||
@ -2424,7 +2425,6 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
GLfloat *tex_coords_buff;
|
GLfloat *tex_coords_buff;
|
||||||
GLfloat quad_coords[8];
|
GLfloat quad_coords[8];
|
||||||
gulong enable_flags = 0;
|
gulong enable_flags = 0;
|
||||||
GLfloat values[4];
|
|
||||||
|
|
||||||
/* FIXME - currently cogl deals with enabling texturing via enable flags,
|
/* 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
|
* but that can't scale to n texture units. Currently we have to be carefull
|
||||||
@ -2467,6 +2467,17 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
break;
|
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
|
/* NB: It could be that no valid texture layers were found, but
|
||||||
* we will still submit a non-textured rectangle in that case. */
|
* we will still submit a non-textured rectangle in that case. */
|
||||||
if (n_valid_layers)
|
if (n_valid_layers)
|
||||||
@ -2476,12 +2487,16 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
{
|
{
|
||||||
CoglHandle layer = valid_layers[i];
|
CoglHandle layer = valid_layers[i];
|
||||||
CoglHandle texture = cogl_material_layer_get_texture (layer);
|
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];
|
GLfloat *out_tex_coords = &tex_coords_buff[i * 8];
|
||||||
GLuint gl_tex_handle;
|
GLuint gl_tex_handle;
|
||||||
|
|
||||||
#define CFX_F COGL_FIXED_TO_FLOAT
|
#define CFX_F COGL_FIXED_TO_FLOAT
|
||||||
/* IN LAYOUT: [ tx1:0, ty1:1, tx2:2, ty2:3 ] */
|
/* IN LAYOUT: [ tx1:0, ty1:1, tx2:2, ty2:3 ] */
|
||||||
|
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[0] = CFX_F (in_tex_coords[0]); /* tx1 */
|
||||||
out_tex_coords[1] = CFX_F (in_tex_coords[1]); /* ty1 */
|
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[2] = CFX_F (in_tex_coords[2]); /* tx2 */
|
||||||
@ -2490,20 +2505,43 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
out_tex_coords[5] = CFX_F (in_tex_coords[3]); /* ty2 */
|
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[6] = CFX_F (in_tex_coords[2]); /* tx2 */
|
||||||
out_tex_coords[7] = CFX_F (in_tex_coords[3]); /* ty2 */
|
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
|
#undef CFX_F
|
||||||
|
|
||||||
/* TODO - support sliced textures */
|
/* TODO - support sliced textures */
|
||||||
cogl_texture_get_gl_texture (texture, &gl_tex_handle, NULL);
|
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));
|
GE (glActiveTexture (GL_TEXTURE0 + i));
|
||||||
cogl_material_layer_flush_gl_sampler_state (layer);
|
cogl_material_layer_flush_gl_sampler_state (layer);
|
||||||
|
{
|
||||||
|
/* 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));
|
GE (glBindTexture (GL_TEXTURE_2D, gl_tex_handle));
|
||||||
/* GE (glEnable (GL_TEXTURE_2D)); */
|
debug = 1;
|
||||||
|
#else
|
||||||
|
GE (glBindTexture (GL_TEXTURE_2D, gl_tex_handle));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
||||||
GE (glTexCoordPointer (2, GL_FLOAT, 0, out_tex_coords));
|
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
|
/* FIXME - cogl only knows about one texture unit a.t.m
|
||||||
* (Also see cleanup note below) */
|
* (Also see cleanup note below) */
|
||||||
@ -2538,12 +2576,28 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
enable_flags |= cogl_material_get_cogl_enable_flags (material);
|
enable_flags |= cogl_material_get_cogl_enable_flags (material);
|
||||||
|
|
||||||
/* FIXME - cogl only knows about one texture unit so assumes that unit 0
|
/* FIXME - cogl only knows about one texture unit so assumes that unit 0
|
||||||
* is always active...*/
|
* is always active... */
|
||||||
|
if (n_valid_layers > 1)
|
||||||
|
{
|
||||||
GE (glActiveTexture (GL_TEXTURE0));
|
GE (glActiveTexture (GL_TEXTURE0));
|
||||||
GE (glClientActiveTexture (GL_TEXTURE0));
|
GE (glClientActiveTexture (GL_TEXTURE0));
|
||||||
|
}
|
||||||
cogl_enable (enable_flags);
|
cogl_enable (enable_flags);
|
||||||
glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
|
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
|
/* FIXME - cogl doesn't currently have a way of caching the
|
||||||
* enable states for more than one texture unit so for now,
|
* enable states for more than one texture unit so for now,
|
||||||
* we just disable anything relating to additional units once
|
* we just disable anything relating to additional units once
|
||||||
@ -2572,5 +2626,6 @@ cogl_material_rectangle (CoglFixed x1,
|
|||||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, values));
|
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, values));
|
||||||
values[0] = 0;
|
values[0] = 0;
|
||||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, values));
|
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, values));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user