diff --git a/cogl.h.in b/cogl.h.in
index 295cf0d4b..ffa5cce0b 100644
--- a/cogl.h.in
+++ b/cogl.h.in
@@ -752,6 +752,85 @@ void cogl_read_pixels (int x,
*/
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:
+ *
+ * {
+ * - setup some OpenGL state.
+ * - draw using OpenGL (e.g. glDrawArrays() )
+ * - reset modified OpenGL state.
+ * - continue using Cogl to draw
+ * }
+ *
+ * You should surround blocks of drawing using raw GL 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
+ * }
+ *
+ *
+ * Don't ever try and do:
+ *
+ * {
+ * - setup some OpenGL state.
+ * - use Cogl to draw
+ * - reset modified OpenGL state.
+ * }
+ *
+ * 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.
diff --git a/common/cogl.c b/common/cogl.c
index 81a0312ba..309e744d5 100644
--- a/common/cogl.c
+++ b/common/cogl.c
@@ -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;
+}
+
diff --git a/doc/reference/cogl/cogl-sections.txt b/doc/reference/cogl/cogl-sections.txt
index f383e2620..5a80895f2 100644
--- a/doc/reference/cogl/cogl-sections.txt
+++ b/doc/reference/cogl/cogl-sections.txt
@@ -74,6 +74,8 @@ cogl_read_pixels
cogl_flush
+cogl_begin_gl
+cogl_end_gl
COGL_TYPE_ATTRIBUTE_TYPE
diff --git a/gl/cogl-context.c b/gl/cogl-context.c
index 2266d9564..f587f8cd1 100644
--- a/gl/cogl-context.c
+++ b/gl/cogl-context.c
@@ -90,6 +90,8 @@ cogl_create_context ()
_context->last_path = 0;
_context->stencil_material = cogl_material_new ();
+ _context->in_begin_gl_block = FALSE;
+
_context->pf_glGenRenderbuffersEXT = NULL;
_context->pf_glBindRenderbufferEXT = NULL;
_context->pf_glRenderbufferStorageEXT = NULL;
diff --git a/gl/cogl-context.h b/gl/cogl-context.h
index fa1ccb637..81d17c4fa 100644
--- a/gl/cogl-context.h
+++ b/gl/cogl-context.h
@@ -110,6 +110,8 @@ typedef struct
guint quad_indices_short_len;
CoglHandle quad_indices_short;
+ gboolean in_begin_gl_block;
+
/* Relying on glext.h to define these */
COGL_PFNGLGENRENDERBUFFERSEXTPROC pf_glGenRenderbuffersEXT;
COGL_PFNGLDELETERENDERBUFFERSEXTPROC pf_glDeleteRenderbuffersEXT;