mutter/cogl/cogl-material-private.h

479 lines
16 KiB
C
Raw Normal View History

/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2008,2009 Intel Corporation.
*
* 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
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*
*
* Authors:
* Robert Bragg <robert@linux.intel.com>
*/
#ifndef __COGL_MATERIAL_PRIVATE_H
#define __COGL_MATERIAL_PRIVATE_H
#include "cogl-material.h"
#include "cogl-matrix.h"
#include "cogl-matrix-stack.h"
#include "cogl-handle.h"
#include <glib.h>
typedef struct _CoglMaterial CoglMaterial;
typedef struct _CoglMaterialLayer CoglMaterialLayer;
/*
* 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;
/* The GL target currently glEnabled or 0 if .enabled == FALSE */
GLenum enabled_gl_target;
/* 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;
/* 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
* when all that's needed is to re-bind the layers gl_texture we use this
* to track when the .layer_gl_texture state is invalid.
*
* XXX: as a further optimization cogl-material.c uses a convention
* of always leaving texture unit 1 active when not dealing with the
* flushing of layer state, so we can assume this is only ever TRUE
* for unit 1.
*/
gboolean dirty_gl_texture;
/* 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
*/
unsigned long layer_differences;
/* The options that may have affected how the layer state updated
* this texture unit. */
gboolean fallback;
gboolean layer0_overridden;
/* When flushing a layers state, fallback options may mean that a
* different CoglTexture is used than layer->texture.
*
* Once a layers state has been flushed we have to keep track of
* changes to that layer so if we are asked to re-flush the same
* layer later we will know what work is required. This also means
* we need to keep track of changes to the CoglTexture of that layer
* so we need to explicitly keep a reference to the final texture
* chosen.
*/
CoglHandle texture;
} CoglTextureUnit;
CoglTextureUnit *
_cogl_get_texture_unit (int index_);
void
_cogl_destroy_texture_units (void);
void
_cogl_bind_gl_texture_transient (GLenum gl_target,
GLuint gl_texture,
gboolean is_foreign);
[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 17:46:42 +00:00
typedef enum _CoglMaterialEqualFlags
{
/* Return FALSE if any component of either material isn't set to its
* default value. (Note: if the materials have corresponding flush
* options indicating that e.g. the material color won't be flushed then
* this will not assert a default color value.) */
COGL_MATERIAL_EQUAL_FLAGS_ASSERT_ALL_DEFAULTS = 1L<<0,
} CoglMaterialEqualFlags;
typedef enum _CoglMaterialLayerDifferenceFlags
{
COGL_MATERIAL_LAYER_DIFFERENCE_TEXTURE = 1L<<0,
COGL_MATERIAL_LAYER_DIFFERENCE_COMBINE = 1L<<1,
COGL_MATERIAL_LAYER_DIFFERENCE_COMBINE_CONSTANT = 1L<<2,
COGL_MATERIAL_LAYER_DIFFERENCE_USER_MATRIX = 1L<<3,
COGL_MATERIAL_LAYER_DIFFERENCE_FILTERS = 1L<<4
} CoglMaterialLayerDifferenceFlags;
typedef enum _CoglMaterialLayerChangeFlags
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 16:15:40 +00:00
{
COGL_MATERIAL_LAYER_CHANGE_TEXTURE = 1L<<0,
COGL_MATERIAL_LAYER_CHANGE_COMBINE = 1L<<1,
COGL_MATERIAL_LAYER_CHANGE_COMBINE_CONSTANT = 1L<<2,
COGL_MATERIAL_LAYER_CHANGE_USER_MATRIX = 1L<<3,
COGL_MATERIAL_LAYER_CHANGE_FILTERS = 1L<<4,
COGL_MATERIAL_LAYER_CHANGE_TEXTURE_INTERN = 1L<<5,
COGL_MATERIAL_LAYER_CHANGE_UNIT = 1L<<6
} CoglMaterialLayerChangeFlags;
struct _CoglMaterialLayer
{
CoglHandleObject _parent;
/* Parent material */
CoglMaterial *material;
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-10 01:57:32 +00:00
unsigned int index; /*!< lowest index is blended first then others on
top */
int unit_index;
unsigned long differences;
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-10 01:57:32 +00:00
CoglHandle texture; /*!< The texture for this layer, or
COGL_INVALID_HANDLE for an empty layer */
[cogl] Move the texture filters to be a property of the material layer The texture filters are now a property of the material layer rather than the texture object. Whenever a texture is painted with a material it sets the filters on all of the GL textures in the Cogl texture. The filter is cached so that it won't be changed unnecessarily. The automatic mipmap generation has changed so that the mipmaps are only generated when the texture is painted instead of every time the data changes. Changing the texture sets a flag to mark that the mipmaps are dirty. This works better if the FBO extension is available because we can use glGenerateMipmap. If the extension is not available it will temporarily enable automatic mipmap generation and reupload the first pixel of each slice. This requires tracking the data for the first pixel. The COGL_TEXTURE_AUTO_MIPMAP flag has been replaced with COGL_TEXTURE_NO_AUTO_MIPMAP so that it will default to auto-mipmapping. The mipmap generation is now effectively free if you are not using a mipmap filter mode so you would only want to disable it if you had some special reason to generate your own mipmaps. ClutterTexture no longer has to store its own copy of the filter mode. Instead it stores it in the material and the property is directly set and read from that. This fixes problems with the filters getting out of sync when a cogl handle is set on the texture directly. It also avoids the mess of having to rerealize the texture if the filter quality changes to HIGH because Cogl will take of generating the mipmaps if needed.
2009-06-04 15:04:57 +00:00
CoglMaterialFilter mag_filter;
CoglMaterialFilter min_filter;
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00:00
CoglMaterialWrapMode wrap_mode_s;
CoglMaterialWrapMode wrap_mode_t;
CoglMaterialWrapMode wrap_mode_r;
/* 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];
GLint texture_combine_alpha_func;
GLint texture_combine_alpha_src[3];
GLint texture_combine_alpha_op[3];
GLfloat texture_combine_constant[4];
/* TODO: Support purely GLSL based material layers */
CoglMatrix matrix;
/* Different material backends (GLSL/ARBfp/Fixed Function) may
* want to associate private data with a layer... */
void *backend_priv;
};
typedef enum _CoglMaterialFlags
{
[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 17:46:42 +00:00
COGL_MATERIAL_FLAG_DEFAULT_COLOR = 1L<<1,
COGL_MATERIAL_FLAG_DEFAULT_GL_MATERIAL = 1L<<2,
COGL_MATERIAL_FLAG_DEFAULT_ALPHA_FUNC = 1L<<3,
COGL_MATERIAL_FLAG_ENABLE_BLEND = 1L<<4,
COGL_MATERIAL_FLAG_DEFAULT_BLEND = 1L<<5,
COGL_MATERIAL_FLAG_DEFAULT_USER_SHADER = 1L<<6,
COGL_MATERIAL_FLAG_DEFAULT_LAYERS = 1L<<7
} CoglMaterialFlags;
/* This defines the initialization state for
* ctx->current_material_flags which should result in the first
* material flush explicitly initializing everything
*/
#define COGL_MATERIAL_FLAGS_INIT \
COGL_MATERIAL_FLAG_DEFAULT_USER_SHADER
typedef enum _CoglMaterialChangeFlag
{
COGL_MATERIAL_CHANGE_COLOR = 1L<<1,
COGL_MATERIAL_CHANGE_GL_MATERIAL = 1L<<2,
COGL_MATERIAL_CHANGE_ALPHA_FUNC = 1L<<3,
COGL_MATERIAL_CHANGE_ENABLE_BLEND = 1L<<4,
COGL_MATERIAL_CHANGE_BLEND = 1L<<5,
COGL_MATERIAL_CHANGE_USER_SHADER = 1L<<6,
COGL_MATERIAL_CHANGE_LAYERS = 1L<<7
} CoglMaterialChangeFlag;
struct _CoglMaterial
{
CoglHandleObject _parent;
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-10 01:57:32 +00:00
unsigned long journal_ref_count;
int backend;
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-10 01:57:32 +00:00
unsigned long flags;
/* If no lighting is enabled; this is the basic material color */
GLubyte unlit[4];
/* Standard OpenGL lighting model attributes */
GLfloat ambient[4];
GLfloat diffuse[4];
GLfloat specular[4];
GLfloat emission[4];
GLfloat shininess;
/* Determines what fragments are discarded based on their alpha */
CoglMaterialAlphaFunc alpha_func;
GLfloat alpha_func_reference;
/* Determines how this material is blended with other primitives */
#ifndef HAVE_COGL_GLES
GLenum blend_equation_rgb;
GLenum blend_equation_alpha;
GLint blend_src_factor_alpha;
GLint blend_dst_factor_alpha;
GLfloat blend_constant[4];
#endif
GLint blend_src_factor_rgb;
GLint blend_dst_factor_rgb;
CoglHandle user_program;
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-10 01:57:32 +00:00
GList *layers;
unsigned int n_layers;
void *backend_priv;
};
typedef struct _CoglMaterialBackend
{
int (*get_max_texture_units) (void);
gboolean (*start) (CoglMaterial *material);
gboolean (*add_layer) (CoglMaterialLayer *layer);
gboolean (*passthrough) (CoglMaterial *material);
gboolean (*end) (CoglMaterial *material);
void (*material_change_notify) (CoglMaterial *material,
unsigned long changes,
GLubyte *new_color);
void (*layer_change_notify) (CoglMaterialLayer *layer,
unsigned long changes);
void (*free_priv) (CoglMaterial *material);
} CoglMaterialBackend;
typedef enum
{
COGL_MATERIAL_PROGRAM_TYPE_GLSL = 1,
COGL_MATERIAL_PROGRAM_TYPE_ARBFP,
COGL_MATERIAL_PROGRAM_TYPE_FIXED
} CoglMaterialProgramType;
/*
* SECTION:cogl-material-internals
* @short_description: Functions for creating custom primitives that make use
* of Cogl materials for filling.
*
* 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.
*/
/*
* _cogl_material_init_default_material:
*
* This initializes the first material owned by the Cogl context. All
* subsequently instantiated materials created via the cogl_material_new()
* API will initially be a copy of this material.
*/
void
_cogl_material_init_default_material (void);
/*
* cogl_material_get_cogl_enable_flags:
* @material: A CoglMaterial object
*
* This determines what flags need to be passed to cogl_enable before this
* material can be used. Normally you shouldn't need to use this function
* directly since Cogl will do this internally, but if you are developing
* custom primitives directly with OpenGL you may want to use this.
*
* Note: This API is hopfully just a stop-gap solution. Ideally cogl_enable
* will be replaced.
*/
/* TODO: find a nicer solution! */
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-10 01:57:32 +00:00
unsigned long
_cogl_material_get_cogl_enable_flags (CoglHandle handle);
gboolean
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
/*
* Ensures the mipmaps are available for the texture in the layer if
* the filter settings would require it
*/
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-10 01:57:32 +00:00
void
_cogl_material_layer_ensure_mipmaps (CoglHandle layer_handler);
/*
[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 17:46:42 +00: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.
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00: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 17:46:42 +00:00
*/
typedef enum _CoglMaterialFlushFlag
{
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00: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 17:46:42 +00:00
} CoglMaterialFlushFlag;
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00:00
/* These constants are used to fill in wrap_mode_overrides */
#define COGL_MATERIAL_WRAP_MODE_OVERRIDE_NONE 0 /* no override */
#define COGL_MATERIAL_WRAP_MODE_OVERRIDE_REPEAT 1
#define COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_EDGE 2
#define COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER 3
/* 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
{
unsigned long s : 2;
unsigned long t : 2;
unsigned long r : 2;
} 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 17:46:42 +00:00
/*
* CoglMaterialFlushOptions:
*
*/
[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 17:46:42 +00:00
typedef struct _CoglMaterialFlushOptions
{
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00: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 17:46:42 +00:00
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00: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 17:46:42 +00:00
} CoglMaterialFlushOptions;
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-10 01:57:32 +00:00
void
_cogl_material_get_colorubv (CoglHandle handle,
guint8 *color);
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-10 01:57:32 +00:00
void
_cogl_material_flush_gl_state (CoglHandle material,
CoglMaterialFlushOptions *options);
[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 17:46:42 +00: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-10 01:57:32 +00:00
gboolean
_cogl_material_equal (CoglHandle material0_handle,
CoglMaterialFlushOptions *material0_flush_options,
CoglHandle material1_handle,
CoglMaterialFlushOptions *material1_flush_options);
[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 17:46:42 +00: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-10 01:57:32 +00:00
CoglHandle
_cogl_material_journal_ref (CoglHandle material_handle);
void
_cogl_material_journal_unref (CoglHandle material_handle);
cogl-material: Add support for setting the wrap mode for a layer Previously, Cogl's texture coordinate system was effectively always GL_REPEAT so that if an application specifies coordinates outside the range 0→1 it would get repeated copies of the texture. It would however change the mode to GL_CLAMP_TO_EDGE if all of the coordinates are in the range 0→1 so that in the common case that the whole texture is being drawn with linear filtering it will not blend in edge pixels from the opposite sides. This patch adds the option for applications to change the wrap mode per layer. There are now three wrap modes: 'repeat', 'clamp-to-edge' and 'automatic'. The automatic map mode is the default and it implements the previous behaviour. The wrap mode can be changed for the s and t coordinates independently. I've tried to make the internals support setting the r coordinate but as we don't support 3D textures yet I haven't exposed any public API for it. The texture backends still have a set_wrap_mode virtual but this value is intended to be transitory and it will be changed whenever the material is flushed (although the backends are expected to cache it so that it won't use too many GL calls). In my understanding this value was always meant to be transitory and all primitives were meant to set the value before drawing. However there were comments suggesting that this is not the expected behaviour. In particular the vertex buffer drawing code never set a wrap mode so it would end up with whatever the texture was previously used for. These issues are now fixed because the material will always set the wrap modes. There is code to manually implement clamp-to-edge for textures that can't be hardware repeated. However this doesn't fully work because it relies on being able to draw the stretched parts using quads with the same values for tx1 and tx2. The texture iteration code doesn't support this so it breaks. This is a separate bug and it isn't trivially solved. When flushing a material there are now extra options to set wrap mode overrides. The overrides are an array of values for each layer that specifies an override for the s, t or r coordinates. The primitives use this to implement the automatic wrap mode. cogl_polygon also uses it to set GL_CLAMP_TO_BORDER mode for its trick to render sliced textures. Although this code has been added it looks like the sliced trick has been broken for a while and I haven't attempted to fix it here. I've added a constant to represent the maximum number of layers that a material supports so that I can size the overrides array. I've set it to 32 because as far as I can tell we have that limit imposed anyway because the other flush options use a guint32 to store a flag about each layer. The overrides array ends up adding 32 bytes to each flush options struct which may be a concern. http://bugzilla.openedhand.com/show_bug.cgi?id=2063
2010-04-01 10:31:33 +00: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);
void
_cogl_material_set_user_program (CoglHandle handle,
CoglHandle program);
void
_cogl_delete_gl_texture (GLuint gl_texture);
void
_cogl_material_apply_legacy_state (CoglHandle handle);
void
_cogl_gl_use_program_wrapper (GLuint program);
#endif /* __COGL_MATERIAL_PRIVATE_H */