Merge branch 'cogl-client-matrix-stacks'

* cogl-client-matrix-stacks:
  Maintain the Cogl assumption that the modelview matrix is normally current
  Finish GLES{1,2} support for client side matrix stacks
  Explicitly make the modelview-matrix current in cogl_{rotate,transform,etc}
  Avoid casting CoglMatrix to a GLfloat * when calling glGetFloatv
  Removes need for casting const float * in _cogl_set_clip_planes
  Virtualize GL matrix operations and use a client-side matrix when GL is indirect
This commit is contained in:
Robert Bragg 2009-03-12 18:59:20 +00:00
commit 5af7c85fa2
25 changed files with 1396 additions and 475 deletions

View File

@ -151,6 +151,27 @@ void cogl_matrix_scale (CoglMatrix *matrix,
float sy,
float sz);
/**
* cogl_matrix_frustum:
* @matrix: A 4x4 transformation matrix
* @left: coord of left vertical clipping plane
* @right: coord of right vertical clipping plane
* @bottom: coord of bottom horizontal clipping plane
* @top: coord of top horizontal clipping plane
* @near: positive distance to near depth clipping plane
* @far: positive distance to far depth clipping plane
*
* Multiplies the matrix by the given frustum perspective matrix.
*
*/
void cogl_matrix_frustum (CoglMatrix *matrix,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far);
/**
* cogl_matrix_transform_point:
* @matrix: A 4x4 transformation matrix

View File

@ -563,6 +563,24 @@ void cogl_clip_stack_save (void);
*/
void cogl_clip_stack_restore (void);
/**
* cogl_flush_gl_state:
* @flags: flags controlling what is flushed; currently unused, pass in 0
*
* As an optimization, COGL functions may not immediately modify GL's
* state, instead batching up changes and applying them "just in
* time." Unapplied state could include glEnable() flags and the
* current transformation matrix among other examples. If you want to
* use GL directly, you need to flush any state COGL may have kept
* around. cogl_flush_gl_state() syncs all of COGL's state to GL.
*
* Since: 1.0
*/
void cogl_flush_gl_state (int flags);
/* private */
void _cogl_set_indirect_context (gboolean indirect);
G_END_DECLS
#undef __COGL_H_INSIDE__

View File

@ -24,6 +24,8 @@ libclutter_cogl_common_la_SOURCES = \
cogl-bitmap.h \
cogl-bitmap.c \
cogl-bitmap-fallback.c \
cogl-current-matrix.c \
cogl-current-matrix.h \
cogl-primitives.h \
cogl-primitives.c \
cogl-bitmap-pixbuf.c \
@ -34,6 +36,8 @@ libclutter_cogl_common_la_SOURCES = \
cogl-vertex-buffer-private.h \
cogl-vertex-buffer.c \
cogl-matrix.c \
cogl-matrix-stack.c \
cogl-matrix-stack.h \
cogl-material.c \
cogl-material-private.h \
cogl-debug.c

View File

@ -0,0 +1,476 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Havoc Pennington <hp@pobox.com> for litl
*
* Copyright (C) 2009 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl.h"
#include "cogl-context.h"
#include "cogl-internal.h"
#include "cogl-current-matrix.h"
#include "cogl-matrix-stack.h"
#ifdef HAVE_COGL_GLES2
#include "cogl-gles2-wrapper.h"
#define glFrustum(L,R,B,T,N,F) \
cogl_wrap_glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
(GLfloat)T, (GLfloat)N, (GLfloat)F)
#elif defined (HAVE_COGL_GLES)
#define glFrustum(L,R,B,T,N,F) \
glFrustumf((GLfloat)L, (GLfloat)R, (GLfloat)B, \
(GLfloat)T, (GLfloat)N, (GLfloat)F)
#endif
#include <string.h>
#include <math.h>
void
_cogl_set_current_matrix (CoglMatrixMode mode)
{
GLenum gl_mode;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (mode == ctx->matrix_mode)
return;
ctx->matrix_mode = mode;
gl_mode = 0; /* silence compiler warning */
switch (mode)
{
case COGL_MATRIX_MODELVIEW:
gl_mode = GL_MODELVIEW;
break;
case COGL_MATRIX_PROJECTION:
gl_mode = GL_PROJECTION;
break;
case COGL_MATRIX_TEXTURE:
gl_mode = GL_TEXTURE;
break;
}
GE (glMatrixMode (gl_mode));
}
static void
_cogl_get_client_stack (CoglContext *ctx,
CoglMatrixStack **current_stack_p)
{
if (ctx->modelview_stack &&
ctx->matrix_mode == COGL_MATRIX_MODELVIEW)
*current_stack_p = ctx->modelview_stack;
else
*current_stack_p = NULL;
}
#define _COGL_GET_CONTEXT_AND_STACK(contextvar, stackvar, rval) \
CoglMatrixStack *stackvar; \
_COGL_GET_CONTEXT (contextvar, rval); \
_cogl_get_client_stack (contextvar, &stackvar)
void
_cogl_current_matrix_push (void)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_push (current_stack);
else
GE (glPushMatrix ());
}
void
_cogl_current_matrix_pop (void)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_pop (current_stack);
else
GE (glPopMatrix ());
}
void
_cogl_current_matrix_identity (void)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_load_identity (current_stack);
else
GE (glLoadIdentity ());
}
void
_cogl_current_matrix_load (const CoglMatrix *matrix)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_set (current_stack, matrix);
else
GE (glLoadMatrixf (cogl_matrix_get_array (matrix)));
}
void
_cogl_current_matrix_multiply (const CoglMatrix *matrix)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_multiply (current_stack, matrix);
else
GE (glMultMatrixf (cogl_matrix_get_array (matrix)));
}
void
_cogl_current_matrix_rotate (float angle,
float x,
float y,
float z)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_rotate (current_stack, angle, x, y, z);
else
GE (glRotatef (angle, x, y, z));
}
void
_cogl_current_matrix_scale (float x,
float y,
float z)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_scale (current_stack, x, y, z);
else
GE (glScalef (x, y, z));
}
void
_cogl_current_matrix_translate (float x,
float y,
float z)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_translate (current_stack, x, y, z);
else
GE (glTranslatef (x, y, z));
}
void
_cogl_current_matrix_frustum (float left,
float right,
float bottom,
float top,
float near_val,
float far_val)
{
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_frustum (current_stack,
left, right,
top, bottom,
near_val,
far_val);
else
GE (glFrustum (left, right, bottom, top, near_val, far_val));
}
void
_cogl_current_matrix_ortho (float left,
float right,
float bottom,
float top,
float near_val,
float far_val)
{
#if 0
_COGL_GET_CONTEXT_AND_STACK (ctx, current_stack, NO_RETVAL);
if (current_stack != NULL)
_cogl_matrix_stack_ortho (current_stack,
left, right,
top, bottom,
near_val,
far_val);
else
GE (glOrtho (left, right, bottom, top, near_val, far_val));
#else
/* Nobody is using glOrtho right now anyway, so not bothering */
g_warning ("%s not implemented, need to code cogl_matrix_ortho() if you need"
" this function",
G_STRFUNC);
#endif
}
void
_cogl_get_matrix (CoglMatrixMode mode,
CoglMatrix *matrix)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->modelview_stack != NULL &&
mode == COGL_MATRIX_MODELVIEW)
{
_cogl_matrix_stack_get (ctx->modelview_stack, matrix);
}
else
{
GLenum gl_mode;
GLfloat gl_matrix[16];
gl_mode = 0; /* silence compiler warning */
switch (mode)
{
case COGL_MATRIX_MODELVIEW:
gl_mode = GL_MODELVIEW_MATRIX;
break;
case COGL_MATRIX_PROJECTION:
gl_mode = GL_PROJECTION_MATRIX;
break;
case COGL_MATRIX_TEXTURE:
gl_mode = GL_TEXTURE_MATRIX;
break;
}
/* Note: we have a redundant copy happening here. If that turns out to be
* a problem then, since this is internal to Cogl, we could pass the
* CoglMatrix pointer directly to glGetFloatv; the only problem with that
* is that if we later add internal flags to CoglMatrix they will need to
* be initialized seperatly.
*/
GE (glGetFloatv (gl_mode, gl_matrix));
cogl_matrix_init_from_array (matrix, gl_matrix);
}
}
void
_cogl_current_matrix_state_init (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
ctx->matrix_mode = COGL_MATRIX_MODELVIEW;
ctx->modelview_stack = NULL;
if (ctx->indirect)
{
ctx->modelview_stack =
_cogl_matrix_stack_new ();
}
}
void
_cogl_current_matrix_state_destroy (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->modelview_stack)
_cogl_matrix_stack_destroy (ctx->modelview_stack);
}
void
_cogl_current_matrix_state_flush (void)
{
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
if (ctx->matrix_mode != COGL_MATRIX_MODELVIEW)
{
g_warning ("matrix state must be flushed in MODELVIEW mode");
return;
}
if (ctx->modelview_stack)
{
_cogl_matrix_stack_flush_to_gl (ctx->modelview_stack,
GL_MODELVIEW);
}
}
void
cogl_push_matrix (void)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
}
void
cogl_pop_matrix (void)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_pop ();
}
void
cogl_scale (float x, float y, float z)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_scale (x, y, z);
}
void
cogl_translate (float x, float y, float z)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_translate (x, y, z);
}
void
cogl_rotate (float angle, float x, float y, float z)
{
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_rotate (angle, x, y, z);
}
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
_cogl_current_matrix_load (matrix);
}
void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
matrix);
}
void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
matrix);
}
void
cogl_perspective (float fovy,
float aspect,
float zNear,
float zFar)
{
float xmax, ymax;
float x, y, c, d;
float fovy_rad_half = (fovy * G_PI) / 360;
CoglMatrix perspective;
GLfloat m[16];
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
memset (&m[0], 0, sizeof (m));
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_identity ();
/*
* Based on the original algorithm in perspective():
*
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
* same true for y, hence: a == 0 && b == 0;
*
* 2) When working with small numbers, we are loosing significant
* precision
*/
ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
xmax = (ymax * aspect);
x = (zNear / xmax);
y = (zNear / ymax);
c = (-(zFar + zNear) / ( zFar - zNear));
d = (-(2 * zFar) * zNear) / (zFar - zNear);
#define M(row,col) m[col*4+row]
M(0,0) = x;
M(1,1) = y;
M(2,2) = c;
M(2,3) = d;
M(3,2) = -1.0;
cogl_matrix_init_from_array (&perspective, m);
_cogl_current_matrix_multiply (&perspective);
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
#define m ctx->inverse_projection
M(0, 0) = (1.0 / x);
M(1, 1) = (1.0 / y);
M(2, 3) = -1.0;
M(3, 2) = (1.0 / d);
M(3, 3) = (c / d);
#undef m
#undef M
}
void
cogl_frustum (float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
float c, d;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_identity ();
_cogl_current_matrix_frustum (left,
right,
bottom,
top,
z_near,
z_far);
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
c = - (z_far + z_near) / (z_far - z_near);
d = - (2 * (z_far * z_near)) / (z_far - z_near);
#define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = (right - left) / (2 * z_near);
M(0,3) = (right + left) / (2 * z_near);
M(1,1) = (top - bottom) / (2 * z_near);
M(1,3) = (top + bottom) / (2 * z_near);
M(2,3) = -1.0;
M(3,2) = 1.0 / d;
M(3,3) = c / d;
#undef M
}

View File

@ -0,0 +1,91 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Havoc Pennington <hp@pobox.com> for litl
*
* Copyright (C) 2009 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __COGL_CURRENT_MATRIX_H
#define __COGL_CURRENT_MATRIX_H
#include <cogl/cogl-matrix.h>
/**
* CoglMatrixMode:
* @COGL_MATRIX_MODELVIEW: Select model-view matrix stack
* @COGL_MATRIX_PROJECTION: Select projection matrix stack
* @COGL_MATRIX_TEXTURE: Select texture matrix stack
*
* There are several matrix stacks affected by the COGL current matrix
* operations (which are private). Code should always leave the
* model-view matrix active, switching to the projection matrix stack
* only temporarily in order to modify the projection matrix. Most
* COGL and Clutter APIs (other than the current matrix operations)
* will assume the model-view matrix is active when the API is
* invoked.
*
* Since: 1.0
*/
typedef enum
{
COGL_MATRIX_MODELVIEW = 1,
COGL_MATRIX_PROJECTION = 2,
COGL_MATRIX_TEXTURE = 3
} CoglMatrixMode;
#define COGL_TYPE_MATRIX_MODE (cogl_matrix_mode_get_type ())
GType cogl_matrix_mode_get_type (void) G_GNUC_CONST;
void _cogl_set_current_matrix (CoglMatrixMode mode);
void _cogl_current_matrix_push (void);
void _cogl_current_matrix_pop (void);
void _cogl_current_matrix_identity (void);
void _cogl_current_matrix_load (const CoglMatrix *matrix);
void _cogl_current_matrix_multiply (const CoglMatrix *matrix);
void _cogl_current_matrix_rotate (float angle,
float x,
float y,
float z);
void _cogl_current_matrix_scale (float x,
float y,
float z);
void _cogl_current_matrix_translate (float x,
float y,
float z);
void _cogl_current_matrix_frustum (float left,
float right,
float bottom,
float top,
float near_val,
float far_val);
void _cogl_current_matrix_ortho (float left,
float right,
float bottom,
float top,
float near_val,
float far_val);
void _cogl_get_matrix (CoglMatrixMode mode,
CoglMatrix *matrix);
void _cogl_current_matrix_state_init (void);
void _cogl_current_matrix_state_destroy (void);
void _cogl_current_matrix_state_flush (void);
#endif /* __COGL_CURRENT_MATRIX_H */

View File

@ -821,9 +821,9 @@ _cogl_material_layer_flush_gl_sampler_state (CoglMaterialLayer *layer,
layer->flags & COGL_MATERIAL_LAYER_FLAG_HAS_USER_MATRIX))
#endif
{
GE (glMatrixMode (GL_TEXTURE));
GE (glLoadMatrixf ((GLfloat *)&layer->matrix));
GE (glMatrixMode (GL_MODELVIEW));
_cogl_set_current_matrix (COGL_MATRIX_TEXTURE);
_cogl_current_matrix_load (&layer->matrix);
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
}
}

