mirror of
https://github.com/brl/mutter.git
synced 2024-11-26 10:00:45 -05:00
cogl: Adds {push,pop,get}_source functions
This exposes the idea of a stack of source materials instead of just having a single current material. This allows the writing of orthogonal code that can change the current source material and restore it to its previous state. It also allows the implementation of new composite primitives that may want to validate the current source material and possibly make override changes in a derived material.
This commit is contained in:
parent
4ccd915064
commit
1b9a247174
@ -298,7 +298,6 @@ add_stencil_clip_rectangle (float x_1,
|
||||
float y_2,
|
||||
gboolean first)
|
||||
{
|
||||
CoglHandle current_source;
|
||||
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
@ -310,8 +309,7 @@ add_stencil_clip_rectangle (float x_1,
|
||||
_cogl_framebuffer_flush_state (framebuffer, 0);
|
||||
|
||||
/* temporarily swap in our special stenciling material */
|
||||
current_source = cogl_object_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->stencil_material);
|
||||
cogl_push_source (ctx->stencil_material);
|
||||
|
||||
if (first)
|
||||
{
|
||||
@ -370,8 +368,7 @@ add_stencil_clip_rectangle (float x_1,
|
||||
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
|
||||
|
||||
/* restore the original source material */
|
||||
cogl_set_source (current_source);
|
||||
cogl_object_unref (current_source);
|
||||
cogl_pop_source ();
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -130,8 +130,8 @@ cogl_create_context (void)
|
||||
_context->legacy_fog_state.enabled = FALSE;
|
||||
|
||||
_context->simple_material = cogl_material_new ();
|
||||
_context->source_material = NULL;
|
||||
_context->arbfp_source_buffer = g_string_new ("");
|
||||
_context->source_stack = NULL;
|
||||
|
||||
_context->legacy_state_set = 0;
|
||||
|
||||
@ -226,8 +226,8 @@ cogl_create_context (void)
|
||||
0, /* auto calc row stride */
|
||||
default_texture_data);
|
||||
|
||||
cogl_set_source (_context->simple_material);
|
||||
_cogl_material_flush_gl_state (_context->source_material, FALSE);
|
||||
cogl_push_source (_context->simple_material);
|
||||
_cogl_material_flush_gl_state (_context->simple_material, FALSE);
|
||||
_cogl_enable (enable_flags);
|
||||
_cogl_flush_face_winding ();
|
||||
|
||||
|
@ -84,8 +84,8 @@ typedef struct
|
||||
|
||||
/* Materials */
|
||||
CoglMaterial *simple_material;
|
||||
CoglMaterial *source_material;
|
||||
GString *arbfp_source_buffer;
|
||||
GList *source_stack;
|
||||
|
||||
int legacy_state_set;
|
||||
|
||||
|
@ -919,5 +919,8 @@ _cogl_material_get_layer_combine_constant (CoglMaterial *material,
|
||||
int layer_index,
|
||||
float *constant);
|
||||
|
||||
void
|
||||
_cogl_material_prune_to_n_layers (CoglMaterial *material, int n);
|
||||
|
||||
#endif /* __COGL_MATERIAL_PRIVATE_H */
|
||||
|
||||
|
@ -181,7 +181,8 @@ _cogl_path_stroke_nodes (void)
|
||||
unsigned int path_start = 0;
|
||||
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglPathData *data;
|
||||
CoglHandle source;
|
||||
CoglMaterial *copy = NULL;
|
||||
CoglMaterial *source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -198,25 +199,25 @@ _cogl_path_stroke_nodes (void)
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
CoglMaterial *users_source = cogl_get_source ();
|
||||
copy = cogl_material_copy (users_source);
|
||||
_cogl_material_apply_legacy_state (copy);
|
||||
source = copy;
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
source = cogl_get_source ();
|
||||
|
||||
if (cogl_material_get_n_layers (source) != 0)
|
||||
{
|
||||
CoglMaterialFlushOptions options;
|
||||
options.flags = COGL_MATERIAL_FLUSH_DISABLE_MASK;
|
||||
/* disable all texture layers */
|
||||
options.disable_layers = (guint32)~0;
|
||||
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
/* If we haven't already created a derivative material... */
|
||||
if (!copy)
|
||||
copy = cogl_material_copy (source);
|
||||
_cogl_material_prune_to_n_layers (copy, 0);
|
||||
source = copy;
|
||||
}
|
||||
|
||||
cogl_push_source (source);
|
||||
|
||||
_cogl_material_flush_gl_state (source, FALSE);
|
||||
|
||||
/* Disable all client texture coordinate arrays */
|
||||
@ -234,8 +235,7 @@ _cogl_path_stroke_nodes (void)
|
||||
path_start += node->path_size;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
cogl_pop_source ();
|
||||
}
|
||||
|
||||
void
|
||||
@ -308,7 +308,7 @@ _cogl_path_fill_nodes (CoglPath *path)
|
||||
textures or textures with waste then it won't work to draw the
|
||||
path directly. Instead we can use draw the texture as a quad
|
||||
clipped to the stencil buffer. */
|
||||
for (l = cogl_material_get_layers (ctx->source_material); l; l = l->next)
|
||||
for (l = cogl_material_get_layers (cogl_get_source ()); l; l = l->next)
|
||||
{
|
||||
CoglHandle layer = l->data;
|
||||
CoglHandle texture = cogl_material_layer_get_texture (layer);
|
||||
@ -352,7 +352,6 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
{
|
||||
CoglPathData *data = path->data;
|
||||
unsigned long enable_flags = COGL_ENABLE_VERTEX_ARRAY;
|
||||
CoglHandle prev_source;
|
||||
CoglFramebuffer *framebuffer = _cogl_get_framebuffer ();
|
||||
CoglMatrixStack *modelview_stack =
|
||||
_cogl_framebuffer_get_modelview_stack (framebuffer);
|
||||
@ -371,10 +370,9 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
_cogl_framebuffer_flush_state (framebuffer, 0);
|
||||
|
||||
/* Just setup a simple material that doesn't use texturing... */
|
||||
prev_source = cogl_object_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->stencil_material);
|
||||
cogl_push_source (ctx->stencil_material);
|
||||
|
||||
_cogl_material_flush_gl_state (ctx->source_material, FALSE);
|
||||
_cogl_material_flush_gl_state (ctx->stencil_material, FALSE);
|
||||
|
||||
_cogl_enable (enable_flags);
|
||||
|
||||
@ -464,8 +462,7 @@ _cogl_add_path_to_stencil_buffer (CoglPath *path,
|
||||
GE (glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
|
||||
|
||||
/* restore the original material */
|
||||
cogl_set_source (prev_source);
|
||||
cogl_object_unref (prev_source);
|
||||
cogl_pop_source ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -495,7 +495,7 @@ _cogl_rectangles_with_multitexture_coords (
|
||||
struct _CoglMutiTexturedRect *rects,
|
||||
int n_rects)
|
||||
{
|
||||
CoglHandle material;
|
||||
CoglMaterial *material;
|
||||
const GList *layers;
|
||||
int n_layers;
|
||||
const GList *tmp;
|
||||
@ -505,7 +505,7 @@ _cogl_rectangles_with_multitexture_coords (
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
material = ctx->source_material;
|
||||
material = cogl_get_source ();
|
||||
|
||||
layers = cogl_material_get_layers (material);
|
||||
n_layers = cogl_material_get_n_layers (material);
|
||||
@ -839,7 +839,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;
|
||||
CoglMaterial *source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -868,13 +868,10 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
||||
v += state->stride;
|
||||
}
|
||||
|
||||
source = cogl_material_copy (cogl_get_source ());
|
||||
|
||||
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;
|
||||
|
||||
options.flags =
|
||||
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE |
|
||||
@ -904,15 +901,12 @@ draw_polygon_sub_texture_cb (CoglHandle tex_handle,
|
||||
}
|
||||
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
|
||||
_cogl_material_flush_gl_state (source, FALSE);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, state->n_vertices));
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
}
|
||||
|
||||
@ -934,7 +928,7 @@ _cogl_texture_polygon_multiple_primitives (const CoglTextureVertex *vertices,
|
||||
|
||||
/* We can assume in this case that we have at least one layer in the
|
||||
* material that corresponds to a sliced cogl texture */
|
||||
layers = cogl_material_get_layers (ctx->source_material);
|
||||
layers = cogl_material_get_layers (cogl_get_source ());
|
||||
layer0 = (CoglHandle)layers->data;
|
||||
tex_handle = cogl_material_layer_get_texture (layer0);
|
||||
|
||||
@ -986,11 +980,12 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
||||
GList *tmp;
|
||||
GLfloat *v;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
CoglMaterial *copy = NULL;
|
||||
CoglMaterial *source;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
material = ctx->source_material;
|
||||
material = cogl_get_source ();
|
||||
layers = cogl_material_get_layers (material);
|
||||
|
||||
/* Convert the vertices into an array of GLfloats ready to pass to
|
||||
@ -1045,11 +1040,12 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
||||
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
copy = cogl_material_copy (cogl_get_source ());
|
||||
_cogl_material_apply_legacy_state (copy);
|
||||
source = copy;
|
||||
}
|
||||
else
|
||||
source = ctx->source_material;
|
||||
source = cogl_get_source ();
|
||||
|
||||
options.flags = 0;
|
||||
|
||||
@ -1066,17 +1062,20 @@ _cogl_multitexture_polygon_single_primitive (const CoglTextureVertex *vertices,
|
||||
if (options.flags)
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
if (!copy)
|
||||
{
|
||||
copy = cogl_material_copy (source);
|
||||
source = copy;
|
||||
}
|
||||
_cogl_material_apply_overrides (copy, &options);
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (source, use_color);
|
||||
|
||||
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
if (G_UNLIKELY (copy))
|
||||
cogl_handle_unref (copy);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1084,7 +1083,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
unsigned int n_vertices,
|
||||
gboolean use_color)
|
||||
{
|
||||
CoglHandle material;
|
||||
CoglMaterial *material;
|
||||
CoglMaterial *copy = NULL;
|
||||
const GList *layers, *tmp;
|
||||
int n_layers;
|
||||
gboolean use_sliced_polygon_fallback = FALSE;
|
||||
@ -1096,8 +1096,6 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
GLfloat *v;
|
||||
CoglMaterialWrapModeOverrides wrap_mode_overrides;
|
||||
CoglMaterialWrapModeOverrides *wrap_mode_overrides_p = NULL;
|
||||
CoglHandle original_source_material = NULL;
|
||||
gboolean overrode_material = FALSE;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
@ -1108,8 +1106,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
* always be done first when preparing to draw. */
|
||||
_cogl_framebuffer_flush_state (_cogl_get_framebuffer (), 0);
|
||||
|
||||
material = ctx->source_material;
|
||||
layers = cogl_material_get_layers (ctx->source_material);
|
||||
material = cogl_get_source ();
|
||||
layers = cogl_material_get_layers (material);
|
||||
n_layers = g_list_length ((GList *)layers);
|
||||
|
||||
memset (&wrap_mode_overrides, 0, sizeof (wrap_mode_overrides));
|
||||
@ -1237,24 +1235,19 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
|
||||
if (use_color)
|
||||
{
|
||||
CoglHandle override;
|
||||
enable_flags |= COGL_ENABLE_COLOR_ARRAY;
|
||||
GE( glColorPointer (4, GL_UNSIGNED_BYTE,
|
||||
stride_bytes,
|
||||
/* NB: [X,Y,Z,TX,TY...,R,G,B,A,...] */
|
||||
v + 3 + 2 * n_layers) );
|
||||
|
||||
if (!_cogl_material_get_real_blend_enabled (ctx->source_material))
|
||||
if (!_cogl_material_get_real_blend_enabled (material))
|
||||
{
|
||||
CoglMaterialBlendEnable blend_enabled =
|
||||
COGL_MATERIAL_BLEND_ENABLE_ENABLED;
|
||||
original_source_material = ctx->source_material;
|
||||
override = cogl_material_copy (original_source_material);
|
||||
_cogl_material_set_blend_enabled (override, blend_enabled);
|
||||
|
||||
/* XXX: cogl_push_source () */
|
||||
overrode_material = TRUE;
|
||||
ctx->source_material = override;
|
||||
copy = cogl_material_copy (material);
|
||||
_cogl_material_set_blend_enabled (copy, blend_enabled);
|
||||
material = copy;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1277,6 +1270,8 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
_cogl_bitmask_set_range (&ctx->temp_bitmask, n_layers, TRUE);
|
||||
_cogl_disable_other_texcoord_arrays (&ctx->temp_bitmask);
|
||||
|
||||
cogl_push_source (material);
|
||||
|
||||
if (use_sliced_polygon_fallback)
|
||||
_cogl_texture_polygon_multiple_primitives (vertices,
|
||||
n_vertices,
|
||||
@ -1291,15 +1286,13 @@ cogl_polygon (const CoglTextureVertex *vertices,
|
||||
fallback_layers,
|
||||
wrap_mode_overrides_p);
|
||||
|
||||
/* XXX: cogl_pop_source () */
|
||||
if (overrode_material)
|
||||
{
|
||||
cogl_handle_unref (ctx->source_material);
|
||||
ctx->source_material = original_source_material;
|
||||
cogl_pop_source ();
|
||||
|
||||
if (copy)
|
||||
cogl_object_unref (copy);
|
||||
/* XXX: when we have weak materials then any override material
|
||||
* should get associated with the original material so we don't
|
||||
* create lots of one-shot materials! */
|
||||
}
|
||||
|
||||
/* Reset the size of the logged vertex array because rendering
|
||||
rectangles expects it to start at 0 */
|
||||
|
@ -1047,7 +1047,6 @@ _cogl_texture_draw_and_read (CoglHandle handle,
|
||||
CoglFramebuffer *framebuffer;
|
||||
int viewport[4];
|
||||
CoglBitmap *alpha_bmp;
|
||||
CoglHandle prev_source;
|
||||
CoglMatrixStack *projection_stack;
|
||||
CoglMatrixStack *modelview_stack;
|
||||
int target_width = _cogl_bitmap_get_width (target_bmp);
|
||||
@ -1093,8 +1092,7 @@ _cogl_texture_draw_and_read (CoglHandle handle,
|
||||
NULL);
|
||||
}
|
||||
|
||||
prev_source = cogl_handle_ref (ctx->source_material);
|
||||
cogl_set_source (ctx->texture_download_material);
|
||||
cogl_push_source (ctx->texture_download_material);
|
||||
|
||||
cogl_material_set_layer (ctx->texture_download_material, 0, handle);
|
||||
|
||||
@ -1178,8 +1176,7 @@ _cogl_texture_draw_and_read (CoglHandle handle,
|
||||
_cogl_matrix_stack_pop (projection_stack);
|
||||
|
||||
/* restore the original material */
|
||||
cogl_set_source (prev_source);
|
||||
cogl_handle_unref (prev_source);
|
||||
cogl_pop_source ();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1524,11 +1524,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
int i;
|
||||
gboolean skip_gl_color = FALSE;
|
||||
CoglMaterialFlushOptions options;
|
||||
CoglHandle source;
|
||||
CoglMaterial *source;
|
||||
CoglMaterial *copy = NULL;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||
|
||||
source = ctx->source_material;
|
||||
source = cogl_get_source ();
|
||||
|
||||
if (buffer->new_attributes)
|
||||
cogl_vertex_buffer_submit_real (buffer);
|
||||
@ -1592,12 +1593,13 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
attribute->stride,
|
||||
pointer));
|
||||
|
||||
if (!_cogl_material_get_real_blend_enabled (ctx->source_material))
|
||||
if (!_cogl_material_get_real_blend_enabled (source))
|
||||
{
|
||||
CoglMaterialBlendEnable blend_enable =
|
||||
COGL_MATERIAL_BLEND_ENABLE_ENABLED;
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_set_blend_enabled (source, blend_enable);
|
||||
copy = cogl_material_copy (source);
|
||||
_cogl_material_set_blend_enabled (copy, blend_enable);
|
||||
source = copy;
|
||||
skip_gl_color = TRUE;
|
||||
}
|
||||
break;
|
||||
@ -1745,9 +1747,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
if (G_UNLIKELY (options.flags))
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_overrides (source, &options);
|
||||
if (!copy)
|
||||
{
|
||||
copy = cogl_material_copy (source);
|
||||
source = copy;
|
||||
}
|
||||
_cogl_material_apply_overrides (copy, &options);
|
||||
|
||||
/* TODO:
|
||||
* overrides = cogl_material_get_data (material,
|
||||
@ -1770,7 +1775,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
* {
|
||||
* overrides = g_slice_new (Overrides);
|
||||
* overrides->weak_material =
|
||||
* cogl_material_weak_copy (ctx->source_material);
|
||||
* cogl_material_weak_copy (source);
|
||||
* _cogl_material_apply_overrides (overrides->weak_material,
|
||||
* &options);
|
||||
*
|
||||
@ -1786,9 +1791,12 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
if (G_UNLIKELY (ctx->legacy_state_set))
|
||||
{
|
||||
/* If we haven't already created a derived material... */
|
||||
if (source == ctx->source_material)
|
||||
source = cogl_material_copy (ctx->source_material);
|
||||
_cogl_material_apply_legacy_state (source);
|
||||
if (!copy)
|
||||
{
|
||||
copy = cogl_material_copy (source);
|
||||
source = copy;
|
||||
}
|
||||
_cogl_material_apply_legacy_state (copy);
|
||||
}
|
||||
|
||||
_cogl_material_flush_gl_state (source, skip_gl_color);
|
||||
@ -1804,7 +1812,7 @@ enable_state_for_drawing_buffer (CoglVertexBuffer *buffer)
|
||||
|
||||
static void
|
||||
disable_state_for_drawing_buffer (CoglVertexBuffer *buffer,
|
||||
CoglHandle source)
|
||||
CoglMaterial *source)
|
||||
{
|
||||
GList *tmp;
|
||||
GLenum gl_type;
|
||||
@ -1814,8 +1822,8 @@ disable_state_for_drawing_buffer (CoglVertexBuffer *buffer,
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
if (G_UNLIKELY (source != ctx->source_material))
|
||||
cogl_handle_unref (source);
|
||||
if (G_UNLIKELY (source != cogl_get_source ()))
|
||||
cogl_object_unref (source);
|
||||
|
||||
/* Disable all the client state that cogl doesn't currently know
|
||||
* about:
|
||||
|
113
cogl/cogl.c
113
cogl/cogl.c
@ -756,7 +756,7 @@ cogl_begin_gl (void)
|
||||
* A user should instead call cogl_set_source_color4ub() before
|
||||
* cogl_begin_gl() to simplify the state flushed.
|
||||
*/
|
||||
_cogl_material_flush_gl_state (ctx->source_material, FALSE);
|
||||
_cogl_material_flush_gl_state (cogl_get_source (), FALSE);
|
||||
|
||||
if (ctx->enable_backface_culling)
|
||||
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||
@ -946,22 +946,113 @@ _cogl_driver_error_quark (void)
|
||||
return g_quark_from_static_string ("cogl-driver-error-quark");
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_source (CoglHandle material_handle)
|
||||
typedef struct _CoglSourceState
|
||||
{
|
||||
CoglMaterial *material;
|
||||
int push_count;
|
||||
} CoglSourceState;
|
||||
|
||||
static void
|
||||
_push_source_real (CoglMaterial *material)
|
||||
{
|
||||
CoglSourceState *top = g_slice_new (CoglSourceState);
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (cogl_is_material (material_handle));
|
||||
top->material = cogl_object_ref (material);
|
||||
top->push_count = 1;
|
||||
|
||||
if (ctx->source_material == material_handle)
|
||||
ctx->source_stack = g_list_prepend (ctx->source_stack, top);
|
||||
}
|
||||
|
||||
/* FIXME: This should take a context pointer for Cogl 2.0 Technically
|
||||
* we could make it so we can retrieve a context reference from the
|
||||
* material, but this would not by symmetric with cogl_pop_source. */
|
||||
void
|
||||
cogl_push_source (CoglMaterial *material)
|
||||
{
|
||||
CoglSourceState *top;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (cogl_is_material (material));
|
||||
|
||||
if (ctx->source_stack)
|
||||
{
|
||||
top = ctx->source_stack->data;
|
||||
if (top->material == material)
|
||||
{
|
||||
top->push_count++;
|
||||
return;
|
||||
}
|
||||
else
|
||||
_push_source_real (material);
|
||||
}
|
||||
else
|
||||
_push_source_real (material);
|
||||
}
|
||||
|
||||
/* FIXME: This needs to take a context pointer for Cogl 2.0 */
|
||||
void
|
||||
cogl_pop_source (void)
|
||||
{
|
||||
CoglSourceState *top;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (ctx->source_stack);
|
||||
|
||||
top = ctx->source_stack->data;
|
||||
top->push_count--;
|
||||
if (top->push_count == 0)
|
||||
{
|
||||
cogl_object_unref (top->material);
|
||||
g_slice_free (CoglSourceState, top);
|
||||
ctx->source_stack = g_list_delete_link (ctx->source_stack,
|
||||
ctx->source_stack);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: This needs to take a context pointer for Cogl 2.0 */
|
||||
CoglMaterial *
|
||||
cogl_get_source (void)
|
||||
{
|
||||
CoglSourceState *top;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NULL);
|
||||
|
||||
g_return_val_if_fail (ctx->source_stack, NULL);
|
||||
|
||||
top = ctx->source_stack->data;
|
||||
return top->material;
|
||||
}
|
||||
|
||||
void
|
||||
cogl_set_source (CoglMaterial *material)
|
||||
{
|
||||
CoglSourceState *top;
|
||||
|
||||
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||
|
||||
g_return_if_fail (cogl_is_material (material));
|
||||
g_return_if_fail (ctx->source_stack);
|
||||
|
||||
top = ctx->source_stack->data;
|
||||
if (top->material == material)
|
||||
return;
|
||||
|
||||
cogl_handle_ref (material_handle);
|
||||
|
||||
if (ctx->source_material)
|
||||
cogl_handle_unref (ctx->source_material);
|
||||
|
||||
ctx->source_material = material_handle;
|
||||
if (top->push_count == 1)
|
||||
{
|
||||
/* NB: top->material may be only thing keeping material
|
||||
* alive currently so ref material first... */
|
||||
cogl_object_ref (material);
|
||||
cogl_object_unref (top->material);
|
||||
top->material = material;
|
||||
}
|
||||
else
|
||||
{
|
||||
top->push_count--;
|
||||
cogl_push_source (material);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
58
cogl/cogl.h
58
cogl/cogl.h
@ -574,19 +574,61 @@ cogl_clear (const CoglColor *color,
|
||||
|
||||
/**
|
||||
* cogl_set_source:
|
||||
* @material: A #CoglHandle for a material
|
||||
* @material: A #CoglMaterial
|
||||
*
|
||||
* This function sets the source material that will be used to fill subsequent
|
||||
* geometry emitted via the cogl API.
|
||||
*
|
||||
* <note>In the future we may add the ability to set a front facing material,
|
||||
* and a back facing material, in which case this function will set both to the
|
||||
* same.</note>
|
||||
* This function changes the material at the top of the source stack.
|
||||
* The material at the top of this stack defines the GPU state used to
|
||||
* process subsequent primitives, such as rectangles drawn with
|
||||
* cogl_rectangle() or vertices drawn using cogl_vertex_buffer_draw().
|
||||
*
|
||||
* Since: 1.0
|
||||
*/
|
||||
void
|
||||
cogl_set_source (CoglHandle material);
|
||||
cogl_set_source (CoglMaterial *material);
|
||||
|
||||
/**
|
||||
* cogl_get_source:
|
||||
*
|
||||
* Returns the current source material as previously set using
|
||||
* cogl_set_source().
|
||||
*
|
||||
* <note>You should typically consider the returned material immutable
|
||||
* and not try to change any of its properties unless you own a
|
||||
* reference to that material. At times you may be able to get a
|
||||
* reference to an internally managed materials and the result of
|
||||
* modifying such materials is undefined.</note>
|
||||
*
|
||||
* Return value: The current source material.
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
CoglMaterial *
|
||||
cogl_get_source (void);
|
||||
|
||||
/**
|
||||
* cogl_push_source:
|
||||
* @material: A #CoglMaterial
|
||||
*
|
||||
* Pushes the given @material to the top of the source stack. The
|
||||
* material at the top of this stack defines the GPU state used to
|
||||
* process later primitives as defined by cogl_set_source().
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
cogl_push_source (CoglMaterial *material);
|
||||
|
||||
/**
|
||||
* cogl_pop_source:
|
||||
*
|
||||
* Removes the material at the top of the source stack. The material
|
||||
* at the top of this stack defines the GPU state used to process
|
||||
* later primitives as defined by cogl_set_source().
|
||||
*
|
||||
* Since: 1.6
|
||||
*/
|
||||
void
|
||||
cogl_pop_source (void);
|
||||
|
||||
/**
|
||||
* cogl_set_source_color:
|
||||
|
@ -61,6 +61,9 @@ cogl_set_source_color
|
||||
cogl_set_source_color4ub
|
||||
cogl_set_source_color4f
|
||||
cogl_set_source_texture
|
||||
cogl_get_source
|
||||
cogl_push_source
|
||||
cogl_pop_source
|
||||
|
||||
<SUBSECTION>
|
||||
CoglReadPixelsFlags
|
||||
|
Loading…
Reference in New Issue
Block a user