material: Adds backend abstraction for fragment processing
As part of an effort to improve the architecture of CoglMaterial internally this overhauls how we flush layer state to OpenGL by adding a formal backend abstraction for fragment processing and further formalizing the CoglTextureUnit abstraction. There are three backends: "glsl", "arbfp" and "fixed". The fixed backend uses the OpenGL fixed function APIs to setup the fragment processing, the arbfp backend uses code generation to handle fragment processing using an ARBfp program, and the GLSL backend is currently only there as a formality to handle user programs associated with a material. (i.e. the glsl backend doesn't yet support code generation) The GLSL backend has highest precedence, then arbfp and finally the fixed. If a backend can't support some particular CoglMaterial feature then it will fallback to the next backend. This adds three new COGL_DEBUG options: * "disable-texturing" as expected should disable all texturing * "disable-arbfp" always make the arbfp backend fallback * "disable-glsl" always make the glsl backend fallback * "show-source" show code generated by the arbfp/glsl backends
This commit is contained in:
parent
8ebf76a9a9
commit
acc44161c1
@ -58,8 +58,6 @@
|
||||
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
|
||||
#define glMapBuffer ctx->drv.pf_glMapBuffer
|
||||
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
|
||||
#define glActiveTexture ctx->drv.pf_glActiveTexture
|
||||
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
|
||||
#ifndef GL_ARRAY_BUFFER
|
||||
#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
|
||||
#endif
|
||||
|
@ -70,6 +70,7 @@ cogl_create_context (void)
|
||||
|
||||
_context->enable_flags = 0;
|
||||
_context->color_alpha = 0;
|
||||
_context->fog_enabled = FALSE;
|
||||
|
||||
_context->enable_backface_culling = FALSE;
|
||||
_context->flushed_front_winding = COGL_FRONT_WINDING_COUNTER_CLOCKWISE;
|
||||
@ -81,10 +82,20 @@ cogl_create_context (void)
|
||||
cogl_matrix_scale (&_context->y_flip_matrix, 1, -1, 1);
|
||||
|
||||
_context->flushed_matrix_mode = COGL_MATRIX_MODELVIEW;
|
||||
_context->texture_units = NULL;
|
||||
|
||||
_context->texture_units =
|
||||
g_array_new (FALSE, FALSE, sizeof (CoglTextureUnit));
|
||||
|
||||
/* See cogl-material.c for more details about why we leave texture unit 1
|
||||
* active by default... */
|
||||
_context->active_texture_unit = 1;
|
||||
GE (glActiveTexture (GL_TEXTURE1));
|
||||
|
||||
_context->simple_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
_context->arbfp_source_buffer = g_string_new ("");
|
||||
|
||||
_context->legacy_state_set = 0;
|
||||
|
||||
_context->default_gl_texture_2d_tex = COGL_INVALID_HANDLE;
|
||||
_context->default_gl_texture_rect_tex = COGL_INVALID_HANDLE;
|
||||
@ -93,15 +104,25 @@ cogl_create_context (void)
|
||||
_context->logged_vertices = g_array_new (FALSE, FALSE, sizeof (GLfloat));
|
||||
|
||||
_context->current_material = NULL;
|
||||
_context->current_material_flags = 0;
|
||||
memset (&_context->current_material_flush_options,
|
||||
0, sizeof (CoglMaterialFlushOptions));
|
||||
_context->current_layers = g_array_new (FALSE, FALSE,
|
||||
sizeof (CoglLayerInfo));
|
||||
_context->current_material_flags = COGL_MATERIAL_FLAGS_INIT;
|
||||
_context->current_material_fallback_layers = 0;
|
||||
_context->current_material_disable_layers = 0;
|
||||
_context->current_material_layer0_override = 0;
|
||||
_context->current_material_skip_gl_color = FALSE;
|
||||
|
||||
_cogl_bitmask_init (&_context->texcoord_arrays_enabled);
|
||||
_cogl_bitmask_init (&_context->temp_bitmask);
|
||||
_cogl_bitmask_init (&_context->texcoord_arrays_to_disable);
|
||||
|
||||
_context->max_texture_units = -1;
|
||||
_context->max_texture_image_units = -1;
|
||||
_context->max_activateable_texture_units = -1;
|
||||
|
||||
_context->current_program = COGL_INVALID_HANDLE;
|
||||
|
||||
_context->current_use_program_type = COGL_MATERIAL_PROGRAM_TYPE_FIXED;
|
||||
_context->current_gl_program = 0;
|
||||
|
||||
_context->framebuffer_stack = _cogl_create_framebuffer_stack ();
|
||||
|
||||
window_buffer = _cogl_onscreen_new ();
|
||||
@ -162,8 +183,6 @@ cogl_create_context (void)
|
||||
|
||||
_context->current_pbo = NULL;
|
||||
|
||||
_context->max_texture_units = -1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -194,9 +213,6 @@ _cogl_destroy_context (void)
|
||||
if (_context->logged_vertices)
|
||||
g_array_free (_context->logged_vertices, TRUE);
|
||||
|
||||
if (_context->current_layers)
|
||||
g_array_free (_context->current_layers, TRUE);
|
||||
|
||||
if (_context->quad_indices_byte)
|
||||
cogl_handle_unref (_context->quad_indices_byte);
|
||||
if (_context->quad_indices_short)
|
||||
|
@ -53,6 +53,7 @@ typedef struct
|
||||
/* Enable cache */
|
||||
unsigned long enable_flags;
|
||||
guint8 color_alpha;
|
||||
gboolean fog_enabled;
|
||||
|
||||
gboolean enable_backface_culling;
|
||||
CoglFrontWinding flushed_front_winding;
|
||||
@ -65,11 +66,16 @@ typedef struct
|
||||
|
||||
/* Client-side matrix stack or NULL if none */
|
||||
CoglMatrixMode flushed_matrix_mode;
|
||||
GList *texture_units;
|
||||
|
||||
GArray *texture_units;
|
||||
int active_texture_unit;
|
||||
|
||||
/* Materials */
|
||||
CoglHandle simple_material;
|
||||
CoglHandle source_material;
|
||||
GString *arbfp_source_buffer;
|
||||
|
||||
int legacy_state_set;
|
||||
|
||||
/* Textures */
|
||||
CoglHandle default_gl_texture_2d_tex;
|
||||
@ -86,8 +92,10 @@ typedef struct
|
||||
/* Some simple caching, to minimize state changes... */
|
||||
CoglHandle current_material;
|
||||
unsigned long current_material_flags;
|
||||
CoglMaterialFlushOptions current_material_flush_options;
|
||||
GArray *current_layers;
|
||||
gboolean current_material_fallback_layers;
|
||||
gboolean current_material_disable_layers;
|
||||
GLuint current_material_layer0_override;
|
||||
gboolean current_material_skip_gl_color;
|
||||
/* Bitmask of texture coordinates arrays that are enabled */
|
||||
CoglBitmask texcoord_arrays_enabled;
|
||||
/* These are temporary bitmasks that are used when disabling
|
||||
@ -129,9 +137,15 @@ typedef struct
|
||||
chances of getting the same colour during an animation */
|
||||
guint8 journal_rectangles_color;
|
||||
|
||||
/* Cached value for GL_MAX_TEXTURE_UNITS to avoid calling
|
||||
/* Cached values for GL_MAX_TEXTURE_[IMAGE_]UNITS to avoid calling
|
||||
glGetInteger too often */
|
||||
GLint max_texture_units;
|
||||
GLint max_texture_image_units;
|
||||
GLint max_activateable_texture_units;
|
||||
|
||||
CoglHandle current_program;
|
||||
CoglMaterialProgramType current_use_program_type;
|
||||
GLuint current_gl_program;
|
||||
|
||||
CoglContextDriver drv;
|
||||
} CoglContext;
|
||||
|
@ -50,6 +50,7 @@ static const GDebugKey cogl_log_debug_keys[] = {
|
||||
{ "draw", COGL_DEBUG_DRAW },
|
||||
{ "opengl", COGL_DEBUG_OPENGL },
|
||||
{ "pango", COGL_DEBUG_PANGO },
|
||||
{ "show-source", COGL_DEBUG_SHOW_SOURCE}
|
||||
};
|
||||
static const int n_cogl_log_debug_keys =
|
||||
G_N_ELEMENTS (cogl_log_debug_keys);
|
||||
@ -61,7 +62,10 @@ static const GDebugKey cogl_behavioural_debug_keys[] = {
|
||||
{ "disable-software-transform", COGL_DEBUG_DISABLE_SOFTWARE_TRANSFORM },
|
||||
{ "force-scanline-paths", COGL_DEBUG_FORCE_SCANLINE_PATHS },
|
||||
{ "dump-atlas-image", COGL_DEBUG_DUMP_ATLAS_IMAGE },
|
||||
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS }
|
||||
{ "disable-atlas", COGL_DEBUG_DISABLE_ATLAS },
|
||||
{ "disable-texturing", COGL_DEBUG_DISABLE_TEXTURING},
|
||||
{ "disable-arbfp", COGL_DEBUG_DISABLE_ARBFP},
|
||||
{ "disable-glsl", COGL_DEBUG_DISABLE_GLSL}
|
||||
};
|
||||
static const int n_cogl_behavioural_debug_keys =
|
||||
G_N_ELEMENTS (cogl_behavioural_debug_keys);
|
||||
@ -115,6 +119,10 @@ _cogl_parse_debug_string (const char *value,
|
||||
OPT ("force-scanline-paths:", "use a scanline based path rasterizer");
|
||||
OPT ("dump-atlas-image:", "dump atlas changes to an image file");
|
||||
OPT ("disable-atlas:", "disable texture atlasing");
|
||||
OPT ("disable-texturing:", "disable texturing primitives");
|
||||
OPT ("disable-arbfp:", "disable use of ARBfp");
|
||||
OPT ("disable-glsl:", "disable use of GLSL");
|
||||
OPT ("show-source:", "show generated ARBfp/GLSL");
|
||||
OPT ("opengl:", "traces some select OpenGL calls");
|
||||
g_printerr ("\n%28s\n", "Special debug values:");
|
||||
OPT ("all:", "Enables all non-behavioural debug options");
|
||||
|
@ -46,7 +46,11 @@ typedef enum {
|
||||
COGL_DEBUG_ATLAS = 1 << 15,
|
||||
COGL_DEBUG_DUMP_ATLAS_IMAGE = 1 << 16,
|
||||
COGL_DEBUG_DISABLE_ATLAS = 1 << 17,
|
||||
COGL_DEBUG_OPENGL = 1 << 18
|
||||
COGL_DEBUG_OPENGL = 1 << 18,
|
||||
COGL_DEBUG_DISABLE_TEXTURING = 1 << 19,
|
||||
COGL_DEBUG_DISABLE_ARBFP = 1 << 20,
|
||||
COGL_DEBUG_DISABLE_GLSL = 1 << 21,
|
||||
COGL_DEBUG_SHOW_SOURCE = 1 << 22
|
||||
} CoglDebugFlags;
|
||||
|
||||
#ifdef COGL_ENABLE_DEBUG
|
||||
|
@ -115,21 +115,6 @@ _cogl_enable (unsigned long flags);
|
||||
unsigned long
|
||||
_cogl_get_enable (void);
|
||||
|
||||
typedef struct _CoglTextureUnit
|
||||
{
|
||||
int index;
|
||||
CoglMatrixStack *matrix_stack;
|
||||
} CoglTextureUnit;
|
||||
|
||||
CoglTextureUnit *
|
||||
_cogl_get_texture_unit (int index_);
|
||||
|
||||
void
|
||||
_cogl_destroy_texture_units (void);
|
||||
|
||||
unsigned int
|
||||
_cogl_get_max_texture_image_units (void);
|
||||
|
||||
void
|
||||
_cogl_flush_face_winding (void);
|
||||
|
||||
|
@ -792,7 +792,16 @@ _cogl_journal_log_quad (const float *position,
|
||||
disable_layers = (1 << n_layers) - 1;
|
||||
disable_layers = ~disable_layers;
|
||||
|
||||
entry->material = _cogl_material_journal_ref (material);
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
material = cogl_material_copy (material);
|
||||
_cogl_material_apply_legacy_state (material);
|
||||
entry->material = _cogl_material_journal_ref (material);
|
||||
cogl_handle_unref (material);
|
||||
}
|
||||
else
|
||||
entry->material = _cogl_material_journal_ref (material);
|
||||
|
||||
entry->n_layers = n_layers;
|
||||
entry->flush_options.flags =
|
||||
COGL_MATERIAL_FLUSH_FALLBACK_MASK |
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#include "cogl-material.h"
|
||||
#include "cogl-matrix.h"
|
||||
#include "cogl-matrix-stack.h"
|
||||
#include "cogl-handle.h"
|
||||
|
||||
#include <glib.h>
|
||||
@ -36,6 +37,92 @@
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
||||
typedef enum _CoglMaterialEqualFlags
|
||||
{
|
||||
/* Return FALSE if any component of either material isn't set to its
|
||||
@ -46,35 +133,41 @@ typedef enum _CoglMaterialEqualFlags
|
||||
|
||||
} CoglMaterialEqualFlags;
|
||||
|
||||
/* XXX: I don't think gtk-doc supports having private enums so these aren't
|
||||
* bundled in with CoglMaterialLayerFlags */
|
||||
typedef enum _CoglMaterialLayerPrivFlags
|
||||
typedef enum _CoglMaterialLayerDifferenceFlags
|
||||
{
|
||||
/* Ref: CoglMaterialLayerFlags
|
||||
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
|
||||
*/
|
||||
COGL_MATERIAL_LAYER_FLAG_DIRTY = 1L<<1,
|
||||
COGL_MATERIAL_LAYER_FLAG_DEFAULT_COMBINE = 1L<<2
|
||||
} CoglMaterialLayerPrivFlags;
|
||||
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;
|
||||
|
||||
/* For tracking the state of a layer that's been flushed to OpenGL */
|
||||
typedef struct _CoglLayerInfo
|
||||
typedef enum _CoglMaterialLayerChangeFlags
|
||||
{
|
||||
CoglHandle handle;
|
||||
unsigned long flags;
|
||||
GLenum gl_target;
|
||||
GLuint gl_texture;
|
||||
gboolean fallback;
|
||||
gboolean disabled;
|
||||
gboolean layer0_overridden;
|
||||
} CoglLayerInfo;
|
||||
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;
|
||||
|
||||
unsigned int index; /*!< lowest index is blended first then others on
|
||||
top */
|
||||
unsigned long flags;
|
||||
|
||||
int unit_index;
|
||||
|
||||
unsigned long differences;
|
||||
|
||||
CoglHandle texture; /*!< The texture for this layer, or
|
||||
COGL_INVALID_HANDLE for an empty layer */
|
||||
|
||||
@ -100,33 +193,48 @@ struct _CoglMaterialLayer
|
||||
/* 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_MATERIAL_FLAG_SHOWN_SAMPLER_WARNING = 1L<<0,
|
||||
|
||||
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_BLEND = 1L<<5,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_USER_SHADER = 1L<<6,
|
||||
COGL_MATERIAL_FLAG_DEFAULT_LAYERS = 1L<<7
|
||||
} CoglMaterialFlags;
|
||||
|
||||
/* ARBfp1.0 program (Fog + ARB_texture_env_combine) */
|
||||
typedef struct _CoglMaterialProgram
|
||||
{
|
||||
GString *source;
|
||||
GLuint gl_program;
|
||||
/* 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
|
||||
|
||||
gboolean *sampled;
|
||||
} CoglMaterialProgram;
|
||||
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;
|
||||
unsigned long journal_ref_count;
|
||||
|
||||
int backend;
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
/* If no lighting is enabled; this is the basic material color */
|
||||
@ -154,12 +262,39 @@ struct _CoglMaterial
|
||||
GLint blend_src_factor_rgb;
|
||||
GLint blend_dst_factor_rgb;
|
||||
|
||||
CoglMaterialProgram program;
|
||||
CoglHandle user_program;
|
||||
|
||||
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
|
||||
@ -197,29 +332,8 @@ _cogl_material_init_default_material (void);
|
||||
unsigned long
|
||||
_cogl_material_get_cogl_enable_flags (CoglHandle handle);
|
||||
|
||||
/*
|
||||
* CoglMaterialLayerFlags:
|
||||
* @COGL_MATERIAL_LAYER_FLAG_USER_MATRIX: Means the user has supplied a
|
||||
* custom texture matrix.
|
||||
*/
|
||||
typedef enum _CoglMaterialLayerFlags
|
||||
{
|
||||
COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX = 1L<<0
|
||||
} CoglMaterialLayerFlags;
|
||||
/* XXX: NB: if you add flags here you will need to update
|
||||
* CoglMaterialLayerPrivFlags!!! */
|
||||
|
||||
/*
|
||||
* cogl_material_layer_get_flags:
|
||||
* @layer_handle: A CoglMaterialLayer layer handle
|
||||
*
|
||||
* This lets you get a number of flag attributes about the layer. Normally
|
||||
* you shouldn't need to use this function directly since Cogl will do this
|
||||
* internally, but if you are developing custom primitives directly with
|
||||
* OpenGL you may need this.
|
||||
*/
|
||||
unsigned long
|
||||
_cogl_material_layer_get_flags (CoglHandle layer_handle);
|
||||
gboolean
|
||||
_cogl_material_layer_has_user_matrix (CoglHandle layer_handle);
|
||||
|
||||
/*
|
||||
* Ensures the mipmaps are available for the texture in the layer if
|
||||
@ -322,5 +436,15 @@ _cogl_material_set_layer_wrap_mode_r (CoglHandle material,
|
||||
CoglMaterialWrapMode
|
||||
_cogl_material_layer_get_wrap_mode_r (CoglHandle layer);
|
||||
|
||||
void
|
||||
_cogl_material_set_user_program (CoglHandle handle,
|
||||
CoglHandle program);
|
||||
|
||||
void
|
||||
_cogl_material_apply_legacy_state (CoglHandle handle);
|
||||
|
||||
void
|
||||
_cogl_gl_use_program_wrapper (GLuint program);
|
||||
|
||||
#endif /* __COGL_MATERIAL_PRIVATE_H */
|
||||
|
||||
|
2770
cogl/cogl-material.c
2770
cogl/cogl-material.c
File diff suppressed because it is too large
Load Diff
@ -132,6 +132,7 @@ _cogl_path_stroke_nodes (void)
|
||||
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglPathData *data;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -151,7 +152,15 @@ _cogl_path_stroke_nodes (void)
|
||||
/* disable all texture layers */
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
|
||||
while (path_start < data->path_nodes->len)
|
||||
{
|
||||
@ -163,6 +172,9 @@ _cogl_path_stroke_nodes (void)
|
||||
|
||||
path_start += node->path_size;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -332,6 +344,8 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
||||
unsigned int bounds_w,
|
||||
unsigned int bounds_h)
|
||||
{
|
||||
CoglHandle source;
|
||||
|
||||
/* This is our edge list it stores intersections between our
|
||||
* curve and scanlines, it should probably be implemented with a
|
||||
* data structure that has smaller overhead for inserting the
|
||||
@ -359,6 +373,14 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, NULL);
|
||||
|
||||
_cogl_enable (COGL_ENABLE_VERTEX_ARRAY
|
||||
@ -502,6 +524,9 @@ _cogl_path_fill_nodes_scanlines (CoglPathNode *path,
|
||||
GE (glDrawArrays (GL_TRIANGLES, 0, spans * 2 * 3));
|
||||
g_free (coords);
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -59,8 +59,6 @@
|
||||
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
|
||||
#define glMapBuffer ctx->drv.pf_glMapBuffer
|
||||
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
|
||||
#define glActiveTexture ctx->drv.pf_glActiveTexture
|
||||
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
|
||||
|
||||
#ifndef GL_PIXEL_UNPACK_BUFFER
|
||||
#define GL_PIXEL_UNPACK_BUFFER GL_PIXEL_UNPACK_BUFFER_ARB
|
||||
|
@ -516,7 +516,6 @@ _cogl_rectangles_with_multitexture_coords (
|
||||
{
|
||||
CoglHandle layer = tmp->data;
|
||||
CoglHandle tex_handle;
|
||||
unsigned long flags;
|
||||
|
||||
if (cogl_material_layer_get_type (layer)
|
||||
!= COGL_MATERIAL_LAYER_TYPE_TEXTURE)
|
||||
@ -619,8 +618,7 @@ _cogl_rectangles_with_multitexture_coords (
|
||||
* waste or if using GL_TEXTURE_RECTANGLE_ARB) then we don't support
|
||||
* multi texturing since we don't know if the result will end up trying
|
||||
* to texture from the waste area. */
|
||||
flags = _cogl_material_layer_get_flags (layer);
|
||||
if (flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX
|
||||
if (_cogl_material_layer_has_user_matrix (layer)
|
||||
&& !_cogl_texture_can_hardware_repeat (tex_handle))
|
||||
{
|
||||
static gboolean warning_seen = FALSE;
|
||||
@ -838,6 +836,7 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
||||
float virtual_origin_y;
|
||||
float v_to_s_scale_x;
|
||||
float v_to_s_scale_y;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -888,9 +887,20 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
||||
options.wrap_mode_overrides.values[0].t =
|
||||
COGL_MATERIAL_WRAP_MODE_OVERRIDE_CLAMP_TO_BORDER;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, state->n_vertices));
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
}
|
||||
|
||||
/* handles 2d-sliced textures with > 1 slice */
|
||||
@ -963,6 +973,7 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
||||
GList *tmp;
|
||||
GLfloat *v;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1028,9 +1039,21 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
||||
options.flags |= COGL_MATERIAL_FLUSH_WRAP_MODE_OVERRIDES;
|
||||
options.wrap_mode_overrides = *wrap_mode_overrides;
|
||||
}
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -159,7 +159,6 @@
|
||||
#define glDeleteBuffers ctx->drv.pf_glDeleteBuffers
|
||||
#define glMapBuffer ctx->drv.pf_glMapBuffer
|
||||
#define glUnmapBuffer ctx->drv.pf_glUnmapBuffer
|
||||
#define glActiveTexture ctx->drv.pf_glActiveTexture
|
||||
#define glClientActiveTexture ctx->drv.pf_glClientActiveTexture
|
||||
#ifndef GL_ARRAY_BUFFER
|
||||
#define GL_ARRAY_BUFFER GL_ARRAY_BUFFER_ARB
|
||||
@ -1509,7 +1508,7 @@ get_gl_type_from_attribute_flags (CoglVertexBufferAttribFlags flags)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
static CoglHandle
|
||||
enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
{
|
||||
GList *tmp;
|
||||
@ -1522,8 +1521,9 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
guint32 fallback_layers = 0;
|
||||
int i;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||
|
||||
if (buffer->new_attributes)
|
||||
cogl_vertex_buffer_submit_real (buffer);
|
||||
@ -1717,18 +1717,29 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
|
||||
options.fallback_layers = fallback_layers;
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
|
||||
_cogl_material_flush_gl_state (source, &options);
|
||||
enable_flags |= _cogl_material_get_cogl_enable_flags (source);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
static void
|
||||
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer,
|
||||
CoglHandle source)
|
||||
{
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
@ -1738,6 +1749,9 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
|
||||
/* Disable all the client state that cogl doesn't currently know
|
||||
* about:
|
||||
*/
|
||||
@ -1798,6 +1812,7 @@ cogl_vertex_buffer_draw (CoglHandle handle,
|
||||
int count)
|
||||
{
|
||||
CoglVertexBuffer *buffer;
|
||||
CoglHandle source;
|
||||
|
||||
if (!cogl_is_vertex_buffer (handle))
|
||||
return;
|
||||
@ -1806,11 +1821,11 @@ cogl_vertex_buffer_draw (CoglHandle handle,
|
||||
|
||||
buffer = _cogl_vertex_buffer_pointer_from_handle (handle);
|
||||
|
||||
enable_state_for_drawing_buffer (buffer);
|
||||
source = enable_state_for_drawing_buffer (buffer);
|
||||
|
||||
GE (glDrawArrays (mode, first, count));
|
||||
|
||||
disable_state_for_drawing_buffer (buffer);
|
||||
disable_state_for_drawing_buffer (buffer, source);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1934,6 +1949,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
|
||||
(cogl_get_features () & COGL_FEATURE_VBOS) ? FALSE : TRUE;
|
||||
gsize byte_offset;
|
||||
CoglVertexBufferIndices *indices = NULL;
|
||||
CoglHandle source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1949,7 +1965,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
|
||||
|
||||
indices = _cogl_vertex_buffer_indices_pointer_from_handle (indices_handle);
|
||||
|
||||
enable_state_for_drawing_buffer (buffer);
|
||||
source = enable_state_for_drawing_buffer (buffer);
|
||||
|
||||
byte_offset = indices_offset * get_indices_type_size (indices->type);
|
||||
if (fallback)
|
||||
@ -1961,7 +1977,7 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
|
||||
GE (glDrawRangeElements (mode, min_index, max_index,
|
||||
count, indices->type, (void *)byte_offset));
|
||||
|
||||
disable_state_for_drawing_buffer (buffer);
|
||||
disable_state_for_drawing_buffer (buffer, source);
|
||||
|
||||
GE (glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, 0));
|
||||
}
|
||||
|
109
cogl/cogl.c
109
cogl/cogl.c
@ -493,6 +493,9 @@ cogl_get_features (void)
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_VBOS))
|
||||
ctx->feature_flags &= ~COGL_FEATURE_VBOS;
|
||||
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_GLSL))
|
||||
ctx->feature_flags &= ~COGL_FEATURE_SHADERS_GLSL;
|
||||
|
||||
return ctx->feature_flags;
|
||||
}
|
||||
|
||||
@ -515,6 +518,9 @@ _cogl_features_available_private (CoglFeatureFlagsPrivate features)
|
||||
if (!ctx->features_cached)
|
||||
_cogl_features_init ();
|
||||
|
||||
if (G_UNLIKELY (cogl_debug_flags & COGL_DEBUG_DISABLE_ARBFP))
|
||||
ctx->feature_flags_private &= ~COGL_FEATURE_PRIVATE_ARB_FP;
|
||||
|
||||
return (ctx->feature_flags_private & features) == features;
|
||||
}
|
||||
|
||||
@ -571,6 +577,8 @@ cogl_set_fog (const CoglColor *fog_color,
|
||||
GLfloat fogColor[4];
|
||||
GLenum gl_mode = GL_LINEAR;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* The cogl journal doesn't currently track fog state changes */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
@ -606,15 +614,20 @@ cogl_set_fog (const CoglColor *fog_color,
|
||||
glFogf (GL_FOG_DENSITY, (GLfloat) density);
|
||||
glFogf (GL_FOG_START, (GLfloat) z_near);
|
||||
glFogf (GL_FOG_END, (GLfloat) z_far);
|
||||
|
||||
ctx->fog_enabled = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_disable_fog (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
/* Currently the journal can't track changes to fog state... */
|
||||
_cogl_journal_flush ();
|
||||
|
||||
glDisable (GL_FOG);
|
||||
ctx->fog_enabled = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
@ -876,102 +889,6 @@ cogl_end_gl (void)
|
||||
ctx->in_begin_gl_block = FALSE;
|
||||
}
|
||||
|
||||
static CoglTextureUnit *
|
||||
_cogl_texture_unit_new (int index_)
|
||||
{
|
||||
CoglTextureUnit *unit = g_new0 (CoglTextureUnit, 1);
|
||||
unit->matrix_stack = _cogl_matrix_stack_new ();
|
||||
unit->index = index_;
|
||||
return unit;
|
||||
}
|
||||
|
||||
static void
|
||||
_cogl_texture_unit_free (CoglTextureUnit *unit)
|
||||
{
|
||||
_cogl_matrix_stack_destroy (unit->matrix_stack);
|
||||
g_free (unit);
|
||||
}
|
||||
|
||||
CoglTextureUnit *
|
||||
_cogl_get_texture_unit (int index_)
|
||||
{
|
||||
GList *l;
|
||||
CoglTextureUnit *unit;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
|
||||
for (l = ctx->texture_units; l; l = l->next)
|
||||
{
|
||||
unit = l->data;
|
||||
|
||||
if (unit->index == index_)
|
||||
return unit;
|
||||
|
||||
/* The units are always sorted, so at this point we know this unit
|
||||
* doesn't exist */
|
||||
if (unit->index > index_)
|
||||
break;
|
||||
}
|
||||
/* NB: if we now insert a new layer before l, that will maintain order.
|
||||
*/
|
||||
|
||||
unit = _cogl_texture_unit_new (index_);
|
||||
|
||||
/* Note: see comment after for() loop above */
|
||||
ctx->texture_units =
|
||||
g_list_insert_before (ctx->texture_units, l, unit);
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
void
|
||||
_cogl_destroy_texture_units (void)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
for (l = ctx->texture_units; l; l = l->next)
|
||||
_cogl_texture_unit_free (l->data);
|
||||
g_list_free (ctx->texture_units);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is more complicated than that, another pass needs to be done when
|
||||
* cogl have a neat way of saying if we are using the fixed function pipeline
|
||||
* or not (for the GL case):
|
||||
* MAX_TEXTURE_UNITS: fixed function pipeline, a texture unit has both a
|
||||
* sampler and a set of texture coordinates
|
||||
* MAX_TEXTURE_IMAGE_UNITS: number of samplers one can use from a fragment
|
||||
* program/shader (ARBfp1.0 asm/GLSL)
|
||||
* MAX_VERTEX_TEXTURE_UNITS: number of samplers one can use from a vertex
|
||||
* program/shader (can be 0)
|
||||
* MAX_COMBINED_TEXTURE_IMAGE_UNITS: Maximum samplers one can use, counting both
|
||||
* the vertex and fragment shaders
|
||||
*
|
||||
* If both the vertex shader and the fragment processing stage access the same
|
||||
* texture image unit, then that counts as using two texture image units
|
||||
* against the latter limit: http://www.opengl.org/sdk/docs/man/xhtml/glGet.xml
|
||||
*
|
||||
* Note that, for now, we use GL_MAX_TEXTURE_UNITS as we are exposing the
|
||||
* fixed function pipeline.
|
||||
*/
|
||||
unsigned int
|
||||
_cogl_get_max_texture_image_units (void)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, 0);
|
||||
|
||||
/* This function is called quite often so we cache the value to
|
||||
avoid too many GL calls */
|
||||
if (ctx->max_texture_units == -1)
|
||||
{
|
||||
ctx->max_texture_units = 1;
|
||||
GE( glGetIntegerv (GL_MAX_TEXTURE_UNITS, &ctx->max_texture_units) );
|
||||
}
|
||||
|
||||
return ctx->max_texture_units;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_push_matrix (void)
|
||||
{
|
||||
|
@ -41,6 +41,8 @@ typedef struct _CoglContextDriver
|
||||
{
|
||||
/* This defines a list of function pointers */
|
||||
#include "cogl-feature-functions.h"
|
||||
|
||||
GLint gl_max_program_temoraries_arb;
|
||||
} CoglContextDriver;
|
||||
|
||||
#undef COGL_FEATURE_BEGIN
|
||||
|
@ -119,6 +119,9 @@ COGL_FEATURE_BEGIN (arbfp, 255, 255,
|
||||
COGL_FEATURE_FUNCTION (void, glGenPrograms,
|
||||
(GLsizei n,
|
||||
GLuint *programs))
|
||||
COGL_FEATURE_FUNCTION (void, glDeletePrograms,
|
||||
(GLsizei n,
|
||||
GLuint *programs))
|
||||
COGL_FEATURE_FUNCTION (void, glBindProgram,
|
||||
(GLenum target,
|
||||
GLuint program))
|
||||
@ -127,47 +130,51 @@ COGL_FEATURE_FUNCTION (void, glProgramString,
|
||||
GLenum format,
|
||||
GLsizei len,
|
||||
const void *program))
|
||||
COGL_FEATURE_FUNCTION (void, glProgramLocalParameter4fv,
|
||||
(GLenum target,
|
||||
GLuint index,
|
||||
GLfloat *params))
|
||||
COGL_FEATURE_END ()
|
||||
|
||||
/* The function names in OpenGL 2.0 are different so we can't easily
|
||||
just check for GL 2.0 */
|
||||
COGL_FEATURE_BEGIN (shaders_glsl, 255, 255,
|
||||
"ARB\0",
|
||||
"shader_objects\0"
|
||||
"vertex_shader\0"
|
||||
"fragment_shader\0",
|
||||
COGL_FEATURE_BEGIN (shaders_glsl, 2, 0,
|
||||
"\0",
|
||||
"\0",
|
||||
COGL_FEATURE_SHADERS_GLSL,
|
||||
0)
|
||||
COGL_FEATURE_FUNCTION (GLhandleARB, glCreateProgramObject,
|
||||
COGL_FEATURE_FUNCTION (GLuint, glCreateProgram,
|
||||
(void))
|
||||
COGL_FEATURE_FUNCTION (GLhandleARB, glCreateShaderObject,
|
||||
COGL_FEATURE_FUNCTION (GLuint, glCreateShader,
|
||||
(GLenum shaderType))
|
||||
COGL_FEATURE_FUNCTION (void, glShaderSource,
|
||||
(GLhandleARB shaderObj,
|
||||
(GLuint shader,
|
||||
GLsizei count,
|
||||
const GLcharARB* *string,
|
||||
const GLchar **string,
|
||||
const GLint *length))
|
||||
COGL_FEATURE_FUNCTION (void, glCompileShader,
|
||||
(GLhandleARB shaderObj))
|
||||
COGL_FEATURE_FUNCTION (void, glAttachObject,
|
||||
(GLhandleARB containerObj,
|
||||
GLhandleARB obj))
|
||||
(GLuint shader))
|
||||
COGL_FEATURE_FUNCTION (void, glDeleteShader,
|
||||
(GLuint shader))
|
||||
COGL_FEATURE_FUNCTION (void, glAttachShader,
|
||||
(GLuint program,
|
||||
GLuint shader))
|
||||
COGL_FEATURE_FUNCTION (void, glLinkProgram,
|
||||
(GLhandleARB programObj))
|
||||
COGL_FEATURE_FUNCTION (void, glUseProgramObject,
|
||||
(GLhandleARB programObj))
|
||||
(GLuint program))
|
||||
COGL_FEATURE_FUNCTION (void, glUseProgram,
|
||||
(GLuint program))
|
||||
COGL_FEATURE_FUNCTION (GLint, glGetUniformLocation,
|
||||
(GLhandleARB programObj,
|
||||
const GLcharARB *name))
|
||||
COGL_FEATURE_FUNCTION (void, glDeleteObject,
|
||||
(GLhandleARB obj))
|
||||
COGL_FEATURE_FUNCTION (void, glGetInfoLog,
|
||||
(GLhandleARB obj,
|
||||
(GLuint program,
|
||||
const GLchar *name))
|
||||
COGL_FEATURE_FUNCTION (void, glDeleteProgram,
|
||||
(GLuint program))
|
||||
COGL_FEATURE_FUNCTION (void, glGetShaderInfoLog,
|
||||
(GLuint shader,
|
||||
GLsizei maxLength,
|
||||
GLsizei *length,
|
||||
GLcharARB *infoLog))
|
||||
COGL_FEATURE_FUNCTION (void, glGetObjectParameteriv,
|
||||
(GLhandleARB obj,
|
||||
GLchar *infoLog))
|
||||
COGL_FEATURE_FUNCTION (void, glGetShaderiv,
|
||||
(GLuint shader,
|
||||
GLenum pname,
|
||||
GLint *params))
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2008,2009 Intel Corporation.
|
||||
* Copyright (C) 2008,2009,2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -35,9 +35,9 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#define glCreateProgramObject ctx->drv.pf_glCreateProgramObject
|
||||
#define glAttachObject ctx->drv.pf_glAttachObject
|
||||
#define glUseProgramObject ctx->drv.pf_glUseProgramObject
|
||||
#define glCreateProgram ctx->drv.pf_glCreateProgram
|
||||
#define glAttachShader ctx->drv.pf_glAttachShader
|
||||
#define glUseProgram ctx->drv.pf_glUseProgram
|
||||
#define glLinkProgram ctx->drv.pf_glLinkProgram
|
||||
#define glGetUniformLocation ctx->drv.pf_glGetUniformLocation
|
||||
#define glUniform1f ctx->drv.pf_glUniform1f
|
||||
@ -59,7 +59,7 @@
|
||||
#define glUniformMatrix2fv ctx->drv.pf_glUniformMatrix2fv
|
||||
#define glUniformMatrix3fv ctx->drv.pf_glUniformMatrix3fv
|
||||
#define glUniformMatrix4fv ctx->drv.pf_glUniformMatrix4fv
|
||||
#define glDeleteObject ctx->drv.pf_glDeleteObject
|
||||
#define glDeleteProgram ctx->drv.pf_glDeleteProgram
|
||||
|
||||
static void _cogl_program_free (CoglProgram *program);
|
||||
|
||||
@ -71,7 +71,7 @@ _cogl_program_free (CoglProgram *program)
|
||||
/* Frees program resources but its handle is not
|
||||
released! Do that separately before this! */
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
glDeleteObject (program->gl_handle);
|
||||
GE (glDeleteProgram (program->gl_handle));
|
||||
}
|
||||
|
||||
CoglHandle
|
||||
@ -81,7 +81,7 @@ cogl_create_program (void)
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
|
||||
program = g_slice_new (CoglProgram);
|
||||
program->gl_handle = glCreateProgramObject ();
|
||||
program->gl_handle = glCreateProgram ();
|
||||
|
||||
return _cogl_program_handle_new (program);
|
||||
}
|
||||
@ -101,7 +101,7 @@ cogl_program_attach_shader (CoglHandle program_handle,
|
||||
program = _cogl_program_pointer_from_handle (program_handle);
|
||||
shader = _cogl_shader_pointer_from_handle (shader_handle);
|
||||
|
||||
glAttachObject (program->gl_handle, shader->gl_handle);
|
||||
GE (glAttachShader (program->gl_handle, shader->gl_handle));
|
||||
}
|
||||
|
||||
void
|
||||
@ -115,33 +115,27 @@ cogl_program_link (CoglHandle handle)
|
||||
|
||||
program = _cogl_program_pointer_from_handle (handle);
|
||||
|
||||
glLinkProgram (program->gl_handle);
|
||||
GE (glLinkProgram (program->gl_handle));
|
||||
}
|
||||
|
||||
void
|
||||
cogl_program_use (CoglHandle handle)
|
||||
{
|
||||
CoglProgram *program;
|
||||
GLhandleARB gl_handle;
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
|
||||
return;
|
||||
g_return_if_fail (handle == COGL_INVALID_HANDLE ||
|
||||
cogl_is_program (handle));
|
||||
|
||||
/* The Cogl journal doesn't currently cope with the use of
|
||||
* shaders so we have to flush all priitives whenever the
|
||||
* current shader changes... */
|
||||
_cogl_journal_flush ();
|
||||
if (ctx->current_program == 0 && handle != 0)
|
||||
ctx->legacy_state_set++;
|
||||
else if (handle == 0 && ctx->current_program != 0)
|
||||
ctx->legacy_state_set--;
|
||||
|
||||
if (handle == COGL_INVALID_HANDLE)
|
||||
gl_handle = 0;
|
||||
else
|
||||
{
|
||||
program = _cogl_program_pointer_from_handle (handle);
|
||||
gl_handle = program->gl_handle;
|
||||
}
|
||||
|
||||
glUseProgramObject (gl_handle);
|
||||
if (handle != COGL_INVALID_HANDLE)
|
||||
cogl_handle_ref (handle);
|
||||
if (ctx->current_program != COGL_INVALID_HANDLE)
|
||||
cogl_handle_unref (ctx->current_program);
|
||||
ctx->current_program = handle;
|
||||
}
|
||||
|
||||
int
|
||||
@ -163,16 +157,34 @@ void
|
||||
cogl_program_uniform_1f (int uniform_no,
|
||||
float value)
|
||||
{
|
||||
CoglProgram *program;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
glUniform1f (uniform_no, value);
|
||||
|
||||
program = ctx->current_program;
|
||||
|
||||
g_return_if_fail (program != NULL);
|
||||
|
||||
_cogl_gl_use_program_wrapper (program->gl_handle);
|
||||
|
||||
GE (glUniform1f (uniform_no, value));
|
||||
}
|
||||
|
||||
void
|
||||
cogl_program_uniform_1i (int uniform_no,
|
||||
int value)
|
||||
{
|
||||
CoglProgram *program;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
glUniform1i (uniform_no, value);
|
||||
|
||||
program = ctx->current_program;
|
||||
|
||||
g_return_if_fail (program != NULL);
|
||||
|
||||
_cogl_gl_use_program_wrapper (program->gl_handle);
|
||||
|
||||
GE (glUniform1i (uniform_no, value));
|
||||
}
|
||||
|
||||
void
|
||||
@ -181,21 +193,29 @@ cogl_program_uniform_float (int uniform_no,
|
||||
int count,
|
||||
const GLfloat *value)
|
||||
{
|
||||
CoglProgram *program;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
program = ctx->current_program;
|
||||
|
||||
g_return_if_fail (program != NULL);
|
||||
|
||||
_cogl_gl_use_program_wrapper (program->gl_handle);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
glUniform1fv (uniform_no, count, value);
|
||||
GE (glUniform1fv (uniform_no, count, value));
|
||||
break;
|
||||
case 2:
|
||||
glUniform2fv (uniform_no, count, value);
|
||||
GE (glUniform2fv (uniform_no, count, value));
|
||||
break;
|
||||
case 3:
|
||||
glUniform3fv (uniform_no, count, value);
|
||||
GE (glUniform3fv (uniform_no, count, value));
|
||||
break;
|
||||
case 4:
|
||||
glUniform4fv (uniform_no, count, value);
|
||||
GE (glUniform4fv (uniform_no, count, value));
|
||||
break;
|
||||
default:
|
||||
g_warning ("%s called with invalid size parameter", G_STRFUNC);
|
||||
@ -208,8 +228,16 @@ cogl_program_uniform_int (int uniform_no,
|
||||
int count,
|
||||
const int *value)
|
||||
{
|
||||
CoglProgram *program;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
program = ctx->current_program;
|
||||
|
||||
g_return_if_fail (program != NULL);
|
||||
|
||||
_cogl_gl_use_program_wrapper (program->gl_handle);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 1:
|
||||
@ -236,18 +264,26 @@ cogl_program_uniform_matrix (int uniform_no,
|
||||
gboolean transpose,
|
||||
const GLfloat *value)
|
||||
{
|
||||
CoglProgram *program;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
program = ctx->current_program;
|
||||
|
||||
g_return_if_fail (program != NULL);
|
||||
|
||||
_cogl_gl_use_program_wrapper (program->gl_handle);
|
||||
|
||||
switch (size)
|
||||
{
|
||||
case 2 :
|
||||
glUniformMatrix2fv (uniform_no, count, transpose, value);
|
||||
GE (glUniformMatrix2fv (uniform_no, count, transpose, value));
|
||||
break;
|
||||
case 3 :
|
||||
glUniformMatrix3fv (uniform_no, count, transpose, value);
|
||||
GE (glUniformMatrix3fv (uniform_no, count, transpose, value));
|
||||
break;
|
||||
case 4 :
|
||||
glUniformMatrix4fv (uniform_no, count, transpose, value);
|
||||
GE (glUniformMatrix4fv (uniform_no, count, transpose, value));
|
||||
break;
|
||||
default :
|
||||
g_warning ("%s called with invalid size parameter", G_STRFUNC);
|
||||
|
@ -31,7 +31,7 @@ typedef struct _CoglProgram CoglProgram;
|
||||
struct _CoglProgram
|
||||
{
|
||||
CoglHandleObject _parent;
|
||||
GLhandleARB gl_handle;
|
||||
GLuint gl_handle;
|
||||
};
|
||||
|
||||
CoglProgram *_cogl_program_pointer_from_handle (CoglHandle handle);
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* An object oriented GL/GLES Abstraction/Utility Layer
|
||||
*
|
||||
* Copyright (C) 2007,2008,2009 Intel Corporation.
|
||||
* Copyright (C) 2007,2008,2009,2010 Intel Corporation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -33,12 +33,12 @@
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#define glCreateShaderObject ctx->drv.pf_glCreateShaderObject
|
||||
#define glGetObjectParameteriv ctx->drv.pf_glGetObjectParameteriv
|
||||
#define glGetInfoLog ctx->drv.pf_glGetInfoLog
|
||||
#define glCompileShader ctx->drv.pf_glCompileShader
|
||||
#define glShaderSource ctx->drv.pf_glShaderSource
|
||||
#define glDeleteObject ctx->drv.pf_glDeleteObject
|
||||
#define glCreateShader ctx->drv.pf_glCreateShader
|
||||
#define glGetShaderiv ctx->drv.pf_glGetShaderiv
|
||||
#define glGetShaderInfoLog ctx->drv.pf_glGetShaderInfoLog
|
||||
#define glCompileShader ctx->drv.pf_glCompileShader
|
||||
#define glShaderSource ctx->drv.pf_glShaderSource
|
||||
#define glDeleteShader ctx->drv.pf_glDeleteShader
|
||||
|
||||
static void _cogl_shader_free (CoglShader *shader);
|
||||
|
||||
@ -50,7 +50,7 @@ _cogl_shader_free (CoglShader *shader)
|
||||
/* Frees shader resources but its handle is not
|
||||
released! Do that separately before this! */
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
glDeleteObject (shader->gl_handle);
|
||||
glDeleteShader (shader->gl_handle);
|
||||
}
|
||||
|
||||
CoglHandle
|
||||
@ -73,7 +73,7 @@ cogl_create_shader (CoglShaderType type)
|
||||
}
|
||||
|
||||
shader = g_slice_new (CoglShader);
|
||||
shader->gl_handle = glCreateShaderObject (gl_type);
|
||||
shader->gl_handle = glCreateShader (gl_type);
|
||||
|
||||
return _cogl_shader_handle_new (shader);
|
||||
}
|
||||
@ -112,7 +112,7 @@ cogl_shader_get_info_log (CoglHandle handle)
|
||||
{
|
||||
CoglShader *shader;
|
||||
char buffer[512];
|
||||
int len;
|
||||
GLsizei len;
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
|
||||
if (!cogl_is_shader (handle))
|
||||
@ -120,7 +120,7 @@ cogl_shader_get_info_log (CoglHandle handle)
|
||||
|
||||
shader = _cogl_shader_pointer_from_handle (handle);
|
||||
|
||||
glGetInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||
glGetShaderInfoLog (shader->gl_handle, 511, &len, buffer);
|
||||
buffer[len]='\0';
|
||||
|
||||
return g_strdup (buffer);
|
||||
@ -142,7 +142,7 @@ cogl_shader_get_type (CoglHandle handle)
|
||||
|
||||
shader = _cogl_shader_pointer_from_handle (handle);
|
||||
|
||||
GE (glGetObjectParameteriv (shader->gl_handle, GL_SHADER_TYPE, &type));
|
||||
GE (glGetShaderiv (shader->gl_handle, GL_SHADER_TYPE, &type));
|
||||
if (type == GL_VERTEX_SHADER)
|
||||
return COGL_SHADER_TYPE_VERTEX;
|
||||
else if (type == GL_FRAGMENT_SHADER)
|
||||
@ -167,7 +167,7 @@ cogl_shader_is_compiled (CoglHandle handle)
|
||||
|
||||
shader = _cogl_shader_pointer_from_handle (handle);
|
||||
|
||||
GE (glGetObjectParameteriv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||
GE (glGetShaderiv (shader->gl_handle, GL_COMPILE_STATUS, &status));
|
||||
if (status == GL_TRUE)
|
||||
return TRUE;
|
||||
else
|
||||
|
@ -115,11 +115,22 @@ cogl_program_use (CoglHandle handle)
|
||||
{
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (handle != COGL_INVALID_HANDLE && !cogl_is_program (handle))
|
||||
return;
|
||||
g_return_if_fail (handle == COGL_INVALID_HANDLE ||
|
||||
cogl_is_program (handle));
|
||||
|
||||
if (ctx->current_program == 0 && handle != 0)
|
||||
ctx->legacy_state_set++;
|
||||
else if (handle == 0 && ctx->current_program != 0)
|
||||
ctx->legacy_state_set--;
|
||||
|
||||
ctx->drv.gles2.settings.user_program = handle;
|
||||
ctx->drv.gles2.settings_dirty = TRUE;
|
||||
|
||||
if (handle != COGL_INVALID_HANDLE)
|
||||
cogl_handle_ref (handle);
|
||||
if (ctx->current_program != COGL_INVALID_HANDLE)
|
||||
cogl_handle_unref (ctx->current_program);
|
||||
ctx->current_program = handle;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user