mirror of
https://github.com/brl/mutter.git
synced 2024-12-03 05:10:40 -05:00
[cogl] Improve ability to break out into raw OpenGL via begin/end mechanism
Although we wouldn't recommend developers try and interleve OpenGL drawing with Cogl drawing - we would prefer patches that improve Cogl to avoid this if possible - we are providing a simple mechanism that will at least give developers a fighting chance if they find it necissary. Note: we aren't helping developers change OpenGL state to modify the behaviour of Cogl drawing functions - it's unlikley that can ever be reliably supported - but if they are trying to do something like: - setup some OpenGL state. - draw using OpenGL (e.g. glDrawArrays() ) - reset modified OpenGL state. - continue using Cogl to draw They should surround their blocks of raw OpenGL with cogl_begin_gl() and cogl_end_gl(): cogl_begin_gl (); - setup some OpenGL state. - draw using OpenGL (e.g. glDrawArrays() ) - reset modified OpenGL state. cogl_end_gl (); - continue using Cogl to draw Again; we aren't supporting code like this: - setup some OpenGL state. - use Cogl to draw - reset modified OpenGL state. When the internals of Cogl evolves, this is very liable to break. cogl_begin_gl() will flush all internally batched Cogl primitives, and emit all internal Cogl state to OpenGL as if it were going to draw something itself. The result is that the OpenGL modelview matrix will be setup; the state corresponding to the current source material will be setup and other world state such as backface culling, depth and fogging enabledness will be also be sent to OpenGL. Note: no special material state is flushed, so if developers want Cogl to setup a simplified material state it is the their responsibility to set a simple source material before calling cogl_begin_gl. E.g. by calling cogl_set_source_color4ub(). Note: It is the developers responsibility to restore any OpenGL state that they modify to how it was after calling cogl_begin_gl() if they don't do this then the result of further Cogl calls is undefined.
This commit is contained in:
parent
99f53c3922
commit
b4bc9eb458
79
cogl.h.in
79
cogl.h.in
@ -752,6 +752,85 @@ void cogl_read_pixels (int x,
|
|||||||
*/
|
*/
|
||||||
void cogl_flush (void);
|
void cogl_flush (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_begin_gl:
|
||||||
|
*
|
||||||
|
* We do not advise nor reliably support the interleaving of raw GL drawing and
|
||||||
|
* Cogl drawing functions, but if you insist, cogl_begin_gl() and cogl_end_gl()
|
||||||
|
* provide a simple mechanism that may at least give you a fighting chance of
|
||||||
|
* succeeding.
|
||||||
|
*
|
||||||
|
* Note: this doesn't help you modify the behaviour of Cogl drawing functions
|
||||||
|
* through the modification of GL state; that will never be reliably supported,
|
||||||
|
* but if you are trying to do something like:
|
||||||
|
* <programlisting>
|
||||||
|
* {
|
||||||
|
* - setup some OpenGL state.
|
||||||
|
* - draw using OpenGL (e.g. glDrawArrays() )
|
||||||
|
* - reset modified OpenGL state.
|
||||||
|
* - continue using Cogl to draw
|
||||||
|
* }
|
||||||
|
* </programlisting>
|
||||||
|
* You should surround blocks of drawing using raw GL with cogl_begin_gl()
|
||||||
|
* and cogl_end_gl():
|
||||||
|
* <programlisting>
|
||||||
|
* {
|
||||||
|
* cogl_begin_gl ();
|
||||||
|
* - setup some OpenGL state.
|
||||||
|
* - draw using OpenGL (e.g. glDrawArrays() )
|
||||||
|
* - reset modified OpenGL state.
|
||||||
|
* cogl_end_gl ();
|
||||||
|
* - continue using Cogl to draw
|
||||||
|
* }
|
||||||
|
* </programlisting>
|
||||||
|
*
|
||||||
|
* Don't ever try and do:
|
||||||
|
* <programlisting>
|
||||||
|
* {
|
||||||
|
* - setup some OpenGL state.
|
||||||
|
* - use Cogl to draw
|
||||||
|
* - reset modified OpenGL state.
|
||||||
|
* }
|
||||||
|
* </programlisting>
|
||||||
|
* When the internals of Cogl evolves, this is very liable to break.
|
||||||
|
*
|
||||||
|
* This function will flush all batched primitives, and subsequently flush
|
||||||
|
* all internal Cogl state to OpenGL as if it were going to draw something
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* The result is that the OpenGL modelview matrix will be setup; the state
|
||||||
|
* corresponding to the current source material will be set up and other world
|
||||||
|
* state such as backface culling, depth and fogging enabledness will be sent
|
||||||
|
* to OpenGL.
|
||||||
|
*
|
||||||
|
* Note: no special material state is flushed, so if you want Cogl to setup a
|
||||||
|
* simplified material state it is your responsibility to set a simple source
|
||||||
|
* material before calling cogl_begin_gl. E.g. by calling
|
||||||
|
* cogl_set_source_color4ub().
|
||||||
|
*
|
||||||
|
* Note: It is your responsibility to restore any OpenGL state that you modify
|
||||||
|
* to how it was after calling cogl_begin_gl() if you don't do this then the
|
||||||
|
* result of further Cogl calls is undefined.
|
||||||
|
*
|
||||||
|
* Note: You can not nest begin/end blocks.
|
||||||
|
*
|
||||||
|
* Again we would like to stress, we do not advise the use of this API and if
|
||||||
|
* possible we would prefer to improve Cogl than have developers require raw
|
||||||
|
* OpenGL.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void cogl_begin_gl (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_end_gl:
|
||||||
|
*
|
||||||
|
* This is the counterpart to cogl_begin_gl() used to delimit blocks of drawing
|
||||||
|
* code using raw OpenGL. Please refer to cogl_begin_gl() for full details.
|
||||||
|
*
|
||||||
|
* Since: 1.0
|
||||||
|
*/
|
||||||
|
void cogl_end_gl (void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Internal API available only to Clutter.
|
* Internal API available only to Clutter.
|
||||||
|
@ -771,3 +771,78 @@ cogl_read_pixels (int x,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_begin_gl (void)
|
||||||
|
{
|
||||||
|
CoglMaterialFlushOptions options;
|
||||||
|
gulong enable_flags;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
if (ctx->in_begin_gl_block)
|
||||||
|
{
|
||||||
|
static gboolean shown = FALSE;
|
||||||
|
if (!shown)
|
||||||
|
g_warning ("You should not nest cogl_begin_gl/cogl_end_gl blocks");
|
||||||
|
shown = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx->in_begin_gl_block = TRUE;
|
||||||
|
|
||||||
|
/* Flush all batched primitives */
|
||||||
|
cogl_flush ();
|
||||||
|
|
||||||
|
/* Flush our clipping state to GL */
|
||||||
|
cogl_clip_ensure ();
|
||||||
|
|
||||||
|
/* Flush any client side matrix state */
|
||||||
|
_cogl_current_matrix_state_flush ();
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup the state for the current material */
|
||||||
|
|
||||||
|
/* We considered flushing a specific, minimal material here to try and
|
||||||
|
* simplify the GL state, but decided to avoid special cases and second
|
||||||
|
* guessing what would be actually helpful.
|
||||||
|
*
|
||||||
|
* A user should instead call cogl_set_source_color4ub() before
|
||||||
|
* cogl_begin_gl() to simplify the state flushed.
|
||||||
|
*/
|
||||||
|
options.flags = 0;
|
||||||
|
_cogl_material_flush_gl_state (ctx->source_material, &options);
|
||||||
|
|
||||||
|
/* FIXME: This api is a bit yukky, ideally it will be removed if we
|
||||||
|
* re-work the cogl_enable mechanism */
|
||||||
|
enable_flags |= _cogl_material_get_cogl_enable_flags (ctx->source_material);
|
||||||
|
|
||||||
|
if (ctx->enable_backface_culling)
|
||||||
|
enable_flags |= COGL_ENABLE_BACKFACE_CULLING;
|
||||||
|
|
||||||
|
cogl_enable (enable_flags);
|
||||||
|
|
||||||
|
/* Disable all client texture coordinate arrays */
|
||||||
|
for (i = 0; i < ctx->n_texcoord_arrays_enabled; i++)
|
||||||
|
{
|
||||||
|
GE (glClientActiveTexture (GL_TEXTURE0 + i));
|
||||||
|
GE (glDisableClientState (GL_TEXTURE_COORD_ARRAY));
|
||||||
|
}
|
||||||
|
ctx->n_texcoord_arrays_enabled = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_end_gl (void)
|
||||||
|
{
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
if (!ctx->in_begin_gl_block)
|
||||||
|
{
|
||||||
|
static gboolean shown = FALSE;
|
||||||
|
if (!shown)
|
||||||
|
g_warning ("cogl_end_gl is being called before cogl_begin_gl");
|
||||||
|
shown = TRUE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx->in_begin_gl_block = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ cogl_read_pixels
|
|||||||
|
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
cogl_flush
|
cogl_flush
|
||||||
|
cogl_begin_gl
|
||||||
|
cogl_end_gl
|
||||||
|
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
COGL_TYPE_ATTRIBUTE_TYPE
|
COGL_TYPE_ATTRIBUTE_TYPE
|
||||||
|
@ -90,6 +90,8 @@ cogl_create_context ()
|
|||||||
_context->last_path = 0;
|
_context->last_path = 0;
|
||||||
_context->stencil_material = cogl_material_new ();
|
_context->stencil_material = cogl_material_new ();
|
||||||
|
|
||||||
|
_context->in_begin_gl_block = FALSE;
|
||||||
|
|
||||||
_context->pf_glGenRenderbuffersEXT = NULL;
|
_context->pf_glGenRenderbuffersEXT = NULL;
|
||||||
_context->pf_glBindRenderbufferEXT = NULL;
|
_context->pf_glBindRenderbufferEXT = NULL;
|
||||||
_context->pf_glRenderbufferStorageEXT = NULL;
|
_context->pf_glRenderbufferStorageEXT = NULL;
|
||||||
|
@ -110,6 +110,8 @@ typedef struct
|
|||||||
guint quad_indices_short_len;
|
guint quad_indices_short_len;
|
||||||
CoglHandle quad_indices_short;
|
CoglHandle quad_indices_short;
|
||||||
|
|
||||||
|
gboolean in_begin_gl_block;
|
||||||
|
|
||||||
/* Relying on glext.h to define these */
|
/* Relying on glext.h to define these */
|
||||||
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
|
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
|
||||||
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
|
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;
|
||||||
|
Loading…
Reference in New Issue
Block a user