327
common/cogl-matrix-stack.c Normal file
View File

@ -0,0 +1,327 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Havoc Pennington <hp@pobox.com> for litl
*
* Copyright (C) 2009 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl.h"
#include "cogl-context.h"
#include "cogl-internal.h"
#include "cogl-matrix-stack.h"
typedef struct {
CoglMatrix matrix;
/* count of pushes with no changes; when a change is
* requested, we create a new state and decrement this
*/
int push_count;
} CoglMatrixState;
/**
* CoglMatrixStack:
*
* Stores a cogl-side matrix stack, which we use as a cache
* so we can get the matrix efficiently when using indirect
* rendering.
*/
struct _CoglMatrixStack
{
GSList *stack;
/* which state does GL have, NULL if unknown */
CoglMatrixState *flushed_state;
};
static CoglMatrixState*
_cogl_matrix_state_new (void)
{
CoglMatrixState *state;
state = g_slice_new0 (CoglMatrixState);
/* load identity */
cogl_matrix_init_identity (&state->matrix);
/* state->push_count defaults to 0 */
return state;
}
static void
_cogl_matrix_state_destroy (CoglMatrixState *state)
{
g_slice_free (CoglMatrixState, state);
}
static CoglMatrixState*
_cogl_matrix_stack_top (CoglMatrixStack *stack)
{
return stack->stack->data;
}
static CoglMatrixState*
_cogl_matrix_stack_top_mutable (CoglMatrixStack *stack)
{
CoglMatrixState *state;
CoglMatrixState *new_top;
state = _cogl_matrix_stack_top (stack);
if (state->push_count == 0)
return state;
state->push_count -= 1;
new_top = _cogl_matrix_state_new ();
new_top->matrix = state->matrix;
if (stack->flushed_state == state)
{
stack->flushed_state = new_top;
}
stack->stack =
g_slist_prepend (stack->stack,
new_top);
return new_top;
}
CoglMatrixStack*
_cogl_matrix_stack_new (void)
{
CoglMatrixStack *stack;
CoglMatrixState *state;
stack = g_slice_new0 (CoglMatrixStack);
state = _cogl_matrix_state_new ();
stack->stack =
g_slist_prepend (stack->stack,
state);
return stack;
}
void
_cogl_matrix_stack_destroy (CoglMatrixStack *stack)
{
while (stack->stack)
{
CoglMatrixState *state;
state = stack->stack->data;
_cogl_matrix_state_destroy (state);
stack->stack =
g_slist_delete_link (stack->stack,
stack->stack);
}
g_slice_free (CoglMatrixStack, stack);
}
void
_cogl_matrix_stack_push (CoglMatrixStack *stack)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top (stack);
/* we lazily create a new stack top if someone changes the matrix
* while push_count > 0
*/
state->push_count += 1;
}
void
_cogl_matrix_stack_pop (CoglMatrixStack *stack)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top (stack);
if (state->push_count > 0)
{
state->push_count -= 1;
}
else
{
if (stack->stack->next == NULL)
{
g_warning ("Too many matrix pops");
return;
}
if (stack->flushed_state == state)
{
stack->flushed_state = NULL;
}
stack->stack =
g_slist_delete_link (stack->stack,
stack->stack);
_cogl_matrix_state_destroy (state);
}
}
void
_cogl_matrix_stack_load_identity (CoglMatrixStack *stack)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_init_identity (&state->matrix);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_scale (CoglMatrixStack *stack,
float x,
float y,
float z)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_scale (&state->matrix, x, y, z);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_translate (CoglMatrixStack *stack,
float x,
float y,
float z)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_translate (&state->matrix, x, y, z);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_rotate (CoglMatrixStack *stack,
float angle,
float x,
float y,
float z)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_rotate (&state->matrix, angle, x, y, z);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_multiply (CoglMatrixStack *stack,
const CoglMatrix *matrix)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_multiply (&state->matrix, &state->matrix, matrix);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top (stack);
*matrix = state->matrix;
}
void
_cogl_matrix_stack_set (CoglMatrixStack *stack,
const CoglMatrix *matrix)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
state->matrix = *matrix;
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top_mutable (stack);
cogl_matrix_frustum (&state->matrix,
left, right, bottom, top,
z_near, z_far);
/* mark dirty */
stack->flushed_state = NULL;
}
void
_cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode)
{
CoglMatrixState *state;
state = _cogl_matrix_stack_top (stack);
if (stack->flushed_state == state)
return;
/* NOTE we assume caller was in MODELVIEW mode */
if (gl_mode != GL_MODELVIEW)
GE (glMatrixMode (gl_mode));
/* In theory it might help the GL implementation if we used our
* local analysis of the matrix and called Translate/Scale rather
* than LoadMatrix to send a 2D matrix
*/
GE (glLoadMatrixf (cogl_matrix_get_array (&state->matrix)));
stack->flushed_state = state;
if (gl_mode != GL_MODELVIEW)
GE (glMatrixMode (GL_MODELVIEW));
}

View File

@ -0,0 +1,67 @@
/*
* Clutter COGL
*
* A basic GL/GLES Abstraction/Utility Layer
*
* Authored By Havoc Pennington <hp@pobox.com> for litl
*
* Copyright (C) 2009 OpenedHand
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __COGL_MATRIX_STACK_H
#define __COGL_MATRIX_STACK_H
#include <cogl/cogl-matrix.h>
typedef struct _CoglMatrixStack CoglMatrixStack;
CoglMatrixStack* _cogl_matrix_stack_new (void);
void _cogl_matrix_stack_destroy (CoglMatrixStack *stack);
void _cogl_matrix_stack_push (CoglMatrixStack *stack);
void _cogl_matrix_stack_pop (CoglMatrixStack *stack);
void _cogl_matrix_stack_load_identity (CoglMatrixStack *stack);
void _cogl_matrix_stack_scale (CoglMatrixStack *stack,
float x,
float y,
float z);
void _cogl_matrix_stack_translate (CoglMatrixStack *stack,
float x,
float y,
float z);
void _cogl_matrix_stack_rotate (CoglMatrixStack *stack,
float angle,
float x,
float y,
float z);
void _cogl_matrix_stack_multiply (CoglMatrixStack *stack,
const CoglMatrix *matrix);
void _cogl_matrix_stack_get (CoglMatrixStack *stack,
CoglMatrix *matrix);
void _cogl_matrix_stack_set (CoglMatrixStack *stack,
const CoglMatrix *matrix);
void _cogl_matrix_stack_frustum (CoglMatrixStack *stack,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far);
void _cogl_matrix_stack_flush_to_gl (CoglMatrixStack *stack,
GLenum gl_mode);
#endif /* __COGL_MATRIX_STACK_H */

View File

