framebuffer: Add cogl_framebuffer draw methods

This adds cogl_framebuffer_ apis for drawing attributes and primitives
that replace corresponding apis that depend on the default CoglContext.
This is part of the on going effort to adapt the Cogl api so it no
longer depends on a global context variable.

All the new drawing functions also take an explicit pipeline argument
since we are also aiming to avoid being a stateful api like Cairo and
OpenGL. Being stateless makes it easier for orthogonal components to
share access to the GPU. Being stateless should also minimize any
impedance miss-match for those wanting to build higher level stateless
apis on top of Cogl.

Note: none of the legacy, global state options such as
cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
cogl_program_use() are supported by these new drawing apis and if set
will simply be silently ignored.

Reviewed-by: Neil Roberts <neil@linux.intel.com>
This commit is contained in:
Robert Bragg 2012-01-08 02:59:04 +00:00
parent 0365f6cda3
commit 92c3063014
25 changed files with 959 additions and 725 deletions

View File

@ -364,7 +364,9 @@ emit_vertex_buffer_geometry (CoglPangoDisplayListNode *node)
cogl_object_unref (attributes[1]);
}
cogl_primitive_draw (node->d.texture.primitive);
cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
cogl_get_source (),
node->d.texture.primitive);
}
static void

View File

@ -69,13 +69,14 @@ typedef enum
COGL_DRAW_SKIP_JOURNAL_FLUSH = 1 << 0,
COGL_DRAW_SKIP_PIPELINE_VALIDATION = 1 << 1,
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH = 1 << 2,
COGL_DRAW_SKIP_LEGACY_STATE = 1 << 3,
/* By default the vertex attribute drawing code will assume that if
there is a color attribute array enabled then we can't determine
if the colors will be opaque so we need to enabling
blending. However when drawing from the journal we know what the
contents of the color array is so we can override this by passing
this flag. */
COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 3
COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE = 1 << 4
} CoglDrawFlags;
/* During CoglContext initialization we register the "cogl_color_in"
@ -94,25 +95,15 @@ _cogl_attribute_immutable_ref (CoglAttribute *attribute);
void
_cogl_attribute_immutable_unref (CoglAttribute *attribute);
void
_cogl_draw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags);
void
_cogl_draw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags);
void
_cogl_attribute_disable_cached_arrays (void);
void
_cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglDrawFlags flags,
CoglAttribute **attributes,
int n_attributes);
#endif /* __COGL_ATTRIBUTE_PRIVATE_H */

View File

@ -538,32 +538,31 @@ apply_attribute_enable_updates (CoglContext *context,
&changed_bits_state);
}
static CoglPipeline *
flush_state (CoglDrawFlags flags,
CoglAttribute **attributes,
int n_attributes,
ValidateLayerState *state)
void
_cogl_flush_attributes_state (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglDrawFlags flags,
CoglAttribute **attributes,
int n_attributes)
{
CoglFramebuffer *framebuffer = cogl_get_draw_framebuffer ();
int i;
gboolean skip_gl_color = FALSE;
CoglPipeline *source = cogl_get_source ();
CoglPipeline *copy = NULL;
int n_tex_coord_attribs = 0;
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
ValidateLayerState layers_state;
CoglContext *ctx = framebuffer->context;
if (!(flags & COGL_DRAW_SKIP_JOURNAL_FLUSH))
_cogl_journal_flush (framebuffer->journal, framebuffer);
state->unit = 0;
state->options.flags = 0;
state->fallback_layers = 0;
layers_state.unit = 0;
layers_state.options.flags = 0;
layers_state.fallback_layers = 0;
if (!(flags & COGL_DRAW_SKIP_PIPELINE_VALIDATION))
cogl_pipeline_foreach_layer (cogl_get_source (),
cogl_pipeline_foreach_layer (pipeline,
validate_layer_cb,
state);
&layers_state);
/* NB: _cogl_framebuffer_flush_state may disrupt various state (such
* as the pipeline state) when flushing the clip stack, so should
@ -572,8 +571,8 @@ flush_state (CoglDrawFlags flags,
* stack can cause some drawing which would change the array
* pointers. */
if (!(flags & COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH))
_cogl_framebuffer_flush_state (cogl_get_draw_framebuffer (),
_cogl_get_read_framebuffer (),
_cogl_framebuffer_flush_state (framebuffer,
framebuffer,
COGL_FRAMEBUFFER_STATE_ALL);
/* In cogl_read_pixels we have a fast-path when reading a single
@ -590,13 +589,13 @@ flush_state (CoglDrawFlags flags,
{
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
if ((flags & COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE) == 0 &&
!_cogl_pipeline_get_real_blend_enabled (source))
!_cogl_pipeline_get_real_blend_enabled (pipeline))
{
CoglPipelineBlendEnable blend_enable =
COGL_PIPELINE_BLEND_ENABLE_ENABLED;
copy = cogl_pipeline_copy (source);
copy = cogl_pipeline_copy (pipeline);
_cogl_pipeline_set_blend_enabled (copy, blend_enable);
source = copy;
pipeline = copy;
}
skip_gl_color = TRUE;
break;
@ -609,15 +608,15 @@ flush_state (CoglDrawFlags flags,
break;
}
if (G_UNLIKELY (state->options.flags))
if (G_UNLIKELY (layers_state.options.flags))
{
/* If we haven't already created a derived pipeline... */
if (!copy)
{
copy = cogl_pipeline_copy (source);
source = copy;
copy = cogl_pipeline_copy (pipeline);
pipeline = copy;
}
_cogl_pipeline_apply_overrides (source, &state->options);
_cogl_pipeline_apply_overrides (pipeline, &layers_state.options);
/* TODO:
* overrides = cogl_pipeline_get_data (pipeline,
@ -640,7 +639,7 @@ flush_state (CoglDrawFlags flags,
* {
* overrides = g_slice_new (Overrides);
* overrides->weak_pipeline =
* cogl_pipeline_weak_copy (cogl_get_source ());
* cogl_pipeline_weak_copy (pipeline);
* _cogl_pipeline_apply_overrides (overrides->weak_pipeline,
* &options);
*
@ -649,23 +648,24 @@ flush_state (CoglDrawFlags flags,
* free_overrides_cb,
* NULL);
* }
* source = overrides->weak_pipeline;
* pipeline = overrides->weak_pipeline;
*/
}
if (G_UNLIKELY (ctx->legacy_state_set) &&
if (G_UNLIKELY (!(flags & COGL_DRAW_SKIP_LEGACY_STATE)) &&
G_UNLIKELY (ctx->legacy_state_set) &&
_cogl_get_enable_legacy_state ())
{
/* If we haven't already created a derived pipeline... */
if (!copy)
{
copy = cogl_pipeline_copy (source);
source = copy;
copy = cogl_pipeline_copy (pipeline);
pipeline = copy;
}
_cogl_pipeline_apply_legacy_state (source);
_cogl_pipeline_apply_legacy_state (pipeline);
}
_cogl_pipeline_flush_gl_state (source, skip_gl_color, n_tex_coord_attribs);
_cogl_pipeline_flush_gl_state (pipeline, skip_gl_color, n_tex_coord_attribs);
_cogl_bitmask_clear_all (&ctx->enable_builtin_attributes_tmp);
_cogl_bitmask_clear_all (&ctx->enable_texcoord_attributes_tmp);
@ -691,7 +691,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_COLOR_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
setup_generic_attribute (ctx, source, attribute, base);
setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@ -706,7 +706,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_NORMAL_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
setup_generic_attribute (ctx, source, attribute, base);
setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@ -720,7 +720,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_TEXTURE_COORD_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
setup_generic_attribute (ctx, source, attribute, base);
setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@ -738,7 +738,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY:
#ifdef HAVE_COGL_GLES2
if (ctx->driver == COGL_DRIVER_GLES2)
setup_generic_attribute (ctx, source, attribute, base);
setup_generic_attribute (ctx, pipeline, attribute, base);
else
#endif
{
@ -753,7 +753,7 @@ flush_state (CoglDrawFlags flags,
case COGL_ATTRIBUTE_NAME_ID_CUSTOM_ARRAY:
#ifdef COGL_PIPELINE_PROGEND_GLSL
if (ctx->driver != COGL_DRIVER_GLES1)
setup_generic_attribute (ctx, source, attribute, base);
setup_generic_attribute (ctx, pipeline, attribute, base);
#endif
break;
default:
@ -763,9 +763,10 @@ flush_state (CoglDrawFlags flags,
_cogl_buffer_unbind (buffer);
}
apply_attribute_enable_updates (ctx, source);
apply_attribute_enable_updates (ctx, pipeline);
return source;
if (copy)
cogl_object_unref (copy);
}
void
@ -782,440 +783,3 @@ _cogl_attribute_disable_cached_arrays (void)
* attributes. */
apply_attribute_enable_updates (ctx, NULL);
}
#ifdef COGL_ENABLE_DEBUG
static int
get_index (void *indices,
CoglIndicesType type,
int _index)
{
if (!indices)
return _index;
switch (type)
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
return ((guint8 *)indices)[_index];
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
return ((guint16 *)indices)[_index];
case COGL_INDICES_TYPE_UNSIGNED_INT:
return ((guint32 *)indices)[_index];
}
g_return_val_if_reached (0);
}
static void
add_line (void *vertices,
void *indices,
CoglIndicesType indices_type,
CoglAttribute *attribute,
int start,
int end,
CoglVertexP3 *lines,
int *n_line_vertices)
{
int start_index = get_index (indices, indices_type, start);
int end_index = get_index (indices, indices_type, end);
float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride);
float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride);
float *o = (float *)(&lines[*n_line_vertices]);
int i;
for (i = 0; i < attribute->n_components; i++)
*(o++) = *(v0++);
for (;i < 3; i++)
*(o++) = 0;
for (i = 0; i < attribute->n_components; i++)
*(o++) = *(v1++);
for (;i < 3; i++)
*(o++) = 0;
*n_line_vertices += 2;
}
static CoglVertexP3 *
get_wire_lines (CoglAttribute *attribute,
CoglVerticesMode mode,
int n_vertices_in,
int *n_vertices_out,
CoglIndices *_indices)
{
CoglAttributeBuffer *attribute_buffer = cogl_attribute_get_buffer (attribute);
void *vertices;
CoglIndexBuffer *index_buffer;
void *indices;
CoglIndicesType indices_type;
int i;
int n_lines;
CoglVertexP3 *out = NULL;
vertices = cogl_buffer_map (COGL_BUFFER (attribute_buffer),
COGL_BUFFER_ACCESS_READ, 0);
if (_indices)
{
index_buffer = cogl_indices_get_buffer (_indices);
indices = cogl_buffer_map (COGL_BUFFER (index_buffer),
COGL_BUFFER_ACCESS_READ, 0);
indices_type = cogl_indices_get_type (_indices);
}
else
{
index_buffer = NULL;
indices = NULL;
indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE;
}
*n_vertices_out = 0;
if (mode == COGL_VERTICES_MODE_TRIANGLES &&
(n_vertices_in % 3) == 0)
{
n_lines = n_vertices_in;
out = g_new (CoglVertexP3, n_lines * 2);
for (i = 0; i < n_vertices_in; i += 3)
{
add_line (vertices, indices, indices_type, attribute,
i, i+1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i+1, i+2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i+2, i, out, n_vertices_out);
}
}
else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN &&
n_vertices_in >= 3)
{
n_lines = 2 * n_vertices_in - 3;
out = g_new (CoglVertexP3, n_lines * 2);
add_line (vertices, indices, indices_type, attribute,
0, 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
1, 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, 2, out, n_vertices_out);
for (i = 3; i < n_vertices_in; i++)
{
add_line (vertices, indices, indices_type, attribute,
i - 1, i, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, i, out, n_vertices_out);
}
}
else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP &&
n_vertices_in >= 3)
{
n_lines = 2 * n_vertices_in - 3;
out = g_new (CoglVertexP3, n_lines * 2);
add_line (vertices, indices, indices_type, attribute,
0, 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
1, 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, 2, out, n_vertices_out);
for (i = 3; i < n_vertices_in; i++)
{
add_line (vertices, indices, indices_type, attribute,
i - 1, i, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i - 2, i, out, n_vertices_out);
}
}
/* In the journal we are a bit sneaky and actually use GL_QUADS
* which isn't actually a valid CoglVerticesMode! */
#ifdef HAVE_COGL_GL
else if (mode == GL_QUADS && (n_vertices_in % 4) == 0)
{
n_lines = n_vertices_in;
out = g_new (CoglVertexP3, n_lines * 2);
for (i = 0; i < n_vertices_in; i += 4)
{
add_line (vertices, indices, indices_type, attribute,
i, i + 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 1, i + 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 2, i + 3, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 3, i, out, n_vertices_out);
}
}
#endif
if (vertices != NULL)
cogl_buffer_unmap (COGL_BUFFER (attribute_buffer));
if (indices != NULL)
cogl_buffer_unmap (COGL_BUFFER (index_buffer));
return out;
}
static void
draw_wireframe (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglIndices *indices)
{
CoglAttribute *position = NULL;
int i;
int n_line_vertices;
static CoglPipeline *wire_pipeline;
CoglAttribute *wire_attribute[1];
CoglVertexP3 *lines;
CoglAttributeBuffer *attribute_buffer;
for (i = 0; i < n_attributes; i++)
{
if (attributes[i]->name_state->name_id ==
COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY)
{
position = attributes[i];
break;
}
}
if (!position)
return;
lines = get_wire_lines (position,
mode,
n_vertices,
&n_line_vertices,
indices);
attribute_buffer =
cogl_attribute_buffer_new (sizeof (CoglVertexP3) * n_line_vertices,
lines);
wire_attribute[0] =
cogl_attribute_new (attribute_buffer, "cogl_position_in",
sizeof (CoglVertexP3),
0,
3,
COGL_ATTRIBUTE_TYPE_FLOAT);
cogl_object_unref (attribute_buffer);
if (!wire_pipeline)
{
wire_pipeline = cogl_pipeline_new ();
cogl_pipeline_set_color4ub (wire_pipeline,
0x00, 0xff, 0x00, 0xff);
}
_cogl_push_source (wire_pipeline, FALSE);
/* temporarily disable the wireframe to avoid recursion! */
COGL_DEBUG_CLEAR_FLAG (COGL_DEBUG_WIREFRAME);
_cogl_draw_attributes (COGL_VERTICES_MODE_LINES,
0,
n_line_vertices,
wire_attribute,
1,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME);
cogl_pop_source ();
cogl_object_unref (wire_attribute[0]);
}
#endif
/* This can be called directly by the CoglJournal to draw attributes
* skipping the implicit journal flush, the framebuffer flush and
* pipeline validation. */
void
_cogl_draw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags)
{
ValidateLayerState state;
CoglPipeline *source;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
source = flush_state (flags, attributes, n_attributes, &state);
GE (ctx, glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
if (G_UNLIKELY (source != cogl_get_source ()))
cogl_object_unref (source);
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
draw_wireframe (mode, first_vertex, n_vertices,
attributes, n_attributes, NULL);
#endif
}
void
cogl_draw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes)
{
_cogl_draw_attributes (mode, first_vertex,
n_vertices,
attributes, n_attributes,
0 /* no flags */);
}
void
cogl_vdraw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
...)
{
va_list ap;
int n_attributes;
CoglAttribute *attribute;
CoglAttribute **attributes;
int i;
va_start (ap, n_vertices);
for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
;
va_end (ap);
attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
va_start (ap, n_vertices);
for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
attributes[i] = attribute;
va_end (ap);
cogl_draw_attributes (mode, first_vertex, n_vertices,
attributes, n_attributes);
}
static size_t
sizeof_index_type (CoglIndicesType type)
{
switch (type)
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
return 1;
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
return 2;
case COGL_INDICES_TYPE_UNSIGNED_INT:
return 4;
}
g_return_val_if_reached (0);
}
void
_cogl_draw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags)
{
ValidateLayerState state;
CoglPipeline *source;
CoglBuffer *buffer;
guint8 *base;
size_t buffer_offset;
size_t index_size;
GLenum indices_gl_type = 0;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
source = flush_state (flags, attributes, n_attributes, &state);
buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
buffer_offset = cogl_indices_get_offset (indices);
index_size = sizeof_index_type (cogl_indices_get_type (indices));
switch (cogl_indices_get_type (indices))
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
indices_gl_type = GL_UNSIGNED_BYTE;
break;
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
indices_gl_type = GL_UNSIGNED_SHORT;
break;
case COGL_INDICES_TYPE_UNSIGNED_INT:
indices_gl_type = GL_UNSIGNED_INT;
break;
}
GE (ctx, glDrawElements ((GLenum)mode,
n_vertices,
indices_gl_type,
base + buffer_offset + index_size * first_vertex));
_cogl_buffer_unbind (buffer);
if (G_UNLIKELY (source != cogl_get_source ()))
cogl_object_unref (source);
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
draw_wireframe (mode, first_vertex, n_vertices,
attributes, n_attributes, indices);
#endif
}
void
cogl_draw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes)
{
_cogl_draw_indexed_attributes (mode, first_vertex,
n_vertices, indices,
attributes, n_attributes,
0 /* no flags */);
}
void
cogl_vdraw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
...)
{
va_list ap;
int n_attributes;
CoglAttribute **attributes;
int i;
CoglAttribute *attribute;
va_start (ap, indices);
for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
;
va_end (ap);
attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
va_start (ap, indices);
for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
attributes[i] = attribute;
va_end (ap);
cogl_draw_indexed_attributes (mode,
first_vertex,
n_vertices,
indices,
attributes,
n_attributes);
}

View File

@ -213,34 +213,6 @@ cogl_attribute_set_buffer (CoglAttribute *attribute,
gboolean
cogl_is_attribute (void *object);
void
cogl_vdraw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
...) G_GNUC_NULL_TERMINATED;
void
cogl_draw_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes);
void
cogl_vdraw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
...) G_GNUC_NULL_TERMINATED;
void
cogl_draw_indexed_attributes (CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes);
G_END_DECLS
#endif /* __COGL_ATTRIBUTE_H__ */

View File

@ -218,9 +218,6 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
_cogl_framebuffer_get_projection_stack (framebuffer);
CoglContext *ctx = cogl_framebuffer_get_context (framebuffer);
/* temporarily swap in our special stenciling pipeline */
_cogl_push_source (ctx->stencil_pipeline, FALSE);
/* This can be called from the journal code which doesn't flush
the matrix stacks between calls so we need to ensure they're
flushed now */
@ -239,7 +236,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( ctx, glStencilOp (GL_REPLACE, GL_REPLACE, GL_REPLACE) );
_cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
_cogl_rectangle_immediate (framebuffer,
ctx->stencil_pipeline,
x_1, y_1, x_2, y_2);
}
else
{
@ -247,7 +246,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
rectangle */
GE( ctx, glStencilFunc (GL_NEVER, 0x1, 0x3) );
GE( ctx, glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
_cogl_rectangle_immediate (x_1, y_1, x_2, y_2);
_cogl_rectangle_immediate (framebuffer,
ctx->stencil_pipeline,
x_1, y_1, x_2, y_2);
/* Subtract one from all pixels in the stencil buffer so that
only pixels where both the original stencil buffer and the
@ -263,7 +264,9 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
_cogl_context_set_current_projection (ctx, projection_stack);
_cogl_context_set_current_modelview (ctx, modelview_stack);
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
_cogl_rectangle_immediate (framebuffer,
ctx->stencil_pipeline,
-1.0, -1.0, 1.0, 1.0);
_cogl_matrix_stack_pop (modelview_stack);
_cogl_matrix_stack_pop (projection_stack);
@ -272,9 +275,6 @@ add_stencil_clip_rectangle (CoglFramebuffer *framebuffer,
/* Restore the stencil mode */
GE( ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
/* restore the original source pipeline */
cogl_pop_source ();
}
typedef void (*SilhouettePaintCallback) (void *user_data);
@ -302,9 +302,6 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
_cogl_context_set_current_projection (ctx, projection_stack);
_cogl_context_set_current_modelview (ctx, modelview_stack);
/* Just setup a simple pipeline that doesn't use texturing... */
_cogl_push_source (ctx->stencil_pipeline, FALSE);
_cogl_pipeline_flush_gl_state (ctx->stencil_pipeline, FALSE, 0);
GE( ctx, glEnable (GL_STENCIL_TEST) );
@ -337,7 +334,9 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
/* Just clear the bounding box */
GE( ctx, glStencilMask (~(GLuint) 0) );
GE( ctx, glStencilOp (GL_ZERO, GL_ZERO, GL_ZERO) );
_cogl_rectangle_immediate (bounds_x1, bounds_y1,
_cogl_rectangle_immediate (framebuffer,
ctx->stencil_pipeline,
bounds_x1, bounds_y1,
bounds_x2, bounds_y2);
}
GE (ctx, glStencilMask (1));
@ -364,8 +363,10 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
_cogl_matrix_stack_push (modelview_stack);
_cogl_matrix_stack_load_identity (modelview_stack);
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
_cogl_rectangle_immediate (-1.0, -1.0, 1.0, 1.0);
_cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline,
-1.0, -1.0, 1.0, 1.0);
_cogl_rectangle_immediate (framebuffer, ctx->stencil_pipeline,
-1.0, -1.0, 1.0, 1.0);
_cogl_matrix_stack_pop (modelview_stack);
_cogl_matrix_stack_pop (projection_stack);
@ -377,9 +378,6 @@ add_stencil_clip_silhouette (CoglFramebuffer *framebuffer,
GE (ctx, glStencilFunc (GL_EQUAL, 0x1, 0x1));
GE (ctx, glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP));
/* restore the original pipeline */
cogl_pop_source ();
}
static void
@ -414,10 +412,13 @@ add_stencil_clip_path (CoglFramebuffer *framebuffer,
static void
paint_primitive_silhouette (void *user_data)
{
_cogl_primitive_draw (user_data,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
_cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
cogl_get_source (),
user_data,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
COGL_DRAW_SKIP_LEGACY_STATE);
}
void

View File

@ -29,6 +29,7 @@
#include "cogl-clip-state-private.h"
#include "cogl-journal-private.h"
#include "cogl-winsys-private.h"
#include "cogl-attribute-private.h"
#ifdef COGL_HAS_XLIB_SUPPORT
#include <X11/Xlib.h>
@ -367,4 +368,34 @@ _cogl_framebuffer_restore_clip_stack (CoglFramebuffer *framebuffer);
void
_cogl_framebuffer_unref (CoglFramebuffer *framebuffer);
void
_cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPrimitive *primitive,
CoglDrawFlags flags);
/* This can be called directly by the CoglJournal to draw attributes
* skipping the implicit journal flush, the framebuffer flush and
* pipeline validation. */
void
_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags);
void
_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags);
#endif /* __COGL_FRAMEBUFFER_PRIVATE_H */

View File

