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:
parent
0c8c273980
commit
2503f7b321
15 changed files with 1957 additions and 960 deletions
175
cogl-material.h
175
cogl-material.h
|
@ -52,6 +52,8 @@ CoglHandle cogl_material_ref (CoglHandle handle);
|
|||
*/
|
||||
void cogl_material_unref (CoglHandle handle);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* cogl_material_set_color:
|
||||
* @material: A CoglMaterial object
|
||||
|
@ -65,6 +67,37 @@ void cogl_material_unref (CoglHandle handle);
|
|||
*/
|
||||
void cogl_material_set_color (CoglHandle material, const CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_material_set_color:
|
||||
* @material: A CoglMaterial object
|
||||
* @red: The red component
|
||||
* @green: The green component
|
||||
* @blue: The blue component
|
||||
* @alpha: The alpha component
|
||||
*
|
||||
* This is the basic color of the material, used when no lighting is enabled.
|
||||
*
|
||||
* The default value is (1.0, 1.0, 1.0, 1.0)
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_set_color4ub (CoglHandle handle,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha);
|
||||
|
||||
/**
|
||||
* cogl_material_get_color:
|
||||
* @material: A CoglMaterial object
|
||||
* @color: The location to store the color
|
||||
*
|
||||
* This retrieves the current material color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_color (CoglHandle handle, CoglColor *color);
|
||||
|
||||
/**
|
||||
* cogl_material_set_ambient:
|
||||
* @material: A CoglMaterial object
|
||||
|
@ -83,6 +116,17 @@ void cogl_material_set_color (CoglHandle material, const CoglColor *color);
|
|||
void cogl_material_set_ambient (CoglHandle material,
|
||||
const CoglColor *ambient);
|
||||
|
||||
/**
|
||||
* cogl_material_get_ambient:
|
||||
* @material: A CoglMaterial object
|
||||
* @ambient: The location to store the ambient color
|
||||
*
|
||||
* This retrieves the materials current ambient color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_ambient (CoglHandle handle, CoglColor *ambient);
|
||||
|
||||
/**
|
||||
* cogl_material_set_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
|
@ -100,6 +144,17 @@ void cogl_material_set_ambient (CoglHandle material,
|
|||
void cogl_material_set_diffuse (CoglHandle material,
|
||||
const CoglColor *diffuse);
|
||||
|
||||
/**
|
||||
* cogl_material_get_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
* @diffuse: The location to store the diffuse color
|
||||
*
|
||||
* This retrieves the materials current diffuse color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_diffuse (CoglHandle handle, CoglColor *diffuse);
|
||||
|
||||
/**
|
||||
* cogl_material_set_ambient_and_diffuse:
|
||||
* @material: A CoglMaterial object
|
||||
|
@ -133,6 +188,17 @@ void cogl_material_set_ambient_and_diffuse (CoglHandle material,
|
|||
void cogl_material_set_specular (CoglHandle material,
|
||||
const CoglColor *specular);
|
||||
|
||||
/**
|
||||
* cogl_material_get_specular:
|
||||
* @material: A CoglMaterial object
|
||||
* @specular: The location to store the specular color
|
||||
*
|
||||
* This retrieves the materials current specular color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_specular (CoglHandle handle, CoglColor *specular);
|
||||
|
||||
/**
|
||||
* cogl_material_set_shininess:
|
||||
* @material: A CoglMaterial object
|
||||
|
@ -148,6 +214,17 @@ void cogl_material_set_specular (CoglHandle material,
|
|||
*/
|
||||
void cogl_material_set_shininess (CoglHandle material,
|
||||
float shininess);
|
||||
/**
|
||||
* cogl_material_get_shininess:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This retrieves the materials current emission color.
|
||||
*
|
||||
* Return value: The materials current shininess value
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
float cogl_material_get_shininess (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_material_set_emission:
|
||||
|
@ -165,6 +242,17 @@ void cogl_material_set_shininess (CoglHandle material,
|
|||
void cogl_material_set_emission (CoglHandle material,
|
||||
const CoglColor *emission);
|
||||
|
||||
/**
|
||||
* cogl_material_get_emission:
|
||||
* @material: A CoglMaterial object
|
||||
* @emission: The location to store the emission color
|
||||
*
|
||||
* This retrieves the materials current emission color.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_get_emission (CoglHandle handle, CoglColor *emission);
|
||||
|
||||
/**
|
||||
* CoglMaterialAlphaFunc:
|
||||
* @COGL_MATERIAL_ALPHA_FUNC_NEVER: Never let the fragment through.
|
||||
|
@ -638,7 +726,7 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
|
|||
|
||||
/**
|
||||
* cogl_material_layer_get_texture:
|
||||
* @material: A CoglMaterial object
|
||||
* @layer_handle: A CoglMaterial layer object
|
||||
*
|
||||
* This lets you extract a CoglTexture handle for a specific layer. Normally
|
||||
* you shouldn't need to use this function directly since Cogl will do this
|
||||
|
@ -653,18 +741,66 @@ CoglMaterialLayerType cogl_material_layer_get_type (CoglHandle layer_handle);
|
|||
CoglHandle cogl_material_layer_get_texture (CoglHandle layer_handle);
|
||||
|
||||
/**
|
||||
* cogl_material_layer_flush_gl_sampler_state:
|
||||
* @material: A CoglMaterial object
|
||||
*
|
||||
* This commits the sampler state for a single material layer to the OpenGL
|
||||
* driver. Normally you shouldn't need to use this function directly since
|
||||
* Cogl will do this internally, but if you are developing custom primitives
|
||||
* directly with OpenGL you may want to use this.
|
||||
*
|
||||
* Note: It assumes you have already activated the appropriate sampler
|
||||
* by calling glActiveTexture ();
|
||||
* CoglMaterialLayerFlags:
|
||||
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
|
||||
* custom texture matrix.
|
||||
*/
|
||||
void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
|
||||
typedef enum _CoglMaterialLayerFlags
|
||||
{
|
||||
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
|
||||
} CoglMaterialLayerFlags;
|
||||
/* XXX: NB: if you add flags here you will need to update
|
||||
* CoglMaterialLayerPrivFlags!!! */
|
||||
|
||||
/**
|
||||
* cogl_material_layer_get_flags:
|
||||
* @layer_handle: A CoglMaterial layer object
|
||||
*
|
||||
* This lets you get a number of flag attributes about the layer. Normally
|
||||
* you shouldn't need to use this function directly since Cogl will do this
|
||||
* internally, but if you are developing custom primitives directly with
|
||||
* OpenGL you may need this.
|
||||
*/
|
||||
gulong cogl_material_layer_get_flags (CoglHandle layer_handle);
|
||||
|
||||
/**
|
||||
* CoglMaterialFlushOption:
|
||||
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: Follow this by a guin32 mask
|
||||
* of the layers that can't be supported with the user supplied texture
|
||||
* and need to be replaced with fallback textures. (1 = fallback, and the
|
||||
* least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_DISABLE_MASK: Follow this by a guint32 mask
|
||||
* of the layers that you want to completly disable texturing for
|
||||
* (1 = fallback, and the least significant bit = layer 0)
|
||||
* @COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE: Follow this by a GLuint OpenGL texture
|
||||
* name to override the texture used for layer 0 of the material. This is
|
||||
* intended for dealing with sliced textures where you will need to point
|
||||
* to each of the texture slices in turn when drawing your geometry.
|
||||
* Passing a value of 0 is the same as not passing the option at all.
|
||||
*/
|
||||
typedef enum _CoglMaterialFlushOption
|
||||
{
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
|
||||
} CoglMaterialFlushOption;
|
||||
|
||||
/**
|
||||
* cogl_material_flush_gl_state:
|
||||
* @material: A CoglMaterial object
|
||||
* @...: A NULL terminated list of (CoglMaterialFlushOption, data) pairs
|
||||
*
|
||||
* This function commits the state of the specified CoglMaterial - including
|
||||
* the texture state for all the layers - to the OpenGL[ES] driver.
|
||||
*
|
||||
* Normally you shouldn't need to use this function directly, but if you
|
||||
* are developing a custom primitive using raw OpenGL that works with
|
||||
* CoglMaterials, then you may want to use this function.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_material_flush_gl_state (CoglHandle material,
|
||||
...) G_GNUC_NULL_TERMINATED;
|
||||
|
||||
/**
|
||||
* cogl_set_source:
|
||||
|
@ -684,19 +820,16 @@ void cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle);
|
|||
void cogl_set_source (CoglHandle material);
|
||||
|
||||
/**
|
||||
* cogl_flush_material_gl_state:
|
||||
* cogl_set_source_texture:
|
||||
* @texture_handle: The Cogl texture you want as your source
|
||||
*
|
||||
* This function commits all the state of the source CoglMaterial - not
|
||||
* including the per-layer state - to the OpenGL[ES] driver.
|
||||
*
|
||||
* Normally you shouldn't need to use this function directly, but if you
|
||||
* are developing a custom primitive using raw OpenGL that works with
|
||||
* CoglMaterials, then you may want to use this function.
|
||||
* This is a convenience function for creating a material with the first
|
||||
* layer set to #texture_handle and setting that material as the source with
|
||||
* cogl_set_source.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
/* XXX: This should be moved with cogl_set_source to cogl.h */
|
||||
void cogl_flush_material_gl_state (void);
|
||||
void cogl_set_source_texture (CoglHandle texture_handle);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -57,8 +57,7 @@ G_BEGIN_DECLS
|
|||
* @width: Width of the rectangle
|
||||
* @height: Height of the rectangle
|
||||
*
|
||||
* Fills a rectangle at the given coordinates with the current
|
||||
* drawing color in a highly optimizied fashion.
|
||||
* Fills a rectangle at the given coordinates with the current source material
|
||||
**/
|
||||
void cogl_rectangle (float x,
|
||||
float y,
|
||||
|
|
185
cogl-texture.h
185
cogl-texture.h
|
@ -359,90 +359,6 @@ CoglHandle cogl_texture_ref (CoglHandle handle);
|
|||
*/
|
||||
void cogl_texture_unref (CoglHandle handle);
|
||||
|
||||
/**
|
||||
* cogl_texture_rectangle:
|
||||
* @handle: a @CoglHandle.
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tx1: x part of texture coordinate to use for upper left pixel
|
||||
* @ty1: y part of texture coordinate to use for upper left pixel
|
||||
* @tx2: x part of texture coordinate to use for lower right pixel
|
||||
* @ty2: y part of texture coordinate to use for left pixel
|
||||
*
|
||||
* Draw a rectangle from a texture to the display, to draw the entire
|
||||
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
|
||||
*/
|
||||
void cogl_texture_rectangle (CoglHandle handle,
|
||||
float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float tx1,
|
||||
float ty1,
|
||||
float tx2,
|
||||
float ty2);
|
||||
|
||||
/**
|
||||
* cogl_texture_polygon:
|
||||
* @handle: A CoglHandle for a texture
|
||||
* @n_vertices: The length of the vertices array
|
||||
* @vertices: An array of #CoglTextureVertex structs
|
||||
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
|
||||
*
|
||||
* Draws a polygon from a texture with the given model and texture
|
||||
* coordinates. This can be used to draw arbitrary shapes textured
|
||||
* with a COGL texture. If @use_color is %TRUE then the current COGL
|
||||
* color will be changed for each vertex using the value specified in
|
||||
* the color member of #CoglTextureVertex. This can be used for
|
||||
* example to make the texture fade out by setting the alpha value of
|
||||
* the color.
|
||||
*
|
||||
* All of the texture coordinates must be in the range [0,1] and
|
||||
* repeating the texture is not supported.
|
||||
*
|
||||
* Because of the way this function is implemented it will currently
|
||||
* only work if either the texture is not sliced or the backend is not
|
||||
* OpenGL ES and the minifying and magnifying functions are both set
|
||||
* to CGL_NEAREST.
|
||||
*/
|
||||
void cogl_texture_polygon (CoglHandle handle,
|
||||
guint n_vertices,
|
||||
CoglTextureVertex *vertices,
|
||||
gboolean use_color);
|
||||
|
||||
/**
|
||||
* cogl_material_rectangle:
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
|
||||
* and one group of texture coordinates, this would be 4)
|
||||
* @tex_coords: An array containing groups of 4 CoglFixed values:
|
||||
* [tx1, ty1, tx2, ty2] that are interpreted as two texture coordinates; one
|
||||
* for the upper left texel, and one for the lower right texel. Each value
|
||||
* should be between 0.0 and 1.0, where the coordinate (0.0, 0.0) represents
|
||||
* the top left of the texture, and (1.0, 1.0) the bottom right.
|
||||
*
|
||||
* This function draws a rectangle using the current source material to
|
||||
* texture or fill with. Since a material may contain multiple texture
|
||||
* layers the interface lets you supply corresponding sets of texture
|
||||
* coordinates.
|
||||
*
|
||||
* The first pair of coordinates are for the first layer (with the smallest
|
||||
* layer index) and if you supply less texture coordinates than there are
|
||||
* layers in the current source material then default texture coordinates
|
||||
* [0.0, 0.0, 1.0, 1.0] are generated.
|
||||
*/
|
||||
void cogl_material_rectangle (CoglFixed x1,
|
||||
CoglFixed y1,
|
||||
CoglFixed x2,
|
||||
CoglFixed y2,
|
||||
gint tex_coords_len,
|
||||
const CoglFixed *tex_coords);
|
||||
|
||||
/**
|
||||
* cogl_bitmap_new_from_file:
|
||||
* @filename: the file to load.
|
||||
|
@ -483,27 +399,110 @@ gboolean cogl_bitmap_get_size_from_file (const gchar *filename,
|
|||
void cogl_bitmap_free (CoglBitmap *bmp);
|
||||
|
||||
/**
|
||||
* cogl_texture_multiple_rectangles:
|
||||
* @handle: a @CoglHandle.
|
||||
* cogl_rectangle_with_texture_coords:
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tx1: x part of texture coordinate to use for upper left pixel
|
||||
* @ty1: y part of texture coordinate to use for upper left pixel
|
||||
* @tx2: x part of texture coordinate to use for lower right pixel
|
||||
* @ty2: y part of texture coordinate to use for left pixel
|
||||
*
|
||||
* Draw a rectangle using the current material and supply texture coordinates
|
||||
* to be used for the first texture layer of the material. To draw the entire
|
||||
* texture pass in @tx1=0.0 @ty1=0.0 @tx2=1.0 @ty2=1.0.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_rectangle_with_texture_coords (float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
float tx1,
|
||||
float ty1,
|
||||
float tx2,
|
||||
float ty2);
|
||||
|
||||
/**
|
||||
* cogl_rectangle_with_multitexture_coords:
|
||||
* @x1: x coordinate upper left on screen.
|
||||
* @y1: y coordinate upper left on screen.
|
||||
* @x2: x coordinate lower right on screen.
|
||||
* @y2: y coordinate lower right on screen.
|
||||
* @tex_coords: An array containing groups of 4 float values:
|
||||
* [tx1, ty1, tx2, ty2] that are interpreted as two texture coordinates; one
|
||||
* for the upper left texel, and one for the lower right texel. Each value
|
||||
* should be between 0.0 and 1.0, where the coordinate (0.0, 0.0) represents
|
||||
* the top left of the texture, and (1.0, 1.0) the bottom right.
|
||||
* @tex_coords_len: The length of the tex_coords array. (e.g. for one layer
|
||||
* and one group of texture coordinates, this would be 4)
|
||||
*
|
||||
* This function draws a rectangle using the current source material to
|
||||
* texture or fill with. As a material may contain multiple texture layers
|
||||
* this interface lets you supply texture coordinates for each layer of the
|
||||
* material.
|
||||
*
|
||||
* The first pair of coordinates are for the first layer (with the smallest
|
||||
* layer index) and if you supply less texture coordinates than there are
|
||||
* layers in the current source material then default texture coordinates
|
||||
* (0.0, 0.0, 1.0, 1.0) are generated.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_rectangle_with_multitexture_coords (float x1,
|
||||
float y1,
|
||||
float x2,
|
||||
float y2,
|
||||
const float *tex_coords,
|
||||
gint tex_coords_len);
|
||||
|
||||
/**
|
||||
* cogl_rectangles_with_texture_coords:
|
||||
* @verts: an array of vertices
|
||||
* @n_rects: number of rectangles to draw
|
||||
*
|
||||
* Draws a series of rectangles in the same way that
|
||||
* cogl_texture_rectangle() does. In some situations it can give a
|
||||
* cogl_rectangle_with_texture_coords() does. In some situations it can give a
|
||||
* significant performance boost to use this function rather than
|
||||
* calling cogl_texture_rectangle() separately for each rectangle.
|
||||
* calling cogl_rectangle_with_texture_coords() separately for each rectangle.
|
||||
*
|
||||
* @verts should point to an array of #float<!-- -->s with
|
||||
* @n_rects * 8 elements. Each group of 8 values corresponds to the
|
||||
* parameters x1, y1, x2, y2, tx1, ty1, tx2 and ty2 and have the same
|
||||
* meaning as in cogl_texture_rectangle().
|
||||
* meaning as in cogl_rectangle_with_texture_coords().
|
||||
*
|
||||
* Since: 0.8.6
|
||||
*/
|
||||
void cogl_texture_multiple_rectangles
|
||||
(CoglHandle handle,
|
||||
const float *verts,
|
||||
guint n_rects);
|
||||
void cogl_rectangles_with_texture_coords (const float *verts,
|
||||
guint n_rects);
|
||||
|
||||
/**
|
||||
* cogl_polygon:
|
||||
* @vertices: An array of #CoglTextureVertex structs
|
||||
* @n_vertices: The length of the vertices array
|
||||
* @use_color: %TRUE if the color member of #CoglTextureVertex should be used
|
||||
*
|
||||
* Draws a convex polygon using the current source material to fill / texture
|
||||
* with according to the texture coordinates passed.
|
||||
*
|
||||
* If @use_color is %TRUE then the color will be changed for each vertex using
|
||||
* the value specified in the color member of #CoglTextureVertex. This can be
|
||||
* used for example to make the texture fade out by setting the alpha value of
|
||||
* the color.
|
||||
*
|
||||
* All of the texture coordinates must be in the range [0,1] and repeating the
|
||||
* texture is not supported.
|
||||
*
|
||||
* Because of the way this function is implemented it will currently only work
|
||||
* if either the texture is not sliced or the backend is not OpenGL ES and the
|
||||
* minifying and magnifying functions are both set to CGL_NEAREST.
|
||||
*
|
||||
* Since 1.0
|
||||
*/
|
||||
void cogl_polygon (CoglTextureVertex *vertices,
|
||||
guint n_vertices,
|
||||
gboolean use_color);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
#include <cogl/cogl-defines-@CLUTTER_COGL@.h>
|
||||
|
||||
#include <cogl/cogl-mesh.h>
|
||||
#include <cogl/cogl-vertex-buffer.h>
|
||||
#include <cogl/cogl-matrix.h>
|
||||
#include <cogl/cogl-vertex-buffer.h>
|
||||
#include <cogl/cogl-fixed.h>
|
||||
|
|
|
@ -9,10 +9,28 @@
|
|||
typedef struct _CoglMaterial CoglMaterial;
|
||||
typedef struct _CoglMaterialLayer CoglMaterialLayer;
|
||||
|
||||
typedef enum _CoglMaterialLayerFlags
|
||||
/* XXX: I don't think gtk-doc supports having private enums so these aren't
|
||||
* bundled in with CoglMaterialLayerFlags */
|
||||
typedef enum _CoglMaterialLayerPrivFlags
|
||||
{
|
||||
COGL_MATERIAL_LAYER_FLAG_USER_MATRIX = 1L<<0,
|
||||
} CoglMaterialLayerFlags;
|
||||
/* Ref: CoglMaterialLayerFlags
|
||||
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
|
||||
*/
|
||||
COGL_MATERIAL_LAYER_FLAG_DIRTY = 1L<<1,
|
||||
COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE = 1L<<2
|
||||
} CoglMaterialLayerPrivFlags;
|
||||
|
||||
/* For tracking the state of a layer that's been flushed to OpenGL */
|
||||
typedef struct _CoglLayerInfo
|
||||
{
|
||||
CoglHandle handle;
|
||||
gulong flags;
|
||||
GLenum gl_target;
|
||||
GLuint gl_texture;
|
||||
gboolean fallback;
|
||||
gboolean disabled;
|
||||
gboolean layer0_overridden;
|
||||
} CoglLayerInfo;
|
||||
|
||||
struct _CoglMaterialLayer
|
||||
{
|
||||
|
@ -42,7 +60,12 @@ typedef enum _CoglMaterialFlags
|
|||
{
|
||||
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<0,
|
||||
COGL_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<1,
|
||||
COGL_MATERIAL_FLAG_DIRTY = 1L<<2
|
||||
COGL_MATERIAL_FLAG_DIRTY = 1L<<2,
|
||||
COGL_MATERIAL_FLAG_LAYERS_DIRTY = 1L<<3,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<4,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<5,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<6,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC = 1L<<7
|
||||
} CoglMaterialFlags;
|
||||
|
||||
struct _CoglMaterial
|
||||
|
|
|
@ -37,20 +37,24 @@ cogl_material_new (void)
|
|||
|
||||
/* Use the same defaults as the GL spec... */
|
||||
unlit[0] = 1.0; unlit[1] = 1.0; unlit[2] = 1.0; unlit[3] = 1.0;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
|
||||
/* Use the same defaults as the GL spec... */
|
||||
ambient[0] = 0.2; ambient[1] = 0.2; ambient[2] = 0.2; ambient[3] = 1.0;
|
||||
diffuse[0] = 0.8; diffuse[1] = 0.8; diffuse[2] = 0.8; diffuse[3] = 1.0;
|
||||
specular[0] = 0; specular[1] = 0; specular[2] = 0; specular[3] = 1.0;
|
||||
emission[0] = 0; emission[1] = 0; emission[2] = 0; emission[3] = 1.0;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
|
||||
/* Use the same defaults as the GL spec... */
|
||||
material->alpha_func = COGL_MATERIAL_ALPHA_FUNC_ALWAYS;
|
||||
material->alpha_func_reference = 0.0;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
|
||||
|
||||
/* Not the same as the GL default, but seems saner... */
|
||||
material->blend_src_factor = COGL_MATERIAL_BLEND_FACTOR_SRC_ALPHA;
|
||||
material->blend_dst_factor = COGL_MATERIAL_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||
|
||||
material->layers = NULL;
|
||||
|
||||
|
@ -69,7 +73,24 @@ _cogl_material_free (CoglMaterial *material)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
@ -88,7 +109,46 @@ cogl_material_set_color (CoglHandle handle,
|
|||
|
||||
memcpy (material->unlit, unlit, sizeof (unlit));
|
||||
|
||||
if (unlit[0] == 1.0 &&
|
||||
unlit[1] == 1.0 &&
|
||||
unlit[2] == 1.0 &&
|
||||
unlit[3] == 1.0)
|
||||
material->flags |= COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
|
||||
if (unlit[3] != 1.0)
|
||||
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_COLOR;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_set_color4ub (CoglHandle handle,
|
||||
guint8 red,
|
||||
guint8 green,
|
||||
guint8 blue,
|
||||
guint8 alpha)
|
||||
{
|
||||
CoglColor color;
|
||||
cogl_color_set_from_4ub (&color, red, green, blue, alpha);
|
||||
cogl_material_set_color (handle, &color);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_get_ambient (CoglHandle handle,
|
||||
CoglColor *ambient)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
cogl_color_set_from_4f (ambient,
|
||||
material->ambient[0],
|
||||
material->ambient[1],
|
||||
material->ambient[2],
|
||||
material->ambient[3]);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -109,6 +169,24 @@ cogl_material_set_ambient (CoglHandle handle,
|
|||
ambient[3] = cogl_color_get_alpha_float (ambient_color);
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_get_diffuse (CoglHandle handle,
|
||||
CoglColor *diffuse)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
cogl_color_set_from_4f (diffuse,
|
||||
material->diffuse[0],
|
||||
material->diffuse[1],
|
||||
material->diffuse[2],
|
||||
material->diffuse[3]);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -129,6 +207,7 @@ cogl_material_set_diffuse (CoglHandle handle,
|
|||
diffuse[3] = cogl_color_get_alpha_float (diffuse_color);
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -139,6 +218,23 @@ cogl_material_set_ambient_and_diffuse (CoglHandle handle,
|
|||
cogl_material_set_diffuse (handle, color);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_get_specular (CoglHandle handle,
|
||||
CoglColor *specular)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
cogl_color_set_from_4f (specular,
|
||||
material->specular[0],
|
||||
material->specular[1],
|
||||
material->specular[2],
|
||||
material->specular[3]);
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_set_specular (CoglHandle handle,
|
||||
const CoglColor *specular_color)
|
||||
|
@ -157,6 +253,19 @@ cogl_material_set_specular (CoglHandle handle,
|
|||
specular[3] = cogl_color_get_alpha_float (specular_color);
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
}
|
||||
|
||||
float
|
||||
cogl_material_get_shininess (CoglHandle handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_val_if_fail (cogl_is_material (handle), 0);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
return material->shininess;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -176,6 +285,24 @@ cogl_material_set_shininess (CoglHandle handle,
|
|||
material->shininess = (GLfloat)shininess * 128.0;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_get_emission (CoglHandle handle,
|
||||
CoglColor *emission)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
cogl_color_set_from_4f (emission,
|
||||
material->emission[0],
|
||||
material->emission[1],
|
||||
material->emission[2],
|
||||
material->emission[3]);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -196,6 +323,7 @@ cogl_material_set_emission (CoglHandle handle,
|
|||
emission[3] = cogl_color_get_alpha_float (emission_color);
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -212,6 +340,7 @@ cogl_material_set_alpha_test_function (CoglHandle handle,
|
|||
material->alpha_func_reference = (GLfloat)alpha_reference;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -228,6 +357,7 @@ cogl_material_set_blend_factors (CoglHandle handle,
|
|||
material->blend_dst_factor = dst_factor;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_DIRTY;
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC;
|
||||
}
|
||||
|
||||
/* Asserts that a layer corresponding to the given index exists. If no
|
||||
|
@ -264,6 +394,7 @@ _cogl_material_get_layer (CoglMaterial *material,
|
|||
|
||||
layer->ref_count = 1;
|
||||
layer->index = index;
|
||||
layer->flags = COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
|
||||
layer->texture = COGL_INVALID_HANDLE;
|
||||
|
||||
/* Choose the same default combine mode as OpenGL:
|
||||
|
@ -284,6 +415,8 @@ _cogl_material_get_layer (CoglMaterial *material,
|
|||
layer->texture_combine_alpha_op[1] =
|
||||
COGL_MATERIAL_LAYER_COMBINE_OP_SRC_ALPHA;
|
||||
|
||||
cogl_matrix_init_identity (&layer->matrix);
|
||||
|
||||
layer_handle = _cogl_material_layer_handle_new (layer);
|
||||
/* Note: see comment after for() loop above */
|
||||
material->layers =
|
||||
|
@ -317,7 +450,7 @@ cogl_material_set_layer (CoglHandle material_handle,
|
|||
{
|
||||
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");
|
||||
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. */
|
||||
}
|
||||
|
||||
cogl_texture_ref (texture_handle);
|
||||
|
||||
if (layer->texture)
|
||||
cogl_texture_unref (layer->texture);
|
||||
|
||||
cogl_texture_ref (texture_handle);
|
||||
layer->texture = texture_handle;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -350,9 +486,7 @@ cogl_material_set_layer_combine_function (
|
|||
g_return_if_fail (cogl_is_material (handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, FALSE);
|
||||
if (!layer)
|
||||
return;
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
|
||||
set_alpha_func = set_rgb_func = TRUE;
|
||||
|
@ -365,6 +499,10 @@ cogl_material_set_layer_combine_function (
|
|||
layer->texture_combine_rgb_func = func;
|
||||
if (set_alpha_func)
|
||||
layer->texture_combine_alpha_func = func;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -377,16 +515,14 @@ cogl_material_set_layer_combine_arg_src (
|
|||
{
|
||||
CoglMaterial *material;
|
||||
CoglMaterialLayer *layer;
|
||||
gboolean set_arg_alpha_src = FALSE;
|
||||
gboolean set_arg_rgb_src = FALSE;
|
||||
gboolean set_arg_alpha_src = FALSE;
|
||||
gboolean set_arg_rgb_src = FALSE;
|
||||
|
||||
g_return_if_fail (cogl_is_material (handle));
|
||||
g_return_if_fail (argument >=0 && argument <= 3);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, FALSE);
|
||||
if (!layer)
|
||||
return;
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
|
||||
set_arg_alpha_src = set_arg_rgb_src = TRUE;
|
||||
|
@ -399,6 +535,10 @@ cogl_material_set_layer_combine_arg_src (
|
|||
layer->texture_combine_rgb_src[argument] = src;
|
||||
if (set_arg_alpha_src)
|
||||
layer->texture_combine_alpha_src[argument] = src;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -418,9 +558,7 @@ cogl_material_set_layer_combine_arg_op (
|
|||
g_return_if_fail (argument >=0 && argument <= 3);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, FALSE);
|
||||
if (!layer)
|
||||
return;
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
if (channels == COGL_MATERIAL_LAYER_COMBINE_CHANNELS_RGBA)
|
||||
set_arg_alpha_op = set_arg_rgb_op = TRUE;
|
||||
|
@ -433,6 +571,10 @@ cogl_material_set_layer_combine_arg_op (
|
|||
layer->texture_combine_rgb_op[argument] = op;
|
||||
if (set_arg_alpha_op)
|
||||
layer->texture_combine_alpha_op[argument] = op;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -446,12 +588,14 @@ cogl_material_set_layer_matrix (CoglHandle material_handle,
|
|||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
|
||||
material = _cogl_material_pointer_from_handle (material_handle);
|
||||
layer = _cogl_material_get_layer (material, layer_index, FALSE);
|
||||
if (!layer)
|
||||
return;
|
||||
layer = _cogl_material_get_layer (material, layer_index, TRUE);
|
||||
|
||||
layer->matrix = *matrix;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_USER_MATRIX;
|
||||
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
layer->flags |= COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX;
|
||||
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -490,6 +634,10 @@ cogl_material_remove_layer (CoglHandle material_handle,
|
|||
if (cogl_texture_get_format (layer->texture) & COGL_A_BIT)
|
||||
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
}
|
||||
|
||||
if (material->unlit[3] != 1.0)
|
||||
material->flags |= COGL_MATERIAL_FLAG_ENABLE_BLEND;
|
||||
material->flags |= COGL_MATERIAL_FLAG_LAYERS_DIRTY;
|
||||
}
|
||||
|
||||
/* XXX: This API is hopfully just a stop-gap solution. Ideally cogl_enable
|
||||
|
@ -553,6 +701,18 @@ cogl_material_layer_get_texture (CoglHandle layer_handle)
|
|||
return layer->texture;
|
||||
}
|
||||
|
||||
gulong
|
||||
cogl_material_layer_get_flags (CoglHandle layer_handle)
|
||||
{
|
||||
CoglMaterialLayer *layer;
|
||||
|
||||
g_return_val_if_fail (cogl_is_material_layer (layer_handle), 0);
|
||||
|
||||
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
|
||||
|
||||
return layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX;
|
||||
}
|
||||
|
||||
static guint
|
||||
get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
|
||||
{
|
||||
|
@ -573,89 +733,81 @@ get_n_args_for_combine_func (CoglMaterialLayerCombineFunc func)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
|
||||
static void
|
||||
_cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
|
||||
CoglLayerInfo *gl_layer_info)
|
||||
{
|
||||
CoglMaterialLayer *layer;
|
||||
int n_rgb_func_args;
|
||||
int n_alpha_func_args;
|
||||
|
||||
g_return_if_fail (cogl_is_material_layer (layer_handle));
|
||||
|
||||
layer = _cogl_material_layer_pointer_from_handle (layer_handle);
|
||||
|
||||
/* XXX: We really want some kind of cache/dirty flag mechanism
|
||||
* somewhere here so we can avoid as much mucking about with
|
||||
* the texture units per primitive as possible!
|
||||
*
|
||||
* E.g. some recent profiling of clutter-actor suggested that
|
||||
* validating/updating the texture environment may currently
|
||||
* be a significant bottleneck. Given that all the actors should
|
||||
* have the same texture environment, that implies we could do a
|
||||
* much better job of avoiding redundant glTexEnv calls.
|
||||
*/
|
||||
|
||||
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)
|
||||
if (!(gl_layer_info &&
|
||||
gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE &&
|
||||
layer->flags & COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE))
|
||||
{
|
||||
GE (glTexEnvi (GL_TEXTURE_ENV, GL_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]));
|
||||
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,
|
||||
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 */
|
||||
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]));
|
||||
}
|
||||
|
||||
if (layer->flags & COGL_MATERIAL_LAYER_FLAG_USER_MATRIX)
|
||||
if (gl_layer_info &&
|
||||
(gl_layer_info->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX ||
|
||||
layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX))
|
||||
{
|
||||
GE (glMatrixMode (GL_TEXTURE));
|
||||
GE (glLoadMatrixf ((GLfloat *)&layer->matrix));
|
||||
|
@ -663,6 +815,275 @@ cogl_material_layer_flush_gl_sampler_state (CoglHandle layer_handle)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _cogl_material_flush_layers_gl_state:
|
||||
* @fallback_mask: is a bitmask of the material layers that need to be
|
||||
* replaced with the default, fallback textures. The fallback textures are
|
||||
* fully transparent textures so they hopefully wont contribute to the
|
||||
* texture combining.
|
||||
*
|
||||
* The intention of fallbacks is to try and preserve
|
||||
* the number of layers the user is expecting so that texture coordinates
|
||||
* they gave will mostly still correspond to the textures they intended, and
|
||||
* have a fighting chance of looking close to their originally intended
|
||||
* result.
|
||||
*
|
||||
* @disable_mask: is a bitmask of the material layers that will simply have
|
||||
* texturing disabled. It's only really intended for disabling all layers
|
||||
* > X; i.e. we'd expect to see a contiguous run of 0 starting from the LSB
|
||||
* and at some point the remaining bits flip to 1. It might work to disable
|
||||
* arbitrary layers; though I'm not sure a.t.m how OpenGL would take to
|
||||
* that.
|
||||
*
|
||||
* The intention of the disable_mask is for emitting geometry when the user
|
||||
* hasn't supplied enough texture coordinates for all the layers and it's
|
||||
* not possible to auto generate default texture coordinates for those
|
||||
* layers.
|
||||
*
|
||||
* @layer0_override_texture: forcibly tells us to bind this GL texture name for
|
||||
* layer 0 instead of plucking the gl_texture from the CoglTexture of layer
|
||||
* 0.
|
||||
*
|
||||
* The intention of this is for any geometry that supports sliced textures.
|
||||
* The code will can iterate each of the slices and re-flush the material
|
||||
* forcing the GL texture of each slice in turn.
|
||||
*
|
||||
* XXX: It might also help if we could specify a texture matrix for code
|
||||
* dealing with slicing that would be multiplied with the users own matrix.
|
||||
*
|
||||
* Normaly texture coords in the range [0, 1] refer to the extents of the
|
||||
* texture, but when your GL texture represents a slice of the real texture
|
||||
* (from the users POV) then a texture matrix would be a neat way of
|
||||
* transforming the mapping for each slice.
|
||||
*
|
||||
* Currently for textured rectangles we manually calculate the texture
|
||||
* coords for each slice based on the users given coords, but this solution
|
||||
* isn't ideal, and can't be used with CoglVertexBuffers.
|
||||
*/
|
||||
static void
|
||||
_cogl_material_flush_layers_gl_state (CoglMaterial *material,
|
||||
guint32 fallback_mask,
|
||||
guint32 disable_mask,
|
||||
GLuint layer0_override_texture)
|
||||
{
|
||||
GList *tmp;
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
for (tmp = material->layers, i = 0; tmp != NULL; tmp = tmp->next, i++)
|
||||
{
|
||||
CoglHandle layer_handle = (CoglHandle)tmp->data;
|
||||
CoglMaterialLayer *layer =
|
||||
_cogl_material_layer_pointer_from_handle (layer_handle);
|
||||
CoglLayerInfo *gl_layer_info = NULL;
|
||||
CoglLayerInfo new_gl_layer_info;
|
||||
GLuint gl_texture;
|
||||
GLenum gl_target;
|
||||
|
||||
new_gl_layer_info.layer0_overridden =
|
||||
layer0_override_texture ? TRUE : FALSE;
|
||||
new_gl_layer_info.fallback =
|
||||
(fallback_mask & (1<<i)) ? TRUE : FALSE;
|
||||
new_gl_layer_info.disabled =
|
||||
(disable_mask & (1<<i)) ? TRUE : FALSE;
|
||||
|
||||
if (i < ctx->current_layers->len)
|
||||
{
|
||||
gl_layer_info =
|
||||
&g_array_index (ctx->current_layers, CoglLayerInfo, i);
|
||||
|
||||
if (gl_layer_info->handle == layer_handle &&
|
||||
!(layer->flags & COGL_MATERIAL_LAYER_FLAG_DIRTY) &&
|
||||
(gl_layer_info->layer0_overridden
|
||||
== new_gl_layer_info.layer0_overridden) &&
|
||||
(gl_layer_info->fallback
|
||||
== new_gl_layer_info.fallback) &&
|
||||
(gl_layer_info->disabled
|
||||
== new_gl_layer_info.disabled))
|
||||
continue;
|
||||
}
|
||||
|
||||
cogl_texture_get_gl_texture (layer->texture, &gl_texture, &gl_target);
|
||||
|
||||
if (new_gl_layer_info.layer0_overridden)
|
||||
gl_texture = layer0_override_texture;
|
||||
else if (new_gl_layer_info.fallback)
|
||||
{
|
||||
CoglHandle tex_handle;
|
||||
|
||||
if (gl_target == GL_TEXTURE_2D)
|
||||
tex_handle = ctx->default_gl_texture_2d_tex;
|
||||
else if (gl_target == GL_TEXTURE_RECTANGLE_ARB)
|
||||
tex_handle = ctx->default_gl_texture_rect_tex;
|
||||
else
|
||||
{
|
||||
g_warning ("We don't have a default texture we can use to fill "
|
||||
"in for an invalid material layer, since it was "
|
||||
"using an unsupported texture target ");
|
||||
/* might get away with this... */
|
||||
tex_handle = ctx->default_gl_texture_2d_tex;
|
||||
}
|
||||
cogl_texture_get_gl_texture (tex_handle, &gl_texture, NULL);
|
||||
}
|
||||
|
||||
GE (glActiveTexture (GL_TEXTURE0 + i));
|
||||
|
||||
if (!gl_layer_info
|
||||
|| gl_layer_info->gl_target != gl_target
|
||||
|| gl_layer_info->gl_texture != gl_texture)
|
||||
GE (glBindTexture (gl_target, gl_texture));
|
||||
|
||||
/* Disable the previous target if it was different */
|
||||
if (gl_layer_info &&
|
||||
gl_layer_info->gl_target != gl_target &&
|
||||
!gl_layer_info->disabled)
|
||||
GE (glDisable (gl_layer_info->gl_target));
|
||||
|
||||
/* Enable/Disable the new target */
|
||||
if (!new_gl_layer_info.disabled)
|
||||
{
|
||||
if (!(gl_layer_info &&
|
||||
gl_layer_info->gl_target == gl_target &&
|
||||
!gl_layer_info->disabled))
|
||||
GE (glEnable (gl_target));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!(gl_layer_info &&
|
||||
gl_layer_info->gl_target == gl_target &&
|
||||
gl_layer_info->disabled))
|
||||
GE (glDisable (gl_target));
|
||||
}
|
||||
|
||||
_cogl_material_layer_flush_gl_sampler_state (layer, gl_layer_info);
|
||||
|
||||
new_gl_layer_info.handle = layer_handle;
|
||||
new_gl_layer_info.flags = layer->flags;
|
||||
new_gl_layer_info.gl_target = gl_target;
|
||||
new_gl_layer_info.gl_texture = gl_texture;
|
||||
|
||||
if (i < ctx->current_layers->len)
|
||||
*gl_layer_info = new_gl_layer_info;
|
||||
else
|
||||
g_array_append_val (ctx->current_layers, new_gl_layer_info);
|
||||
|
||||
layer->flags &= ~COGL_MATERIAL_LAYER_FLAG_DIRTY;
|
||||
|
||||
if ((i+1) >= CGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Disable additional texture units that may have previously been in use.. */
|
||||
for (; i < ctx->current_layers->len; i++)
|
||||
{
|
||||
CoglLayerInfo *gl_layer_info =
|
||||
&g_array_index (ctx->current_layers, CoglLayerInfo, i);
|
||||
|
||||
if (!gl_layer_info->disabled)
|
||||
{
|
||||
GE (glActiveTexture (GL_TEXTURE0 + i));
|
||||
GE (glDisable (gl_layer_info->gl_target));
|
||||
gl_layer_info->disabled = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
material->flags &= ~COGL_MATERIAL_FLAG_DIRTY;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_material_flush_base_gl_state (CoglMaterial *material)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_COLOR))
|
||||
{
|
||||
GE (glColor4fv (material->unlit));
|
||||
}
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL))
|
||||
{
|
||||
/* FIXME - we only need to set these if lighting is enabled... */
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
|
||||
}
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC))
|
||||
{
|
||||
/* NB: Currently the Cogl defines are compatible with the GL ones: */
|
||||
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
|
||||
}
|
||||
|
||||
if (!(ctx->current_material_flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC
|
||||
&& material->flags & COGL_MATERIAL_FLAG_DEFAULT_BLEND_FUNC))
|
||||
{
|
||||
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cogl_material_flush_gl_state (CoglHandle handle, ...)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
va_list ap;
|
||||
CoglMaterialFlushOption option;
|
||||
guint32 fallback_layers = 0;
|
||||
guint32 disable_layers = 0;
|
||||
GLuint layer0_override_texture = 0;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
material = _cogl_material_pointer_from_handle (handle);
|
||||
|
||||
if (ctx->current_material == material &&
|
||||
!(material->flags & COGL_MATERIAL_FLAG_DIRTY) &&
|
||||
!(material->flags & COGL_MATERIAL_FLAG_LAYERS_DIRTY))
|
||||
return;
|
||||
|
||||
if (ctx->current_material != material ||
|
||||
material->flags & COGL_MATERIAL_FLAG_DIRTY)
|
||||
_cogl_material_flush_base_gl_state (material);
|
||||
|
||||
if (ctx->current_material != material ||
|
||||
material->flags & COGL_MATERIAL_FLAG_LAYERS_DIRTY)
|
||||
{
|
||||
va_start (ap, handle);
|
||||
while ((option = va_arg (ap, CoglMaterialFlushOption)))
|
||||
{
|
||||
if (option == COGL_MATERIAL_FLUSH_FALLBACK_MASK)
|
||||
fallback_layers = va_arg (ap, guint32);
|
||||
else if (option == COGL_MATERIAL_FLUSH_DISABLE_MASK)
|
||||
disable_layers = va_arg (ap, guint32);
|
||||
else if (option == COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE)
|
||||
layer0_override_texture = va_arg (ap, GLuint);
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
_cogl_material_flush_layers_gl_state (material,
|
||||
fallback_layers,
|
||||
disable_layers,
|
||||
layer0_override_texture);
|
||||
}
|
||||
|
||||
/* NB: we have to take a reference so that next time
|
||||
* cogl_material_flush_gl_state is called, we can compare the incomming
|
||||
* material pointer with ctx->current_material
|
||||
*/
|
||||
cogl_material_ref (handle);
|
||||
cogl_material_unref (ctx->current_material);
|
||||
|
||||
ctx->current_material = handle;
|
||||
ctx->current_material_flags = material->flags;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TODO: Should go in cogl.c, but that implies duplication which is also
|
||||
* not ideal. */
|
||||
void
|
||||
|
@ -675,40 +1096,24 @@ cogl_set_source (CoglHandle material_handle)
|
|||
if (ctx->source_material == material_handle)
|
||||
return;
|
||||
|
||||
cogl_material_ref (material_handle);
|
||||
|
||||
if (ctx->source_material)
|
||||
cogl_material_unref (ctx->source_material);
|
||||
|
||||
cogl_material_ref (material_handle);
|
||||
ctx->source_material = material_handle;
|
||||
}
|
||||
/* TODO: add cogl_set_front_source (), and cogl_set_back_source () */
|
||||
|
||||
void
|
||||
cogl_flush_material_gl_state (void)
|
||||
cogl_set_source_texture (CoglHandle texture_handle)
|
||||
{
|
||||
CoglMaterial *material;
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
CoglColor white;
|
||||
|
||||
material = _cogl_material_pointer_from_handle (ctx->source_material);
|
||||
|
||||
if (ctx->source_material == ctx->current_material
|
||||
&& !(material->flags & COGL_MATERIAL_FLAG_DIRTY))
|
||||
return;
|
||||
|
||||
GE (glColor4fv (material->unlit));
|
||||
|
||||
/* FIXME - we only need to set these if lighting is enabled... */
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, material->ambient));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, material->diffuse));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, material->specular));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_EMISSION, material->emission));
|
||||
GE (glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, &material->shininess));
|
||||
|
||||
/* NB: Currently the Cogl defines are compatible with the GL ones: */
|
||||
GE (glAlphaFunc (material->alpha_func, material->alpha_func_reference));
|
||||
|
||||
GE (glBlendFunc (material->blend_src_factor, material->blend_dst_factor));
|
||||
|
||||
ctx->current_material = ctx->source_material;
|
||||
cogl_material_set_layer (ctx->default_material, 0, texture_handle);
|
||||
cogl_color_set_from_4ub (&white, 0xff, 0xff, 0xff, 0xff);
|
||||
cogl_material_set_color (ctx->default_material, &white);
|
||||
cogl_set_source (ctx->default_material);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,19 +43,18 @@ void _cogl_path_add_node (gboolean new_sub_path,
|
|||
float y);
|
||||
void _cogl_path_fill_nodes ();
|
||||
void _cogl_path_stroke_nodes ();
|
||||
void _cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height);
|
||||
|
||||
void
|
||||
cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
cogl_clip_ensure ();
|
||||
|
||||
_cogl_rectangle (x, y, width, height);
|
||||
cogl_rectangle_with_multitexture_coords (x, y,
|
||||
x+width,
|
||||
y+height,
|
||||
NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -134,6 +134,7 @@
|
|||
#include "cogl-context.h"
|
||||
#include "cogl-handle.h"
|
||||
#include "cogl-vertex-buffer-private.h"
|
||||
#include "cogl-texture-private.h"
|
||||
|
||||
#define PAD_FOR_ALIGNMENT(VAR, TYPE_SIZE) \
|
||||
(VAR = TYPE_SIZE + ((VAR - 1) & ~(TYPE_SIZE - 1)))
|
||||
|
@ -1416,12 +1417,15 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
|
|||
static void
|
||||
enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
||||
{
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
GLuint generic_index = 0;
|
||||
gulong enable_flags = COGL_ENABLE_BLEND;
|
||||
/* FIXME: I don't think it's appropriate to force enable
|
||||
* GL_BLEND here. */
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
GLuint generic_index = 0;
|
||||
gulong enable_flags = 0;
|
||||
guint max_texcoord_attrib_unit = 0;
|
||||
const GList *layers;
|
||||
guint32 fallback_mask = 0;
|
||||
guint32 disable_mask = ~0;
|
||||
int i;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
@ -1460,17 +1464,16 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
|||
(const GLvoid *)attribute->u.vbo_offset));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
|
||||
/* FIXME: set the active texture unit */
|
||||
/* NB: Cogl currently manages unit 0 */
|
||||
enable_flags |= (COGL_ENABLE_TEXCOORD_ARRAY
|
||||
| COGL_ENABLE_TEXTURE_2D);
|
||||
/* FIXME: I don't think it's appropriate to force enable
|
||||
* GL_TEXTURE_2D here. */
|
||||
/* GE (glEnableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glEnableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
GE (glTexCoordPointer (attribute->n_components,
|
||||
gl_type,
|
||||
attribute->stride,
|
||||
(const GLvoid *)attribute->u.vbo_offset));
|
||||
if (attribute->texture_unit > max_texcoord_attrib_unit)
|
||||
max_texcoord_attrib_unit = attribute->texture_unit;
|
||||
disable_mask &= ~(1 << attribute->texture_unit);
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
|
||||
enable_flags |= COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
@ -1505,8 +1508,51 @@ enable_state_for_drawing_attributes_buffer (CoglVertexBuffer *buffer)
|
|||
}
|
||||
}
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
layers = cogl_material_get_layers (ctx->source_material);
|
||||
for (tmp = (GList *)layers, i = 0;
|
||||
tmp != NULL && i <= max_texcoord_attrib_unit;
|
||||
tmp = tmp->next, i++)
|
||||
{
|
||||
CoglHandle layer = (CoglHandle)tmp->data;
|
||||
CoglHandle tex_handle = cogl_material_layer_get_texture (layer);
|
||||
CoglTexture *texture =
|
||||
_cogl_texture_pointer_from_handle (tex_handle);
|
||||
|
||||
if (cogl_texture_is_sliced (tex_handle)
|
||||
|| _cogl_texture_span_has_waste (texture, 0, 0))
|
||||
{
|
||||
g_warning ("Disabling layer %d of the current source material, "
|
||||
"because texturing with the vertex buffer API is not "
|
||||
"currently supported using sliced textures, or textures "
|
||||
"with waste\n", i);
|
||||
|
||||
/* XXX: maybe we can add a mechanism for users to forcibly use
|
||||
* textures with waste where it would be their responsability to use
|
||||
* texture coords in the range [0,1] such that sampling outside isn't
|
||||
* required. We can then use a texture matrix (or a modification of
|
||||
* the users own matrix) to map 1 to the edge of the texture data.
|
||||
*
|
||||
* Potentially, given the same guarantee as above we could also
|
||||
* support a single sliced layer too. We would have to redraw the
|
||||
* vertices once for each layer, each time with a fiddled texture
|
||||
* matrix.
|
||||
*/
|
||||
fallback_mask |= (1 << i);
|
||||
}
|
||||
else if (!(disable_mask & (1 << i)))
|
||||
fallback_mask |= (1 << i);
|
||||
}
|
||||
|
||||
cogl_material_flush_gl_state (ctx->source_material,
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
|
||||
fallback_mask,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
disable_mask,
|
||||
NULL);
|
||||
|
||||
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
|
||||
cogl_enable (enable_flags);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1550,9 +1596,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
|||
GE (glDisableClientState (GL_NORMAL_ARRAY));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_TEXTURE_COORD_ARRAY:
|
||||
/* FIXME: set the active texture unit */
|
||||
/* NB: Cogl currently manages unit 0 */
|
||||
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */
|
||||
GE (glClientActiveTexture (GL_TEXTURE0 +
|
||||
attribute->texture_unit));
|
||||
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||
break;
|
||||
case COGL_VERTEX_BUFFER_ATTRIB_FLAG_VERTEX_ARRAY:
|
||||
/* GE (glDisableClientState (GL_VERTEX_ARRAY)); */
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "cogl-internal.h"
|
||||
#include "cogl-util.h"
|
||||
#include "cogl-context.h"
|
||||
#include "cogl-texture-private.h"
|
||||
#include "cogl-material-private.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -39,6 +41,9 @@ static CoglContext *_context = NULL;
|
|||
gboolean
|
||||
cogl_create_context ()
|
||||
{
|
||||
GLubyte default_texture_data[] = { 0xff, 0xff, 0xff, 0x0 };
|
||||
gulong enable_flags = 0;
|
||||
|
||||
if (_context != NULL)
|
||||
return FALSE;
|
||||
|
||||
|
@ -52,19 +57,26 @@ cogl_create_context ()
|
|||
_context->enable_flags = 0;
|
||||
_context->color_alpha = 255;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->texture_vertices = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglTextureGLVertex));
|
||||
_context->texture_indices = g_array_new (FALSE, FALSE,
|
||||
sizeof (GLushort));
|
||||
|
||||
_context->material_handles = NULL;
|
||||
_context->material_layer_handles = NULL;
|
||||
_context->default_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
|
||||
_context->texture_handles = NULL;
|
||||
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
|
||||
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
|
||||
|
||||
_context->journal = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
|
||||
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
|
||||
_context->static_indices = g_array_new (FALSE, FALSE, sizeof (GLushort));
|
||||
_context->polygon_vertices = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglTextureGLVertex));
|
||||
|
||||
_context->current_material = NULL;
|
||||
_context->current_material_flags = 0;
|
||||
_context->current_layers = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglLayerInfo));
|
||||
_context->n_texcoord_arrays_enabled = 0;
|
||||
|
||||
_context->fbo_handles = NULL;
|
||||
_context->draw_buffer = COGL_WINDOW_BUFFER;
|
||||
|
@ -78,6 +90,10 @@ cogl_create_context ()
|
|||
|
||||
_context->vertex_buffer_handles = NULL;
|
||||
|
||||
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
|
||||
_context->last_path = 0;
|
||||
_context->stencil_material = cogl_material_new ();
|
||||
|
||||
_context->pf_glGenRenderbuffersEXT = NULL;
|
||||
_context->pf_glBindRenderbufferEXT = NULL;
|
||||
_context->pf_glRenderbufferStorageEXT = NULL;
|
||||
|
@ -123,15 +139,37 @@ cogl_create_context ()
|
|||
|
||||
_context->pf_glDrawRangeElements = NULL;
|
||||
|
||||
/* Init OpenGL state */
|
||||
GE( glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE) );
|
||||
GE( glColorMask (TRUE, TRUE, TRUE, FALSE) );
|
||||
GE( glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) );
|
||||
cogl_enable (0);
|
||||
|
||||
/* Initialise the clip stack */
|
||||
_cogl_clip_stack_state_init ();
|
||||
|
||||
/* Create default textures used for fall backs */
|
||||
_context->default_gl_texture_2d_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
_context->default_gl_texture_rect_tex =
|
||||
cogl_texture_new_from_data (1, /* width */
|
||||
1, /* height */
|
||||
-1, /* max waste */
|
||||
FALSE, /* auto mipmap */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888, /* data format */
|
||||
/* internal format */
|
||||
COGL_PIXEL_FORMAT_RGBA_8888,
|
||||
0, /* auto calc row stride */
|
||||
&default_texture_data);
|
||||
|
||||
cogl_set_source (_context->default_material);
|
||||
cogl_material_flush_gl_state (_context->source_material, NULL);
|
||||
enable_flags =
|
||||
cogl_material_get_cogl_enable_flags (_context->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -155,10 +193,25 @@ cogl_destroy_context ()
|
|||
if (_context->program_handles)
|
||||
g_array_free (_context->program_handles, TRUE);
|
||||
|
||||
if (_context->texture_vertices)
|
||||
g_array_free (_context->texture_vertices, TRUE);
|
||||
if (_context->texture_indices)
|
||||
g_array_free (_context->texture_indices, TRUE);
|
||||
if (_context->default_gl_texture_2d_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_2d_tex);
|
||||
if (_context->default_gl_texture_rect_tex)
|
||||
cogl_texture_unref (_context->default_gl_texture_rect_tex);
|
||||
|
||||
if (_context->default_material)
|
||||
cogl_material_unref (_context->default_material);
|
||||
|
||||
if (_context->journal)
|
||||
g_array_free (_context->journal, TRUE);
|
||||
if (_context->logged_vertices)
|
||||
g_array_free (_context->logged_vertices, TRUE);
|
||||
|
||||
if (_context->static_indices)
|
||||
g_array_free (_context->static_indices, TRUE);
|
||||
if (_context->polygon_vertices)
|
||||
g_array_free (_context->polygon_vertices, TRUE);
|
||||
if (_context->current_layers)
|
||||
g_array_free (_context->current_layers, TRUE);
|
||||
|
||||
g_free (_context);
|
||||
}
|
||||
|
|
|
@ -50,33 +50,34 @@ typedef struct
|
|||
|
||||
gboolean enable_backface_culling;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
|
||||
/* Cache of inverse projection matrix */
|
||||
GLfloat inverse_projection[16];
|
||||
|
||||
/* Textures */
|
||||
GArray *texture_handles;
|
||||
GArray *texture_vertices;
|
||||
GArray *texture_indices;
|
||||
/* The gl texture number that the above vertices apply to. This to
|
||||
detect when a different slice is encountered so that the vertices
|
||||
can be flushed */
|
||||
GLuint texture_current;
|
||||
GLenum texture_target;
|
||||
GLenum texture_wrap_mode;
|
||||
GArray *texture_handles;
|
||||
CoglHandle default_gl_texture_2d_tex;
|
||||
CoglHandle default_gl_texture_rect_tex;
|
||||
|
||||
/* Materials */
|
||||
GArray *material_handles;
|
||||
GArray *material_layer_handles;
|
||||
CoglHandle default_material;
|
||||
CoglHandle source_material;
|
||||
|
||||
/* Batching geometry... */
|
||||
/* We journal the texture rectangles we want to submit to OpenGL so
|
||||
* we have an oppertunity to optimise the final order so that we
|
||||
* can batch things together. */
|
||||
GArray *journal;
|
||||
GArray *logged_vertices;
|
||||
GArray *static_indices;
|
||||
GArray *polygon_vertices;
|
||||
|
||||
/* Some simple caching, to minimize state changes... */
|
||||
CoglHandle current_material;
|
||||
gulong current_material_flags;
|
||||
GArray *current_layers;
|
||||
guint n_texcoord_arrays_enabled;
|
||||
|
||||
/* Framebuffer objects */
|
||||
GArray *fbo_handles;
|
||||
|
@ -94,6 +95,15 @@ typedef struct
|
|||
/* Vertex buffers */
|
||||
GArray *vertex_buffer_handles;
|
||||
|
||||
/* Primitives */
|
||||
floatVec2 path_start;
|
||||
floatVec2 path_pen;
|
||||
GArray *path_nodes;
|
||||
guint last_path;
|
||||
floatVec2 path_nodes_min;
|
||||
floatVec2 path_nodes_max;
|
||||
CoglHandle stencil_material;
|
||||
|
||||
/* Relying on glext.h to define these */
|
||||
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
|
||||
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
|
||||
|
|
|
@ -51,13 +51,10 @@ const char *_cogl_error_string(GLenum errorCode);
|
|||
#endif /* COGL_DEBUG */
|
||||
|
||||
#define COGL_ENABLE_BLEND (1<<1)
|
||||
#define COGL_ENABLE_TEXTURE_2D (1<<2)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<3)
|
||||
#define COGL_ENABLE_TEXTURE_RECT (1<<4)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<5)
|
||||
#define COGL_ENABLE_TEXCOORD_ARRAY (1<<6)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<7)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<8)
|
||||
#define COGL_ENABLE_ALPHA_TEST (1<<2)
|
||||
#define COGL_ENABLE_VERTEX_ARRAY (1<<3)
|
||||
#define COGL_ENABLE_COLOR_ARRAY (1<<4)
|
||||
#define COGL_ENABLE_BACKFACE_CULLING (1<<5)
|
||||
|
||||
gint
|
||||
_cogl_get_format_bpp (CoglPixelFormat format);
|
||||
|
|
|
@ -38,27 +38,13 @@
|
|||
|
||||
#define _COGL_MAX_BEZ_RECURSE_DEPTH 16
|
||||
|
||||
void
|
||||
_cogl_rectangle (float x,
|
||||
float y,
|
||||
float width,
|
||||
float height)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
cogl_enable (ctx->color_alpha < 255
|
||||
? COGL_ENABLE_BLEND : 0);
|
||||
|
||||
GE( glRectf (x, y, x + width, y + height) );
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_path_add_node (gboolean new_sub_path,
|
||||
float x,
|
||||
float y)
|
||||
{
|
||||
CoglPathNode new_node;
|
||||
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
new_node.x = (x);
|
||||
|
@ -89,13 +75,18 @@ _cogl_path_add_node (gboolean new_sub_path,
|
|||
void
|
||||
_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_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
| (ctx->color_alpha < 255
|
||||
? COGL_ENABLE_BLEND : 0));
|
||||
|
||||
enable_flags |= cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
cogl_material_flush_gl_state (ctx->source_material,
|
||||
COGL_MATERIAL_FLUSH_DISABLE_MASK,
|
||||
(guint32)~0, /* disable all texture layers */
|
||||
NULL);
|
||||
|
||||
while (path_start < ctx->path_nodes->len)
|
||||
{
|
||||
|
@ -106,7 +97,7 @@ _cogl_path_stroke_nodes ()
|
|||
(guchar *) path
|
||||
+ G_STRUCT_OFFSET (CoglPathNode, x)) );
|
||||
GE( glDrawArrays (GL_LINE_STRIP, 0, path->path_size) );
|
||||
|
||||
|
||||
path_start += path->path_size;
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +130,8 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
|||
float bounds_w;
|
||||
float bounds_h;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
_cogl_path_get_bounds (nodes_min, nodes_max,
|
||||
&bounds_x, &bounds_y, &bounds_w, &bounds_h);
|
||||
|
||||
|
@ -159,10 +152,17 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
|||
|
||||
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
|
||||
GE( glDepthMask (FALSE) );
|
||||
|
||||
|
||||
while (path_start < path_size)
|
||||
{
|
||||
cogl_enable (COGL_ENABLE_VERTEX_ARRAY);
|
||||
gulong enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
|
||||
/* Just setup a simple material that doesn't use texturing... */
|
||||
cogl_material_flush_gl_state (ctx->stencil_material, NULL);
|
||||
|
||||
enable_flags |=
|
||||
cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
cogl_enable (enable_flags);
|
||||
|
||||
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
|
||||
(guchar *) path
|
||||
|
@ -207,11 +207,11 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
|
|||
GE( glMatrixMode (GL_MODELVIEW) );
|
||||
GE( glPopMatrix () );
|
||||
}
|
||||
|
||||
|
||||
GE( glStencilMask (~(GLuint) 0) );
|
||||
GE( glDepthMask (TRUE) );
|
||||
GE( glColorMask (TRUE, TRUE, TRUE, TRUE) );
|
||||
|
||||
|
||||
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
}
|
||||
|
|
|
@ -28,11 +28,9 @@
|
|||
|
||||
#include "cogl-bitmap.h"
|
||||
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
typedef struct _CoglCompositeTexture CoglCompositeTexture;
|
||||
typedef struct _CoglCompositeTextureLayer CoglCompositeTextureLayer;
|
||||
typedef struct _CoglTexture CoglTexture;
|
||||
typedef struct _CoglTexSliceSpan CoglTexSliceSpan;
|
||||
typedef struct _CoglSpanIter CoglSpanIter;
|
||||
|
||||
struct _CoglTexSliceSpan
|
||||
{
|
||||
|
@ -61,26 +59,23 @@ struct _CoglTexture
|
|||
gboolean auto_mipmap;
|
||||
};
|
||||
|
||||
struct _CoglCompositeTextureLayer
|
||||
/* To improve batching of geometry when submitting vertices to OpenGL we
|
||||
* log the texture rectangles we want to draw to a journal, so when we
|
||||
* later flush the journal we aim to batch data, and gl draw calls. */
|
||||
typedef struct _CoglJournalEntry
|
||||
{
|
||||
guint ref_count;
|
||||
|
||||
guint index; /*!< lowest index is blended first then others
|
||||
on top */
|
||||
CoglTexture *tex; /*!< The texture for this layer, or NULL
|
||||
for an empty layer */
|
||||
|
||||
/* TODO: Add more control over the texture environment for each texture
|
||||
* unit. For example we should support dot3 normal mapping. */
|
||||
};
|
||||
|
||||
struct _CoglCompositeTexture
|
||||
{
|
||||
guint ref_count;
|
||||
GList *layers;
|
||||
};
|
||||
CoglHandle material;
|
||||
gint n_layers;
|
||||
guint32 fallback_mask;
|
||||
GLuint layer0_override_texture;
|
||||
} CoglJournalEntry;
|
||||
|
||||
CoglTexture*
|
||||
_cogl_texture_pointer_from_handle (CoglHandle handle);
|
||||
|
||||
gboolean
|
||||
_cogl_texture_span_has_waste (CoglTexture *tex,
|
||||
gint x_span_index,
|
||||
gint y_span_index);
|
||||
|
||||
#endif /* __COGL_TEXTURE_H */
|
||||
|
|
1424
gl/cogl-texture.c
1424
gl/cogl-texture.c
File diff suppressed because it is too large
Load diff
128
gl/cogl.c
128
gl/cogl.c
|
@ -180,16 +180,16 @@ cogl_paint_init (const CoglColor *color)
|
|||
glDisable (GL_LIGHTING);
|
||||
glDisable (GL_FOG);
|
||||
|
||||
/*
|
||||
/*
|
||||
* Disable the depth test for now as has some strange side effects,
|
||||
* mainly on x/y axis rotation with multiple layers at same depth
|
||||
* (eg rotating text on a bg has very strange effect). Seems no clean
|
||||
* 100% effective way to fix without other odd issues.. So for now
|
||||
* mainly on x/y axis rotation with multiple layers at same depth
|
||||
* (eg rotating text on a bg has very strange effect). Seems no clean
|
||||
* 100% effective way to fix without other odd issues.. So for now
|
||||
* move to application to handle and add cogl_enable_depth_test()
|
||||
* as for custom actors (i.e groups) to enable if need be.
|
||||
*
|
||||
* glEnable (GL_DEPTH_TEST);
|
||||
* glEnable (GL_ALPHA_TEST)
|
||||
* glEnable (GL_DEPTH_TEST);
|
||||
* glEnable (GL_ALPHA_TEST)
|
||||
* glDepthFunc (GL_LEQUAL);
|
||||
* glAlphaFunc (GL_GREATER, 0.1);
|
||||
*/
|
||||
|
@ -251,7 +251,7 @@ cogl_toggle_flag (CoglContext *ctx,
|
|||
GE( glDisable (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -278,7 +278,7 @@ cogl_toggle_client_flag (CoglContext *ctx,
|
|||
GE( glDisableClientState (gl_flag) );
|
||||
ctx->enable_flags &= ~flag;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -289,33 +289,19 @@ cogl_enable (gulong flags)
|
|||
* hope of lessening number GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BLEND,
|
||||
GL_BLEND);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXTURE_2D,
|
||||
GL_TEXTURE_2D);
|
||||
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_BACKFACE_CULLING,
|
||||
GL_CULL_FACE);
|
||||
|
||||
#ifdef GL_TEXTURE_RECTANGLE_ARB
|
||||
cogl_toggle_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXTURE_RECT,
|
||||
GL_TEXTURE_RECTANGLE_ARB);
|
||||
#endif
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_VERTEX_ARRAY,
|
||||
GL_VERTEX_ARRAY);
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_TEXCOORD_ARRAY,
|
||||
GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
|
||||
cogl_toggle_client_flag (ctx, flags,
|
||||
COGL_ENABLE_COLOR_ARRAY,
|
||||
GL_COLOR_ARRAY);
|
||||
|
@ -325,7 +311,7 @@ gulong
|
|||
cogl_get_enable ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
return ctx->enable_flags;
|
||||
}
|
||||
|
||||
|
@ -336,7 +322,7 @@ cogl_blend_func (COGLenum src_factor, COGLenum dst_factor)
|
|||
* hope of lessening GL traffic.
|
||||
*/
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
if (ctx->blend_src_factor != src_factor ||
|
||||
ctx->blend_dst_factor != dst_factor)
|
||||
{
|
||||
|
@ -351,14 +337,14 @@ cogl_enable_depth_test (gboolean setting)
|
|||
{
|
||||
if (setting)
|
||||
{
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_DEPTH_TEST);
|
||||
glEnable (GL_ALPHA_TEST);
|
||||
glDepthFunc (GL_LEQUAL);
|
||||
glAlphaFunc (GL_GREATER, 0.1);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_DEPTH_TEST);
|
||||
glDisable (GL_ALPHA_TEST);
|
||||
}
|
||||
}
|
||||
|
@ -375,14 +361,12 @@ void
|
|||
cogl_set_source_color (const CoglColor *color)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
glColor4ub (cogl_color_get_red_byte (color),
|
||||
cogl_color_get_green_byte (color),
|
||||
cogl_color_get_blue_byte (color),
|
||||
cogl_color_get_alpha_byte (color));
|
||||
|
||||
/* Store alpha for proper blending enables */
|
||||
ctx->color_alpha = cogl_color_get_alpha_byte (color);
|
||||
|
||||
/* In case cogl_set_source_texture was previously used... */
|
||||
cogl_material_remove_layer (ctx->default_material, 0);
|
||||
|
||||
cogl_material_set_color (ctx->default_material, color);
|
||||
cogl_set_source (ctx->default_material);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -512,7 +496,7 @@ _cogl_add_stencil_clip (float x_offset,
|
|||
if (first)
|
||||
{
|
||||
GE( glEnable (GL_STENCIL_TEST) );
|
||||
|
||||
|
||||
/* Initially disallow everything */
|
||||
GE( glClearStencil (0) );
|
||||
GE( glClear (GL_STENCIL_BUFFER_BIT) );
|
||||
|
@ -815,7 +799,7 @@ _cogl_features_init ()
|
|||
GLint num_stencil_bits = 0;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
|
||||
flags = COGL_FEATURE_TEXTURE_READ_PIXELS;
|
||||
|
||||
gl_extensions = (const gchar*) glGetString (GL_EXTENSIONS);
|
||||
|
@ -827,7 +811,7 @@ _cogl_features_init ()
|
|||
#endif
|
||||
flags |= COGL_FEATURE_TEXTURE_NPOT;
|
||||
}
|
||||
|
||||
|
||||
#ifdef GL_YCBCR_MESA
|
||||
if (cogl_check_extension ("GL_MESA_ycbcr_texture", gl_extensions))
|
||||
{
|
||||
|
@ -842,47 +826,47 @@ _cogl_features_init ()
|
|||
ctx->pf_glCreateProgramObjectARB =
|
||||
(COGL_PFNGLCREATEPROGRAMOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glCreateProgramObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glCreateShaderObjectARB =
|
||||
(COGL_PFNGLCREATESHADEROBJECTARBPROC)
|
||||
cogl_get_proc_address ("glCreateShaderObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glShaderSourceARB =
|
||||
(COGL_PFNGLSHADERSOURCEARBPROC)
|
||||
cogl_get_proc_address ("glShaderSourceARB");
|
||||
|
||||
|
||||
ctx->pf_glCompileShaderARB =
|
||||
(COGL_PFNGLCOMPILESHADERARBPROC)
|
||||
cogl_get_proc_address ("glCompileShaderARB");
|
||||
|
||||
|
||||
ctx->pf_glAttachObjectARB =
|
||||
(COGL_PFNGLATTACHOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glAttachObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glLinkProgramARB =
|
||||
(COGL_PFNGLLINKPROGRAMARBPROC)
|
||||
cogl_get_proc_address ("glLinkProgramARB");
|
||||
|
||||
|
||||
ctx->pf_glUseProgramObjectARB =
|
||||
(COGL_PFNGLUSEPROGRAMOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glUseProgramObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glGetUniformLocationARB =
|
||||
(COGL_PFNGLGETUNIFORMLOCATIONARBPROC)
|
||||
cogl_get_proc_address ("glGetUniformLocationARB");
|
||||
|
||||
|
||||
ctx->pf_glDeleteObjectARB =
|
||||
(COGL_PFNGLDELETEOBJECTARBPROC)
|
||||
cogl_get_proc_address ("glDeleteObjectARB");
|
||||
|
||||
|
||||
ctx->pf_glGetInfoLogARB =
|
||||
(COGL_PFNGLGETINFOLOGARBPROC)
|
||||
cogl_get_proc_address ("glGetInfoLogARB");
|
||||
|
||||
|
||||
ctx->pf_glGetObjectParameterivARB =
|
||||
(COGL_PFNGLGETOBJECTPARAMETERIVARBPROC)
|
||||
cogl_get_proc_address ("glGetObjectParameterivARB");
|
||||
|
||||
|
||||
ctx->pf_glUniform1fARB =
|
||||
(COGL_PFNGLUNIFORM1FARBPROC)
|
||||
cogl_get_proc_address ("glUniform1fARB");
|
||||
|
@ -898,7 +882,7 @@ _cogl_features_init ()
|
|||
ctx->pf_glDisableVertexAttribArrayARB =
|
||||
(COGL_PFNGLDISABLEVERTEXATTRIBARRAYARBPROC)
|
||||
cogl_get_proc_address ("glDisableVertexAttribArrayARB");
|
||||
|
||||
|
||||
ctx->pf_glUniform2fARB =
|
||||
(COGL_PFNGLUNIFORM2FARBPROC)
|
||||
cogl_get_proc_address ("glUniform2fARB");
|
||||
|
@ -962,7 +946,7 @@ _cogl_features_init ()
|
|||
ctx->pf_glUniformMatrix2fvARB =
|
||||
(COGL_PFNGLUNIFORMMATRIX2FVARBPROC)
|
||||
cogl_get_proc_address ("glUniformMatrix2fvARB");
|
||||
|
||||
|
||||
ctx->pf_glUniformMatrix3fvARB =
|
||||
(COGL_PFNGLUNIFORMMATRIX3FVARBPROC)
|
||||
cogl_get_proc_address ("glUniformMatrix3fvARB");
|
||||
|
@ -1006,50 +990,50 @@ _cogl_features_init ()
|
|||
ctx->pf_glDisableVertexAttribArrayARB)
|
||||
flags |= COGL_FEATURE_SHADERS_GLSL;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_object", gl_extensions) ||
|
||||
cogl_check_extension ("GL_ARB_framebuffer_object", gl_extensions))
|
||||
{
|
||||
{
|
||||
ctx->pf_glGenRenderbuffersEXT =
|
||||
(COGL_PFNGLGENRENDERBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glGenRenderbuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glDeleteRenderbuffersEXT =
|
||||
(COGL_PFNGLDELETERENDERBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glDeleteRenderbuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glBindRenderbufferEXT =
|
||||
(COGL_PFNGLBINDRENDERBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBindRenderbufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glRenderbufferStorageEXT =
|
||||
(COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC)
|
||||
cogl_get_proc_address ("glRenderbufferStorageEXT");
|
||||
|
||||
|
||||
ctx->pf_glGenFramebuffersEXT =
|
||||
(COGL_PFNGLGENFRAMEBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glGenFramebuffersEXT");
|
||||
|
||||
|
||||
ctx->pf_glBindFramebufferEXT =
|
||||
(COGL_PFNGLBINDFRAMEBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBindFramebufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glFramebufferTexture2DEXT =
|
||||
(COGL_PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
|
||||
cogl_get_proc_address ("glFramebufferTexture2DEXT");
|
||||
|
||||
|
||||
ctx->pf_glFramebufferRenderbufferEXT =
|
||||
(COGL_PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glFramebufferRenderbufferEXT");
|
||||
|
||||
|
||||
ctx->pf_glCheckFramebufferStatusEXT =
|
||||
(COGL_PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
|
||||
cogl_get_proc_address ("glCheckFramebufferStatusEXT");
|
||||
|
||||
|
||||
ctx->pf_glDeleteFramebuffersEXT =
|
||||
(COGL_PFNGLDELETEFRAMEBUFFERSEXTPROC)
|
||||
cogl_get_proc_address ("glDeleteFramebuffersEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glGenRenderbuffersEXT &&
|
||||
ctx->pf_glBindRenderbufferEXT &&
|
||||
ctx->pf_glRenderbufferStorageEXT &&
|
||||
|
@ -1061,23 +1045,23 @@ _cogl_features_init ()
|
|||
ctx->pf_glDeleteFramebuffersEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_blit", gl_extensions))
|
||||
{
|
||||
ctx->pf_glBlitFramebufferEXT =
|
||||
(COGL_PFNGLBLITFRAMEBUFFEREXTPROC)
|
||||
cogl_get_proc_address ("glBlitFramebufferEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glBlitFramebufferEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN_BLIT;
|
||||
}
|
||||
|
||||
|
||||
if (cogl_check_extension ("GL_EXT_framebuffer_multisample", gl_extensions))
|
||||
{
|
||||
ctx->pf_glRenderbufferStorageMultisampleEXT =
|
||||
(COGL_PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
|
||||
cogl_get_proc_address ("glRenderbufferStorageMultisampleEXT");
|
||||
|
||||
|
||||
if (ctx->pf_glRenderbufferStorageMultisampleEXT)
|
||||
flags |= COGL_FEATURE_OFFSCREEN_MULTISAMPLE;
|
||||
}
|
||||
|
@ -1140,10 +1124,10 @@ CoglFeatureFlags
|
|||
cogl_get_features ()
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return ctx->feature_flags;
|
||||
}
|
||||
|
||||
|
@ -1151,10 +1135,10 @@ gboolean
|
|||
cogl_features_available (CoglFeatureFlags features)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
|
||||
return (ctx->feature_flags & features) == features;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue