Bug 945 - Clipping+fbo cloning bugs
* clutter/cogl/gl/cogl.c: * clutter/cogl/gles/cogl.c: * clutter/cogl/cogl.h.in: Add cogl_clip_stack_save, cogl_clip_stack_restore, cogl_viewport and cogl_frustum. * clutter/cogl/gl/cogl-fbo.h: * clutter/cogl/gl/cogl-fbo.c: Try to attach a stencil buffer when creating an FBO. * clutter/cogl/common/cogl-clip-stack.c: Add functions to save and restore the whole state of the stack. * clutter/clutter-texture.c (clutter_texture_paint): When rendering the FBO source, setup a temporary asymmetric perspective projection matrix to render it as it would appear on screen. * clutter/clutter-private.h: * clutter/clutter-actor.c (_clutter_actor_apply_modelview_transform_recursive): No longer static and exported in clutter-private.h
This commit is contained in:
parent
88a561fa01
commit
ef76d8e5e2
60
cogl.h.in
60
cogl.h.in
@ -338,14 +338,35 @@ void cogl_get_bitmasks (gint *red,
|
|||||||
* @z_near: Nearest visible point
|
* @z_near: Nearest visible point
|
||||||
* @z_far: Furthest visible point along the z-axis
|
* @z_far: Furthest visible point along the z-axis
|
||||||
*
|
*
|
||||||
* Multiplies the current set matrix with a projection matrix based
|
* Replaces the current projection matrix with a perspective matrix
|
||||||
* on the provided values.
|
* based on the provided values.
|
||||||
*/
|
*/
|
||||||
void cogl_perspective (ClutterFixed fovy,
|
void cogl_perspective (ClutterFixed fovy,
|
||||||
ClutterFixed aspect,
|
ClutterFixed aspect,
|
||||||
ClutterFixed z_near,
|
ClutterFixed z_near,
|
||||||
ClutterFixed z_far);
|
ClutterFixed z_far);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_frustum:
|
||||||
|
* @left: Left clipping plane
|
||||||
|
* @right: Right clipping plane
|
||||||
|
* @bottom: Bottom clipping plane
|
||||||
|
* @top: Top clipping plane
|
||||||
|
* @z_near: Nearest visible point
|
||||||
|
* @z_far: Furthest visible point along the z-axis
|
||||||
|
*
|
||||||
|
* Replaces the current projection matrix with a perspective matrix
|
||||||
|
* for the given viewing frustum.
|
||||||
|
*
|
||||||
|
* Since: 0.8.2
|
||||||
|
*/
|
||||||
|
void cogl_frustum (ClutterFixed left,
|
||||||
|
ClutterFixed right,
|
||||||
|
ClutterFixed bottom,
|
||||||
|
ClutterFixed top,
|
||||||
|
ClutterFixed z_near,
|
||||||
|
ClutterFixed z_far);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_setup_viewport:
|
* cogl_setup_viewport:
|
||||||
* @width: Width of the viewport
|
* @width: Width of the viewport
|
||||||
@ -369,6 +390,18 @@ void cogl_setup_viewport (guint width,
|
|||||||
ClutterFixed z_near,
|
ClutterFixed z_near,
|
||||||
ClutterFixed z_far);
|
ClutterFixed z_far);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_viewport:
|
||||||
|
* @width: Width of the viewport
|
||||||
|
* @height: Height of the viewport
|
||||||
|
*
|
||||||
|
* Replace the current viewport with the given values.
|
||||||
|
*
|
||||||
|
* Since: 0.8.2
|
||||||
|
*/
|
||||||
|
void cogl_viewport (guint width,
|
||||||
|
guint height);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_push_matrix:
|
* cogl_push_matrix:
|
||||||
*
|
*
|
||||||
@ -511,6 +544,29 @@ void cogl_clip_set (ClutterFixed x_offset,
|
|||||||
*/
|
*/
|
||||||
void cogl_clip_unset (void);
|
void cogl_clip_unset (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_clip_stack_save:
|
||||||
|
*
|
||||||
|
* Save the entire state of the clipping stack and then clear all
|
||||||
|
* clipping. The previous state can be returned to with
|
||||||
|
* cogl_clip_stack_restore(). Each call to cogl_clip_set() after this
|
||||||
|
* must be matched by a call to cogl_clip_unset() before calling
|
||||||
|
* cogl_clip_stack_restore().
|
||||||
|
*
|
||||||
|
* Since: 0.8.2
|
||||||
|
*/
|
||||||
|
void cogl_clip_stack_save (void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cogl_clip_stack_restore:
|
||||||
|
*
|
||||||
|
* Restore the state of the clipping stack that was previously saved
|
||||||
|
* by cogl_clip_stack_save().
|
||||||
|
*
|
||||||
|
* Since: 0.8.2
|
||||||
|
*/
|
||||||
|
void cogl_clip_stack_restore (void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cogl_enable_depth_test:
|
* cogl_enable_depth_test:
|
||||||
* @setting: %TRUE to enable depth testing or %FALSE to disable.
|
* @setting: %TRUE to enable depth testing or %FALSE to disable.
|
||||||
|
@ -50,6 +50,12 @@ typedef struct _CoglClipStackEntry CoglClipStackEntry;
|
|||||||
|
|
||||||
struct _CoglClipStackEntry
|
struct _CoglClipStackEntry
|
||||||
{
|
{
|
||||||
|
/* If this is set then this entry clears the clip stack. This is
|
||||||
|
used to clear the stack when drawing an FBO put to keep the
|
||||||
|
entries so they can be restored when the FBO drawing is
|
||||||
|
completed */
|
||||||
|
gboolean clear;
|
||||||
|
|
||||||
/* The rectangle for this clip */
|
/* The rectangle for this clip */
|
||||||
ClutterFixed x_offset;
|
ClutterFixed x_offset;
|
||||||
ClutterFixed y_offset;
|
ClutterFixed y_offset;
|
||||||
@ -61,7 +67,6 @@ struct _CoglClipStackEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
static GList *cogl_clip_stack_top = NULL;
|
static GList *cogl_clip_stack_top = NULL;
|
||||||
static GList *cogl_clip_stack_bottom = NULL;
|
|
||||||
static int cogl_clip_stack_depth = 0;
|
static int cogl_clip_stack_depth = 0;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -93,6 +98,7 @@ cogl_clip_set (ClutterFixed x_offset,
|
|||||||
CoglClipStackEntry *entry = g_slice_new (CoglClipStackEntry);
|
CoglClipStackEntry *entry = g_slice_new (CoglClipStackEntry);
|
||||||
|
|
||||||
/* Make a new entry */
|
/* Make a new entry */
|
||||||
|
entry->clear = FALSE;
|
||||||
entry->x_offset = x_offset;
|
entry->x_offset = x_offset;
|
||||||
entry->y_offset = y_offset;
|
entry->y_offset = y_offset;
|
||||||
entry->width = width;
|
entry->width = width;
|
||||||
@ -105,8 +111,6 @@ cogl_clip_set (ClutterFixed x_offset,
|
|||||||
|
|
||||||
/* Store it in the stack */
|
/* Store it in the stack */
|
||||||
cogl_clip_stack_top = g_list_prepend (cogl_clip_stack_top, entry);
|
cogl_clip_stack_top = g_list_prepend (cogl_clip_stack_top, entry);
|
||||||
if (cogl_clip_stack_bottom == NULL)
|
|
||||||
cogl_clip_stack_bottom = cogl_clip_stack_top;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -118,8 +122,6 @@ cogl_clip_unset (void)
|
|||||||
g_slice_free (CoglClipStackEntry, cogl_clip_stack_top->data);
|
g_slice_free (CoglClipStackEntry, cogl_clip_stack_top->data);
|
||||||
cogl_clip_stack_top = g_list_delete_link (cogl_clip_stack_top,
|
cogl_clip_stack_top = g_list_delete_link (cogl_clip_stack_top,
|
||||||
cogl_clip_stack_top);
|
cogl_clip_stack_top);
|
||||||
if (cogl_clip_stack_top == NULL)
|
|
||||||
cogl_clip_stack_bottom = NULL;
|
|
||||||
cogl_clip_stack_depth--;
|
cogl_clip_stack_depth--;
|
||||||
|
|
||||||
/* Rebuild the clip */
|
/* Rebuild the clip */
|
||||||
@ -131,7 +133,7 @@ _cogl_clip_stack_rebuild (gboolean just_stencil)
|
|||||||
{
|
{
|
||||||
int has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
|
int has_clip_planes = cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES);
|
||||||
GList *node;
|
GList *node;
|
||||||
int depth = 1;
|
int depth = 0;
|
||||||
|
|
||||||
/* Disable clip planes if the stack is empty */
|
/* Disable clip planes if the stack is empty */
|
||||||
if (has_clip_planes && cogl_clip_stack_depth < 1)
|
if (has_clip_planes && cogl_clip_stack_depth < 1)
|
||||||
@ -141,8 +143,14 @@ _cogl_clip_stack_rebuild (gboolean just_stencil)
|
|||||||
if (cogl_clip_stack_depth < (has_clip_planes ? 2 : 1))
|
if (cogl_clip_stack_depth < (has_clip_planes ? 2 : 1))
|
||||||
_cogl_disable_stencil_buffer ();
|
_cogl_disable_stencil_buffer ();
|
||||||
|
|
||||||
|
/* Find the bottom of the stack */
|
||||||
|
for (node = cogl_clip_stack_top; depth < cogl_clip_stack_depth - 1;
|
||||||
|
node = node->next)
|
||||||
|
depth++;
|
||||||
|
|
||||||
/* Re-add every entry from the bottom of the stack up */
|
/* Re-add every entry from the bottom of the stack up */
|
||||||
for (node = cogl_clip_stack_bottom; node; node = node->prev, depth++)
|
depth = 1;
|
||||||
|
for (; depth <= cogl_clip_stack_depth; node = node->prev, depth++)
|
||||||
if (!just_stencil || !has_clip_planes || depth > 1)
|
if (!just_stencil || !has_clip_planes || depth > 1)
|
||||||
{
|
{
|
||||||
const CoglClipStackEntry *entry = (CoglClipStackEntry *) node->data;
|
const CoglClipStackEntry *entry = (CoglClipStackEntry *) node->data;
|
||||||
@ -156,12 +164,16 @@ _cogl_clip_stack_rebuild (gboolean just_stencil)
|
|||||||
void
|
void
|
||||||
_cogl_clip_stack_merge (void)
|
_cogl_clip_stack_merge (void)
|
||||||
{
|
{
|
||||||
GList *node = cogl_clip_stack_bottom;
|
GList *node = cogl_clip_stack_top;
|
||||||
|
int i;
|
||||||
|
|
||||||
/* Merge the current clip stack on top of whatever is in the stencil
|
/* Merge the current clip stack on top of whatever is in the stencil
|
||||||
buffer */
|
buffer */
|
||||||
if (node)
|
if (cogl_clip_stack_depth)
|
||||||
{
|
{
|
||||||
|
for (i = 0; i < cogl_clip_stack_depth - 1; i++)
|
||||||
|
node = node->next;
|
||||||
|
|
||||||
/* Skip the first entry if we have clipping planes */
|
/* Skip the first entry if we have clipping planes */
|
||||||
if (cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES))
|
if (cogl_features_available (COGL_FEATURE_FOUR_CLIP_PLANES))
|
||||||
node = node->prev;
|
node = node->prev;
|
||||||
@ -178,3 +190,43 @@ _cogl_clip_stack_merge (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_stack_save (void)
|
||||||
|
{
|
||||||
|
CoglClipStackEntry *entry = g_slice_new (CoglClipStackEntry);
|
||||||
|
|
||||||
|
/* Push an entry into the stack to mark that it should be cleared */
|
||||||
|
entry->clear = TRUE;
|
||||||
|
cogl_clip_stack_top = g_list_prepend (cogl_clip_stack_top, entry);
|
||||||
|
|
||||||
|
/* Reset the depth to zero */
|
||||||
|
cogl_clip_stack_depth = 0;
|
||||||
|
|
||||||
|
/* Rebuilding the stack will now disabling all clipping */
|
||||||
|
_cogl_clip_stack_rebuild (FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_clip_stack_restore (void)
|
||||||
|
{
|
||||||
|
GList *node;
|
||||||
|
|
||||||
|
/* The top of the stack should be a clear marker */
|
||||||
|
g_assert (cogl_clip_stack_top);
|
||||||
|
g_assert (((CoglClipStackEntry *) cogl_clip_stack_top->data)->clear);
|
||||||
|
|
||||||
|
/* Remove the top entry */
|
||||||
|
g_slice_free (CoglClipStackEntry, cogl_clip_stack_top->data);
|
||||||
|
cogl_clip_stack_top = g_list_delete_link (cogl_clip_stack_top,
|
||||||
|
cogl_clip_stack_top);
|
||||||
|
|
||||||
|
/* Recalculate the depth of the stack */
|
||||||
|
cogl_clip_stack_depth = 0;
|
||||||
|
for (node = cogl_clip_stack_top;
|
||||||
|
node && !((CoglClipStackEntry *) node->data)->clear;
|
||||||
|
node = node->next)
|
||||||
|
cogl_clip_stack_depth++;
|
||||||
|
|
||||||
|
_cogl_clip_stack_rebuild (FALSE);
|
||||||
|
}
|
||||||
|
@ -26,11 +26,6 @@
|
|||||||
#ifndef __COGL_CLIP_STACK_H
|
#ifndef __COGL_CLIP_STACK_H
|
||||||
#define __COGL_CLIP_STACK_H
|
#define __COGL_CLIP_STACK_H
|
||||||
|
|
||||||
void cogl_clip_set (ClutterFixed x_offset,
|
|
||||||
ClutterFixed y_offset,
|
|
||||||
ClutterFixed width,
|
|
||||||
ClutterFixed height);
|
|
||||||
void cogl_clip_unset (void);
|
|
||||||
void _cogl_clip_stack_rebuild (gboolean just_stencil);
|
void _cogl_clip_stack_rebuild (gboolean just_stencil);
|
||||||
void _cogl_clip_stack_merge (void);
|
void _cogl_clip_stack_merge (void);
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@ CoglPixelFormat
|
|||||||
CoglBufferTarget
|
CoglBufferTarget
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
cogl_perspective
|
cogl_perspective
|
||||||
|
cogl_frustum
|
||||||
cogl_setup_viewport
|
cogl_setup_viewport
|
||||||
|
cogl_viewport
|
||||||
cogl_get_modelview_matrix
|
cogl_get_modelview_matrix
|
||||||
cogl_get_projection_matrix
|
cogl_get_projection_matrix
|
||||||
cogl_get_viewport
|
cogl_get_viewport
|
||||||
@ -28,6 +30,8 @@ cogl_rotate
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
cogl_clip_set
|
cogl_clip_set
|
||||||
cogl_clip_unset
|
cogl_clip_unset
|
||||||
|
cogl_clip_stack_save
|
||||||
|
cogl_clip_stack_restore
|
||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
cogl_enable_depth_test
|
cogl_enable_depth_test
|
||||||
cogl_alpha_func
|
cogl_alpha_func
|
||||||
|
@ -68,6 +68,7 @@ typedef struct
|
|||||||
|
|
||||||
/* 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_PFNGLBINDRENDERBUFFEREXTPROC pf_glBindRenderbufferEXT;
|
COGL_PFNGLBINDRENDERBUFFEREXTPROC pf_glBindRenderbufferEXT;
|
||||||
COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC pf_glRenderbufferStorageEXT;
|
COGL_PFNGLRENDERBUFFERSTORAGEEXTPROC pf_glRenderbufferStorageEXT;
|
||||||
COGL_PFNGLGENFRAMEBUFFERSEXTPROC pf_glGenFramebuffersEXT;
|
COGL_PFNGLGENFRAMEBUFFERSEXTPROC pf_glGenFramebuffersEXT;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
/* Expecting EXT functions not to be defined - redirect to pointers in context */
|
/* Expecting EXT functions not to be defined - redirect to pointers in context */
|
||||||
#define glGenRenderbuffersEXT ctx->pf_glGenRenderbuffersEXT
|
#define glGenRenderbuffersEXT ctx->pf_glGenRenderbuffersEXT
|
||||||
|
#define glDeleteRenderbuffersEXT ctx->pf_glDeleteRenderbuffersEXT
|
||||||
#define glBindRenderbufferEXT ctx->pf_glBindRenderbufferEXT
|
#define glBindRenderbufferEXT ctx->pf_glBindRenderbufferEXT
|
||||||
#define glRenderbufferStorageEXT ctx->pf_glRenderbufferStorageEXT
|
#define glRenderbufferStorageEXT ctx->pf_glRenderbufferStorageEXT
|
||||||
#define glGenFramebuffersEXT ctx->pf_glGenFramebuffersEXT
|
#define glGenFramebuffersEXT ctx->pf_glGenFramebuffersEXT
|
||||||
@ -68,6 +69,7 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
|
|||||||
CoglTexSliceSpan *y_span;
|
CoglTexSliceSpan *y_span;
|
||||||
GLuint tex_gl_handle;
|
GLuint tex_gl_handle;
|
||||||
GLuint fbo_gl_handle;
|
GLuint fbo_gl_handle;
|
||||||
|
GLuint gl_stencil_handle;
|
||||||
GLenum status;
|
GLenum status;
|
||||||
|
|
||||||
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
_COGL_GET_CONTEXT (ctx, COGL_INVALID_HANDLE);
|
||||||
@ -92,21 +94,47 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
|
|||||||
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
x_span = &g_array_index (tex->slice_x_spans, CoglTexSliceSpan, 0);
|
||||||
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
y_span = &g_array_index (tex->slice_y_spans, CoglTexSliceSpan, 0);
|
||||||
tex_gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
tex_gl_handle = g_array_index (tex->slice_gl_handles, GLuint, 0);
|
||||||
|
|
||||||
|
/* Create a renderbuffer for stenciling */
|
||||||
|
GE( glGenRenderbuffersEXT (1, &gl_stencil_handle) );
|
||||||
|
GE( glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, gl_stencil_handle) );
|
||||||
|
GE( glRenderbufferStorageEXT (GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT,
|
||||||
|
cogl_texture_get_width (texhandle),
|
||||||
|
cogl_texture_get_height (texhandle)) );
|
||||||
|
GE( glBindRenderbufferEXT (GL_RENDERBUFFER_EXT, 0) );
|
||||||
|
|
||||||
/* Generate framebuffer */
|
/* Generate framebuffer */
|
||||||
glGenFramebuffersEXT (1, &fbo_gl_handle);
|
glGenFramebuffersEXT (1, &fbo_gl_handle);
|
||||||
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo_gl_handle) );
|
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo_gl_handle) );
|
||||||
GE( glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
GE( glFramebufferTexture2DEXT (GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||||
tex->gl_target, tex_gl_handle, 0) );
|
tex->gl_target, tex_gl_handle, 0) );
|
||||||
|
GE( glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_STENCIL_ATTACHMENT_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT, gl_stencil_handle) );
|
||||||
|
|
||||||
/* Make sure it's complete */
|
/* Make sure it's complete */
|
||||||
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
||||||
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
{
|
{
|
||||||
GE( glDeleteFramebuffersEXT (1, &fbo_gl_handle) );
|
/* Stencil renderbuffers aren't always supported. Try again
|
||||||
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0) );
|
without the stencil buffer */
|
||||||
return COGL_INVALID_HANDLE;
|
GE( glFramebufferRenderbufferEXT (GL_FRAMEBUFFER_EXT,
|
||||||
|
GL_STENCIL_ATTACHMENT_EXT,
|
||||||
|
GL_RENDERBUFFER_EXT,
|
||||||
|
0) );
|
||||||
|
GE( glDeleteRenderbuffersEXT (1, &gl_stencil_handle) );
|
||||||
|
gl_stencil_handle = 0;
|
||||||
|
|
||||||
|
status = glCheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
|
||||||
|
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
|
||||||
|
{
|
||||||
|
/* Still failing, so give up */
|
||||||
|
GE( glDeleteFramebuffersEXT (1, &fbo_gl_handle) );
|
||||||
|
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0) );
|
||||||
|
return COGL_INVALID_HANDLE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0) );
|
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, 0) );
|
||||||
@ -114,10 +142,11 @@ cogl_offscreen_new_to_texture (CoglHandle texhandle)
|
|||||||
/* Allocate and init a CoglFbo object (store non-wasted size
|
/* Allocate and init a CoglFbo object (store non-wasted size
|
||||||
for subsequent blits and viewport setup) */
|
for subsequent blits and viewport setup) */
|
||||||
fbo = (CoglFbo*) g_malloc (sizeof (CoglFbo));
|
fbo = (CoglFbo*) g_malloc (sizeof (CoglFbo));
|
||||||
fbo->ref_count = 1;
|
fbo->ref_count = 1;
|
||||||
fbo->width = x_span->size - x_span->waste;
|
fbo->width = x_span->size - x_span->waste;
|
||||||
fbo->height = y_span->size - y_span->waste;
|
fbo->height = y_span->size - y_span->waste;
|
||||||
fbo->gl_handle = fbo_gl_handle;
|
fbo->gl_handle = fbo_gl_handle;
|
||||||
|
fbo->gl_stencil_handle = gl_stencil_handle;
|
||||||
|
|
||||||
COGL_HANDLE_DEBUG_NEW (offscreen, fbo);
|
COGL_HANDLE_DEBUG_NEW (offscreen, fbo);
|
||||||
|
|
||||||
@ -140,7 +169,8 @@ _cogl_offscreen_free (CoglFbo *fbo)
|
|||||||
|
|
||||||
/* Frees FBO resources but its handle is not
|
/* Frees FBO resources but its handle is not
|
||||||
released! Do that separately before this! */
|
released! Do that separately before this! */
|
||||||
|
if (fbo->gl_stencil_handle)
|
||||||
|
GE( glDeleteRenderbuffersEXT (1, &fbo->gl_stencil_handle) );
|
||||||
GE( glDeleteFramebuffersEXT (1, &fbo->gl_handle) );
|
GE( glDeleteFramebuffersEXT (1, &fbo->gl_handle) );
|
||||||
g_free (fbo);
|
g_free (fbo);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ typedef struct
|
|||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
GLuint gl_handle;
|
GLuint gl_handle;
|
||||||
|
GLuint gl_stencil_handle;
|
||||||
|
|
||||||
} CoglFbo;
|
} CoglFbo;
|
||||||
|
|
||||||
|
67
gl/cogl.c
67
gl/cogl.c
@ -746,6 +746,9 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
|
|
||||||
memset (&m[0], 0, sizeof (m));
|
memset (&m[0], 0, sizeof (m));
|
||||||
|
|
||||||
|
GE( glMatrixMode (GL_PROJECTION) );
|
||||||
|
GE( glLoadIdentity () );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Based on the original algorithm in perspective():
|
* Based on the original algorithm in perspective():
|
||||||
*
|
*
|
||||||
@ -773,6 +776,8 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
|
|
||||||
GE( glMultMatrixf (m) );
|
GE( glMultMatrixf (m) );
|
||||||
|
|
||||||
|
GE( glMatrixMode (GL_MODELVIEW) );
|
||||||
|
|
||||||
/* Calculate and store the inverse of the matrix */
|
/* Calculate and store the inverse of the matrix */
|
||||||
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
|
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
|
||||||
|
|
||||||
@ -786,6 +791,60 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
#undef M
|
#undef M
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_frustum (ClutterFixed left,
|
||||||
|
ClutterFixed right,
|
||||||
|
ClutterFixed bottom,
|
||||||
|
ClutterFixed top,
|
||||||
|
ClutterFixed z_near,
|
||||||
|
ClutterFixed z_far)
|
||||||
|
{
|
||||||
|
GLfloat c, d;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
GE( glMatrixMode (GL_PROJECTION) );
|
||||||
|
GE( glLoadIdentity () );
|
||||||
|
|
||||||
|
GE( glFrustum (CLUTTER_FIXED_TO_DOUBLE (left),
|
||||||
|
CLUTTER_FIXED_TO_DOUBLE (right),
|
||||||
|
CLUTTER_FIXED_TO_DOUBLE (bottom),
|
||||||
|
CLUTTER_FIXED_TO_DOUBLE (top),
|
||||||
|
CLUTTER_FIXED_TO_DOUBLE (z_near),
|
||||||
|
CLUTTER_FIXED_TO_DOUBLE (z_far)) );
|
||||||
|
|
||||||
|
GE( glMatrixMode (GL_MODELVIEW) );
|
||||||
|
|
||||||
|
/* Calculate and store the inverse of the matrix */
|
||||||
|
memset (ctx->inverse_projection, 0, sizeof (GLfloat) * 16);
|
||||||
|
|
||||||
|
c = -CLUTTER_FIXED_TO_FLOAT (z_far + z_near)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (z_far - z_near);
|
||||||
|
d = -CLUTTER_FIXED_TO_FLOAT (2 * CFX_QMUL (z_far, z_near))
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (z_far - z_near);
|
||||||
|
|
||||||
|
#define M(row,col) ctx->inverse_projection[col*4+row]
|
||||||
|
M(0,0) = CLUTTER_FIXED_TO_FLOAT (right - left)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (2 * z_near);
|
||||||
|
M(0,3) = CLUTTER_FIXED_TO_FLOAT (right + left)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (2 * z_near);
|
||||||
|
M(1,1) = CLUTTER_FIXED_TO_FLOAT (top - bottom)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (2 * z_near);
|
||||||
|
M(1,3) = CLUTTER_FIXED_TO_FLOAT (top + bottom)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (2 * z_near);
|
||||||
|
M(2,3) = -1.0f;
|
||||||
|
M(3,2) = 1.0f / d;
|
||||||
|
M(3,3) = c / d;
|
||||||
|
#undef M
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_viewport (guint width,
|
||||||
|
guint height)
|
||||||
|
{
|
||||||
|
GE( glViewport (0, 0, width, height) );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_setup_viewport (guint width,
|
cogl_setup_viewport (guint width,
|
||||||
guint height,
|
guint height,
|
||||||
@ -798,12 +857,8 @@ cogl_setup_viewport (guint width,
|
|||||||
|
|
||||||
GE( glViewport (0, 0, width, height) );
|
GE( glViewport (0, 0, width, height) );
|
||||||
|
|
||||||
GE( glMatrixMode (GL_PROJECTION) );
|
|
||||||
GE( glLoadIdentity () );
|
|
||||||
|
|
||||||
cogl_perspective (fovy, aspect, z_near, z_far);
|
cogl_perspective (fovy, aspect, z_near, z_far);
|
||||||
|
|
||||||
GE( glMatrixMode (GL_MODELVIEW) );
|
|
||||||
GE( glLoadIdentity () );
|
GE( glLoadIdentity () );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -969,6 +1024,10 @@ _cogl_features_init ()
|
|||||||
(COGL_PFNGLGENRENDERBUFFERSEXTPROC)
|
(COGL_PFNGLGENRENDERBUFFERSEXTPROC)
|
||||||
cogl_get_proc_address ("glGenRenderbuffersEXT");
|
cogl_get_proc_address ("glGenRenderbuffersEXT");
|
||||||
|
|
||||||
|
ctx->pf_glDeleteRenderbuffersEXT =
|
||||||
|
(COGL_PFNGLDELETERENDERBUFFERSEXTPROC)
|
||||||
|
cogl_get_proc_address ("glDeleteRenderbuffersEXT");
|
||||||
|
|
||||||
ctx->pf_glBindRenderbufferEXT =
|
ctx->pf_glBindRenderbufferEXT =
|
||||||
(COGL_PFNGLBINDRENDERBUFFEREXTPROC)
|
(COGL_PFNGLBINDRENDERBUFFEREXTPROC)
|
||||||
cogl_get_proc_address ("glBindRenderbufferEXT");
|
cogl_get_proc_address ("glBindRenderbufferEXT");
|
||||||
|
@ -666,6 +666,31 @@ cogl_wrap_glMultMatrixx (const GLfixed *m)
|
|||||||
cogl_wrap_glMultMatrix (new_matrix);
|
cogl_wrap_glMultMatrix (new_matrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_wrap_glFrustumx (GLfixed left, GLfixed right,
|
||||||
|
GLfixed bottom, GLfixed top,
|
||||||
|
GLfixed z_near, GLfixed z_far)
|
||||||
|
{
|
||||||
|
float matrix[16];
|
||||||
|
float two_near = CLUTTER_FIXED_TO_FLOAT (2 * z_near);
|
||||||
|
|
||||||
|
memset (matrix, 0, sizeof (matrix));
|
||||||
|
|
||||||
|
matrix[0] = two_near / CLUTTER_FIXED_TO_FLOAT (right - left);
|
||||||
|
matrix[5] = two_near / CLUTTER_FIXED_TO_FLOAT (top - bottom);
|
||||||
|
matrix[8] = CLUTTER_FIXED_TO_FLOAT (right + left)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (right - left);
|
||||||
|
matrix[9] = CLUTTER_FIXED_TO_FLOAT (top + bottom)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (top - bottom);
|
||||||
|
matrix[10] = -CLUTTER_FIXED_TO_FLOAT (z_far + z_near)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (z_far - z_near);
|
||||||
|
matrix[11] = -1.0f;
|
||||||
|
matrix[14] = -two_near * CLUTTER_FIXED_TO_FLOAT (z_far)
|
||||||
|
/ CLUTTER_FIXED_TO_FLOAT (z_far - z_near);
|
||||||
|
|
||||||
|
cogl_wrap_glMultMatrix (matrix);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z)
|
cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z)
|
||||||
{
|
{
|
||||||
|
@ -204,6 +204,9 @@ void cogl_wrap_glPopMatrix ();
|
|||||||
void cogl_wrap_glMatrixMode (GLenum mode);
|
void cogl_wrap_glMatrixMode (GLenum mode);
|
||||||
void cogl_wrap_glLoadIdentity ();
|
void cogl_wrap_glLoadIdentity ();
|
||||||
void cogl_wrap_glMultMatrixx (const GLfixed *m);
|
void cogl_wrap_glMultMatrixx (const GLfixed *m);
|
||||||
|
void cogl_wrap_glFrustumx (GLfixed left, GLfixed right,
|
||||||
|
GLfixed bottom, GLfixed top,
|
||||||
|
GLfixed z_near, GLfixed z_far);
|
||||||
void cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z);
|
void cogl_wrap_glScalex (GLfixed x, GLfixed y, GLfixed z);
|
||||||
void cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z);
|
void cogl_wrap_glTranslatex (GLfixed x, GLfixed y, GLfixed z);
|
||||||
void cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
|
void cogl_wrap_glRotatex (GLfixed angle, GLfixed x, GLfixed y, GLfixed z);
|
||||||
@ -268,6 +271,7 @@ void _cogl_gles2_clear_cache_for_program (CoglHandle program);
|
|||||||
#define cogl_wrap_glMatrixMode glMatrixMode
|
#define cogl_wrap_glMatrixMode glMatrixMode
|
||||||
#define cogl_wrap_glLoadIdentity glLoadIdentity
|
#define cogl_wrap_glLoadIdentity glLoadIdentity
|
||||||
#define cogl_wrap_glMultMatrixx glMultMatrixx
|
#define cogl_wrap_glMultMatrixx glMultMatrixx
|
||||||
|
#define cogl_wrap_glFrustumx glFrustumx
|
||||||
#define cogl_wrap_glScalex glScalex
|
#define cogl_wrap_glScalex glScalex
|
||||||
#define cogl_wrap_glTranslatex glTranslatex
|
#define cogl_wrap_glTranslatex glTranslatex
|
||||||
#define cogl_wrap_glRotatex glRotatex
|
#define cogl_wrap_glRotatex glRotatex
|
||||||
|
55
gles/cogl.c
55
gles/cogl.c
@ -661,7 +661,10 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
|
|
||||||
memset (&m[0], 0, sizeof (m));
|
memset (&m[0], 0, sizeof (m));
|
||||||
|
|
||||||
/*
|
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||||
|
GE( cogl_wrap_glLoadIdentity () );
|
||||||
|
|
||||||
|
/*
|
||||||
* Based on the original algorithm in perspective():
|
* Based on the original algorithm in perspective():
|
||||||
*
|
*
|
||||||
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
|
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
|
||||||
@ -688,6 +691,8 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
|
|
||||||
GE( cogl_wrap_glMultMatrixx (m) );
|
GE( cogl_wrap_glMultMatrixx (m) );
|
||||||
|
|
||||||
|
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||||
|
|
||||||
/* Calculate and store the inverse of the matrix */
|
/* Calculate and store the inverse of the matrix */
|
||||||
memset (ctx->inverse_projection, 0, sizeof (ClutterFixed) * 16);
|
memset (ctx->inverse_projection, 0, sizeof (ClutterFixed) * 16);
|
||||||
|
|
||||||
@ -702,6 +707,51 @@ cogl_perspective (ClutterFixed fovy,
|
|||||||
#undef M
|
#undef M
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_frustum (ClutterFixed left,
|
||||||
|
ClutterFixed right,
|
||||||
|
ClutterFixed bottom,
|
||||||
|
ClutterFixed top,
|
||||||
|
ClutterFixed z_near,
|
||||||
|
ClutterFixed z_far)
|
||||||
|
{
|
||||||
|
ClutterFixed c, d;
|
||||||
|
|
||||||
|
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
|
||||||
|
|
||||||
|
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
||||||
|
GE( cogl_wrap_glLoadIdentity () );
|
||||||
|
|
||||||
|
GE( cogl_wrap_glFrustumx (left, right,
|
||||||
|
bottom, top,
|
||||||
|
z_near, z_far) );
|
||||||
|
|
||||||
|
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
||||||
|
|
||||||
|
/* Calculate and store the inverse of the matrix */
|
||||||
|
memset (ctx->inverse_projection, 0, sizeof (ClutterFixed) * 16);
|
||||||
|
|
||||||
|
c = -CFX_QDIV (z_far + z_near, z_far - z_near);
|
||||||
|
d = -CFX_QDIV (2 * CFX_QMUL (z_far, z_near), z_far - z_near);
|
||||||
|
|
||||||
|
#define M(row,col) ctx->inverse_projection[col*4+row]
|
||||||
|
M(0,0) = CFX_QDIV (right - left, 2 * z_near);
|
||||||
|
M(0,3) = CFX_QDIV (right + left, 2 * z_near);
|
||||||
|
M(1,1) = CFX_QDIV (top - bottom, 2 * z_near);
|
||||||
|
M(1,3) = CFX_QDIV (top + bottom, 2 * z_near);
|
||||||
|
M(2,3) = -CFX_ONE;
|
||||||
|
M(3,2) = CFX_QDIV (CFX_ONE, d);
|
||||||
|
M(3,3) = CFX_QDIV (c, d);
|
||||||
|
#undef M
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cogl_viewport (guint width,
|
||||||
|
guint height)
|
||||||
|
{
|
||||||
|
GE( glViewport (0, 0, width, height) );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cogl_setup_viewport (guint w,
|
cogl_setup_viewport (guint w,
|
||||||
guint h,
|
guint h,
|
||||||
@ -715,8 +765,6 @@ cogl_setup_viewport (guint w,
|
|||||||
ClutterFixed z_camera;
|
ClutterFixed z_camera;
|
||||||
|
|
||||||
GE( glViewport (0, 0, width, height) );
|
GE( glViewport (0, 0, width, height) );
|
||||||
GE( cogl_wrap_glMatrixMode (GL_PROJECTION) );
|
|
||||||
GE( cogl_wrap_glLoadIdentity () );
|
|
||||||
|
|
||||||
/* For Ortho projection.
|
/* For Ortho projection.
|
||||||
* cogl_wrap_glOrthox (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
|
* cogl_wrap_glOrthox (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
|
||||||
@ -724,7 +772,6 @@ cogl_setup_viewport (guint w,
|
|||||||
|
|
||||||
cogl_perspective (fovy, aspect, z_near, z_far);
|
cogl_perspective (fovy, aspect, z_near, z_far);
|
||||||
|
|
||||||
GE( cogl_wrap_glMatrixMode (GL_MODELVIEW) );
|
|
||||||
GE( cogl_wrap_glLoadIdentity () );
|
GE( cogl_wrap_glLoadIdentity () );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user