@ -41,6 +41,7 @@
#include "cogl-winsys-private.h"
#include "cogl-pipeline-state-private.h"
#include "cogl-matrix-private.h"
#include "cogl-primitive-private.h"
#ifndef GL_FRAMEBUFFER
#define GL_FRAMEBUFFER 0x8D40
@ -2416,3 +2417,489 @@ _cogl_framebuffer_unref (CoglFramebuffer *framebuffer)
/* Chain-up */
_cogl_object_default_unref (framebuffer);
}
#ifdef COGL_ENABLE_DEBUG
static int
get_index (void *indices,
CoglIndicesType type,
int _index)
{
if (!indices)
return _index;
switch (type)
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
return ((guint8 *)indices)[_index];
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
return ((guint16 *)indices)[_index];
case COGL_INDICES_TYPE_UNSIGNED_INT:
return ((guint32 *)indices)[_index];
}
g_return_val_if_reached (0);
}
static void
add_line (void *vertices,
void *indices,
CoglIndicesType indices_type,
CoglAttribute *attribute,
int start,
int end,
CoglVertexP3 *lines,
int *n_line_vertices)
{
int start_index = get_index (indices, indices_type, start);
int end_index = get_index (indices, indices_type, end);
float *v0 = (float *)((guint8 *)vertices + start_index * attribute->stride);
float *v1 = (float *)((guint8 *)vertices + end_index * attribute->stride);
float *o = (float *)(&lines[*n_line_vertices]);
int i;
for (i = 0; i < attribute->n_components; i++)
*(o++) = *(v0++);
for (;i < 3; i++)
*(o++) = 0;
for (i = 0; i < attribute->n_components; i++)
*(o++) = *(v1++);
for (;i < 3; i++)
*(o++) = 0;
*n_line_vertices += 2;
}
static CoglVertexP3 *
get_wire_lines (CoglAttribute *attribute,
CoglVerticesMode mode,
int n_vertices_in,
int *n_vertices_out,
CoglIndices *_indices)
{
CoglAttributeBuffer *attribute_buffer = cogl_attribute_get_buffer (attribute);
void *vertices;
CoglIndexBuffer *index_buffer;
void *indices;
CoglIndicesType indices_type;
int i;
int n_lines;
CoglVertexP3 *out = NULL;
vertices = cogl_buffer_map (COGL_BUFFER (attribute_buffer),
COGL_BUFFER_ACCESS_READ, 0);
if (_indices)
{
index_buffer = cogl_indices_get_buffer (_indices);
indices = cogl_buffer_map (COGL_BUFFER (index_buffer),
COGL_BUFFER_ACCESS_READ, 0);
indices_type = cogl_indices_get_type (_indices);
}
else
{
index_buffer = NULL;
indices = NULL;
indices_type = COGL_INDICES_TYPE_UNSIGNED_BYTE;
}
*n_vertices_out = 0;
if (mode == COGL_VERTICES_MODE_TRIANGLES &&
(n_vertices_in % 3) == 0)
{
n_lines = n_vertices_in;
out = g_new (CoglVertexP3, n_lines * 2);
for (i = 0; i < n_vertices_in; i += 3)
{
add_line (vertices, indices, indices_type, attribute,
i, i+1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i+1, i+2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i+2, i, out, n_vertices_out);
}
}
else if (mode == COGL_VERTICES_MODE_TRIANGLE_FAN &&
n_vertices_in >= 3)
{
n_lines = 2 * n_vertices_in - 3;
out = g_new (CoglVertexP3, n_lines * 2);
add_line (vertices, indices, indices_type, attribute,
0, 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
1, 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, 2, out, n_vertices_out);
for (i = 3; i < n_vertices_in; i++)
{
add_line (vertices, indices, indices_type, attribute,
i - 1, i, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, i, out, n_vertices_out);
}
}
else if (mode == COGL_VERTICES_MODE_TRIANGLE_STRIP &&
n_vertices_in >= 3)
{
n_lines = 2 * n_vertices_in - 3;
out = g_new (CoglVertexP3, n_lines * 2);
add_line (vertices, indices, indices_type, attribute,
0, 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
1, 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
0, 2, out, n_vertices_out);
for (i = 3; i < n_vertices_in; i++)
{
add_line (vertices, indices, indices_type, attribute,
i - 1, i, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i - 2, i, out, n_vertices_out);
}
}
/* In the journal we are a bit sneaky and actually use GL_QUADS
* which isn't actually a valid CoglVerticesMode! */
#ifdef HAVE_COGL_GL
else if (mode == GL_QUADS && (n_vertices_in % 4) == 0)
{
n_lines = n_vertices_in;
out = g_new (CoglVertexP3, n_lines * 2);
for (i = 0; i < n_vertices_in; i += 4)
{
add_line (vertices, indices, indices_type, attribute,
i, i + 1, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 1, i + 2, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 2, i + 3, out, n_vertices_out);
add_line (vertices, indices, indices_type, attribute,
i + 3, i, out, n_vertices_out);
}
}
#endif
if (vertices != NULL)
cogl_buffer_unmap (COGL_BUFFER (attribute_buffer));
if (indices != NULL)
cogl_buffer_unmap (COGL_BUFFER (index_buffer));
return out;
}
static void
draw_wireframe (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglIndices *indices)
{
CoglAttribute *position = NULL;
int i;
int n_line_vertices;
static CoglPipeline *wire_pipeline;
CoglAttribute *wire_attribute[1];
CoglVertexP3 *lines;
CoglAttributeBuffer *attribute_buffer;
for (i = 0; i < n_attributes; i++)
{
if (attributes[i]->name_state->name_id ==
COGL_ATTRIBUTE_NAME_ID_POSITION_ARRAY)
{
position = attributes[i];
break;
}
}
if (!position)
return;
lines = get_wire_lines (position,
mode,
n_vertices,
&n_line_vertices,
indices);
attribute_buffer =
cogl_attribute_buffer_new (sizeof (CoglVertexP3) * n_line_vertices,
lines);
wire_attribute[0] =
cogl_attribute_new (attribute_buffer, "cogl_position_in",
sizeof (CoglVertexP3),
0,
3,
COGL_ATTRIBUTE_TYPE_FLOAT);
cogl_object_unref (attribute_buffer);
if (!wire_pipeline)
{
wire_pipeline = cogl_pipeline_new ();
cogl_pipeline_set_color4ub (wire_pipeline,
0x00, 0xff, 0x00, 0xff);
}
/* temporarily disable the wireframe to avoid recursion! */
COGL_DEBUG_CLEAR_FLAG (COGL_DEBUG_WIREFRAME);
_cogl_framebuffer_draw_attributes (framebuffer,
wire_pipeline,
COGL_VERTICES_MODE_LINES,
0,
n_line_vertices,
wire_attribute,
1,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
COGL_DRAW_SKIP_LEGACY_STATE);
COGL_DEBUG_SET_FLAG (COGL_DEBUG_WIREFRAME);
cogl_object_unref (wire_attribute[0]);
}
#endif
/* This can be called directly by the CoglJournal to draw attributes
* skipping the implicit journal flush, the framebuffer flush and
* pipeline validation. */
void
_cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags)
{
_cogl_flush_attributes_state (framebuffer, pipeline, flags,
attributes, n_attributes);
GE (framebuffer->context,
glDrawArrays ((GLenum)mode, first_vertex, n_vertices));
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
draw_wireframe (framebuffer, pipeline,
mode, first_vertex, n_vertices,
attributes, n_attributes, NULL);
#endif
}
void
cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes)
{
_cogl_framebuffer_draw_attributes (framebuffer,
pipeline,
mode,
first_vertex,
n_vertices,
attributes, n_attributes,
COGL_DRAW_SKIP_LEGACY_STATE);
}
void
cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
...)
{
va_list ap;
int n_attributes;
CoglAttribute *attribute;
CoglAttribute **attributes;
int i;
va_start (ap, n_vertices);
for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
;
va_end (ap);
attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
va_start (ap, n_vertices);
for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
attributes[i] = attribute;
va_end (ap);
_cogl_framebuffer_draw_attributes (framebuffer,
pipeline,
mode, first_vertex, n_vertices,
attributes, n_attributes,
COGL_DRAW_SKIP_LEGACY_STATE);
}
static size_t
sizeof_index_type (CoglIndicesType type)
{
switch (type)
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
return 1;
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
return 2;
case COGL_INDICES_TYPE_UNSIGNED_INT:
return 4;
}
g_return_val_if_reached (0);
}
void
_cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes,
CoglDrawFlags flags)
{
CoglBuffer *buffer;
guint8 *base;
size_t buffer_offset;
size_t index_size;
GLenum indices_gl_type = 0;
_cogl_flush_attributes_state (framebuffer, pipeline, flags,
attributes, n_attributes);
buffer = COGL_BUFFER (cogl_indices_get_buffer (indices));
base = _cogl_buffer_bind (buffer, COGL_BUFFER_BIND_TARGET_INDEX_BUFFER);
buffer_offset = cogl_indices_get_offset (indices);
index_size = sizeof_index_type (cogl_indices_get_type (indices));
switch (cogl_indices_get_type (indices))
{
case COGL_INDICES_TYPE_UNSIGNED_BYTE:
indices_gl_type = GL_UNSIGNED_BYTE;
break;
case COGL_INDICES_TYPE_UNSIGNED_SHORT:
indices_gl_type = GL_UNSIGNED_SHORT;
break;
case COGL_INDICES_TYPE_UNSIGNED_INT:
indices_gl_type = GL_UNSIGNED_INT;
break;
}
GE (framebuffer->context,
glDrawElements ((GLenum)mode,
n_vertices,
indices_gl_type,
base + buffer_offset + index_size * first_vertex));
_cogl_buffer_unbind (buffer);
#ifdef COGL_ENABLE_DEBUG
if (G_UNLIKELY (COGL_DEBUG_ENABLED (COGL_DEBUG_WIREFRAME)))
draw_wireframe (framebuffer, pipeline,
mode, first_vertex, n_vertices,
attributes, n_attributes, indices);
#endif
}
void
cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes)
{
_cogl_framebuffer_draw_indexed_attributes (framebuffer,
pipeline,
mode, first_vertex,
n_vertices, indices,
attributes, n_attributes,
COGL_DRAW_SKIP_LEGACY_STATE);
}
void
cogl_vdraw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
...)
{
va_list ap;
int n_attributes;
CoglAttribute **attributes;
int i;
CoglAttribute *attribute;
va_start (ap, indices);
for (n_attributes = 0; va_arg (ap, CoglAttribute *); n_attributes++)
;
va_end (ap);
attributes = g_alloca (sizeof (CoglAttribute *) * n_attributes);
va_start (ap, indices);
for (i = 0; (attribute = va_arg (ap, CoglAttribute *)); i++)
attributes[i] = attribute;
va_end (ap);
_cogl_framebuffer_draw_indexed_attributes (framebuffer,
pipeline,
mode,
first_vertex,
n_vertices,
indices,
attributes,
n_attributes,
COGL_DRAW_SKIP_LEGACY_STATE);
}
void
_cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPrimitive *primitive,
CoglDrawFlags flags)
{
if (primitive->indices)
_cogl_framebuffer_draw_indexed_attributes (framebuffer,
pipeline,
primitive->mode,
primitive->first_vertex,
primitive->n_vertices,
primitive->indices,
primitive->attributes,
primitive->n_attributes,
flags);
else
_cogl_framebuffer_draw_attributes (framebuffer,
pipeline,
primitive->mode,
primitive->first_vertex,
primitive->n_vertices,
primitive->attributes,
primitive->n_attributes,
flags);
}
void
cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPrimitive *primitive)
{
_cogl_framebuffer_draw_primitive (framebuffer, pipeline, primitive,
COGL_DRAW_SKIP_LEGACY_STATE);
}

