2009-04-27 10:48:12 -04:00
|
|
|
/*
|
|
|
|
* Cogl
|
|
|
|
*
|
|
|
|
* An object oriented GL/GLES Abstraction/Utility Layer
|
|
|
|
*
|
2010-04-08 07:21:04 -04:00
|
|
|
* Copyright (C) 2008,2009,2010 Intel Corporation.
|
2009-04-27 10:48:12 -04:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2010-04-08 07:21:04 -04:00
|
|
|
* License along with this library. If not, see
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
2010-03-01 07:56:10 -05:00
|
|
|
*
|
|
|
|
*
|
2009-04-27 10:48:12 -04:00
|
|
|
*
|
|
|
|
* Authors:
|
|
|
|
* Robert Bragg <robert@linux.intel.com>
|
|
|
|
*/
|
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
#ifndef __COGL_MATERIAL_PRIVATE_H
|
|
|
|
#define __COGL_MATERIAL_PRIVATE_H
|
|
|
|
|
|
|
|
#include "cogl-material.h"
|
|
|
|
#include "cogl-matrix.h"
|
2010-04-26 05:01:43 -04:00
|
|
|
#include "cogl-matrix-stack.h"
|
2009-04-01 12:16:44 -04:00
|
|
|
#include "cogl-handle.h"
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
|
|
|
#include <glib.h>
|
|
|
|
|
|
|
|
typedef struct _CoglMaterial CoglMaterial;
|
|
|
|
typedef struct _CoglMaterialLayer CoglMaterialLayer;
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* cogl-material.c owns the GPU's texture unit state so we have some
|
|
|
|
* private structures for describing the current state of a texture
|
|
|
|
* unit that we track in a per context array (ctx->texture_units) that
|
|
|
|
* grows according to the largest texture unit used so far...
|
|
|
|
*
|
|
|
|
* Roughly speaking the members in this structure are of two kinds:
|
|
|
|
* either they are a low level reflection of the state we send to
|
|
|
|
* OpenGL or they are for high level meta data assoicated with the
|
|
|
|
* texture unit when flushing CoglMaterialLayers that is typically
|
|
|
|
* used to optimize subsequent re-flushing of the same layer.
|
|
|
|
*
|
|
|
|
* The low level members are at the top, and the high level members
|
|
|
|
* start with the .layer member.
|
|
|
|
*/
|
|
|
|
typedef struct _CoglTextureUnit
|
|
|
|
{
|
|
|
|
/* The base 0 texture unit index which can be used with
|
|
|
|
* glActiveTexture () */
|
|
|
|
int index;
|
|
|
|
|
|
|
|
/* Whether or not the corresponding gl_target has been glEnabled */
|
|
|
|
gboolean enabled;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* The GL target currently glEnabled or the target last enabled
|
|
|
|
* if .enabled == FALSE */
|
|
|
|
GLenum current_gl_target;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
|
|
|
/* The raw GL texture object name for which we called glBindTexture when
|
|
|
|
* we flushed the last layer. (NB: The CoglTexture associated
|
|
|
|
* with a layer may represent more than one GL texture) */
|
|
|
|
GLuint gl_texture;
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
/* Foreign textures are those not created or deleted by Cogl. If we ever
|
|
|
|
* call glBindTexture for a foreign texture then the next time we are
|
|
|
|
* asked to glBindTexture we can't try and optimize a redundant state
|
|
|
|
* change because we don't know if the original texture name was deleted
|
|
|
|
* and now we are being asked to bind a recycled name. */
|
|
|
|
gboolean is_foreign;
|
|
|
|
|
|
|
|
/* We have many components in Cogl that need to temporarily bind arbitrary
|
|
|
|
* textures e.g. to query texture object parameters and since we don't
|
|
|
|
* want that to result in too much redundant reflushing of layer state
|
2010-04-08 07:21:04 -04:00
|
|
|
* when all that's needed is to re-bind the layer's gl_texture we use this
|
|
|
|
* to track when the unit->gl_texture state is out of sync with the GL
|
|
|
|
* texture object really bound too (GL_TEXTURE0+unit->index).
|
2010-04-26 05:01:43 -04:00
|
|
|
*
|
|
|
|
* XXX: as a further optimization cogl-material.c uses a convention
|
2010-04-08 07:21:04 -04:00
|
|
|
* of always using texture unit 1 for these transient bindings so we
|
|
|
|
* can assume this is only ever TRUE for unit 1.
|
2010-04-26 05:01:43 -04:00
|
|
|
*/
|
|
|
|
gboolean dirty_gl_texture;
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
/* A matrix stack giving us the means to associate a texture
|
|
|
|
* transform matrix with the texture unit. */
|
|
|
|
CoglMatrixStack *matrix_stack;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Higher level layer state associated with the unit...
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* The CoglMaterialLayer whos state was flushed to update this
|
|
|
|
* texture unit last.
|
|
|
|
*
|
|
|
|
* This will be set to NULL if the layer is modified or freed which
|
|
|
|
* means when we come to flush a layer; if this pointer is still
|
|
|
|
* valid and == to the layer being flushed we don't need to update
|
|
|
|
* any texture unit state. */
|
|
|
|
CoglMaterialLayer *layer;
|
|
|
|
|
|
|
|
/* To help minimize the state changes required we track the
|
|
|
|
* difference flags associated with the layer whos state was last
|
|
|
|
* flushed to update this texture unit.
|
|
|
|
*
|
|
|
|
* Note: we track this explicitly because .layer may get invalidated
|
|
|
|
* if that layer is modified or deleted. Even if the layer is
|
|
|
|
* invalidated though these flags can be used to optimize the state
|
|
|
|
* flush of the next layer
|
|
|
|
*/
|
2010-04-08 07:21:04 -04:00
|
|
|
unsigned long layer_changes_since_flush;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Whenever a CoglTexture's internal GL texture storage changes
|
|
|
|
* cogl-material.c is notified with a call to
|
|
|
|
* _cogl_material_texture_storage_change_notify which inturn sets
|
|
|
|
* this to TRUE for each texture unit that it is currently bound
|
|
|
|
* too. When we later come to flush some material state then we will
|
|
|
|
* always check this to potentially force an update of the texture
|
|
|
|
* state even if the material hasn't changed. */
|
|
|
|
gboolean texture_storage_changed;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
|
|
|
} CoglTextureUnit;
|
|
|
|
|
|
|
|
CoglTextureUnit *
|
|
|
|
_cogl_get_texture_unit (int index_);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_destroy_texture_units (void);
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
void
|
|
|
|
_cogl_bind_gl_texture_transient (GLenum gl_target,
|
|
|
|
GLuint gl_texture,
|
|
|
|
gboolean is_foreign);
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#if defined (HAVE_COGL_GL)
|
2010-06-15 11:44:52 -04:00
|
|
|
|
|
|
|
/* NB: material->backend is currently a 3bit unsigned int bitfield */
|
|
|
|
#define COGL_MATERIAL_BACKEND_GLSL 0
|
|
|
|
#define COGL_MATERIAL_BACKEND_GLSL_MASK (1L<<0)
|
|
|
|
#define COGL_MATERIAL_BACKEND_ARBFP 1
|
|
|
|
#define COGL_MATERIAL_BACKEND_ARBFP_MASK (1L<<1)
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED 2
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<2)
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#define COGL_MATERIAL_N_BACKENDS 3
|
2010-06-15 11:44:52 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#elif defined (HAVE_COGL_GLES2)
|
2010-06-15 11:44:52 -04:00
|
|
|
|
|
|
|
#define COGL_MATERIAL_BACKEND_GLSL 0
|
|
|
|
#define COGL_MATERIAL_BACKEND_GLSL_MASK (1L<<0)
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED 1
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<1)
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#define COGL_MATERIAL_N_BACKENDS 2
|
2010-06-15 11:44:52 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#else /* HAVE_COGL_GLES */
|
2010-06-15 11:44:52 -04:00
|
|
|
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED 0
|
|
|
|
#define COGL_MATERIAL_BACKEND_FIXED_MASK (1L<<0)
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#define COGL_MATERIAL_N_BACKENDS 1
|
2010-06-15 11:44:52 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
#endif
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
|
2010-06-15 11:44:52 -04:00
|
|
|
#define COGL_MATERIAL_BACKEND_DEFAULT 0
|
|
|
|
#define COGL_MATERIAL_BACKEND_UNDEFINED 3
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef enum
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
{
|
2010-04-08 07:21:04 -04:00
|
|
|
COGL_MATERIAL_LAYER_STATE_UNIT = 1L<<0,
|
|
|
|
COGL_MATERIAL_LAYER_STATE_TEXTURE = 1L<<1,
|
|
|
|
COGL_MATERIAL_LAYER_STATE_FILTERS = 1L<<2,
|
|
|
|
COGL_MATERIAL_LAYER_STATE_WRAP_MODES = 1L<<3,
|
|
|
|
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE = 1L<<4,
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT = 1L<<5,
|
|
|
|
COGL_MATERIAL_LAYER_STATE_USER_MATRIX = 1L<<6,
|
|
|
|
|
|
|
|
/* COGL_MATERIAL_LAYER_STATE_TEXTURE_INTERN = 1L<<7, */
|
|
|
|
|
|
|
|
COGL_MATERIAL_LAYER_STATE_ALL_SPARSE =
|
|
|
|
COGL_MATERIAL_LAYER_STATE_UNIT |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_TEXTURE |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_FILTERS |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_WRAP_MODES |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_USER_MATRIX,
|
|
|
|
|
|
|
|
COGL_MATERIAL_LAYER_STATE_NEEDS_BIG_STATE =
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_COMBINE_CONSTANT |
|
|
|
|
COGL_MATERIAL_LAYER_STATE_USER_MATRIX
|
|
|
|
|
|
|
|
} CoglMaterialLayerState;
|
|
|
|
|
|
|
|
typedef struct
|
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.
2009-01-23 11:15:40 -05:00
|
|
|
{
|
2010-04-08 07:21:04 -04:00
|
|
|
/* The texture combine state determines how the color of individual
|
|
|
|
* texture fragments are calculated. */
|
|
|
|
GLint texture_combine_rgb_func;
|
|
|
|
GLint texture_combine_rgb_src[3];
|
|
|
|
GLint texture_combine_rgb_op[3];
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
GLint texture_combine_alpha_func;
|
|
|
|
GLint texture_combine_alpha_src[3];
|
|
|
|
GLint texture_combine_alpha_op[3];
|
|
|
|
|
|
|
|
float texture_combine_constant[4];
|
|
|
|
|
|
|
|
/* The texture matrix dscribes how to transform texture coordinates */
|
|
|
|
CoglMatrix matrix;
|
|
|
|
|
|
|
|
} CoglMaterialLayerBigState;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
|
|
|
struct _CoglMaterialLayer
|
|
|
|
{
|
2010-04-08 07:21:04 -04:00
|
|
|
/* XXX: Please think twice about adding members that *have* be
|
|
|
|
* initialized during a _cogl_material_layer_copy. We are aiming
|
|
|
|
* to have copies be as cheap as possible and copies may be
|
|
|
|
* done by the primitives APIs which means they may happen
|
|
|
|
* in performance critical code paths.
|
|
|
|
*
|
|
|
|
* XXX: If you are extending the state we track please consider if
|
|
|
|
* the state is expected to vary frequently across many materials or
|
|
|
|
* if the state can be shared among many derived materials instead.
|
|
|
|
* This will determine if the state should be added directly to this
|
|
|
|
* structure which will increase the memory overhead for *all*
|
|
|
|
* layers or if instead it can go under ->big_state.
|
|
|
|
*/
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* the parent in terms of class hierarchy */
|
|
|
|
CoglHandleObject _parent;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Some layers have a material owner, which is to say that the layer
|
|
|
|
* is referenced in that materials->layer_differences list. A layer
|
|
|
|
* doesn't always have an owner and may simply be an ancestor for
|
|
|
|
* other layers that keeps track of some shared state. */
|
|
|
|
CoglMaterial *owner;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Layers are sparse structures defined as a diff against
|
|
|
|
* their parent... */
|
|
|
|
CoglMaterialLayer *parent;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* As an optimization for creating leaf node layers (the most
|
|
|
|
* common) we don't require any list node allocations to link
|
|
|
|
* to a single descendant. */
|
|
|
|
CoglMaterialLayer *first_child;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Layers are sparse structures defined as a diff against
|
|
|
|
* their parent and may have multiple children which depend
|
|
|
|
* on them to define the values of properties which they don't
|
|
|
|
* change. */
|
|
|
|
GList *children;
|
2008-12-23 18:50:02 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* The lowest index is blended first then others on top */
|
|
|
|
int index;
|
2009-06-04 11:04:57 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Different material backends (GLSL/ARBfp/Fixed Function) may
|
|
|
|
* want to associate private data with a layer...
|
|
|
|
*
|
|
|
|
* NB: we have per backend pointers because a layer may be
|
|
|
|
* associated with multiple materials with different backends.
|
|
|
|
*/
|
|
|
|
void *backend_priv[COGL_MATERIAL_N_BACKENDS];
|
2010-04-01 06:31:33 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* A mask of which state groups are different in this layer
|
|
|
|
* in comparison to its parent. */
|
|
|
|
unsigned long differences;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Common differences
|
|
|
|
*
|
|
|
|
* As a basic way to reduce memory usage we divide the layer
|
|
|
|
* state into two groups; the minimal state modified in 90% of
|
|
|
|
* all layers and the rest, so that the second group can
|
|
|
|
* be allocated dynamically when required.
|
|
|
|
*/
|
2008-12-23 18:50:02 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Each layer is directly associated with a single texture unit */
|
|
|
|
int unit_index;
|
2009-05-10 19:40:41 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* The texture for this layer, or COGL_INVALID_HANDLE for an empty
|
|
|
|
* layer */
|
|
|
|
CoglHandle texture;
|
|
|
|
gboolean texture_overridden;
|
|
|
|
/* If ->texture_overridden == TRUE then the texture is instead
|
|
|
|
* defined by these... */
|
|
|
|
GLuint slice_gl_texture;
|
|
|
|
GLenum slice_gl_target;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
CoglMaterialFilter mag_filter;
|
|
|
|
CoglMaterialFilter min_filter;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
CoglMaterialWrapMode wrap_mode_s;
|
|
|
|
CoglMaterialWrapMode wrap_mode_t;
|
|
|
|
CoglMaterialWrapMode wrap_mode_r;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Infrequent differences aren't currently tracked in
|
|
|
|
* a separate, dynamically allocated structure as they are
|
|
|
|
* for materials... */
|
|
|
|
CoglMaterialLayerBigState *big_state;
|
2009-11-17 19:26:09 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* bitfields */
|
2009-11-17 19:26:09 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Determines if layer->first_child and layer->children are
|
|
|
|
* initialized pointers. */
|
|
|
|
unsigned int has_children:1;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Determines if layer->big_state is valid */
|
|
|
|
unsigned int has_big_state:1;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
};
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Used in material->differences masks and for notifying material
|
|
|
|
* state changes... */
|
|
|
|
typedef enum _CoglMaterialState
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_STATE_COLOR = 1L<<0,
|
|
|
|
COGL_MATERIAL_STATE_BLEND_ENABLE = 1L<<1,
|
|
|
|
COGL_MATERIAL_STATE_LAYERS = 1L<<2,
|
|
|
|
|
|
|
|
COGL_MATERIAL_STATE_LIGHTING = 1L<<3,
|
|
|
|
COGL_MATERIAL_STATE_ALPHA_FUNC = 1L<<4,
|
|
|
|
COGL_MATERIAL_STATE_BLEND = 1L<<5,
|
|
|
|
COGL_MATERIAL_STATE_USER_SHADER = 1L<<6,
|
2010-05-26 06:33:32 -04:00
|
|
|
COGL_MATERIAL_STATE_DEPTH = 1L<<7,
|
2010-04-08 07:21:04 -04:00
|
|
|
|
2010-05-26 06:33:32 -04:00
|
|
|
COGL_MATERIAL_STATE_REAL_BLEND_ENABLE = 1L<<8,
|
2010-04-08 07:21:04 -04:00
|
|
|
|
|
|
|
COGL_MATERIAL_STATE_ALL_SPARSE =
|
|
|
|
COGL_MATERIAL_STATE_COLOR |
|
|
|
|
COGL_MATERIAL_STATE_BLEND_ENABLE |
|
|
|
|
COGL_MATERIAL_STATE_LAYERS |
|
|
|
|
COGL_MATERIAL_STATE_LIGHTING |
|
|
|
|
COGL_MATERIAL_STATE_ALPHA_FUNC |
|
|
|
|
COGL_MATERIAL_STATE_BLEND |
|
2010-05-26 06:33:32 -04:00
|
|
|
COGL_MATERIAL_STATE_USER_SHADER |
|
|
|
|
COGL_MATERIAL_STATE_DEPTH,
|
2010-04-08 07:21:04 -04:00
|
|
|
|
|
|
|
COGL_MATERIAL_STATE_AFFECTS_BLENDING =
|
|
|
|
COGL_MATERIAL_STATE_COLOR |
|
|
|
|
COGL_MATERIAL_STATE_BLEND_ENABLE |
|
|
|
|
COGL_MATERIAL_STATE_LAYERS |
|
|
|
|
COGL_MATERIAL_STATE_LIGHTING |
|
|
|
|
COGL_MATERIAL_STATE_BLEND |
|
|
|
|
COGL_MATERIAL_STATE_USER_SHADER,
|
|
|
|
|
|
|
|
COGL_MATERIAL_STATE_NEEDS_BIG_STATE =
|
|
|
|
COGL_MATERIAL_STATE_LIGHTING |
|
|
|
|
COGL_MATERIAL_STATE_ALPHA_FUNC |
|
|
|
|
COGL_MATERIAL_STATE_BLEND |
|
2010-05-26 06:33:32 -04:00
|
|
|
COGL_MATERIAL_STATE_USER_SHADER |
|
|
|
|
COGL_MATERIAL_STATE_DEPTH
|
2010-04-08 07:21:04 -04:00
|
|
|
|
|
|
|
} CoglMaterialState;
|
2008-12-23 18:50:02 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_AMBIENT = 1,
|
|
|
|
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_DIFFUSE,
|
|
|
|
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SPECULAR,
|
|
|
|
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_EMISSION,
|
|
|
|
COGL_MATERIAL_LIGHTING_STATE_PROPERTY_SHININESS
|
|
|
|
} CoglMaterialLightingStateProperty;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
/* Standard OpenGL lighting model attributes */
|
2010-04-08 07:21:04 -04:00
|
|
|
float ambient[4];
|
|
|
|
float diffuse[4];
|
|
|
|
float specular[4];
|
|
|
|
float emission[4];
|
|
|
|
float shininess;
|
|
|
|
} CoglMaterialLightingState;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
/* Determines what fragments are discarded based on their alpha */
|
|
|
|
CoglMaterialAlphaFunc alpha_func;
|
|
|
|
GLfloat alpha_func_reference;
|
2010-04-08 07:21:04 -04:00
|
|
|
} CoglMaterialAlphaFuncState;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef enum _CoglMaterialBlendEnable
|
|
|
|
{
|
|
|
|
/* XXX: we want to detect users mistakenly using TRUE or FALSE
|
|
|
|
* so start the enum at 2. */
|
|
|
|
COGL_MATERIAL_BLEND_ENABLE_ENABLED = 2,
|
|
|
|
COGL_MATERIAL_BLEND_ENABLE_DISABLED,
|
|
|
|
COGL_MATERIAL_BLEND_ENABLE_AUTOMATIC
|
|
|
|
} CoglMaterialBlendEnable;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
/* Determines how this material is blended with other primitives */
|
2009-05-10 19:40:41 -04:00
|
|
|
#ifndef HAVE_COGL_GLES
|
2010-04-08 07:21:04 -04:00
|
|
|
GLenum blend_equation_rgb;
|
|
|
|
GLenum blend_equation_alpha;
|
|
|
|
GLint blend_src_factor_alpha;
|
|
|
|
GLint blend_dst_factor_alpha;
|
|
|
|
CoglColor blend_constant;
|
2009-05-10 19:40:41 -04:00
|
|
|
#endif
|
2010-04-08 07:21:04 -04:00
|
|
|
GLint blend_src_factor_rgb;
|
|
|
|
GLint blend_dst_factor_rgb;
|
|
|
|
} CoglMaterialBlendState;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
|
2010-05-26 06:33:32 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
gboolean depth_test_enabled;
|
|
|
|
CoglDepthTestFunction depth_test_function;
|
|
|
|
gboolean depth_writing_enabled;
|
|
|
|
float depth_range_near;
|
|
|
|
float depth_range_far;
|
|
|
|
} CoglMaterialDepthState;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
CoglMaterialLightingState lighting_state;
|
|
|
|
CoglMaterialAlphaFuncState alpha_state;
|
|
|
|
CoglMaterialBlendState blend_state;
|
2010-04-26 05:01:43 -04:00
|
|
|
CoglHandle user_program;
|
2010-05-26 06:33:32 -04:00
|
|
|
CoglMaterialDepthState depth_state;
|
2010-04-08 07:21:04 -04:00
|
|
|
} CoglMaterialBigState;
|
2009-11-17 19:26:09 -05:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_FLAG_DIRTY_LAYERS_CACHE = 1L<<0,
|
|
|
|
COGL_MATERIAL_FLAG_DIRTY_GET_LAYERS_LIST = 1L<<1
|
|
|
|
} CoglMaterialFlag;
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
CoglMaterial *owner;
|
|
|
|
CoglMaterialLayer *layer;
|
|
|
|
} CoglMaterialLayerCacheEntry;
|
|
|
|
|
|
|
|
struct _CoglMaterial
|
|
|
|
{
|
|
|
|
/* XXX: Please think twice about adding members that *have* be
|
|
|
|
* initialized during a cogl_material_copy. We are aiming to have
|
|
|
|
* copies be as cheap as possible and copies may be done by the
|
|
|
|
* primitives APIs which means they may happen in performance
|
|
|
|
* critical code paths.
|
|
|
|
*
|
|
|
|
* XXX: If you are extending the state we track please consider if
|
|
|
|
* the state is expected to vary frequently across many materials or
|
|
|
|
* if the state can be shared among many derived materials instead.
|
|
|
|
* This will determine if the state should be added directly to this
|
|
|
|
* structure which will increase the memory overhead for *all*
|
|
|
|
* materials or if instead it can go under ->big_state.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* the parent in terms of class hierarchy */
|
|
|
|
CoglHandleObject _parent;
|
|
|
|
|
|
|
|
/* We need to track if a material is referenced in the journal
|
|
|
|
* because we can't allow modification to these materials without
|
|
|
|
* flushing the journal first */
|
|
|
|
unsigned long journal_ref_count;
|
|
|
|
|
|
|
|
/* Materials are sparse structures defined as a diff against
|
|
|
|
* their parent. */
|
|
|
|
CoglMaterial *parent;
|
|
|
|
|
|
|
|
/* As an optimization for creating leaf node materials (the most
|
|
|
|
* common) we don't require any list node allocations to link
|
|
|
|
* to a single descendant.
|
|
|
|
*
|
|
|
|
* Only valid if ->has_children bitfield is set */
|
|
|
|
CoglMaterial *first_child;
|
|
|
|
|
|
|
|
/* Materials are sparse structures defined as a diff against
|
|
|
|
* their parent and may have multiple children which depend
|
|
|
|
* on them to define the values of properties which they don't
|
|
|
|
* change.
|
|
|
|
*
|
|
|
|
* Only valid if ->has_children bitfield is set */
|
|
|
|
GList *children;
|
|
|
|
|
|
|
|
/* A mask of which sparse state groups are different in this
|
|
|
|
* material in comparison to its parent. */
|
|
|
|
unsigned long differences;
|
|
|
|
|
2010-06-10 14:03:57 -04:00
|
|
|
/* The fragment processing backends can associate private data with a
|
|
|
|
* material. */
|
|
|
|
void *backend_privs[COGL_MATERIAL_N_BACKENDS];
|
2010-04-08 07:21:04 -04:00
|
|
|
|
2010-05-27 10:19:15 -04:00
|
|
|
/* Whenever a material is modified we increment the age. There's no
|
|
|
|
* guarantee that it won't wrap but it can nevertheless be a
|
|
|
|
* convenient mechanism to determine when a material has been
|
|
|
|
* changed to you can invalidate some some associated cache that
|
|
|
|
* depends on the old state. */
|
|
|
|
unsigned long age;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* This is the primary color of the material.
|
|
|
|
*
|
|
|
|
* This is a sparse property, ref COGL_MATERIAL_STATE_COLOR */
|
|
|
|
CoglColor color;
|
|
|
|
|
|
|
|
/* A material may be made up with multiple layers used to combine
|
|
|
|
* textures together.
|
|
|
|
*
|
|
|
|
* This is sparse state, ref COGL_MATERIAL_STATE_LAYERS */
|
|
|
|
GList *layer_differences;
|
|
|
|
unsigned int n_layers;
|
|
|
|
|
|
|
|
/* As a basic way to reduce memory usage we divide the material
|
|
|
|
* state into two groups; the minimal state modified in 90% of
|
|
|
|
* all materials and the rest, so that the second group can
|
|
|
|
* be allocated dynamically when required... */
|
|
|
|
CoglMaterialBigState *big_state;
|
|
|
|
|
2010-05-18 19:36:31 -04:00
|
|
|
/* For debugging purposes it's possible to associate a static const
|
|
|
|
* string with a material which can be an aid when trying to trace
|
|
|
|
* where the material originates from */
|
|
|
|
const char *static_breadcrumb;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Cached state... */
|
|
|
|
|
|
|
|
/* A cached, complete list of the layers this material depends
|
|
|
|
* on sorted by layer->unit_index. */
|
|
|
|
CoglMaterialLayer **layers_cache;
|
|
|
|
/* To avoid a separate ->layers_cache allocation for common
|
|
|
|
* materials with only a few layers... */
|
|
|
|
CoglMaterialLayer *short_layers_cache[3];
|
|
|
|
|
|
|
|
/* The deprecated cogl_material_get_layers() API returns a
|
|
|
|
* const GList of layers, which we track here... */
|
|
|
|
GList *deprecated_get_layers_list;
|
|
|
|
|
|
|
|
/* XXX: consider adding an authorities cache to speed up sparse
|
|
|
|
* property value lookups:
|
|
|
|
* CoglMaterial *authorities_cache[COGL_MATERIAL_N_SPARSE_PROPERTIES];
|
|
|
|
* and corresponding authorities_cache_dirty:1 bitfield
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* bitfields */
|
|
|
|
|
2010-06-10 14:03:57 -04:00
|
|
|
/* A material can have private data associated with it for multiple
|
|
|
|
* fragment processing backends. Although only one backend is
|
|
|
|
* associated with a material the backends may want to cache private
|
|
|
|
* state with the ancestors of other materials and those ancestors
|
|
|
|
* could currently be associated with different backends.
|
|
|
|
*
|
|
|
|
* Each set bit indicates if the correspondong ->backend_privs[]
|
|
|
|
* entry is valid.
|
|
|
|
*/
|
|
|
|
unsigned int backend_priv_set_mask:COGL_MATERIAL_N_BACKENDS;
|
|
|
|
|
2010-05-27 15:04:49 -04:00
|
|
|
/* Weak materials don't count as dependants on their parents which
|
|
|
|
* means that the parent material can be modified without
|
|
|
|
* considering how the modifications may affect the weak material.
|
|
|
|
*/
|
|
|
|
unsigned int is_weak:1;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* Determines if material->big_state is valid */
|
|
|
|
unsigned int has_big_state:1;
|
|
|
|
|
|
|
|
/* By default blending is enabled automatically depending on the
|
|
|
|
* unlit color, the lighting colors or the texture format. The user
|
|
|
|
* can override this to explicitly enable or disable blending.
|
|
|
|
*
|
|
|
|
* This is a sparse property */
|
|
|
|
unsigned int blend_enable:3;
|
|
|
|
|
|
|
|
/* There are many factors that can determine if we need to enable
|
|
|
|
* blending, this holds our final decision */
|
|
|
|
unsigned int real_blend_enable:1;
|
|
|
|
|
|
|
|
/* Determines if material->first_child and material->children are
|
|
|
|
* initialized pointers. */
|
|
|
|
unsigned int has_children:1;
|
|
|
|
|
|
|
|
unsigned int layers_cache_dirty:1;
|
|
|
|
unsigned int deprecated_get_layers_list_dirty:1;
|
|
|
|
|
2010-05-18 19:36:31 -04:00
|
|
|
/* For debugging purposes it's possible to associate a static const
|
|
|
|
* string with a material which can be an aid when trying to trace
|
|
|
|
* where the material originates from */
|
|
|
|
unsigned int has_static_breadcrumb:1;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* There are multiple fragment processing backends for CoglMaterial,
|
|
|
|
* glsl, arbfp and fixed. This identifies the backend being used for
|
|
|
|
* the material and any private state the backend has associated
|
|
|
|
* with the material. */
|
|
|
|
unsigned int backend:3;
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
};
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
typedef struct _CoglMaterialBackend
|
|
|
|
{
|
|
|
|
int (*get_max_texture_units) (void);
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
gboolean (*start) (CoglMaterial *material,
|
|
|
|
int n_layers,
|
|
|
|
unsigned long materials_difference);
|
|
|
|
gboolean (*add_layer) (CoglMaterial *material,
|
|
|
|
CoglMaterialLayer *layer,
|
|
|
|
unsigned long layers_difference);
|
2010-04-26 05:01:43 -04:00
|
|
|
gboolean (*passthrough) (CoglMaterial *material);
|
2010-04-08 07:21:04 -04:00
|
|
|
gboolean (*end) (CoglMaterial *material,
|
|
|
|
unsigned long materials_difference);
|
2010-04-26 05:01:43 -04:00
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
void (*material_pre_change_notify) (CoglMaterial *material,
|
|
|
|
CoglMaterialState change,
|
|
|
|
const CoglColor *new_color);
|
2010-06-10 14:03:57 -04:00
|
|
|
void (*material_set_parent_notify) (CoglMaterial *material);
|
2010-04-08 07:21:04 -04:00
|
|
|
void (*layer_pre_change_notify) (CoglMaterialLayer *layer,
|
|
|
|
CoglMaterialLayerState change);
|
2010-04-26 05:01:43 -04:00
|
|
|
|
|
|
|
void (*free_priv) (CoglMaterial *material);
|
2010-04-08 07:21:04 -04:00
|
|
|
void (*free_layer_priv) (CoglMaterialLayer *layer);
|
2010-04-26 05:01:43 -04:00
|
|
|
} CoglMaterialBackend;
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_PROGRAM_TYPE_GLSL = 1,
|
|
|
|
COGL_MATERIAL_PROGRAM_TYPE_ARBFP,
|
|
|
|
COGL_MATERIAL_PROGRAM_TYPE_FIXED
|
|
|
|
} CoglMaterialProgramType;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
void
|
|
|
|
_cogl_material_init_default_material (void);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_material_init_default_layers (void);
|
|
|
|
|
2009-05-23 12:42:10 -04:00
|
|
|
/*
|
|
|
|
* SECTION:cogl-material-internals
|
|
|
|
* @short_description: Functions for creating custom primitives that make use
|
2010-02-09 09:41:37 -05:00
|
|
|
* of Cogl materials for filling.
|
2009-05-23 12:42:10 -04:00
|
|
|
*
|
|
|
|
* Normally you shouldn't need to use this API directly, but if you need to
|
|
|
|
* developing a custom/specialised primitive - probably using raw OpenGL - then
|
|
|
|
* this API aims to expose enough of the material internals to support being
|
|
|
|
* able to fill your geometry according to a given Cogl material.
|
|
|
|
*/
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
gboolean
|
|
|
|
_cogl_material_get_real_blend_enabled (CoglHandle handle);
|
2009-05-23 12:42:10 -04:00
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
gboolean
|
|
|
|
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
|
2009-05-23 12:42:10 -04:00
|
|
|
|
2010-01-14 12:57:43 -05:00
|
|
|
/*
|
2010-06-09 12:39:59 -04:00
|
|
|
* Calls the pre_paint method on the layer texture if there is
|
|
|
|
* one. This will determine whether mipmaps are needed based on the
|
|
|
|
* filter settings.
|
2010-01-14 12:57:43 -05:00
|
|
|
*/
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
void
|
2010-06-09 12:39:59 -04:00
|
|
|
_cogl_material_layer_pre_paint (CoglHandle layer_handler);
|
2010-01-14 12:57:43 -05:00
|
|
|
|
2009-05-23 12:42:10 -04:00
|
|
|
/*
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
* CoglMaterialFlushFlag:
|
|
|
|
* @COGL_MATERIAL_FLUSH_FALLBACK_MASK: The fallback_layers member is set to
|
|
|
|
* a guint32 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: The disable_layers member is set to
|
|
|
|
* 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: The layer0_override_texture member is
|
|
|
|
* set to 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.
|
|
|
|
* @COGL_MATERIAL_FLUSH_SKIP_GL_COLOR: When flushing the GL state for the
|
|
|
|
* material don't call glColor.
|
2010-04-01 06:31:33 -04:00
|
|
|
* @COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES: Specifies that a bitmask
|
|
|
|
* of overrides for the wrap modes for some or all layers is
|
|
|
|
* given.
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
*/
|
|
|
|
typedef enum _CoglMaterialFlushFlag
|
|
|
|
{
|
2010-04-01 06:31:33 -04:00
|
|
|
COGL_MATERIAL_FLUSH_FALLBACK_MASK = 1L<<0,
|
|
|
|
COGL_MATERIAL_FLUSH_DISABLE_MASK = 1L<<1,
|
|
|
|
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE = 1L<<2,
|
|
|
|
COGL_MATERIAL_FLUSH_SKIP_GL_COLOR = 1L<<3,
|
|
|
|
COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES = 1L<<4
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
} CoglMaterialFlushFlag;
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
/* This isn't defined in the GLES headers */
|
|
|
|
#ifndef GL_CLAMP_TO_BORDER
|
|
|
|
#define GL_CLAMP_TO_BORDER 0x812d
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* GL_ALWAYS is just used here as a value that is known not to clash
|
|
|
|
* with any valid GL wrap modes.
|
|
|
|
*
|
|
|
|
* XXX: keep the values in sync with the CoglMaterialWrapMode enum
|
|
|
|
* so no conversion is actually needed.
|
|
|
|
*/
|
|
|
|
typedef enum _CoglMaterialWrapModeInternal
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT = GL_REPEAT,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE = GL_CLAMP_TO_EDGE,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER = GL_CLAMP_TO_BORDER,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_AUTOMATIC = GL_ALWAYS
|
|
|
|
} CoglMaterialWrapModeInternal;
|
|
|
|
|
|
|
|
typedef enum _CoglMaterialWrapModeOverride
|
|
|
|
{
|
|
|
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_NONE = 0,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT =
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_REPEAT,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE =
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_EDGE,
|
|
|
|
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER =
|
|
|
|
COGL_MATERIAL_WRAP_MODE_INTERNAL_CLAMP_TO_BORDER,
|
|
|
|
} CoglMaterialWrapModeOverride;
|
2010-04-01 06:31:33 -04:00
|
|
|
|
|
|
|
/* There can't be more than 32 layers because we need to fit a bitmask
|
|
|
|
of the layers into a guint32 */
|
|
|
|
#define COGL_MATERIAL_MAX_LAYERS 32
|
|
|
|
|
|
|
|
typedef struct _CoglMaterialWrapModeOverrides
|
|
|
|
{
|
|
|
|
struct
|
|
|
|
{
|
2010-04-08 07:21:04 -04:00
|
|
|
CoglMaterialWrapModeOverride s;
|
|
|
|
CoglMaterialWrapModeOverride t;
|
|
|
|
CoglMaterialWrapModeOverride r;
|
2010-04-01 06:31:33 -04:00
|
|
|
} values[COGL_MATERIAL_MAX_LAYERS];
|
|
|
|
} CoglMaterialWrapModeOverrides;
|
|
|
|
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
/*
|
|
|
|
* CoglMaterialFlushOptions:
|
|
|
|
*
|
2009-05-23 12:42:10 -04:00
|
|
|
*/
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
typedef struct _CoglMaterialFlushOptions
|
2009-05-23 12:42:10 -04:00
|
|
|
{
|
2010-04-01 06:31:33 -04:00
|
|
|
CoglMaterialFlushFlag flags;
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
|
2010-04-01 06:31:33 -04:00
|
|
|
guint32 fallback_layers;
|
|
|
|
guint32 disable_layers;
|
|
|
|
GLuint layer0_override_texture;
|
|
|
|
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
} CoglMaterialFlushOptions;
|
2009-05-23 12:42:10 -04:00
|
|
|
|
2010-06-15 11:44:52 -04:00
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_set_active_texture_unit (int unit_index);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_delete_gl_texture (GLuint gl_texture);
|
|
|
|
|
|
|
|
int
|
|
|
|
_cogl_get_max_texture_image_units (void);
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_use_program (CoglHandle program_handle, CoglMaterialProgramType type);
|
|
|
|
|
|
|
|
unsigned int
|
|
|
|
_cogl_get_n_args_for_combine_func (GLint func);
|
|
|
|
|
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
void
|
|
|
|
_cogl_material_get_colorubv (CoglHandle handle,
|
|
|
|
guint8 *color);
|
2009-06-04 09:23:16 -04:00
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
void
|
|
|
|
_cogl_material_flush_gl_state (CoglHandle material,
|
2010-05-18 17:42:49 -04:00
|
|
|
gboolean skip_gl_state);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
gboolean
|
|
|
|
_cogl_material_equal (CoglHandle material0_handle,
|
|
|
|
CoglHandle material1_handle,
|
2010-04-08 07:21:04 -04:00
|
|
|
gboolean skip_gl_color);
|
[cogl] Improving Cogl journal to minimize driver overheads + GPU state changes
Previously the journal was always flushed at the end of
_cogl_rectangles_with_multitexture_coords, (i.e. the end of any
cogl_rectangle* calls) but now we have broadened the potential for batching
geometry. In ideal circumstances we will only flush once per scene.
In summary the journal works like this:
When you use any of the cogl_rectangle* APIs then nothing is emitted to the
GPU at this point, we just log one or more quads into the journal. A
journal entry consists of the quad coordinates, an associated material
reference, and a modelview matrix. Ideally the journal only gets flushed
once at the end of a scene, but in fact there are things to consider that
may cause unwanted flushing, including:
- modifying materials mid-scene
This is because each quad in the journal has an associated material
reference (i.e. not copy), so if you try and modify a material that is
already referenced in the journal we force a flush first)
NOTE: For now this means you should avoid using cogl_set_source_color()
since that currently uses a single shared material. Later we
should change it to use a pool of materials that is recycled
when the journal is flushed.
- modifying any state that isn't currently logged, such as depth, fog and
backface culling enables.
The first thing that happens when flushing, is to upload all the vertex data
associated with the journal into a single VBO.
We then go through a process of splitting up the journal into batches that
have compatible state so they can be emitted to the GPU together. This is
currently broken up into 3 levels so we can stagger the state changes:
1) we break the journal up according to changes in the number of material layers
associated with logged quads. The number of layers in a material determines
the stride of the associated vertices, so we have to update our vertex
array offsets at this level. (i.e. calling gl{Vertex,Color},Pointer etc)
2) we further split batches up according to material compatability. (e.g.
materials with different textures) We flush material state at this level.
3) Finally we split batches up according to modelview changes. At this level
we update the modelview matrix and actually emit the actual draw command.
This commit is largely about putting the initial design in-place; this will be
followed by other changes that take advantage of the extended batching.
2009-06-17 13:46:42 -04:00
|
|
|
|
cogl: improves header and coding style consistency
We've had complaints that our Cogl code/headers are a bit "special" so
this is a first pass at tidying things up by giving them some
consistency. These changes are all consistent with how new code in Cogl
is being written, but the style isn't consistently applied across all
code yet.
There are two parts to this patch; but since each one required a large
amount of effort to maintain tidy indenting it made sense to combine the
changes to reduce the time spent re indenting the same lines.
The first change is to use a consistent style for declaring function
prototypes in headers. Cogl headers now consistently use this style for
prototypes:
return_type
cogl_function_name (CoglType arg0,
CoglType arg1);
Not everyone likes this style, but it seems that most of the currently
active Cogl developers agree on it.
The second change is to constrain the use of redundant glib data types
in Cogl. Uses of gint, guint, gfloat, glong, gulong and gchar have all
been replaced with int, unsigned int, float, long, unsigned long and char
respectively. When talking about pixel data; use of guchar has been
replaced with guint8, otherwise unsigned char can be used.
The glib types that we continue to use for portability are gboolean,
gint{8,16,32,64}, guint{8,16,32,64} and gsize.
The general intention is that Cogl should look palatable to the widest
range of C programmers including those outside the Gnome community so
- especially for the public API - we want to minimize the number of
foreign looking typedefs.
2010-02-09 20:57:32 -05:00
|
|
|
CoglHandle
|
|
|
|
_cogl_material_journal_ref (CoglHandle material_handle);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_material_journal_unref (CoglHandle material_handle);
|
2009-05-23 12:42:10 -04:00
|
|
|
|
2010-04-01 06:31:33 -04:00
|
|
|
/* TODO: These should be made public once we add support for 3D
|
|
|
|
textures in Cogl */
|
|
|
|
void
|
|
|
|
_cogl_material_set_layer_wrap_mode_r (CoglHandle material,
|
|
|
|
int layer_index,
|
|
|
|
CoglMaterialWrapMode mode);
|
|
|
|
|
|
|
|
CoglMaterialWrapMode
|
|
|
|
_cogl_material_layer_get_wrap_mode_r (CoglHandle layer);
|
2009-05-23 12:42:10 -04:00
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
void
|
|
|
|
_cogl_material_set_user_program (CoglHandle handle,
|
|
|
|
CoglHandle program);
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
void
|
|
|
|
_cogl_material_texture_storage_change_notify (CoglHandle texture);
|
|
|
|
|
2010-04-26 05:01:43 -04:00
|
|
|
void
|
|
|
|
_cogl_material_apply_legacy_state (CoglHandle handle);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_gl_use_program_wrapper (GLuint program);
|
|
|
|
|
2010-05-18 17:42:49 -04:00
|
|
|
void
|
|
|
|
_cogl_material_apply_overrides (CoglMaterial *material,
|
|
|
|
CoglMaterialFlushOptions *options);
|
|
|
|
|
2010-04-08 07:21:04 -04:00
|
|
|
CoglMaterialBlendEnable
|
|
|
|
_cogl_material_get_blend_enabled (CoglHandle handle);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_material_set_blend_enabled (CoglHandle handle,
|
|
|
|
CoglMaterialBlendEnable enable);
|
|
|
|
|
2010-05-18 19:36:31 -04:00
|
|
|
void
|
|
|
|
_cogl_material_set_static_breadcrumb (CoglHandle handle,
|
|
|
|
const char *breadcrumb);
|
|
|
|
|
2010-05-27 10:19:15 -04:00
|
|
|
unsigned long
|
|
|
|
_cogl_material_get_age (CoglHandle handle);
|
|
|
|
|
2010-06-15 11:44:52 -04:00
|
|
|
CoglMaterial *
|
|
|
|
_cogl_material_get_authority (CoglMaterial *material,
|
|
|
|
unsigned long difference);
|
|
|
|
|
|
|
|
typedef gboolean (*CoglMaterialChildCallback) (CoglMaterial *child,
|
|
|
|
void *user_data);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_material_foreach_child (CoglMaterial *material,
|
|
|
|
CoglMaterialChildCallback callback,
|
|
|
|
void *user_data);
|
|
|
|
|
|
|
|
unsigned long
|
|
|
|
_cogl_material_layer_compare_differences (CoglMaterialLayer *layer0,
|
|
|
|
CoglMaterialLayer *layer1);
|
|
|
|
|
|
|
|
CoglMaterialLayer *
|
|
|
|
_cogl_material_layer_get_authority (CoglMaterialLayer *layer,
|
|
|
|
unsigned long difference);
|
|
|
|
|
|
|
|
CoglHandle
|
|
|
|
_cogl_material_layer_get_texture (CoglMaterialLayer *layer);
|
|
|
|
|
|
|
|
typedef gboolean (*CoglMaterialLayerCallback) (CoglMaterialLayer *layer,
|
|
|
|
void *user_data);
|
|
|
|
|
|
|
|
void
|
|
|
|
_cogl_material_foreach_layer (CoglMaterial *material,
|
|
|
|
CoglMaterialLayerCallback callback,
|
|
|
|
void *user_data);
|
|
|
|
|
|
|
|
int
|
|
|
|
_cogl_material_layer_get_unit_index (CoglMaterialLayer *layer);
|
|
|
|
|
Adds a CoglMaterial abstraction, which includes support for multi-texturing
My previous work to provide muti-texturing support has been extended into
a CoglMaterial abstraction that adds control over the texture combine
functions (controlling how multiple texture layers are blended together),
the gl blend function (used for blending the final primitive with the
framebuffer), the alpha function (used to discard fragments based on
their alpha channel), describing attributes such as a diffuse, ambient and
specular color (for use with the standard OpenGL lighting model), and
per layer rotations. (utilizing the new CoglMatrix utility API)
For now the only way this abstraction is exposed is via a new
cogl_material_rectangle function, that is similar to cogl_texture_rectangle
but doesn't take a texture handle (the source material is pulled from
the context), and the array of texture coordinates is extended to be able
to supply coordinates for each layer.
Note: this function doesn't support sliced textures; supporting sliced
textures is a non trivial problem, considering the ability to rotate layers.
Note: cogl_material_rectangle, has quite a few workarounds, for a number of
other limitations within Cogl a.t.m.
Note: The GLES1/2 multi-texturing support has yet to be updated to use
the material abstraction.
2008-12-11 15:11:30 -05:00
|
|
|
#endif /* __COGL_MATERIAL_PRIVATE_H */
|
|
|
|
|