@ -140,6 +140,48 @@ cogl_matrix_transform_point (const CoglMatrix *matrix,
*w = matrix->wx * _x + matrix->wy * _y + matrix->wz * _z + matrix->ww * _w;
}
void
cogl_matrix_frustum (CoglMatrix *matrix,
float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
float x, y, a, b, c, d;
CoglMatrix frustum;
x = (2.0f * z_near) / (right - left);
y = (2.0f * z_near) / (top - bottom);
a = (right + left) / (right - left);
b = (top + bottom) / (top - bottom);
c = -(z_far + z_near) / ( z_far - z_near);
d = -(2.0f * z_far* z_near) / (z_far - z_near);
frustum.xx = x;
frustum.yx = 0.0f;
frustum.zx = 0.0f;
frustum.wx = 0.0f;
frustum.xy = 0.0f;
frustum.yy = y;
frustum.zy = 0.0f;
frustum.wy = 0.0f;
frustum.xz = a;
frustum.yz = b;
frustum.zz = c;
frustum.wz = -1.0f;
frustum.xw = 0.0f;
frustum.yw = 0.0f;
frustum.zw = d;
frustum.ww = 0.0f;
cogl_matrix_multiply (matrix, matrix, &frustum);
}
void
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
{

View File

@ -35,6 +35,7 @@
#include "cogl-fixed.h"
#include "cogl-internal.h"
#include "cogl-material.h"
#include "cogl-current-matrix.h"
#include "cogl-offscreen.h"
#include "cogl-shader.h"
#include "cogl-texture.h"
@ -208,6 +209,28 @@ cogl_buffer_target_get_type (void)
return gtype;
}
GType
cogl_matrix_mode_get_type (void)
{
static GType gtype = 0;
if (G_UNLIKELY (gtype == 0))
{
static const GEnumValue values[] = {
{ COGL_MATRIX_MODELVIEW, "COGL_MATRIX_MODELVIEW", "modelview" },
{ COGL_MATRIX_PROJECTION, "COGL_MATRIX_PROJECTION", "projection" },
{ COGL_MATRIX_TEXTURE, "COGL_MATRIX_TEXTURE", "texture" },
{ 0, NULL, NULL }
};
gtype =
g_enum_register_static (g_intern_static_string ("CoglMatrixMode"),
values);
}
return gtype;
}
GType
cogl_texture_flags_get_type (void)
{

View File

@ -1621,6 +1621,8 @@ cogl_vertex_buffer_draw (CoglHandle handle,
enable_state_for_drawing_buffer (buffer);
_cogl_current_matrix_state_flush ();
/* FIXME: flush cogl cache */
GE (glDrawArrays (mode, first, count));
@ -1647,6 +1649,8 @@ cogl_vertex_buffer_draw_elements (CoglHandle handle,
enable_state_for_drawing_buffer (buffer);
_cogl_current_matrix_state_flush ();
/* FIXME: flush cogl cache */
GE (glDrawRangeElements (mode, min_index, max_index,
count, indices_type, indices));

View File

@ -37,6 +37,7 @@
#include <string.h>
static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE;
gboolean
cogl_create_context ()
@ -59,6 +60,8 @@ cogl_create_context ()
_context->enable_backface_culling = FALSE;
_context->indirect = gl_is_indirect;
_context->material_handles = NULL;
_context->material_layer_handles = NULL;
_context->default_material = cogl_material_new ();
@ -143,6 +146,9 @@ cogl_create_context ()
/* Initialise the clip stack */
_cogl_clip_stack_state_init ();
/* Initialise matrix stack */
_cogl_current_matrix_state_init ();
/* Create default textures used for fall backs */
_context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */
@ -182,6 +188,8 @@ cogl_destroy_context ()
_cogl_clip_stack_state_destroy ();
_cogl_current_matrix_state_destroy ();
if (_context->path_nodes)
g_array_free (_context->path_nodes, TRUE);
@ -226,3 +234,32 @@ _cogl_context_get_default ()
return _context;
}
/**
* _cogl_set_indirect_context:
* @indirect: TRUE if GL context is indirect
*
* Advises COGL that the GL context is indirect (commands are sent
* over a socket). COGL uses this information to try to avoid
* round-trips in its use of GL, for example.
*
* This function cannot be called "on the fly," only before COGL
* initializes.
*/
void
_cogl_set_indirect_context (gboolean indirect)
{
/* we get called multiple times if someone creates
* more than the default stage
*/
if (_context != NULL)
{
if (indirect != _context->indirect)
g_warning ("Right now all stages will be treated as "
"either direct or indirect, ignoring attempt "
"to change to indirect=%d", indirect);
return;
}
gl_is_indirect = indirect;
}

View File

@ -28,6 +28,8 @@
#include "cogl-primitives.h"
#include "cogl-clip-stack.h"
#include "cogl-matrix-stack.h"
#include "cogl-current-matrix.h"
typedef struct
{
@ -48,6 +50,12 @@ typedef struct
gboolean enable_backface_culling;
gboolean indirect;
/* Client-side matrix stack or NULL if none */
CoglMatrixMode matrix_mode;
CoglMatrixStack *modelview_stack;
/* Cache of inverse projection matrix */
float inverse_projection[16];

View File

@ -264,30 +264,30 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
/* Push the viewport and matrix setup if redirecting
from a non-screen buffer */
GE( glPushAttrib (GL_VIEWPORT_BIT) );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
}
else
{
/* Override viewport and matrix setup if redirecting
from another offscreen buffer */
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_identity ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_identity ();
}
/* Setup new viewport and matrices */
GE( glViewport (0, 0, fbo->width, fbo->height) );
GE( glTranslatef (-1.0f, -1.0f, 0.0f) );
GE( glScalef (2.0f / fbo->width, 2.0f / fbo->height, 1.0f) );
_cogl_current_matrix_translate (-1.0f, -1.0f, 0.0f);
_cogl_current_matrix_scale (2.0f / fbo->width, 2.0f / fbo->height, 1.0f);
/* Bind offscreen framebuffer object */
GE( glBindFramebufferEXT (GL_FRAMEBUFFER_EXT, fbo->gl_handle) );
@ -313,12 +313,12 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
/* Pop viewport and matrices if redirecting back
from an offscreen buffer */
GE( glPopAttrib () );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPopMatrix () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_pop ();
}
/* Bind window framebuffer object */

View File

@ -87,6 +87,7 @@ _cogl_path_stroke_nodes ()
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */
NULL);
_cogl_current_matrix_state_flush ();
while (path_start < ctx->path_nodes->len)
{
@ -161,6 +162,7 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
GE( glDepthMask (FALSE) );
_cogl_current_matrix_state_flush ();
while (path_start < path_size)
{
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
@ -196,16 +198,28 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
/* Decrement all of the bits twice so that only pixels where the
value is 3 will remain */
GE( glPushMatrix () );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
/* Cogl generally assumes the modelview matrix is current, so since
* cogl_rectangle will be flushing GL state and emitting geometry
* to OpenGL it will be confused if we leave the projection matrix
* active... */
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
GE( glPopMatrix () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
}
GE( glStencilMask (~(GLuint) 0) );

View File

@ -2056,7 +2056,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
cogl_enable (enable_flags);
GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer));
_cogl_current_matrix_state_flush ();
GE (glDrawRangeElements (GL_TRIANGLES,
0, ctx->static_indices->len - 1,
6 * batch_len,
@ -2085,6 +2085,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
color == 2 ? 0xff : 0x00,
0xff);
cogl_material_flush_gl_state (outline, NULL);
_cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_LINE_LOOP, 4 * i, 4) );
}
}
@ -2896,6 +2897,7 @@ _cogl_texture_sliced_polygon (CoglTextureVertex *vertices,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
gl_handle,
NULL);
_cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
}
@ -2986,6 +2988,7 @@ _cogl_multitexture_unsliced_polygon (CoglTextureVertex *vertices,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
NULL);
_cogl_current_matrix_state_flush ();
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
}