View File

@ -973,6 +973,216 @@ cogl_framebuffer_clear4f (CoglFramebuffer *framebuffer,
float blue,
float alpha);
/**
* cogl_framebuffer_draw_primitive:
* @framebuffer: A destination #CoglFramebuffer
* @pipeline: A #CoglPipeline state object
* @primitive: A #CoglPrimitive geometry object
*
* Draws the given @primitive geometry to the specified destination
* @framebuffer using the graphics processing pipeline described by @pipeline.
*
* <note>This api doesn't support any of the legacy global state options such
* as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
* cogl_program_use()</note>
*
* Stability: unstable
* Since: 1.10
*/
void
cogl_framebuffer_draw_primitive (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglPrimitive *primitive);
/**
* cogl_framebuffer_vdraw_attributes:
* @framebuffer: A destination #CoglFramebuffer
* @pipeline: A #CoglPipeline state object
* @mode: The #CoglVerticesMode defining the topology of vertices
* @first_vertex: The vertex offset within the given attributes to draw from
* @n_vertices: The number of vertices to draw from the given attributes
* @...: A set of vertex #CoglAttribute<!-- -->s defining vertex geometry
*
* First defines a geometry primitive by grouping a set of vertex attributes;
* specifying a @first_vertex; a number of vertices (@n_vertices) and
* specifying what kind of topology the vertices have via @mode.
*
* Then the function draws the given @primitive geometry to the specified
* destination @framebuffer using the graphics processing pipeline described by
* @pipeline.
*
* The list of #CoglAttribute<!-- -->s define the attributes of the vertices to
* be drawn, such as positions, colors and normals and should be %NULL
* terminated.
*
* Stability: unstable
* Since: 1.10
*/
void
cogl_framebuffer_vdraw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
...) G_GNUC_NULL_TERMINATED;
/**
* cogl_framebuffer_draw_attributes:
* @framebuffer: A destination #CoglFramebuffer
* @pipeline: A #CoglPipeline state object
* @mode: The #CoglVerticesMode defining the topology of vertices
* @first_vertex: The vertex offset within the given attributes to draw from
* @n_vertices: The number of vertices to draw from the given attributes
* @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex
* geometry
* @n_attributes: The number of attributes in the @attributes array.
*
* First defines a geometry primitive by grouping a set of vertex @attributes;
* specifying a @first_vertex; a number of vertices (@n_vertices) and
* specifying what kind of topology the vertices have via @mode.
*
* Then the function draws the given @primitive geometry to the specified
* destination @framebuffer using the graphics processing pipeline described by
* @pipeline.
*
* The list of #CoglAttribute<!-- -->s define the attributes of the vertices to
* be drawn, such as positions, colors and normals and the number of attributes
* is given as @n_attributes.
*
* <note>This api doesn't support any of the legacy global state options such
* as cogl_set_depth_test_enabled(), cogl_set_backface_culling_enabled() or
* cogl_program_use()</note>
*
* Stability: unstable
* Since: 1.10
*/
void
cogl_framebuffer_draw_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglAttribute **attributes,
int n_attributes);
/**
* cogl_framebuffer_vdraw_indexed_attributes:
* @framebuffer: A destination #CoglFramebuffer
* @pipeline: A #CoglPipeline state object
* @mode: The #CoglVerticesMode defining the topology of vertices
* @first_vertex: The vertex offset within the given attributes to draw from
* @n_vertices: The number of vertices to draw from the given attributes
* @indices: The array of indices used by the GPU to lookup attribute
* data for each vertex.
* @...: A set of vertex #CoglAttribute<!-- -->s defining vertex geometry
*
* Behaves the same as cogl_framebuffer_vdraw_attributes() except that
* instead of reading vertex data sequentially from the specified
* attributes the @indices provide an indirection for how the data
* should be indexed allowing a random access order to be
* specified.
*
* For example an indices array of [0, 1, 2, 0, 2, 3] could be used
* used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES +
* @n_vertices = 6) but only provide attribute data for the 4 corners
* of a rectangle. When the GPU needs to read in each of the 6
* vertices it will read the @indices array for each vertex in
* sequence and use the index to look up the vertex attribute data. So
* here you can see that first and fourth vertex will point to the
* same data and third and fifth vertex will also point to shared
* data.
*
* Drawing with indices can be a good way of minimizing the size of a
* mesh by allowing you to avoid data for duplicate vertices because
* multiple entries in the index array can refer back to a single
* shared vertex.
*
* <note>The @indices array must at least be as long @first_vertex +
* @n_vertices otherwise the GPU will overrun the indices array when
* looking up vertex data.</note>
*
* Since it's very common to want to draw a run of rectangles using
* indices to avoid duplicating vertex data you can use
* cogl_get_rectangle_indices() to get a set of indices that can be
* shared.
*
* <note>This api doesn't support any of the legacy global state
* options such as cogl_set_depth_test_enabled(),
* cogl_set_backface_culling_enabled() or cogl_program_use()</note>
*
* Stability: unstable
* Since: 1.10
*/
void
cogl_framebuffer_vdraw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
...) G_GNUC_NULL_TERMINATED;
/**
* cogl_framebuffer_draw_indexed_attributes:
* @framebuffer: A destination #CoglFramebuffer
* @pipeline: A #CoglPipeline state object
* @mode: The #CoglVerticesMode defining the topology of vertices
* @first_vertex: The vertex offset within the given attributes to draw from
* @n_vertices: The number of vertices to draw from the given attributes
* @indices: The array of indices used by the GPU to lookup attribute
* data for each vertex.
* @attributes: An array of pointers to #CoglAttribute<-- -->s defining vertex
* geometry
* @n_attributes: The number of attributes in the @attributes array.
*
* Behaves the same as cogl_framebuffer_draw_attributes() except that
* instead of reading vertex data sequentially from the specified
* @attributes the @indices provide an indirection for how the data
* should be indexed allowing a random access order to be
* specified.
*
* For example an indices array of [0, 1, 2, 0, 2, 3] could be used
* used to draw two triangles (@mode = %COGL_VERTICES_MODE_TRIANGLES +
* @n_vertices = 6) but only provide attribute data for the 4 corners
* of a rectangle. When the GPU needs to read in each of the 6
* vertices it will read the @indices array for each vertex in
* sequence and use the index to look up the vertex attribute data. So
* here you can see that first and fourth vertex will point to the
* same data and third and fifth vertex will also point to shared
* data.
*
* Drawing with indices can be a good way of minimizing the size of a
* mesh by allowing you to avoid data for duplicate vertices because
* multiple entries in the index array can refer back to a single
* shared vertex.
*
* <note>The @indices array must at least be as long @first_vertex +
* @n_vertices otherwise the GPU will overrun the indices array when
* looking up vertex data.</note>
*
* Since it's very common to want to draw a run of rectangles using
* indices to avoid duplicating vertex data you can use
* cogl_get_rectangle_indices() to get a set of indices that can be
* shared.
*
* <note>This api doesn't support any of the legacy global state
* options such as cogl_set_depth_test_enabled(),
* cogl_set_backface_culling_enabled() or cogl_program_use()</note>
*
* Stability: unstable
* Since: 1.10
*/
void
cogl_framebuffer_draw_indexed_attributes (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
CoglVerticesMode mode,
int first_vertex,
int n_vertices,
CoglIndices *indices,
CoglAttribute **attributes,
int n_attributes);
/* XXX: Should we take an n_buffers + buffer id array instead of using
* the CoglBufferBits type which doesn't seem future proof? */
/**

View File

@ -273,7 +273,8 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
CoglAttribute **attributes;
CoglDrawFlags draw_flags = (COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
COGL_DRAW_SKIP_LEGACY_STATE);
COGL_STATIC_TIMER (time_flush_modelview_and_entries,
"flush: pipeline+entries", /* parent */
@ -296,7 +297,6 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
}
attributes = (CoglAttribute **)state->attributes->data;
_cogl_push_source (state->source, FALSE);
if (!_cogl_pipeline_get_real_blend_enabled (state->source))
draw_flags |= COGL_DRAW_COLOR_ATTRIBUTE_IS_OPAQUE;
@ -305,33 +305,40 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
if (ctx->driver == COGL_DRIVER_GL)
{
/* XXX: it's rather evil that we sneak in the GL_QUADS enum here... */
_cogl_draw_attributes (GL_QUADS,
state->current_vertex, batch_len * 4,
attributes,
state->attributes->len,
draw_flags);
_cogl_framebuffer_draw_attributes (state->framebuffer,
state->source,
GL_QUADS,
state->current_vertex, batch_len * 4,
attributes,
state->attributes->len,
draw_flags);
}
else
#endif /* HAVE_COGL_GL */
{
if (batch_len > 1)
{
_cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES,
state->current_vertex * 6 / 4,
batch_len * 6,
state->indices,
attributes,
state->attributes->len,
draw_flags);
CoglVerticesMode mode = COGL_VERTICES_MODE_TRIANGLES;
int first_vertex = state->current_vertex * 6 / 4;
_cogl_framebuffer_draw_indexed_attributes (state->framebuffer,
state->source,
mode,
first_vertex,
batch_len * 6,
state->indices,
attributes,
state->attributes->len,
draw_flags);
}
else
{
_cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
state->current_vertex, 4,
attributes,
state->attributes->len,
draw_flags);
_cogl_framebuffer_draw_attributes (state->framebuffer,
state->source,
COGL_VERTICES_MODE_TRIANGLE_FAN,
state->current_vertex, 4,
attributes,
state->attributes->len,
draw_flags);
}
}
@ -369,15 +376,16 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
(ctxt->journal_rectangles_color & 4) ?
color_intensity : 0,
0xff);
cogl_set_source (outline);
loop_attributes[0] = attributes[0]; /* we just want the position */
for (i = 0; i < batch_len; i++)
_cogl_draw_attributes (COGL_VERTICES_MODE_LINE_LOOP,
4 * i + state->current_vertex, 4,
loop_attributes,
1,
draw_flags);
_cogl_framebuffer_draw_attributes (state->framebuffer,
outline,
COGL_VERTICES_MODE_LINE_LOOP,
4 * i + state->current_vertex, 4,
loop_attributes,
1,
draw_flags);
/* Go to the next color */
do
@ -390,8 +398,6 @@ _cogl_journal_flush_modelview_and_entries (CoglJournalEntry *batch_start,
state->current_vertex += (4 * batch_len);
cogl_pop_source ();
COGL_TIMER_STOP (_cogl_uprof_context, time_flush_modelview_and_entries);
}

