diff --git a/src/cairo-gl-composite.c b/src/cairo-gl-composite.c index a32e00d0b..7cbe894df 100644 --- a/src/cairo-gl-composite.c +++ b/src/cairo-gl-composite.c @@ -414,6 +414,8 @@ static void _cairo_gl_composite_bind_to_shader (cairo_gl_context_t *ctx, cairo_gl_composite_t *setup) { + _cairo_gl_shader_bind_matrix4f(ctx, "ModelViewProjectionMatrix", + ctx->modelviewprojection_matrix); _cairo_gl_operand_bind_to_shader (ctx, &setup->src, CAIRO_GL_TEX_SOURCE); _cairo_gl_operand_bind_to_shader (ctx, &setup->mask, CAIRO_GL_TEX_MASK); } diff --git a/src/cairo-gl-device.c b/src/cairo-gl-device.c index 25423e009..3537dc907 100644 --- a/src/cairo-gl-device.c +++ b/src/cairo-gl-device.c @@ -269,6 +269,46 @@ _cairo_gl_ensure_framebuffer (cairo_gl_context_t *ctx, } } +/* + * Stores a parallel projection transformation in matrix 'm', + * using column-major order. + * + * This is equivalent to: + * + * glLoadIdentity() + * gluOrtho2D() + * + * The calculation for the ortho tranformation was taken from the + * mesa source code. + */ +static void +_gl_identity_ortho (GLfloat *m, + GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top) +{ +#define M(row,col) m[col*4+row] + M(0,0) = 2.f / (right - left); + M(0,1) = 0.f; + M(0,2) = 0.f; + M(0,3) = -(right + left) / (right - left); + + M(1,0) = 0.f; + M(1,1) = 2.f / (top - bottom); + M(1,2) = 0.f; + M(1,3) = -(top + bottom) / (top - bottom); + + M(2,0) = 0.f; + M(2,1) = 0.f; + M(2,2) = -1.f; + M(2,3) = 0.f; + + M(3,0) = 0.f; + M(3,1) = 0.f; + M(3,2) = 0.f; + M(3,3) = 1.f; +#undef M +} + void _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, cairo_gl_surface_t *surface) @@ -295,13 +335,10 @@ _cairo_gl_context_set_destination (cairo_gl_context_t *ctx, glViewport (0, 0, surface->width, surface->height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); if (_cairo_gl_surface_is_texture (surface)) - glOrtho (0, surface->width, 0, surface->height, -1.0, 1.0); + _gl_identity_ortho (ctx->modelviewprojection_matrix, + 0, surface->width, 0, surface->height); else - glOrtho (0, surface->width, surface->height, 0, -1.0, 1.0); - - glMatrixMode (GL_MODELVIEW); - glLoadIdentity (); + _gl_identity_ortho (ctx->modelviewprojection_matrix, + 0, surface->width, surface->height, 0); } diff --git a/src/cairo-gl-private.h b/src/cairo-gl-private.h index 3dd75f857..61c382d9e 100644 --- a/src/cairo-gl-private.h +++ b/src/cairo-gl-private.h @@ -259,6 +259,7 @@ struct _cairo_gl_context { cairo_bool_t has_mesa_pack_invert; cairo_gl_dispatch_t dispatch; + GLfloat modelviewprojection_matrix[16]; void (*acquire) (void *ctx); void (*release) (void *ctx); diff --git a/src/cairo-gl-shaders.c b/src/cairo-gl-shaders.c index 13efccb02..6a3a6067b 100644 --- a/src/cairo-gl-shaders.c +++ b/src/cairo-gl-shaders.c @@ -518,9 +518,10 @@ cairo_gl_shader_get_vertex_source (cairo_gl_var_type_t src, cairo_gl_shader_emit_variable (stream, mask, CAIRO_GL_TEX_MASK); _cairo_output_stream_printf (stream, + "uniform mat4 ModelViewProjectionMatrix;\n" "void main()\n" "{\n" - " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"); + " gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"); cairo_gl_shader_emit_vertex (stream, src, CAIRO_GL_TEX_SOURCE); cairo_gl_shader_emit_vertex (stream, mask, CAIRO_GL_TEX_MASK);