268
gl/cogl.c
View File

@ -201,37 +201,6 @@ cogl_clear (const CoglColor *color)
*/
}
/* FIXME: inline most of these */
void
cogl_push_matrix (void)
{
GE( glPushMatrix() );
}
void
cogl_pop_matrix (void)
{
GE( glPopMatrix() );
}
void
cogl_scale (float x, float y, float z)
{
GE( glScalef (x, y, z) );
}
void
cogl_translate (float x, float y, float z)
{
GE( glTranslatef (x, y, z) );
}
void
cogl_rotate (float angle, float x, float y, float z)
{
GE( glRotatef (angle, x, y, z) );
}
static inline gboolean
cogl_toggle_flag (CoglContext *ctx,
gulong new_flags,
@ -357,29 +326,20 @@ cogl_set_source_color (const CoglColor *color)
}
static void
apply_matrix (const float *matrix, float *vertex)
{
int x, y;
float vertex_out[4] = { 0 };
for (y = 0; y < 4; y++)
for (x = 0; x < 4; x++)
vertex_out[y] += vertex[x] * matrix[y + x * 4];
memcpy (vertex, vertex_out, sizeof (vertex_out));
}
static void
project_vertex (float *modelview,
float *project,
project_vertex (const CoglMatrix *modelview_matrix,
const CoglMatrix *projection_matrix,
float *vertex)
{
int i;
/* Apply the modelview matrix */
apply_matrix (modelview, vertex);
cogl_matrix_transform_point (modelview_matrix,
&vertex[0], &vertex[1],
&vertex[2], &vertex[3]);
/* Apply the projection matrix */
apply_matrix (project, vertex);
cogl_matrix_transform_point (projection_matrix,
&vertex[0], &vertex[1],
&vertex[2], &vertex[3]);
/* Convert from homogenized coordinates */
for (i = 0; i < 4; i++)
vertex[i] /= vertex[3];
@ -396,6 +356,7 @@ set_clip_plane (GLint plane_num,
GLdouble plane[4];
#endif
GLfloat angle;
CoglMatrix inverse_projection;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Calculate the angle between the axes and the line crossing the
@ -403,18 +364,20 @@ set_clip_plane (GLint plane_num,
angle = atan2f (vertex_b[1] - vertex_a[1],
vertex_b[0] - vertex_a[0]) * (180.0/G_PI);
GE( glPushMatrix () );
_cogl_current_matrix_push ();
/* Load the identity matrix and multiply by the reverse of the
projection matrix so we can specify the plane in screen
coordinates */
GE( glLoadIdentity () );
GE( glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
_cogl_current_matrix_identity ();
cogl_matrix_init_from_array (&inverse_projection,
ctx->inverse_projection);
_cogl_current_matrix_multiply (&inverse_projection);
/* Rotate about point a */
GE( glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) );
_cogl_current_matrix_translate (vertex_a[0], vertex_a[1], vertex_a[2]);
/* Rotate the plane by the calculated angle so that it will connect
the two points */
GE( glRotatef (angle, 0.0f, 0.0f, 1.0f) );
GE( glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) );
_cogl_current_matrix_rotate (angle, 0.0f, 0.0f, 1.0f);
_cogl_current_matrix_translate (-vertex_a[0], -vertex_a[1], -vertex_a[2]);
plane[0] = 0;
plane[1] = -1.0;
@ -426,7 +389,7 @@ set_clip_plane (GLint plane_num,
GE( glClipPlane (plane_num, plane) );
#endif
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
}
void
@ -435,7 +398,8 @@ _cogl_set_clip_planes (float x_offset,
float width,
float height)
{
GLfloat modelview[16], projection[16];
CoglMatrix modelview_matrix;
CoglMatrix projection_matrix;
float vertex_tl[4] = { x_offset, y_offset, 0, 1.0 };
float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 };
@ -443,13 +407,15 @@ _cogl_set_clip_planes (float x_offset,
float vertex_br[4] = { x_offset + width, y_offset + height,
0, 1.0 };
GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
GE( glGetFloatv (GL_PROJECTION_MATRIX, projection) );
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
&projection_matrix);
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
&modelview_matrix);
project_vertex (modelview, projection, vertex_tl);
project_vertex (modelview, projection, vertex_tr);
project_vertex (modelview, projection, vertex_bl);
project_vertex (modelview, projection, vertex_br);
project_vertex (&modelview_matrix, &projection_matrix, vertex_tl);
project_vertex (&modelview_matrix, &projection_matrix, vertex_tr);
project_vertex (&modelview_matrix, &projection_matrix, vertex_bl);
project_vertex (&modelview_matrix, &projection_matrix, vertex_br);
/* If the order of the top and bottom lines is different from the
order of the left and right lines then the clip rect must have
@ -513,15 +479,27 @@ _cogl_add_stencil_clip (float x_offset,
only pixels where both the original stencil buffer and the
rectangle are set will be valid */
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
/* Cogl generally assumes the modelview matrix is current, so since
* cogl_rectangle will be flushing GL state and emitting geometry
* to OpenGL it will be confused if we leave the projection matrix
* active... */
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
GE( glPopMatrix () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
}
/* Restore the stencil mode */
@ -529,14 +507,6 @@ _cogl_add_stencil_clip (float x_offset,
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
}
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
const GLfloat *gl_matrix = cogl_matrix_get_array (matrix);
GE (glLoadMatrixf (gl_matrix));
}
void
_cogl_disable_stencil_buffer (void)
{
@ -561,108 +531,6 @@ _cogl_disable_clip_planes (void)
GE( glDisable (GL_CLIP_PLANE0) );
}
void
cogl_perspective (float fovy,
float aspect,
float zNear,
float zFar)
{
float xmax, ymax;
float x, y, c, d;
float fovy_rad_half = (fovy * G_PI) / 360;
GLfloat m[16];
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
memset (&m[0], 0, sizeof (m));
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
/*
* Based on the original algorithm in perspective():
*
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
* same true for y, hence: a == 0 && b == 0;
*
* 2) When working with small numbers, we are loosing significant
* precision
*/
ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
xmax = (ymax * aspect);
x = (zNear / xmax);
y = (zNear / ymax);
c = (-(zFar + zNear) / ( zFar - zNear));
d = (-(2 * zFar) * zNear) / (zFar - zNear);
#define M(row,col) m[col*4+row]
M(0,0) = x;
M(1,1) = y;
M(2,2) = c;
M(2,3) = d;
M(3,2) = -1.0;
GE( glMultMatrixf (m) );
GE( glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
#define m ctx->inverse_projection
M(0, 0) = (1.0 / x);
M(1, 1) = (1.0 / y);
M(2, 3) = -1.0;
M(3, 2) = (1.0 / d);
M(3, 3) = (c / d);
#undef m
#undef M
}
void
cogl_frustum (float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
float c, d;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
GE( glFrustum ((GLdouble)(left),
(GLdouble)(right),
(GLdouble)(bottom),
(GLdouble)(top),
(GLdouble)(z_near),
(GLdouble)(z_far)) );
GE( glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
c = - (z_far + z_near) / (z_far - z_near);
d = - (2 * (z_far * z_near)) / (z_far - z_near);
#define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = (right - left) / (2 * z_near);
M(0,3) = (right + left) / (2 * z_near);
M(1,1) = (top - bottom) / (2 * z_near);
M(1,3) = (top + bottom) / (2 * z_near);
M(2,3) = -1.0;
M(3,2) = 1.0 / d;
M(3,3) = c / d;
#undef M
}
void
cogl_viewport (guint width,
guint height)
@ -684,8 +552,8 @@ cogl_setup_viewport (guint width,
GE( glViewport (0, 0, width, height) );
/* For Ortho projection.
* glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
*/
* _cogl_current_matrix_ortho (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
*/
cogl_perspective (fovy, aspect, z_near, z_far);
@ -731,11 +599,10 @@ cogl_setup_viewport (guint width,
cogl_get_projection_matrix (&projection_matrix);
z_camera = 0.5 * projection_matrix.xx;
GE( glLoadIdentity () );
GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
GE( glScalef (1.0f / width, -1.0f / height, 1.0f / width) );
GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
_cogl_current_matrix_identity ();
_cogl_current_matrix_translate (-0.5f, -0.5f, -z_camera);
_cogl_current_matrix_scale (1.0f / width, -1.0f / height, 1.0f / width);
_cogl_current_matrix_translate (0.0f, -1.0 * height, 0.0f);
}
#ifdef HAVE_CLUTTER_OSX
@ -1122,28 +989,6 @@ cogl_features_available (CoglFeatureFlags features)
return (ctx->feature_flags & features) == features;
}
void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
float m[16];
glGetFloatv (GL_MODELVIEW_MATRIX, m);
/* Since it's internal to Cogl and CoglMatrix doesn't currently have
* any flag members, we could avoid this extra copy if it really
* bothers anyone */
cogl_matrix_init_from_array (matrix, m);
}
void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
float m[16];
glGetFloatv (GL_PROJECTION_MATRIX, m);
/* Since it's internal to Cogl and CoglMatrix doesn't currently have
* any flag members, we could avoid this extra copy if it really
* bothers anyone */
cogl_matrix_init_from_array (matrix, m);
}
void
cogl_get_viewport (float v[4])
{
@ -1234,3 +1079,8 @@ cogl_disable_fog (void)
glDisable (GL_FOG);
}
void
cogl_flush_gl_state (int flags)
{
_cogl_current_matrix_state_flush ();
}

View File

@ -39,6 +39,7 @@
#include <string.h>
static CoglContext *_context = NULL;
static gboolean gl_is_indirect = FALSE;
gboolean
cogl_create_context ()
@ -61,6 +62,8 @@ cogl_create_context ()
_context->enable_backface_culling = FALSE;
_context->indirect = gl_is_indirect;
_context->material_handles = NULL;
_context->material_layer_handles = NULL;
_context->default_material = cogl_material_new ();
@ -104,6 +107,9 @@ cogl_create_context ()
/* Initialise the clip stack */
_cogl_clip_stack_state_init ();
/* Initialise matrix stack */
_cogl_current_matrix_state_init ();
/* Create default textures used for fall backs */
_context->default_gl_texture_2d_tex =
cogl_texture_new_from_data (1, /* width */
@ -143,6 +149,8 @@ cogl_destroy_context ()
_cogl_clip_stack_state_destroy ();
_cogl_current_matrix_state_destroy ();
if (_context->path_nodes)
g_array_free (_context->path_nodes, TRUE);
@ -187,3 +195,32 @@ _cogl_context_get_default ()
return _context;
}
/**
* _cogl_set_indirect_context:
* @indirect: TRUE if GL context is indirect
*
* Advises COGL that the GL context is indirect (commands are sent
* over a socket). COGL uses this information to try to avoid
* round-trips in its use of GL, for example.
*
* This function cannot be called "on the fly," only before COGL
* initializes.
*/
void
_cogl_set_indirect_context (gboolean indirect)
{
/* we get called multiple times if someone creates
* more than the default stage
*/
if (_context != NULL)
{
if (indirect != _context->indirect)
g_warning ("Right now all stages will be treated as "
"either direct or indirect, ignoring attempt "
"to change to indirect=%d", indirect);
return;
}
gl_is_indirect = indirect;
}

View File

@ -28,6 +28,8 @@
#include "cogl-primitives.h"
#include "cogl-clip-stack.h"
#include "cogl-matrix-stack.h"
#include "cogl-current-matrix.h"
#include "cogl-gles2-wrapper.h"
@ -50,6 +52,12 @@ typedef struct
gboolean enable_backface_culling;
gboolean indirect;
/* Client-side matrix stack or NULL if none */
CoglMatrixMode matrix_mode;
CoglMatrixStack *modelview_stack;
/* Cache of inverse projection matrix */
float inverse_projection[16];

View File

@ -206,33 +206,29 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
from a non-screen buffer */
GE( glGetIntegerv (GL_VIEWPORT, ctx->viewport_store) );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
}
else
{
/* Override viewport and matrix setup if redirecting
from another offscreen buffer */
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_identity ();
GE( glMatrixMode (GL_MODELVIEW) );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_identity ();
}
/* Setup new viewport and matrices */
GE( glViewport (0, 0, fbo->width, fbo->height) );
GE( glTranslatef (-1.0, -1.0, 0) );
GE( glScalef (((float)(2) /
(float)(fbo->width)),
((float)(2) /
(float)(fbo->height)),
1.0) );
_cogl_current_matrix_translate (-1.0f, -1.0f, 0.0f);
_cogl_current_matrix_scale (2.0f / fbo->width, 2.0f / fbo->height, 1.0f);
/* Bind offscreen framebuffer object */
GE( glBindFramebuffer (GL_FRAMEBUFFER, fbo->gl_handle) );
@ -265,11 +261,11 @@ cogl_draw_buffer (CoglBufferTarget target, CoglHandle offscreen)
GE( glViewport (ctx->viewport_store[0], ctx->viewport_store[1],
ctx->viewport_store[2], ctx->viewport_store[3]) );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPopMatrix () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_pop ();
}
/* Bind window framebuffer object */