View File

@ -575,34 +575,6 @@ _cogl_primitive_immutable_unref (CoglPrimitive *primitive)
_cogl_attribute_immutable_unref (primitive->attributes[i]);
}
void
_cogl_primitive_draw (CoglPrimitive *primitive,
CoglDrawFlags flags)
{
if (primitive->indices)
_cogl_draw_indexed_attributes (primitive->mode,
primitive->first_vertex,
primitive->n_vertices,
primitive->indices,
primitive->attributes,
primitive->n_attributes,
flags);
else
_cogl_draw_attributes (primitive->mode,
primitive->first_vertex,
primitive->n_vertices,
primitive->attributes,
primitive->n_attributes,
flags);
}
/* XXX: cogl_draw_primitive() ? */
void
cogl_primitive_draw (CoglPrimitive *primitive)
{
_cogl_primitive_draw (primitive, 0 /* no flags */);
}
void
cogl_primitive_foreach_attribute (CoglPrimitive *primitive,
CoglPrimitiveAttributeCallback callback,

View File

@ -802,18 +802,6 @@ cogl_primitive_get_indices (CoglPrimitive *primitive);
CoglPrimitive *
cogl_primitive_copy (CoglPrimitive *primitive);
/**
* cogl_primitive_draw:
* @primitive: A #CoglPrimitive object
*
* Draw the given @primitive with the current source material.
*
* Since: 1.6
* Stability: Unstable
*/
void
cogl_primitive_draw (CoglPrimitive *primitive);
/**
* cogl_is_primitive:
* @object: A #CoglObject

View File

@ -33,7 +33,9 @@ G_BEGIN_DECLS
where the code may be called while the journal is already being
flushed. In that case using the journal would go wrong */
void
_cogl_rectangle_immediate (float x_1,
_cogl_rectangle_immediate (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
float x_1,
float y_1,
float x_2,
float y_2);

View File

@ -38,6 +38,7 @@
#include "cogl-attribute-private.h"
#include "cogl-private.h"
#include "cogl-meta-texture.h"
#include "cogl-framebuffer-private.h"
#include <string.h>
#include <math.h>
@ -839,7 +840,9 @@ cogl_rectangle (float x_1,
}
void
_cogl_rectangle_immediate (float x_1,
_cogl_rectangle_immediate (CoglFramebuffer *framebuffer,
CoglPipeline *pipeline,
float x_1,
float y_1,
float x_2,
float y_2)
@ -866,14 +869,17 @@ _cogl_rectangle_immediate (float x_1,
2, /* n_components */
COGL_ATTRIBUTE_TYPE_FLOAT);
_cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_STRIP,
0, /* first_index */
4, /* n_vertices */
attributes,
1,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH);
_cogl_framebuffer_draw_attributes (framebuffer,
pipeline,
COGL_VERTICES_MODE_TRIANGLE_STRIP,
0, /* first_index */
4, /* n_vertices */
attributes,
1,
COGL_DRAW_SKIP_JOURNAL_FLUSH |
COGL_DRAW_SKIP_PIPELINE_VALIDATION |
COGL_DRAW_SKIP_FRAMEBUFFER_FLUSH |
COGL_DRAW_SKIP_LEGACY_STATE);
cogl_object_unref (attributes[0]);
@ -1093,12 +1099,21 @@ cogl_polygon (const CoglTextureVertex *vertices,
v,
ctx->polygon_vertices->len * sizeof (float));
/* XXX: although this may seem redundant, we need to do this since
* cogl_polygon() can be used with legacy state and its the source stack
* which track whether legacy state is enabled.
*
* (We only have a CoglDrawFlag to disable legacy state not one
* to enable it) */
cogl_push_source (pipeline);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLE_FAN,
0, n_vertices,
attributes,
n_attributes);
_cogl_framebuffer_draw_attributes (cogl_get_draw_framebuffer (),
pipeline,
COGL_VERTICES_MODE_TRIANGLE_FAN,
0, n_vertices,
attributes,
n_attributes,
0 /* no draw flags */);
cogl_pop_source ();

View File

@ -1618,9 +1618,18 @@ update_primitive_and_draw (CoglVertexBuffer *buffer,
pipeline_priv);
}
/* XXX: although this may seem redundant, we need to do this since
* CoglVertexBuffers can be used with legacy state and its the source stack
* which track whether legacy state is enabled.
*
* (We only have a CoglDrawFlag to disable legacy state not one
* to enable it) */
cogl_push_source (pipeline_priv->real_source);
cogl_primitive_draw (buffer->primitive);
_cogl_framebuffer_draw_primitive (cogl_get_draw_framebuffer (),
pipeline_priv->real_source,
buffer->primitive,
0 /* no draw flags */);
cogl_pop_source ();
}

