gl: Use a custom shader uniform for the ModelViewProjection matrix

The built-in gl_ModelViewProjectionMatrix uniform (and others) has been
deprecated and removed in recent GLSL versions and is not supported
at all in GLSL ES. A custom uniform for the same purpose works across
all versions.

[ickle: base _gl_identity_ortho on the 2D variant of glOrtho i.e. with
        fixed near/far values of [-1, 1]]
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
This commit is contained in:
Alexandros Frantzis 2011-01-31 18:02:02 +02:00 committed by Chris Wilson
parent d88ada384f
commit 80a92b6d79
4 changed files with 49 additions and 8 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);

View file

@ -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);