View File

@ -1505,6 +1505,8 @@ cogl_wrap_glGetIntegerv (GLenum pname, GLint *params)
void
cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params)
{
CoglGles2WrapperTextureUnit *texture_unit;
_COGL_GET_GLES2_WRAPPER (w, NO_RETVAL);
switch (pname)
@ -1519,6 +1521,14 @@ cogl_wrap_glGetFloatv (GLenum pname, GLfloat *params)
sizeof (GLfloat) * 16);
break;
case GL_TEXTURE_MATRIX:
texture_unit = w->texture_units + w->active_texture_unit;
memcpy (params,
texture_unit->texture_stack
+ texture_unit->texture_stack_pos * 16,
sizeof (GLfloat) * 16);
break;
case GL_VIEWPORT:
glGetFloatv (GL_VIEWPORT, params);
break;

View File

@ -255,6 +255,7 @@ struct _CoglGles2WrapperShader
#define GL_MODELVIEW_MATRIX 0x0BA6
#define GL_PROJECTION_MATRIX 0x0BA7
#define GL_TEXTURE_MATRIX 0x0BA8
#define GL_GENERATE_MIPMAP 0x8191

View File

@ -87,6 +87,7 @@ _cogl_path_stroke_nodes ()
COGL_MATERIAL_FLUSH_DISABLE_MASK,
(guint32)~0, /* disable all texture layers */
NULL);
_cogl_current_matrix_state_flush ();
while (path_start < ctx->path_nodes->len)
{
@ -167,6 +168,7 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glColorMask (FALSE, FALSE, FALSE, FALSE) );
GE( glDepthMask (FALSE) );
_cogl_current_matrix_state_flush ();
while (path_start < path_size)
{
GE( glVertexPointer (2, GL_FLOAT, sizeof (CoglPathNode),
@ -202,16 +204,28 @@ _cogl_add_path_to_stencil_buffer (floatVec2 nodes_min,
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
/* Decrement all of the bits twice so that only pixels where the
value is 3 will remain */
GE( glPushMatrix () );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
/* Cogl generally assumes the modelview matrix is current, so since
* cogl_rectangle will be flushing GL state and emitting geometry
* to OpenGL it will be confused if we leave the projection matrix
* active... */
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
GE( glPopMatrix () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
}
GE( glStencilMask (~(GLuint) 0) );

View File

@ -504,18 +504,18 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
(0,0 in bottom-left corner to draw the texture
upside-down so we match the way glReadPixels works) */
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
GE( glOrthof (0, (float)(viewport[2]),
0, (float)(viewport[3]),
(float)(0),
(float)(100)) );
_cogl_current_matrix_ortho (0, (float)(viewport[2]),
0, (float)(viewport[3]),
(float)(0),
(float)(100));
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
/* Draw to all channels */
cogl_draw_buffer (COGL_WINDOW_BUFFER | COGL_MASK_BUFFER, 0);
@ -611,10 +611,10 @@ _cogl_texture_download_from_gl (CoglTexture *tex,
}
/* Restore old state */
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
glMatrixMode (GL_MODELVIEW);
glPopMatrix ();
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_pop ();
cogl_draw_buffer (COGL_WINDOW_BUFFER, 0);
@ -2169,7 +2169,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
cogl_enable (enable_flags);
GE (glVertexPointer (2, GL_FLOAT, stride, vertex_pointer));
_cogl_current_matrix_state_flush ();
GE (glDrawRangeElements (GL_TRIANGLES,
0, ctx->static_indices->len - 1,
6 * batch_len,
@ -2198,6 +2198,7 @@ _cogl_journal_flush_quad_batch (CoglJournalEntry *batch_start,
color == 2 ? 0xff : 0x00,
0xff);
cogl_material_flush_gl_state (outline, NULL);
_cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_LINE_LOOP, 4 * i, 4) );
}
}
@ -2986,6 +2987,7 @@ _cogl_texture_sliced_polygon (CoglTextureVertex *vertices,
COGL_MATERIAL_FLUSH_LAYER0_OVERRIDE,
gl_handle,
NULL);
_cogl_current_matrix_state_flush ();
GE( glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices) );
}
@ -3069,6 +3071,7 @@ _cogl_multitexture_unsliced_polygon (CoglTextureVertex *vertices,
COGL_MATERIAL_FLUSH_FALLBACK_MASK,
fallback_mask,
NULL);
_cogl_current_matrix_state_flush ();
GE (glDrawArrays (GL_TRIANGLE_FAN, 0, n_vertices));
}