View File

@ -230,10 +230,12 @@ _cogl_path_stroke_nodes (CoglPath *path)
{
node = &g_array_index (data->path_nodes, CoglPathNode, path_start);
cogl_vdraw_attributes (COGL_VERTICES_MODE_LINE_STRIP,
0, node->path_size,
data->stroke_attributes[path_num],
NULL);
cogl_framebuffer_vdraw_attributes (cogl_get_draw_framebuffer (),
source,
COGL_VERTICES_MODE_LINE_STRIP,
0, node->path_size,
data->stroke_attributes[path_num],
NULL);
path_num++;
}
@ -322,8 +324,9 @@ void
_cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
{
gboolean needs_fallback = FALSE;
CoglPipeline *pipeline = cogl_get_source ();
_cogl_pipeline_foreach_layer_internal (cogl_get_source (),
_cogl_pipeline_foreach_layer_internal (pipeline,
validate_layer_cb, &needs_fallback);
if (needs_fallback)
{
@ -333,13 +336,15 @@ _cogl_path_fill_nodes (CoglPath *path, CoglDrawFlags flags)
_cogl_path_build_fill_attribute_buffer (path);
_cogl_draw_indexed_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
path->data->fill_vbo_n_indices,
path->data->fill_vbo_indices,
path->data->fill_attributes,
COGL_PATH_N_ATTRIBUTES,
flags);
_cogl_framebuffer_draw_indexed_attributes (cogl_get_draw_framebuffer (),
pipeline,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
path->data->fill_vbo_n_indices,
path->data->fill_vbo_indices,
path->data->fill_attributes,
COGL_PATH_N_ATTRIBUTES,
flags);
}
void

View File

@ -88,11 +88,6 @@
<title>Geometry</title>
<xi:include href="xml/cogl-primitive.xml"/>
<xi:include href="xml/cogl-paths.xml"/>
</section>
<section id="cogl-drawing-apis">
<title>Drawing</title>
<xi:include href="xml/cogl-drawing.xml"/>
<xi:include href="xml/cogl-rectangle.xml"/>
</section>

View File

@ -237,7 +237,6 @@ cogl_primitive_set_mode
cogl_primitive_set_attributes
cogl_primitive_get_indices
cogl_primitive_set_indices
cogl_primitive_draw
cogl_primitive_copy
CoglPrimitiveAttributeCallback
cogl_primitive_foreach_attribute
@ -306,15 +305,6 @@ cogl_path_fill
cogl_path_stroke
</SECTION>
<SECTION>
<FILE>cogl-drawing</FILE>
<TITLE>Draw Vertex Attributes</TITLE>
cogl_draw_vertex_attributes
cogl_draw_vertex_attributes_array
cogl_draw_indexed_vertex_attributes
cogl_draw_indexed_vertex_attributes_array
</SECTION>
<SECTION>
<FILE>cogl-texture</FILE>
<TITLE>The Texture Interface</TITLE>
@ -419,6 +409,13 @@ cogl_framebuffer_set_point_samples_per_pixel
cogl_framebuffer_get_context
cogl_framebuffer_clear
cogl_framebuffer_clear4f
<SUBSECTION>
cogl_framebuffer_draw_primitive
cogl_framebuffer_draw_attributes
cogl_framebuffer_draw_indexed_attributes
<SUBSECTION>
cogl_framebuffer_swap_buffers
cogl_framebuffer_swap_region
cogl_framebuffer_add_swap_buffers_callback

View File

@ -115,17 +115,7 @@ paint (Data *data)
cogl_framebuffer_rotate (fb, rotation, 0, 1, 0);
cogl_framebuffer_rotate (fb, rotation, 1, 0, 0);
/* Whenever you draw something with Cogl using geometry defined by
* one of cogl_rectangle, cogl_polygon, cogl_path or
* cogl_vertex_buffer then you have a current pipeline that defines
* how that geometry should be processed.
*
* Here we are making our crate pipeline current which will sample
* the crate texture when fragment processing. */
cogl_set_source (data->crate_pipeline);
/* Give Cogl some geometry to draw. */
cogl_primitive_draw (data->prim);
cogl_framebuffer_draw_primitive (fb, data->crate_pipeline, data->prim);
cogl_set_depth_test_enabled (FALSE);

View File

@ -10,6 +10,7 @@ main (int argc, char **argv)
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglPipeline *pipeline;
GError *error = NULL;
CoglVertexP2C4 triangle_vertices[] = {
{0, 0.7, 0xff, 0x00, 0x00, 0x80},
@ -26,19 +27,20 @@ main (int argc, char **argv)
onscreen = cogl_onscreen_new (ctx, 640, 480);
cogl_onscreen_show (onscreen);
fb = COGL_FRAMEBUFFER (onscreen);
cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new ();
for (;;) {
CoglPollFD *poll_fds;
int n_poll_fds;
gint64 timeout;
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (triangle);
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_swap_buffers (fb);
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);

View File

@ -77,8 +77,6 @@ main (int argc, char **argv)
cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
}
cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new ();
@ -93,12 +91,11 @@ main (int argc, char **argv)
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_scale (fb, 0.5, 1, 1);
cogl_framebuffer_translate (fb, -1, 0, 0);
cogl_set_source (pipeline);
cogl_primitive_draw (triangle);
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_pop_matrix (fb);
cogl_push_framebuffer (offscreen_fb);
cogl_primitive_draw (triangle);
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_resolve_samples (offscreen_fb);
cogl_pop_framebuffer ();

View File

@ -9,6 +9,7 @@
typedef struct Data
{
CoglPrimitive *triangle;
CoglPipeline *pipeline;
float center_x, center_y;
CoglFramebuffer *fb;
gboolean quit;
@ -24,7 +25,7 @@ redraw (Data *data)
cogl_framebuffer_push_matrix (fb);
cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);
cogl_primitive_draw (data->triangle);
cogl_framebuffer_draw_primitive (fb, data->pipeline, data->triangle);
cogl_framebuffer_pop_matrix (fb);
cogl_framebuffer_swap_buffers (fb);
@ -147,10 +148,9 @@ main (int argc, char **argv)
cogl_onscreen_show (onscreen);
cogl_push_framebuffer (data.fb);
data.triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
data.pipeline = cogl_pipeline_new ();
while (!data.quit)
{
CoglPollFD *poll_fds;
@ -173,8 +173,6 @@ main (int argc, char **argv)
cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
}
cogl_pop_framebuffer ();
cogl_object_unref (ctx);
cogl_object_unref (display);
cogl_object_unref (renderer);

View File

@ -42,6 +42,7 @@ main (int argc, char **argv)
CoglContext *ctx;
CoglOnscreen *onscreen;
CoglFramebuffer *fb;
CoglPipeline *pipeline;
GError *error = NULL;
guint32 visual;
XVisualInfo template, *xvisinfo;
@ -147,10 +148,10 @@ main (int argc, char **argv)
XMapWindow (xdpy, xwin);
fb = COGL_FRAMEBUFFER (onscreen);
cogl_push_framebuffer (fb);
triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
pipeline = cogl_pipeline_new ();
for (;;)
{
CoglPollFD *poll_fds;
@ -170,7 +171,7 @@ main (int argc, char **argv)
cogl_xlib_renderer_handle_event (renderer, &event);
}
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (triangle);
cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
cogl_framebuffer_swap_buffers (fb);
cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);

