[cogl] Make sure Cogl always knows the current window geometry

Because Cogl defines the origin of viewport and window coordinates to be
top-left it always needs to know the size of the current window so that Cogl
window/viewport coordinates can be transformed into OpenGL coordinates.

This also fixes cogl_read_pixels to use the current draw buffer height
instead of the viewport height to determine the OpenGL y coordinate to use
for glReadPixels.
This commit is contained in:
Robert Bragg 2009-10-21 23:24:49 +01:00
parent 2d610c2300
commit b4770c1e9b
4 changed files with 36 additions and 7 deletions

View File

@ -102,7 +102,7 @@ cogl_create_context (void)
_context->window_buffer = window_buffer;
cogl_set_draw_buffer (COGL_WINDOW_BUFFER, 0/* ignored */);
_context->dirty_bound_framebuffer = TRUE;
_context->dirty_viewport = TRUE;
_context->dirty_gl_viewport = TRUE;
_context->path_nodes = g_array_new (FALSE, FALSE, sizeof (CoglPathNode));
_context->last_path = 0;

View File

@ -90,7 +90,7 @@ typedef struct
GSList *draw_buffer_stack;
CoglHandle window_buffer;
gboolean dirty_bound_framebuffer;
gboolean dirty_viewport;
gboolean dirty_gl_viewport;
/* Primitives */
floatVec2 path_start;

View File

@ -163,7 +163,7 @@ _cogl_draw_buffer_set_viewport (CoglHandle handle,
draw_buffer->viewport_height = height;
if (_cogl_get_draw_buffer () == draw_buffer)
ctx->dirty_viewport = TRUE;
ctx->dirty_gl_viewport = TRUE;
}
int
@ -377,6 +377,26 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
g_free (onscreen);
}
void
_cogl_onscreen_clutter_backend_set_size (int width, int height)
{
CoglDrawBuffer *draw_buffer;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
draw_buffer = COGL_DRAW_BUFFER (ctx->window_buffer);
if (draw_buffer->width == width && draw_buffer->height == height)
return;
draw_buffer->width = width;
draw_buffer->height = height;
/* We'll need to recalculate the GL viewport state derived
* from the Cogl viewport */
ctx->dirty_gl_viewport = 1;
}
GSList *
_cogl_create_draw_buffer_stack (void)
{
@ -434,7 +454,7 @@ cogl_set_draw_buffer (CoglBufferTarget target, CoglHandle handle)
entry->target = target;
ctx->dirty_bound_framebuffer = 1;
ctx->dirty_viewport = 1;
ctx->dirty_gl_viewport = 1;
if (draw_buffer != COGL_INVALID_HANDLE)
cogl_handle_ref (draw_buffer);
@ -531,13 +551,19 @@ _cogl_draw_buffer_flush_state (CoglHandle handle,
ctx->dirty_bound_framebuffer = FALSE;
}
if (ctx->dirty_viewport)
if (ctx->dirty_gl_viewport)
{
/* Convert the Cogl viewport y offset to an OpenGL viewport y offset
* (NB: OpenGL defines its window and viewport origins to be bottom
* left, while Cogl defines them to be top left.) */
int gl_viewport_y = draw_buffer->height -
(draw_buffer->viewport_y + draw_buffer->viewport_height);
GE (glViewport (draw_buffer->viewport_x,
draw_buffer->viewport_y,
gl_viewport_y,
draw_buffer->viewport_width,
draw_buffer->viewport_height));
ctx->dirty_viewport = FALSE;
ctx->dirty_gl_viewport = FALSE;
}
/* XXX: Flushing clip state may trash the modelview and projection

View File

@ -869,6 +869,9 @@ void cogl_flush_gl_state (int flags);
void _cogl_set_indirect_context (gboolean indirect);
void _cogl_set_viewport (int x, int y, int width, int height);
void
_cogl_onscreen_clutter_backend_set_size (int width, int height);
G_END_DECLS
#undef __COGL_H_INSIDE__