View File

@ -124,37 +124,6 @@ cogl_clear (const CoglColor *color)
*/
}
/* FIXME: inline most of these */
void
cogl_push_matrix (void)
{
GE( glPushMatrix() );
}
void
cogl_pop_matrix (void)
{
GE( glPopMatrix() );
}
void
cogl_scale (float x, float y, float z)
{
GE( glScalef (x, y, z) );
}
void
cogl_translate (float x, float y, float z)
{
GE( glTranslatef (x, y, z) );
}
void
cogl_rotate (float angle, float x, float y, float z)
{
GE( glRotatef (angle, x, y, z) );
}
static inline gboolean
cogl_toggle_flag (CoglContext *ctx,
gulong new_flags,
@ -319,6 +288,7 @@ set_clip_plane (GLint plane_num,
GLdouble plane[4];
#endif
GLfloat angle;
CoglMatrix inverse_projection;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
/* Calculate the angle between the axes and the line crossing the
@ -326,18 +296,20 @@ set_clip_plane (GLint plane_num,
angle = atan2f (vertex_b[1] - vertex_a[1],
vertex_b[0] - vertex_a[0]) * (180.0/G_PI);
GE( glPushMatrix () );
_cogl_current_matrix_push ();
/* Load the identity matrix and multiply by the reverse of the
projection matrix so we can specify the plane in screen
coordinates */
GE( glLoadIdentity () );
GE( glMultMatrixf ((GLfloat *) ctx->inverse_projection) );
_cogl_current_matrix_identity ();
cogl_matrix_init_from_array (&inverse_projection,
ctx->inverse_projection);
_cogl_current_matrix_multiply (&inverse_projection);
/* Rotate about point a */
GE( glTranslatef (vertex_a[0], vertex_a[1], vertex_a[2]) );
_cogl_current_matrix_translate (vertex_a[0], vertex_a[1], vertex_a[2]);
/* Rotate the plane by the calculated angle so that it will connect
the two points */
GE( glRotatef (angle, 0.0f, 0.0f, 1.0f) );
GE( glTranslatef (-vertex_a[0], -vertex_a[1], -vertex_a[2]) );
_cogl_current_matrix_rotate (angle, 0.0f, 0.0f, 1.0f);
_cogl_current_matrix_translate (-vertex_a[0], -vertex_a[1], -vertex_a[2]);
plane[0] = 0;
plane[1] = -1.0;
@ -349,7 +321,7 @@ set_clip_plane (GLint plane_num,
GE( glClipPlane (plane_num, plane) );
#endif
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
}
void
@ -358,7 +330,10 @@ _cogl_set_clip_planes (float x_offset,
float width,
float height)
{
GLfloat modelview[16], projection[16];
CoglMatrix modelview_matrix;
CoglMatrix projection_matrix;
GLfloat *modelview;
GLfloat *projection;
float vertex_tl[4] = { x_offset, y_offset, 0, 1.0 };
float vertex_tr[4] = { x_offset + width, y_offset, 0, 1.0 };
@ -366,8 +341,18 @@ _cogl_set_clip_planes (float x_offset,
float vertex_br[4] = { x_offset + width, y_offset + height,
0, 1.0 };
GE( glGetFloatv (GL_MODELVIEW_MATRIX, modelview) );
GE( glGetFloatv (GL_PROJECTION_MATRIX, projection) );
/* hack alert: there's no way to get *and modify*
* CoglMatrix as a float array. So we just
* use a cast instead of cogl_matrix_get_array(),
* and know that we will not call any more CoglMatrix
* methods after we write to it directly.
*/
_cogl_get_matrix (COGL_MATRIX_PROJECTION,
&projection_matrix);
projection = (GLfloat*) &projection_matrix;
_cogl_get_matrix (COGL_MATRIX_MODELVIEW,
&modelview_matrix);
modelview = (GLfloat*) &modelview_matrix;
project_vertex (modelview, projection, vertex_tl);
project_vertex (modelview, projection, vertex_tr);
@ -436,15 +421,27 @@ _cogl_add_stencil_clip (float x_offset,
only pixels where both the original stencil buffer and the
rectangle are set will be valid */
GE( glStencilOp (GL_DECR, GL_DECR, GL_DECR) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
GE( glMatrixMode (GL_PROJECTION) );
GE( glPushMatrix () );
GE( glLoadIdentity () );
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
/* Cogl generally assumes the modelview matrix is current, so since
* cogl_rectangle will be flushing GL state and emitting geometry
* to OpenGL it will be confused if we leave the projection matrix
* active... */
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
_cogl_current_matrix_push ();
_cogl_current_matrix_identity ();
cogl_rectangle (-1.0, -1.0, 1.0, 1.0);
GE( glPopMatrix () );
GE( glMatrixMode (GL_MODELVIEW) );
GE( glPopMatrix () );
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_PROJECTION);
_cogl_current_matrix_pop ();
_cogl_set_current_matrix (COGL_MATRIX_MODELVIEW);
}
/* Restore the stencil mode */
@ -452,14 +449,6 @@ _cogl_add_stencil_clip (float x_offset,
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
}
void
_cogl_set_matrix (const CoglMatrix *matrix)
{
const GLfloat *gl_matrix = cogl_matrix_get_array (matrix);
GE (glLoadMatrixf (gl_matrix));
}
void
_cogl_disable_stencil_buffer (void)
{
@ -484,108 +473,6 @@ _cogl_disable_clip_planes (void)
GE( glDisable (GL_CLIP_PLANE0) );
}
void
cogl_perspective (float fovy,
float aspect,
float zNear,
float zFar)
{
float xmax, ymax;
float x, y, c, d;
float fovy_rad_half = (fovy * G_PI) / 360;
GLfloat m[16];
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
memset (&m[0], 0, sizeof (m));
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
/*
* Based on the original algorithm in perspective():
*
* 1) xmin = -xmax => xmax + xmin == 0 && xmax - xmin == 2 * xmax
* same true for y, hence: a == 0 && b == 0;
*
* 2) When working with small numbers, we are loosing significant
* precision
*/
ymax = (zNear * (sinf (fovy_rad_half) / cosf (fovy_rad_half)));
xmax = (ymax * aspect);
x = (zNear / xmax);
y = (zNear / ymax);
c = (-(zFar + zNear) / ( zFar - zNear));
d = (-(2 * zFar) * zNear) / (zFar - zNear);
#define M(row,col) m[col*4+row]
M(0,0) = x;
M(1,1) = y;
M(2,2) = c;
M(2,3) = d;
M(3,2) = -1.0;
GE( glMultMatrixf (m) );
GE( glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
#define m ctx->inverse_projection
M(0, 0) = (1.0 / x);
M(1, 1) = (1.0 / y);
M(2, 3) = -1.0;
M(3, 2) = (1.0 / d);
M(3, 3) = (c / d);
#undef m
#undef M
}
void
cogl_frustum (float left,
float right,
float bottom,
float top,
float z_near,
float z_far)
{
float c, d;
_COGL_GET_CONTEXT (ctx, NO_RETVAL);
GE( glMatrixMode (GL_PROJECTION) );
GE( glLoadIdentity () );
GE( glFrustumf (left,
right,
bottom,
top,
z_near,
z_far) );
GE( glMatrixMode (GL_MODELVIEW) );
/* Calculate and store the inverse of the matrix */
memset (ctx->inverse_projection, 0, sizeof (float) * 16);
c = - (z_far + z_near) / (z_far - z_near);
d = - (2 * (z_far * z_near)) / (z_far - z_near);
#define M(row,col) ctx->inverse_projection[col*4+row]
M(0,0) = (right - left) / (2 * z_near);
M(0,3) = (right + left) / (2 * z_near);
M(1,1) = (top - bottom) / (2 * z_near);
M(1,3) = (top + bottom) / (2 * z_near);
M(2,3) = -1.0;
M(3,2) = 1.0 / d;
M(3,3) = c / d;
#undef M
}
void
cogl_viewport (guint width,
guint height)
@ -607,8 +494,8 @@ cogl_setup_viewport (guint width,
GE( glViewport (0, 0, width, height) );
/* For Ortho projection.
* glOrthof (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
*/
* _cogl_current_matrix_ortho (0, width << 16, 0, height << 16, -1 << 16, 1 << 16);
*/
cogl_perspective (fovy, aspect, z_near, z_far);
@ -621,13 +508,10 @@ cogl_setup_viewport (guint width,
cogl_get_projection_matrix (&projection_matrix);
z_camera = 0.5 * projection_matrix.xx;
GE( glLoadIdentity () );
GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
GE( glScalef (1.0f / width, -1.0f / height, 1.0f / width) );
GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
_cogl_current_matrix_identity ();
_cogl_current_matrix_translate (-0.5f, -0.5f, -z_camera);
_cogl_current_matrix_scale (1.0f / width, -1.0f / height, 1.0f / width);
_cogl_current_matrix_translate (0.0f, -1.0 * height, 0.0f);
}
static void
@ -679,28 +563,6 @@ cogl_features_available (CoglFeatureFlags features)
return (ctx->feature_flags & features) == features;
}
void
cogl_get_modelview_matrix (CoglMatrix *matrix)
{
float m[16];
glGetFloatv (GL_MODELVIEW_MATRIX, m);
/* Since it's internal to Cogl and CoglMatrix doesn't currently have
* any flag members, we could avoid this extra copy if it really
* bothers anyone */
cogl_matrix_init_from_array (matrix, m);
}
void
cogl_get_projection_matrix (CoglMatrix *matrix)
{
float m[16];
glGetFloatv (GL_PROJECTION_MATRIX, m);
/* Since it's internal to Cogl and CoglMatrix doesn't currently have
* any flag members, we could avoid this extra copy if it really
* bothers anyone */
cogl_matrix_init_from_array (matrix, m);
}
void
cogl_get_viewport (float v[4])
{
@ -796,3 +658,8 @@ cogl_disable_fog (void)
glDisable (GL_FOG);
}
void
cogl_flush_gl_state (int flags)
{
_cogl_current_matrix_state_flush ();
}