[cogl/wip/cogl-1.14: 2/50] framebuffer: Support texture based depth buffers
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/cogl-1.14: 2/50] framebuffer: Support texture based depth buffers
- Date: Fri, 18 Jan 2013 11:55:56 +0000 (UTC)
commit 87bc616d34589beaf972a79ffed35199b3d16d2e
Author: Damien Lespiau <damien lespiau intel com>
Date: Wed May 23 18:19:29 2012 +0100
framebuffer: Support texture based depth buffers
This commit introduces some new framebuffer api to be able to
enable texture based depth buffers for a framebuffer (currently
only supported for offscreen framebuffers) and once allocated
to be able to retrieve the depth buffer as a texture for further
usage, say, to implement shadow mapping.
The API works as follow:
* Before the framebuffer is allocated, you can request that a depth
texture is created with
cogl_framebuffer_set_depth_texture_enabled()
* cogl_framebuffer_get_depth_texture() can then be used to grab a
CoglTexture once the framebuffer has been allocated.
cogl/cogl-bitmap-conversion.c | 3 +
cogl/cogl-bitmap-packing.h | 6 ++
cogl/cogl-context.h | 4 +-
cogl/cogl-framebuffer-private.h | 4 +
cogl/cogl-framebuffer.c | 170 +++++++++++++++++++++++++++++++++++++--
cogl/cogl-framebuffer.h | 60 ++++++++++++++
cogl/cogl-gles2-context.c | 1 +
cogl/cogl-types.h | 26 +++++--
cogl/driver/gl/cogl-gl.c | 24 ++++++
cogl/driver/gles/cogl-gles.c | 30 +++++++
examples/cogl-info.c | 6 ++
11 files changed, 319 insertions(+), 15 deletions(-)
---
diff --git a/cogl/cogl-bitmap-conversion.c b/cogl/cogl-bitmap-conversion.c
index 17b26e6..ca611ee 100644
--- a/cogl/cogl-bitmap-conversion.c
+++ b/cogl/cogl-bitmap-conversion.c
@@ -306,6 +306,9 @@ _cogl_bitmap_needs_short_temp_buffer (CoglPixelFormat format)
floats */
switch (format)
{
+ case COGL_PIXEL_FORMAT_DEPTH_16:
+ case COGL_PIXEL_FORMAT_DEPTH_32:
+ case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
diff --git a/cogl/cogl-bitmap-packing.h b/cogl/cogl-bitmap-packing.h
index f84af02..d2fc4fb 100644
--- a/cogl/cogl-bitmap-packing.h
+++ b/cogl/cogl-bitmap-packing.h
@@ -370,6 +370,9 @@ G_PASTE (_cogl_unpack_, component_type) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
G_PASTE (_cogl_unpack_abgr_2101010_, component_type) (src, dst, width);
break;
+ case COGL_PIXEL_FORMAT_DEPTH_16:
+ case COGL_PIXEL_FORMAT_DEPTH_32:
+ case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@@ -711,6 +714,9 @@ G_PASTE (_cogl_pack_, component_type) (CoglPixelFormat format,
case COGL_PIXEL_FORMAT_ABGR_2101010_PRE:
G_PASTE (_cogl_pack_abgr_2101010_, component_type) (src, dst, width);
break;
+ case COGL_PIXEL_FORMAT_DEPTH_16:
+ case COGL_PIXEL_FORMAT_DEPTH_32:
+ case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index c44a08b..d09f46d 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -206,7 +206,8 @@ cogl_is_context (void *object);
* for swap buffer completions.
* @COGL_FEATURE_ID_GLES2_CONTEXT: Whether creating new GLES2 contexts is
* suported.
- *
+ * @COGL_FEATURE_ID_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering
+ * the depth buffer to a texture.
*
* All the capabilities that can vary between different GPUs supported
* by Cogl. Applications that depend on any of these features should explicitly
@@ -235,6 +236,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_MIRRORED_REPEAT,
COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
COGL_FEATURE_ID_GLES2_CONTEXT,
+ COGL_FEATURE_ID_DEPTH_TEXTURE,
/*< private > */
_COGL_N_FEATURE_IDS
diff --git a/cogl/cogl-framebuffer-private.h b/cogl/cogl-framebuffer-private.h
index fe3fe25..a13f2b9 100644
--- a/cogl/cogl-framebuffer-private.h
+++ b/cogl/cogl-framebuffer-private.h
@@ -53,6 +53,7 @@ typedef struct
CoglBool need_stencil;
int samples_per_pixel;
CoglBool swap_throttled;
+ CoglBool depth_texture_enabled;
} CoglFramebufferConfig;
/* Flags to pass to _cogl_offscreen_new_to_texture_full */
@@ -190,6 +191,8 @@ struct _CoglOffscreen
int texture_level_width;
int texture_level_height;
+ CoglTexture *depth_texture;
+
CoglOffscreenAllocateFlags allocation_flags;
/* FIXME: _cogl_offscreen_new_to_texture_full should be made to use
@@ -421,6 +424,7 @@ _cogl_framebuffer_try_creating_gl_fbo (CoglContext *ctx,
int texture_level,
int texture_level_width,
int texture_level_height,
+ CoglTexture *depth_texture,
CoglFramebufferConfig *config,
CoglOffscreenAllocateFlags flags,
CoglGLFramebuffer *gl_framebuffer);
diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c
index 3802b63..250d654 100644
--- a/cogl/cogl-framebuffer.c
+++ b/cogl/cogl-framebuffer.c
@@ -817,9 +817,83 @@ _cogl_offscreen_free (CoglOffscreen *offscreen)
if (offscreen->texture != NULL)
cogl_object_unref (offscreen->texture);
+ if (offscreen->depth_texture != NULL)
+ cogl_object_unref (offscreen->depth_texture);
+
g_free (offscreen);
}
+static CoglTexture *
+create_depth_texture (CoglContext *ctx,
+ int width,
+ int height)
+{
+ CoglPixelFormat format;
+ CoglTexture2D *depth_texture;
+
+ if (ctx->private_feature_flags &
+ (COGL_PRIVATE_FEATURE_EXT_PACKED_DEPTH_STENCIL |
+ COGL_PRIVATE_FEATURE_OES_PACKED_DEPTH_STENCIL))
+ {
+ format = COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8;
+ }
+ else
+ format = COGL_PIXEL_FORMAT_DEPTH_16;
+
+ depth_texture = cogl_texture_2d_new_with_size (ctx,
+ width, height,
+ format,
+ NULL);
+
+ return COGL_TEXTURE (depth_texture);
+}
+
+static CoglTexture *
+attach_depth_texture (CoglContext *ctx,
+ CoglTexture *depth_texture,
+ CoglOffscreenAllocateFlags flags)
+{
+ GLuint tex_gl_handle;
+ GLenum tex_gl_target;
+
+ if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL)
+ {
+ /* attach a GL_DEPTH_STENCIL texture to the GL_DEPTH_ATTACHMENT and
+ * GL_STENCIL_ATTACHMENT attachement points */
+ g_assert (cogl_texture_get_format (depth_texture) ==
+ COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8);
+
+ cogl_texture_get_gl_texture (depth_texture,
+ &tex_gl_handle, &tex_gl_target);
+
+ GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ tex_gl_target, tex_gl_handle,
+ 0));
+ GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER,
+ GL_STENCIL_ATTACHMENT,
+ tex_gl_target, tex_gl_handle,
+ 0));
+ }
+ else if (flags & COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH)
+ {
+ /* attach a newly created GL_DEPTH_COMPONENT16 texture to the
+ * GL_DEPTH_ATTACHMENT attachement point */
+ g_assert (cogl_texture_get_format (depth_texture) ==
+ COGL_PIXEL_FORMAT_DEPTH_16);
+
+ cogl_texture_get_gl_texture (COGL_TEXTURE (depth_texture),
+ &tex_gl_handle, &tex_gl_target);
+
+ GE (ctx, glFramebufferTexture2D (GL_FRAMEBUFFER,
+ GL_DEPTH_ATTACHMENT,
+ tex_gl_target, tex_gl_handle,
+ 0));
+ }
+
+ return COGL_TEXTURE (depth_texture);
+}
+
static GList *
try_creating_renderbuffers (CoglContext *ctx,
int width,
@@ -937,6 +1011,7 @@ try_creating_fbo (CoglContext *ctx,
int texture_level,
int texture_level_width,
int texture_level_height,
+ CoglTexture *depth_texture,
CoglFramebufferConfig *config,
CoglOffscreenAllocateFlags flags,
CoglGLFramebuffer *gl_framebuffer)
@@ -987,12 +1062,31 @@ try_creating_fbo (CoglContext *ctx,
tex_gl_target, tex_gl_handle,
texture_level));
- gl_framebuffer->renderbuffers =
- try_creating_renderbuffers (ctx,
- texture_level_width,
- texture_level_height,
- flags,
- n_samples);
+ /* attach either a depth/stencil texture, a depth texture or render buffers
+ * depending on what we've been asked to provide */
+
+ if (depth_texture &&
+ flags & (COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL |
+ COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH))
+ {
+ attach_depth_texture (ctx, depth_texture, flags);
+
+ /* Let's clear the flags that are now fulfilled as we might need to
+ * create renderbuffers (for the ALLOCATE_FLAG_DEPTH |
+ * ALLOCATE_FLAG_STENCIL case) */
+ flags &= ~(COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL |
+ COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH);
+ }
+
+ if (flags)
+ {
+ gl_framebuffer->renderbuffers =
+ try_creating_renderbuffers (ctx,
+ texture_level_width,
+ texture_level_height,
+ flags,
+ n_samples);
+ }
/* Make sure it's complete */
status = ctx->glCheckFramebufferStatus (GL_FRAMEBUFFER);
@@ -1031,6 +1125,7 @@ _cogl_framebuffer_try_creating_gl_fbo (CoglContext *ctx,
int texture_level,
int texture_level_width,
int texture_level_height,
+ CoglTexture *depth_texture,
CoglFramebufferConfig *config,
CoglOffscreenAllocateFlags flags,
CoglGLFramebuffer *gl_framebuffer)
@@ -1040,6 +1135,7 @@ _cogl_framebuffer_try_creating_gl_fbo (CoglContext *ctx,
texture_level,
texture_level_width,
texture_level_height,
+ depth_texture,
config,
flags,
gl_framebuffer);
@@ -1054,6 +1150,24 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
CoglOffscreenAllocateFlags flags;
CoglGLFramebuffer *gl_framebuffer = &offscreen->gl_framebuffer;
+ if (fb->config.depth_texture_enabled &&
+ offscreen->depth_texture == NULL)
+ {
+ offscreen->depth_texture =
+ create_depth_texture (ctx,
+ offscreen->texture_level_width,
+ offscreen->texture_level_height);
+
+ if (offscreen->depth_texture)
+ _cogl_texture_associate_framebuffer (offscreen->depth_texture, fb);
+ else
+ {
+ g_set_error (error, COGL_FRAMEBUFFER_ERROR,
+ COGL_FRAMEBUFFER_ERROR_ALLOCATE,
+ "Failed to allocate depth texture for framebuffer");
+ }
+ }
+
/* XXX: The framebuffer_object spec isn't clear in defining whether attaching
* a texture as a renderbuffer with mipmap filtering enabled while the
* mipmaps have not been uploaded should result in an incomplete framebuffer
@@ -1072,6 +1186,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = 0,
gl_framebuffer)) ||
@@ -1082,6 +1197,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = ctx->last_offscreen_allocate_flags,
gl_framebuffer)) ||
@@ -1094,6 +1210,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH_STENCIL,
gl_framebuffer)) ||
@@ -1103,6 +1220,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH |
COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
@@ -1113,6 +1231,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_STENCIL,
gl_framebuffer) ||
@@ -1122,6 +1241,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = COGL_OFFSCREEN_ALLOCATE_FLAG_DEPTH,
gl_framebuffer) ||
@@ -1131,6 +1251,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&fb->config,
flags = 0,
gl_framebuffer))
@@ -1145,7 +1266,7 @@ _cogl_offscreen_allocate (CoglOffscreen *offscreen,
ctx->have_last_offscreen_allocate_flags = TRUE;
}
- /* Save the flags we managed so successfully allocate the
+ /* Save the flags we managed to successfully allocate the
* renderbuffers with in case we need to make renderbuffers for a
* GLES2 context later */
offscreen->allocation_flags = flags;
@@ -1173,6 +1294,15 @@ cogl_framebuffer_allocate (CoglFramebuffer *framebuffer,
if (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN)
{
+ if (framebuffer->config.depth_texture_enabled)
+ {
+ g_set_error (error, COGL_FRAMEBUFFER_ERROR,
+ COGL_FRAMEBUFFER_ERROR_ALLOCATE,
+ "Can't allocate onscreen framebuffer with a "
+ "texture based depth buffer");
+ return FALSE;
+ }
+
if (!winsys->onscreen_init (onscreen, error))
return FALSE;
}
@@ -1928,6 +2058,32 @@ cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer)
return framebuffer->format;
}
+void
+cogl_framebuffer_set_depth_texture_enabled (CoglFramebuffer *framebuffer,
+ CoglBool enabled)
+{
+ _COGL_RETURN_IF_FAIL (!framebuffer->allocated);
+
+ framebuffer->config.depth_texture_enabled = enabled;
+}
+
+CoglBool
+cogl_framebuffer_get_depth_texture_enabled (CoglFramebuffer *framebuffer)
+{
+ return framebuffer->config.depth_texture_enabled;
+}
+
+CoglTexture *
+cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer)
+{
+ /* lazily allocate the framebuffer... */
+ if (!cogl_framebuffer_allocate (framebuffer, NULL))
+ return NULL;
+
+ _COGL_RETURN_VAL_IF_FAIL (cogl_is_offscreen (framebuffer), NULL);
+ return COGL_OFFSCREEN(framebuffer)->depth_texture;
+}
+
int
cogl_framebuffer_get_samples_per_pixel (CoglFramebuffer *framebuffer)
{
diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h
index d72845f..b7563b6 100644
--- a/cogl/cogl-framebuffer.h
+++ b/cogl/cogl-framebuffer.h
@@ -46,6 +46,7 @@
#ifdef COGL_ENABLE_EXPERIMENTAL_API
#include <cogl/cogl-quaternion.h>
#include <cogl/cogl-euler.h>
+#include <cogl/cogl-texture.h>
#endif
G_BEGIN_DECLS
@@ -812,6 +813,65 @@ CoglPixelFormat
cogl_framebuffer_get_color_format (CoglFramebuffer *framebuffer);
/**
+ * cogl_framebuffer_set_depth_texture_enabled:
+ * @framebuffer: A #CoglFramebuffer
+ * @enabled: TRUE or FALSE
+ *
+ * If @enabled is #TRUE, the depth buffer used when rendering to @framebuffer
+ * is available as a texture. You can retrieve the texture with
+ * cogl_framebuffer_get_depth_texture().
+ *
+ * <note>It's possible that your GPU does not support depth textures. You
+ * should check the %COGL_FEATURE_ID_DEPTH_TEXTURE feature before using this
+ * function.</note>
+ * <note>It's not valid to call this function after the framebuffer has been
+ * allocated as the creation of the depth texture is done at allocation time.
+ * </note>
+ *
+ * Since: 1.14
+ * Stability: unstable
+ */
+void
+cogl_framebuffer_set_depth_texture_enabled (CoglFramebuffer *framebuffer,
+ CoglBool enabled);
+
+/**
+ * cogl_framebuffer_get_depth_texture_enabled:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Queries whether texture based depth buffer has been enabled via
+ * cogl_framebuffer_set_depth_texture_enabled().
+ *
+ * Return value: %TRUE if a depth texture has been enabled, else
+ * %FALSE.
+ *
+ * Since: 1.14
+ * Stability: unstable
+ */
+CoglBool
+cogl_framebuffer_get_depth_texture_enabled (CoglFramebuffer *framebuffer);
+
+/**
+ * cogl_framebuffer_get_depth_texture:
+ * @framebuffer: A #CoglFramebuffer
+ *
+ * Retrieves the depth buffer of @framebuffer as a #CoglTexture. You need to
+ * call cogl_framebuffer_get_depth_texture(fb, TRUE); before using this
+ * function.
+ *
+ * <note>Calling this function implicitely allocates the framebuffer.</note>
+ * <note>The texture returned stays valid as long as the framebuffer stays
+ * valid.</note>
+ *
+ * Returns: (transfer none): the depth texture
+ *
+ * Since: 1.14
+ * Stability: unstable
+ */
+CoglTexture *
+cogl_framebuffer_get_depth_texture (CoglFramebuffer *framebuffer);
+
+/**
* cogl_framebuffer_set_samples_per_pixel:
* @framebuffer: A #CoglFramebuffer framebuffer
* @samples_per_pixel: The minimum number of samples per pixel
diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
index ed95b69..3d5fef4 100644
--- a/cogl/cogl-gles2-context.c
+++ b/cogl/cogl-gles2-context.c
@@ -1722,6 +1722,7 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
offscreen->texture_level,
offscreen->texture_level_width,
offscreen->texture_level_height,
+ offscreen->depth_texture,
&COGL_FRAMEBUFFER (offscreen)->config,
offscreen->allocation_flags,
&gles2_offscreen->gl_framebuffer))
diff --git a/cogl/cogl-types.h b/cogl/cogl-types.h
index 933cac0..3d73696 100644
--- a/cogl/cogl-types.h
+++ b/cogl/cogl-types.h
@@ -206,18 +206,22 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
#define COGL_BGR_BIT (1 << 5)
#define COGL_AFIRST_BIT (1 << 6)
#define COGL_PREMULT_BIT (1 << 7)
+#define COGL_DEPTH_BIT (1 << 8)
+#define COGL_STENCIL_BIT (1 << 9)
/* XXX: Notes to those adding new formats here...
*
* First this diagram outlines how we allocate the 32bits of a
* CoglPixelFormat currently...
*
- * 4 bits for flags
- * |--|
+ * 6 bits for flags
+ * |-----|
* enum unused 4 bits for the bytes-per-pixel
* and component alignment info
- * |------| |---------------| |--|
- * 00000000 xxxxxxxx xxxxxxxx PFBA0000
+ * |------| |-------------| |--|
+ * 00000000 xxxxxxxx xxxxxxSD PFBA0000
+ * ^ stencil
+ * ^ depth
* ^ premult
* ^ alpha first
* ^ bgr order
@@ -239,7 +243,7 @@ typedef struct _CoglTextureVertex CoglTextureVertex;
* 4-6 = 2 bpp, not aligned (e.g. 565, 4444, 5551)
* 7 = YUV: undefined bpp, undefined alignment
* 9 = 2 bpp, aligned
- * 10 = undefined
+ * 10 = depth, aligned (8, 16, 24, 32, 32f)
* 11 = undefined
* 12 = 3 bpp, not aligned
* 13 = 4 bpp, not aligned (e.g. 2101010)
@@ -357,7 +361,12 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
COGL_PIXEL_FORMAT_RGBA_1010102_PRE = (COGL_PIXEL_FORMAT_RGBA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_BGRA_1010102_PRE = (COGL_PIXEL_FORMAT_BGRA_1010102 | COGL_PREMULT_BIT),
COGL_PIXEL_FORMAT_ARGB_2101010_PRE = (COGL_PIXEL_FORMAT_ARGB_2101010 | COGL_PREMULT_BIT),
- COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT)
+ COGL_PIXEL_FORMAT_ABGR_2101010_PRE = (COGL_PIXEL_FORMAT_ABGR_2101010 | COGL_PREMULT_BIT),
+
+ COGL_PIXEL_FORMAT_DEPTH_16 = (9 | COGL_DEPTH_BIT),
+ COGL_PIXEL_FORMAT_DEPTH_32 = (3 | COGL_DEPTH_BIT),
+
+ COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8 = (3 | COGL_DEPTH_BIT | COGL_STENCIL_BIT)
} CoglPixelFormat;
/**
@@ -400,6 +409,8 @@ typedef enum { /*< prefix=COGL_PIXEL_FORMAT >*/
* supported with CoglBufferAccess including read support.
* @COGL_FEATURE_MAP_BUFFER_FOR_WRITE: Whether cogl_buffer_map() is
* supported with CoglBufferAccess including write support.
+ * @COGL_FEATURE_DEPTH_TEXTURE: Whether #CoglFramebuffer support rendering the
+ * depth buffer to a texture.
*
* Flags for the supported features.
*
@@ -429,7 +440,8 @@ typedef enum
COGL_FEATURE_SHADERS_ARBFP = (1 << 20),
COGL_FEATURE_MAP_BUFFER_FOR_READ = (1 << 21),
COGL_FEATURE_MAP_BUFFER_FOR_WRITE = (1 << 22),
- COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23)
+ COGL_FEATURE_ONSCREEN_MULTIPLE = (1 << 23),
+ COGL_FEATURE_DEPTH_TEXTURE = (1 << 24)
} CoglFeatureFlags;
/**
diff --git a/cogl/driver/gl/cogl-gl.c b/cogl/driver/gl/cogl-gl.c
index fed8737..e734805 100644
--- a/cogl/driver/gl/cogl-gl.c
+++ b/cogl/driver/gl/cogl-gl.c
@@ -199,6 +199,23 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
+ case COGL_PIXEL_FORMAT_DEPTH_16:
+ glintformat = GL_DEPTH_COMPONENT16;
+ glformat = GL_DEPTH_COMPONENT;
+ gltype = GL_UNSIGNED_SHORT;
+ break;
+ case COGL_PIXEL_FORMAT_DEPTH_32:
+ glintformat = GL_DEPTH_COMPONENT32;
+ glformat = GL_DEPTH_COMPONENT;
+ gltype = GL_UNSIGNED_INT;
+ break;
+
+ case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
+ glintformat = GL_DEPTH_STENCIL;
+ glformat = GL_DEPTH_STENCIL;
+ gltype = GL_UNSIGNED_INT_24_8;
+ break;
+
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@@ -403,6 +420,13 @@ _cogl_driver_update_features (CoglContext *ctx,
COGL_FEATURE_ID_OFFSCREEN_MULTISAMPLE, TRUE);
}
+ if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 3, 0) ||
+ _cogl_check_extension ("GL_ARB_depth_texture", gl_extensions))
+ {
+ flags |= COGL_FEATURE_DEPTH_TEXTURE;
+ COGL_FLAGS_SET (ctx->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
+ }
+
if (COGL_CHECK_GL_VERSION (gl_major, gl_minor, 2, 1) ||
_cogl_check_extension ("GL_EXT_pixel_buffer_object", gl_extensions))
private_flags |= COGL_PRIVATE_FEATURE_PBOS;
diff --git a/cogl/driver/gles/cogl-gles.c b/cogl/driver/gles/cogl-gles.c
index 417fee5..d0c96b8 100644
--- a/cogl/driver/gles/cogl-gles.c
+++ b/cogl/driver/gles/cogl-gles.c
@@ -33,6 +33,13 @@
#include "cogl-renderer-private.h"
#include "cogl-private.h"
+#ifndef GL_UNSIGNED_INT_24_8
+#define GL_UNSIGNED_INT_24_8 0x84FA
+#endif
+#ifndef GL_DEPTH_STENCIL
+#define GL_DEPTH_STENCIL 0x84F9
+#endif
+
static CoglBool
_cogl_driver_pixel_format_from_gl_internal (CoglContext *context,
GLenum gl_int_format,
@@ -137,6 +144,23 @@ _cogl_driver_pixel_format_to_gl (CoglContext *context,
gltype = GL_UNSIGNED_SHORT_5_5_5_1;
break;
+ case COGL_PIXEL_FORMAT_DEPTH_16:
+ glintformat = GL_DEPTH_COMPONENT;
+ glformat = GL_DEPTH_COMPONENT;
+ gltype = GL_UNSIGNED_SHORT;
+ break;
+ case COGL_PIXEL_FORMAT_DEPTH_32:
+ glintformat = GL_DEPTH_COMPONENT;
+ glformat = GL_DEPTH_COMPONENT;
+ gltype = GL_UNSIGNED_INT;
+ break;
+
+ case COGL_PIXEL_FORMAT_DEPTH_24_STENCIL_8:
+ glintformat = GL_DEPTH_STENCIL;
+ glformat = GL_DEPTH_STENCIL;
+ gltype = GL_UNSIGNED_INT_24_8;
+ break;
+
case COGL_PIXEL_FORMAT_ANY:
case COGL_PIXEL_FORMAT_YUV:
g_assert_not_reached ();
@@ -247,6 +271,12 @@ _cogl_driver_update_features (CoglContext *context,
COGL_FEATURE_ID_UNSIGNED_INT_INDICES, TRUE);
}
+ if (_cogl_check_extension ("GL_OES_depth_texture", gl_extensions))
+ {
+ flags |= COGL_FEATURE_DEPTH_TEXTURE;
+ COGL_FLAGS_SET (context->features, COGL_FEATURE_ID_DEPTH_TEXTURE, TRUE);
+ }
+
if (_cogl_check_extension ("GL_OES_texture_npot", gl_extensions))
{
flags |= (COGL_FEATURE_TEXTURE_NPOT |
diff --git a/examples/cogl-info.c b/examples/cogl-info.c
index b7dab00..7c43fe2 100644
--- a/examples/cogl-info.c
+++ b/examples/cogl-info.c
@@ -109,6 +109,12 @@ struct {
"GLES2 API integration supported",
"Support for creating a GLES2 context for using the GLES2 API in a "
"way that's integrated with Cogl."
+ },
+ {
+ COGL_FEATURE_ID_DEPTH_TEXTURE,
+ "Depth Textures",
+ "CoglFramebuffers can be configured to render their depth buffer into "
+ "a texture"
}
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]