View File

@ -80,6 +80,7 @@ struct _CoglandCompositor
GQueue frame_callbacks;
CoglPrimitive *triangle;
CoglPipeline *triangle_pipeline;
GSource *wayland_event_source;
@ -512,7 +513,8 @@ paint_cb (void *user_data)
cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);
cogl_primitive_draw (compositor->triangle);
cogl_framebuffer_draw_primitive (fb, compositor->triangle_pipeline,
compositor->triangle);
for (l2 = compositor->surfaces; l2; l2 = l2->next)
{
@ -751,6 +753,7 @@ main (int argc, char **argv)
compositor.triangle = cogl_primitive_new_p2c4 (COGL_VERTICES_MODE_TRIANGLES,
3, triangle_vertices);
compositor.triangle_pipeline = cogl_pipeline_new ();
g_timeout_add (16, paint_cb, &compositor);

View File

@ -6,6 +6,7 @@
typedef struct _TestState
{
CoglFramebuffer *fb;
CoglPipeline *pipeline;
} TestState;
@ -57,21 +58,19 @@ test_float_verts (TestState *state, int offset_x, int offset_y)
4, /* n_components */
COGL_ATTRIBUTE_TYPE_FLOAT);
cogl_push_source (state->pipeline);
cogl_push_matrix ();
cogl_translate (offset_x, offset_y, 0.0f);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
6, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_framebuffer_draw_attributes (state->fb,
state->pipeline,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
6, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_pop_matrix ();
cogl_pop_source ();
cogl_object_unref (attributes[1]);
cogl_object_unref (attributes[0]);
cogl_object_unref (buffer);
@ -119,16 +118,16 @@ test_byte_verts (TestState *state, int offset_x, int offset_y)
COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
cogl_attribute_set_normalized (attributes[1], TRUE);
cogl_push_source (state->pipeline);
cogl_push_matrix ();
cogl_translate (offset_x, offset_y, 0.0f);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
6, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_framebuffer_draw_attributes (state->fb,
state->pipeline,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
6, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_object_unref (attributes[1]);
@ -144,16 +143,16 @@ test_byte_verts (TestState *state, int offset_x, int offset_y)
cogl_translate (20, 0, 0);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_framebuffer_draw_attributes (state->fb,
state->pipeline,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
2 /* n_attributes */);
cogl_pop_matrix ();
cogl_pop_source ();
cogl_object_unref (attributes[0]);
cogl_object_unref (attributes[1]);
cogl_object_unref (buffer);
@ -200,21 +199,19 @@ test_short_verts (TestState *state, int offset_x, int offset_y)
2, /* n_components */
COGL_ATTRIBUTE_TYPE_SHORT);
cogl_push_source (pipeline);
cogl_push_matrix ();
cogl_translate (offset_x + 10.0f, offset_y + 10.0f, 0.0f);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
1 /* n_attributes */);
cogl_framebuffer_draw_attributes (state->fb,
pipeline,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
1 /* n_attributes */);
cogl_pop_matrix ();
cogl_pop_source ();
cogl_object_unref (attributes[0]);
/* Test again treating the attribute as unsigned */
@ -228,21 +225,19 @@ test_short_verts (TestState *state, int offset_x, int offset_y)
pipeline2 = cogl_pipeline_copy (pipeline);
cogl_pipeline_set_color4ub (pipeline2, 0, 255, 0, 255);
cogl_push_source (pipeline2);
cogl_push_matrix ();
cogl_translate (offset_x + 10.0f - 65525.0f, offset_y - 65525, 0.0f);
cogl_draw_attributes (COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
1 /* n_attributes */);
cogl_framebuffer_draw_attributes (state->fb,
pipeline2,
COGL_VERTICES_MODE_TRIANGLES,
0, /* first_vertex */
3, /* n_vertices */
attributes,
1 /* n_attributes */);
cogl_pop_matrix ();
cogl_pop_source ();
cogl_object_unref (attributes[0]);
cogl_object_unref (pipeline2);
@ -277,6 +272,7 @@ test_cogl_custom_attributes (TestUtilsGTestFixture *fixture,
{
CoglSnippet *snippet;
TestState state;
state.fb = shared_state->fb;
cogl_ortho (/* left, right */
0, cogl_framebuffer_get_width (shared_state->fb),

View File

@ -177,9 +177,7 @@ test_paint (TestState *state)
(PRIM_COLOR >> 8) & 0xff,
(PRIM_COLOR >> 0) & 0xff);
cogl_pipeline_set_layer_texture (pipeline, 0, tex);
cogl_handle_unref (tex);
cogl_set_source (pipeline);
cogl_object_unref (pipeline);
cogl_object_unref (tex);
for (i = 0; i < G_N_ELEMENTS (test_prim_funcs); i++)
{
@ -190,13 +188,15 @@ test_paint (TestState *state)
cogl_push_matrix ();
cogl_translate (i * 10, 0, 0);
cogl_primitive_draw (prim);
cogl_framebuffer_draw_primitive (state->fb, pipeline, prim);
cogl_pop_matrix ();
test_utils_check_pixel (i * 10 + 2, 2, expected_color);
cogl_object_unref (prim);
}
cogl_object_unref (pipeline);
}
static gboolean