-/* $Id: matrix.c,v 1.5 1999/10/08 09:27:11 keithw Exp $ */
+/* $Id: matrix.c,v 1.23 2000/10/30 13:32:00 keithw Exp $ */
/*
* Mesa 3-D graphics library
- * Version: 3.1
+ * Version: 3.5
*
- * Copyright (C) 1999 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
*/
-
-
-
/*
* Matrix operations
*
- *
* NOTES:
* 1. 4x4 transformation matrices are stored in memory in column major order.
* 2. Points/vertices are to be thought of as column vectors.
* 3. Transformation of a point p by a matrix M is: p' = M * p
- *
*/
#ifdef PC_HEADER
#include "all.h"
#else
-#ifndef XFree86Server
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#else
-#include "GL/xf86glx.h"
-#endif
+#include "glheader.h"
+#include "buffers.h"
#include "context.h"
#include "enums.h"
#include "macros.h"
#include "matrix.h"
+#include "mem.h"
#include "mmath.h"
#include "types.h"
-#ifdef XFree86Server
-#include "GL/xf86glx.h"
-#endif
#endif
"MATRIX_2D_NO_ROT",
"MATRIX_3D"
};
-static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b );
static GLfloat Identity[16] = {
};
+
+static void matmul4( GLfloat *product, const GLfloat *a, const GLfloat *b );
+
+
static void print_matrix_floats( const GLfloat m[16] )
{
int i;
{
fprintf(stderr, "Matrix type: %s, flags: %x\n", types[m->type], m->flags);
print_matrix_floats(m->m);
-#if 1
fprintf(stderr, "Inverse: \n");
if (m->inv) {
GLfloat prod[16];
matmul4(prod, m->m, m->inv);
fprintf(stderr, "Mat * Inverse:\n");
print_matrix_floats(prod);
- } else
+ }
+ else {
fprintf(stderr, " - not available\n");
-#endif
+ }
}
{
GLint i;
for (i = 0; i < 4; i++) {
- GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
+ const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
}
-
-
/* Multiply two matrices known to occupy only the top three rows,
* such as typical modelling matrices, and ortho matrices.
- *
- * KW: 3*9 = 27 muls
*/
static void matmul34( GLfloat *product, const GLfloat *a, const GLfloat *b )
{
GLint i;
for (i = 0; i < 3; i++) {
- GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
+ const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0);
P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1);
P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2);
{
GLint i;
for (i = 0; i < 4; i++) {
- GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
+ const GLfloat ai0=A(i,0), ai1=A(i,1), ai2=A(i,2), ai3=A(i,3);
P(i,0) = ai0 * B(0,0) + ai1 * B(1,0) + ai2 * B(2,0) + ai3 * B(3,0);
P(i,1) = ai0 * B(0,1) + ai1 * B(1,1) + ai2 * B(2,1) + ai3 * B(3,1);
P(i,2) = ai0 * B(0,2) + ai1 * B(1,2) + ai2 * B(2,2) + ai3 * B(3,2);
#undef P
-
#define SWAP_ROWS(a, b) { GLfloat *_tmp = a; (a)=(b); (b)=_tmp; }
#define MAT(m,r,c) (m)[(c)*4+(r)]
}
#undef SWAP_ROWS
+
/* Adapted from graphics gems II.
*/
static GLboolean invert_matrix_3d_general( GLmatrix *mat )
const GLfloat *in = mat->m;
GLfloat *out = mat->inv;
- if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING))
- {
+ if (!TEST_MAT_FLAGS(mat, MAT_FLAGS_ANGLE_PRESERVING)) {
return invert_matrix_3d_general( mat );
}
- if (mat->flags & MAT_FLAG_UNIFORM_SCALE)
- {
- GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) +
- MAT(in,0,1) * MAT(in,0,1) +
- MAT(in,0,2) * MAT(in,0,2));
+ if (mat->flags & MAT_FLAG_UNIFORM_SCALE) {
+ GLfloat scale = (MAT(in,0,0) * MAT(in,0,0) +
+ MAT(in,0,1) * MAT(in,0,1) +
+ MAT(in,0,2) * MAT(in,0,2));
if (scale == 0.0)
return GL_FALSE;
MAT(out,1,2) = scale * MAT(in,2,1);
MAT(out,2,2) = scale * MAT(in,2,2);
}
- else if (mat->flags & MAT_FLAG_ROTATION)
- {
+ else if (mat->flags & MAT_FLAG_ROTATION) {
/* Transpose the 3 by 3 upper-left submatrix. */
MAT(out,0,0) = MAT(in,0,0);
MAT(out,1,0) = MAT(in,0,1);
MAT(out,1,2) = MAT(in,2,1);
MAT(out,2,2) = MAT(in,2,2);
}
- else /* pure translation */
- {
+ else {
+ /* pure translation */
MEMCPY( out, Identity, sizeof(Identity) );
MAT(out,0,3) = - MAT(in,0,3);
MAT(out,1,3) = - MAT(in,1,3);
return GL_TRUE;
}
- if (mat->flags & MAT_FLAG_TRANSLATION)
- {
+ if (mat->flags & MAT_FLAG_TRANSLATION) {
/* Do the translation part */
MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0) +
MAT(in,1,3) * MAT(out,0,1) +
MAT(in,1,3) * MAT(out,2,1) +
MAT(in,2,3) * MAT(out,2,2) );
}
- else
- {
+ else {
MAT(out,0,3) = MAT(out,1,3) = MAT(out,2,3) = 0.0;
}
MAT(out,1,1) = 1.0 / MAT(in,1,1);
MAT(out,2,2) = 1.0 / MAT(in,2,2);
- if (mat->flags & MAT_FLAG_TRANSLATION)
- {
+ if (mat->flags & MAT_FLAG_TRANSLATION) {
MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
MAT(out,2,3) = - (MAT(in,2,3) * MAT(out,2,2));
MAT(out,0,0) = 1.0 / MAT(in,0,0);
MAT(out,1,1) = 1.0 / MAT(in,1,1);
- if (mat->flags & MAT_FLAG_TRANSLATION)
- {
+ if (mat->flags & MAT_FLAG_TRANSLATION) {
MAT(out,0,3) = - (MAT(in,0,3) * MAT(out,0,0));
MAT(out,1,3) = - (MAT(in,1,3) * MAT(out,1,1));
}
typedef GLboolean (*inv_mat_func)( GLmatrix *mat );
+
static inv_mat_func inv_mat_tab[7] = {
invert_matrix_general,
invert_matrix_identity,
};
-GLboolean gl_matrix_invert( GLmatrix *mat )
+static GLboolean matrix_invert( GLmatrix *mat )
{
if (inv_mat_tab[mat->type](mat)) {
-#if 0
- GLmatrix m; m.inv = 0; m.type = 0; m.flags = 0;
- matmul4( m.m, mat->m, mat->inv );
- printf("inverted matrix of type %s:\n", types[mat->type]);
- gl_print_matrix( mat );
- gl_print_matrix( &m );
-#endif
return GL_TRUE;
} else {
MEMCPY( mat->inv, Identity, sizeof(Identity) );
+void gl_matrix_transposef( GLfloat to[16], const GLfloat from[16] )
+{
+ to[0] = from[0];
+ to[1] = from[4];
+ to[2] = from[8];
+ to[3] = from[12];
+ to[4] = from[1];
+ to[5] = from[5];
+ to[6] = from[9];
+ to[7] = from[13];
+ to[8] = from[2];
+ to[9] = from[6];
+ to[10] = from[10];
+ to[11] = from[14];
+ to[12] = from[3];
+ to[13] = from[7];
+ to[14] = from[11];
+ to[15] = from[15];
+}
+
+
+
+void gl_matrix_transposed( GLdouble to[16], const GLdouble from[16] )
+{
+ to[0] = from[0];
+ to[1] = from[4];
+ to[2] = from[8];
+ to[3] = from[12];
+ to[4] = from[1];
+ to[5] = from[5];
+ to[6] = from[9];
+ to[7] = from[13];
+ to[8] = from[2];
+ to[9] = from[6];
+ to[10] = from[10];
+ to[11] = from[14];
+ to[12] = from[3];
+ to[13] = from[7];
+ to[14] = from[11];
+ to[15] = from[15];
+}
+
+
+
/*
* Generate a 4x4 transformation matrix from glRotate parameters.
*/
mag = GL_SQRT( x*x + y*y + z*z );
- if (mag == 0.0) {
+ if (mag <= 1.0e-4) {
/* generate an identity matrix and return */
MEMCPY(m, Identity, sizeof(GLfloat)*16);
return;
GLuint mask = 0;
GLuint i;
- for (i = 0 ; i < 16 ; i++)
- {
+ for (i = 0 ; i < 16 ; i++) {
if (m[i] == 0.0) mask |= (1<<i);
}
if (mask == MASK_IDENTITY) {
mat->type = MATRIX_IDENTITY;
}
- else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT)
- {
+ else if ((mask & MASK_2D_NO_ROT) == MASK_2D_NO_ROT) {
mat->type = MATRIX_2D_NO_ROT;
if ((mask & MASK_NO_2D_SCALE) != MASK_NO_2D_SCALE)
mat->flags = MAT_FLAG_GENERAL_SCALE;
}
- else if ((mask & MASK_2D) == MASK_2D)
- {
+ else if ((mask & MASK_2D) == MASK_2D) {
GLfloat mm = DOT2(m, m);
GLfloat m4m4 = DOT2(m+4,m+4);
GLfloat mm4 = DOT2(m,m+4);
mat->flags |= MAT_FLAG_ROTATION;
}
- else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT)
- {
+ else if ((mask & MASK_3D_NO_ROT) == MASK_3D_NO_ROT) {
mat->type = MATRIX_3D_NO_ROT;
/* Check for scale */
if (SQ(m[0]-m[5]) < SQ(1e-6) &&
SQ(m[0]-m[10]) < SQ(1e-6)) {
- if (SQ(m[0]-1.0) > SQ(1e-6))
+ if (SQ(m[0]-1.0) > SQ(1e-6)) {
mat->flags |= MAT_FLAG_UNIFORM_SCALE;
- } else
+ }
+ }
+ else {
mat->flags |= MAT_FLAG_GENERAL_SCALE;
+ }
}
- else if ((mask & MASK_3D) == MASK_3D)
- {
+ else if ((mask & MASK_3D) == MASK_3D) {
GLfloat c1 = DOT3(m,m);
GLfloat c2 = DOT3(m+4,m+4);
GLfloat c3 = DOT3(m+8,m+8);
if (SQ(c1-1.0) > SQ(1e-6))
mat->flags |= MAT_FLAG_UNIFORM_SCALE;
/* else no scale at all */
- } else
+ }
+ else {
mat->flags |= MAT_FLAG_GENERAL_SCALE;
+ }
/* Check for rotation */
if (SQ(d1) < SQ(1e-6)) {
else
mat->flags |= MAT_FLAG_GENERAL_3D;
}
- else
+ else {
mat->flags |= MAT_FLAG_GENERAL_3D; /* shear, etc */
+ }
}
- else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F)
- {
+ else if ((mask & MASK_PERSPECTIVE) == MASK_PERSPECTIVE && m[11]==-1.0F) {
mat->type = MATRIX_PERSPECTIVE;
mat->flags |= MAT_FLAG_GENERAL;
}
}
else if (TEST_MAT_FLAGS(mat, (MAT_FLAG_TRANSLATION |
MAT_FLAG_UNIFORM_SCALE |
- MAT_FLAG_GENERAL_SCALE)))
- {
+ MAT_FLAG_GENERAL_SCALE))) {
if ( m[10]==1.0F && m[14]==0.0F ) {
mat->type = MATRIX_2D_NO_ROT;
}
else if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D)) {
if ( m[ 8]==0.0F
&& m[ 9]==0.0F
- && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F)
- {
+ && m[2]==0.0F && m[6]==0.0F && m[10]==1.0F && m[14]==0.0F) {
mat->type = MATRIX_2D;
}
- else
- {
+ else {
mat->type = MATRIX_3D;
}
}
else if ( m[4]==0.0F && m[12]==0.0F
&& m[1]==0.0F && m[13]==0.0F
&& m[2]==0.0F && m[6]==0.0F
- && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F)
- {
+ && m[3]==0.0F && m[7]==0.0F && m[11]==-1.0F && m[15]==0.0F) {
mat->type = MATRIX_PERSPECTIVE;
}
else {
mat->type = MATRIX_GENERAL;
}
-
}
}
if (mat->inv && (mat->flags & MAT_DIRTY_INVERSE)) {
- gl_matrix_invert( mat );
+ matrix_invert( mat );
}
mat->flags &= ~(MAT_DIRTY_FLAGS|
}
+static void matrix_copy( GLmatrix *to, const GLmatrix *from )
+{
+ MEMCPY( to->m, from->m, sizeof(Identity) );
+ to->flags = from->flags | MAT_DIRTY_DEPENDENTS;
+ to->type = from->type;
+
+ if (to->inv != 0) {
+ if (from->inv == 0) {
+ matrix_invert( to );
+ }
+ else {
+ MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);
+ }
+ }
+}
+
+/*
+ * Multiply a matrix by an array of floats with known properties.
+ */
+static void mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags )
+{
+ mat->flags |= (flags |
+ MAT_DIRTY_TYPE |
+ MAT_DIRTY_INVERSE |
+ MAT_DIRTY_DEPENDENTS);
+
+ if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
+ matmul34( mat->m, mat->m, m );
+ else
+ matmul4( mat->m, mat->m, m );
+
+}
+
+
+void gl_calculate_model_project_matrix( GLcontext *ctx )
+{
+ gl_matrix_mul( &ctx->ModelProjectMatrix,
+ &ctx->ProjectionMatrix,
+ &ctx->ModelView );
+
+ gl_matrix_analyze( &ctx->ModelProjectMatrix );
+}
+
+
+void gl_matrix_ctr( GLmatrix *m )
+{
+ if ( m->m == 0 ) {
+ m->m = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+ }
+ MEMCPY( m->m, Identity, sizeof(Identity) );
+ m->inv = 0;
+ m->type = MATRIX_IDENTITY;
+ m->flags = MAT_DIRTY_DEPENDENTS;
+}
+
+void gl_matrix_dtr( GLmatrix *m )
+{
+ if ( m->m != 0 ) {
+ ALIGN_FREE( m->m );
+ m->m = 0;
+ }
+ if ( m->inv != 0 ) {
+ ALIGN_FREE( m->inv );
+ m->inv = 0;
+ }
+}
+
+
+void gl_matrix_alloc_inv( GLmatrix *m )
+{
+ if ( m->inv == 0 ) {
+ m->inv = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 );
+ MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
+ }
+}
+
+
+void gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
+{
+ dest->flags = (a->flags |
+ b->flags |
+ MAT_DIRTY_TYPE |
+ MAT_DIRTY_INVERSE |
+ MAT_DIRTY_DEPENDENTS);
+
+ if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
+ matmul34( dest->m, a->m, b->m );
+ else
+ matmul4( dest->m, a->m, b->m );
+}
+
+
+
+/**********************************************************************/
+/* API functions */
+/**********************************************************************/
+
+
#define GET_ACTIVE_MATRIX(ctx, mat, flags, where) \
do { \
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, where); \
switch (ctx->Transform.MatrixMode) { \
case GL_MODELVIEW: \
mat = &ctx->ModelView; \
- flags |= NEW_MODELVIEW; \
+ flags |= _NEW_MODELVIEW; \
break; \
case GL_PROJECTION: \
mat = &ctx->ProjectionMatrix; \
- flags |= NEW_PROJECTION; \
+ flags |= _NEW_PROJECTION; \
break; \
case GL_TEXTURE: \
mat = &ctx->TextureMatrix[ctx->Texture.CurrentTransformUnit]; \
- flags |= NEW_TEXTURE_MATRIX; \
+ flags |= _NEW_TEXTURE_MATRIX; \
+ break; \
+ case GL_COLOR: \
+ mat = &ctx->ColorMatrix; \
+ flags |= _NEW_COLOR_MATRIX; \
break; \
default: \
gl_problem(ctx, where); \
} while (0)
-void gl_Frustum( GLcontext *ctx,
- GLdouble left, GLdouble right,
- GLdouble bottom, GLdouble top,
- GLdouble nearval, GLdouble farval )
+void
+_mesa_Frustum( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval )
{
+ GET_CURRENT_CONTEXT(ctx);
GLfloat x, y, a, b, c, d;
GLfloat m[16];
GLmatrix *mat = 0;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
+ mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE );
- gl_mat_mul_floats( mat, m, MAT_FLAG_PERSPECTIVE );
-
-
- if (ctx->Transform.MatrixMode == GL_PROJECTION)
- {
+ if (ctx->Transform.MatrixMode == GL_PROJECTION) {
/* Need to keep a stack of near/far values in case the user push/pops
* the projection matrix stack so that we can call Driver.NearFar()
* after a pop.
}
-void gl_Ortho( GLcontext *ctx,
- GLdouble left, GLdouble right,
- GLdouble bottom, GLdouble top,
- GLdouble nearval, GLdouble farval )
+void
+_mesa_Ortho( GLdouble left, GLdouble right,
+ GLdouble bottom, GLdouble top,
+ GLdouble nearval, GLdouble farval )
{
+ GET_CURRENT_CONTEXT(ctx);
GLfloat x, y, z;
GLfloat tx, ty, tz;
GLfloat m[16];
GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glOrtho" );
if ((left == right) || (bottom == top) || (nearval == farval)) {
- gl_error( ctx, GL_INVALID_VALUE, "gl_Ortho((l = r) or (b = top) or (n=f)" );
+ gl_error( ctx, GL_INVALID_VALUE,
+ "gl_Ortho((l = r) or (b = top) or (n=f)" );
return;
}
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = 0.0F; M(3,3) = 1.0F;
#undef M
- gl_mat_mul_floats( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION));
+ mat_mul_floats( mat, m, (MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION));
if (ctx->Driver.NearFar) {
(*ctx->Driver.NearFar)( ctx, nearval, farval );
}
-void gl_MatrixMode( GLcontext *ctx, GLenum mode )
+void
+_mesa_MatrixMode( GLenum mode )
{
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glMatrixMode");
switch (mode) {
case GL_MODELVIEW:
case GL_PROJECTION:
case GL_TEXTURE:
+ case GL_COLOR:
ctx->Transform.MatrixMode = mode;
break;
default:
-void gl_PushMatrix( GLcontext *ctx )
+void
+_mesa_PushMatrix( void )
{
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPushMatrix");
if (MESA_VERBOSE&VERBOSE_API)
switch (ctx->Transform.MatrixMode) {
case GL_MODELVIEW:
- if (ctx->ModelViewStackDepth>=MAX_MODELVIEW_STACK_DEPTH-1) {
+ if (ctx->ModelViewStackDepth >= MAX_MODELVIEW_STACK_DEPTH - 1) {
gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
return;
}
- gl_matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
- &ctx->ModelView );
+ matrix_copy( &ctx->ModelViewStack[ctx->ModelViewStackDepth++],
+ &ctx->ModelView );
break;
case GL_PROJECTION:
- if (ctx->ProjectionStackDepth>=MAX_PROJECTION_STACK_DEPTH) {
+ if (ctx->ProjectionStackDepth >= MAX_PROJECTION_STACK_DEPTH - 1) {
gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
return;
}
- gl_matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
- &ctx->ProjectionMatrix );
+ matrix_copy( &ctx->ProjectionStack[ctx->ProjectionStackDepth++],
+ &ctx->ProjectionMatrix );
/* Save near and far projection values */
ctx->NearFarStack[ctx->ProjectionStackDepth][0]
case GL_TEXTURE:
{
GLuint t = ctx->Texture.CurrentTransformUnit;
- if (ctx->TextureStackDepth[t] >= MAX_TEXTURE_STACK_DEPTH) {
+ if (ctx->TextureStackDepth[t] >= MAX_TEXTURE_STACK_DEPTH - 1) {
gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
return;
}
- gl_matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
- &ctx->TextureMatrix[t] );
+ matrix_copy( &ctx->TextureStack[t][ctx->TextureStackDepth[t]++],
+ &ctx->TextureMatrix[t] );
+ }
+ break;
+ case GL_COLOR:
+ if (ctx->ColorStackDepth >= MAX_COLOR_STACK_DEPTH - 1) {
+ gl_error( ctx, GL_STACK_OVERFLOW, "glPushMatrix");
+ return;
}
+ matrix_copy( &ctx->ColorStack[ctx->ColorStackDepth++],
+ &ctx->ColorMatrix );
break;
default:
gl_problem(ctx, "Bad matrix mode in gl_PushMatrix");
-void gl_PopMatrix( GLcontext *ctx )
+void
+_mesa_PopMatrix( void )
{
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glPopMatrix");
if (MESA_VERBOSE&VERBOSE_API)
gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
return;
}
- gl_matrix_copy( &ctx->ModelView,
- &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
- ctx->NewState |= NEW_MODELVIEW;
+ matrix_copy( &ctx->ModelView,
+ &ctx->ModelViewStack[--ctx->ModelViewStackDepth] );
+ ctx->NewState |= _NEW_MODELVIEW;
break;
case GL_PROJECTION:
if (ctx->ProjectionStackDepth==0) {
return;
}
- gl_matrix_copy( &ctx->ProjectionMatrix,
- &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
- ctx->NewState |= NEW_PROJECTION;
+ matrix_copy( &ctx->ProjectionMatrix,
+ &ctx->ProjectionStack[--ctx->ProjectionStackDepth] );
+ ctx->NewState |= _NEW_PROJECTION;
/* Device driver near/far values */
{
gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
return;
}
- gl_matrix_copy(&ctx->TextureMatrix[t],
- &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
+ matrix_copy(&ctx->TextureMatrix[t],
+ &ctx->TextureStack[t][--ctx->TextureStackDepth[t]]);
+ ctx->NewState |= _NEW_TEXTURE_MATRIX;
}
break;
+ case GL_COLOR:
+ if (ctx->ColorStackDepth==0) {
+ gl_error( ctx, GL_STACK_UNDERFLOW, "glPopMatrix");
+ return;
+ }
+ matrix_copy(&ctx->ColorMatrix,
+ &ctx->ColorStack[--ctx->ColorStackDepth]);
+ ctx->NewState |= _NEW_COLOR_MATRIX;
+ break;
default:
gl_problem(ctx, "Bad matrix mode in gl_PopMatrix");
}
-void gl_LoadIdentity( GLcontext *ctx )
+void
+_mesa_LoadIdentity( void )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadIdentity");
}
-void gl_LoadMatrixf( GLcontext *ctx, const GLfloat *m )
+void
+_mesa_LoadMatrixf( const GLfloat *m )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glLoadMatrix");
}
+void
+_mesa_LoadMatrixd( const GLdouble *m )
+{
+ GLfloat f[16];
+ GLint i;
+ for (i = 0; i < 16; i++)
+ f[i] = m[i];
+ _mesa_LoadMatrixf(f);
+}
+
+
/*
* Multiply the active matrix by an arbitary matrix.
*/
-void gl_MultMatrixf( GLcontext *ctx, const GLfloat *m )
+void
+_mesa_MultMatrixf( const GLfloat *m )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glMultMatrix" );
matmul4( mat->m, mat->m, m );
/*
* Multiply the active matrix by an arbitary matrix.
*/
-void gl_MultMatrixd( GLcontext *ctx, const GLdouble *m )
+void
+_mesa_MultMatrixd( const GLdouble *m )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glMultMatrix" );
matmul4fd( mat->m, mat->m, m );
-/*
- * Multiply a matrix by an array of floats with known properties.
- */
-void gl_mat_mul_floats( GLmatrix *mat, const GLfloat *m, GLuint flags )
-{
- mat->flags |= (flags |
- MAT_DIRTY_TYPE |
- MAT_DIRTY_INVERSE |
- MAT_DIRTY_DEPENDENTS);
-
- if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
- matmul34( mat->m, mat->m, m );
- else
- matmul4( mat->m, mat->m, m );
-
-}
-
-/*
- * Multiply a matrix by an array of floats with known properties.
- */
-void gl_mat_mul_mat( GLmatrix *mat, const GLmatrix *m )
-{
- mat->flags |= (m->flags |
- MAT_DIRTY_TYPE |
- MAT_DIRTY_INVERSE |
- MAT_DIRTY_DEPENDENTS);
-
- if (TEST_MAT_FLAGS(mat, MAT_FLAGS_3D))
- matmul34( mat->m, mat->m, m->m );
- else
- matmul4( mat->m, mat->m, m->m );
-}
-
-
-
/*
* Execute a glRotate call
*/
-void gl_Rotatef( GLcontext *ctx,
- GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
+void
+_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
{
+ GET_CURRENT_CONTEXT(ctx);
GLfloat m[16];
if (angle != 0.0F) {
GLmatrix *mat = 0;
GET_ACTIVE_MATRIX( ctx, mat, ctx->NewState, "glRotate" );
gl_rotation_matrix( angle, x, y, z, m );
- gl_mat_mul_floats( mat, m, MAT_FLAG_ROTATION );
+ mat_mul_floats( mat, m, MAT_FLAG_ROTATION );
}
}
+void
+_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Rotatef(angle, x, y, z);
+}
+
+
/*
* Execute a glScale call
*/
-void gl_Scalef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+void
+_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GLfloat *m;
GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glScale");
MAT_DIRTY_DEPENDENTS);
}
+
+void
+_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Scalef(x, y, z);
+}
+
+
/*
* Execute a glTranslate call
*/
-void gl_Translatef( GLcontext *ctx, GLfloat x, GLfloat y, GLfloat z )
+void
+_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z )
{
+ GET_CURRENT_CONTEXT(ctx);
GLmatrix *mat = 0;
GLfloat *m;
GET_ACTIVE_MATRIX(ctx, mat, ctx->NewState, "glTranslate");
}
+void
+_mesa_Translated( GLdouble x, GLdouble y, GLdouble z )
+{
+ _mesa_Translatef(x, y, z);
+}
+
+
+
+void
+_mesa_LoadTransposeMatrixfARB( const GLfloat *m )
+{
+ GLfloat tm[16];
+ gl_matrix_transposef(tm, m);
+ _mesa_LoadMatrixf(tm);
+}
+
+
+void
+_mesa_LoadTransposeMatrixdARB( const GLdouble *m )
+{
+ GLdouble tm[16];
+ gl_matrix_transposed(tm, m);
+ _mesa_LoadMatrixd(tm);
+}
+
+
+void
+_mesa_MultTransposeMatrixfARB( const GLfloat *m )
+{
+ GLfloat tm[16];
+ gl_matrix_transposef(tm, m);
+ _mesa_MultMatrixf(tm);
+}
+
+
+void
+_mesa_MultTransposeMatrixdARB( const GLdouble *m )
+{
+ GLdouble tm[16];
+ gl_matrix_transposed(tm, m);
+ _mesa_MultMatrixd(tm);
+}
+
+
+/*
+ * Called via glViewport or display list execution.
+ */
+void
+_mesa_Viewport( GLint x, GLint y, GLsizei width, GLsizei height )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ gl_Viewport(ctx, x, y, width, height);
+}
+
+
+
/*
* Define a new viewport and reallocate auxillary buffers if the size of
* the window (color buffer) has changed.
+ *
+ * XXX This is directly called by device drivers, BUT this function
+ * may be renamed _mesa_Viewport (without ctx arg) in the future so
+ * use of _mesa_Viewport is encouraged.
*/
-void gl_Viewport( GLcontext *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height )
+void
+gl_Viewport( GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height )
{
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glViewport");
ctx->Viewport.WindowMap.m[MAT_TX] = ctx->Viewport.WindowMap.m[MAT_SX] + x;
ctx->Viewport.WindowMap.m[MAT_SY] = (GLfloat) height / 2.0F;
ctx->Viewport.WindowMap.m[MAT_TY] = ctx->Viewport.WindowMap.m[MAT_SY] + y;
- ctx->Viewport.WindowMap.m[MAT_SZ] = 0.5 * DEPTH_SCALE;
- ctx->Viewport.WindowMap.m[MAT_TZ] = 0.5 * DEPTH_SCALE;
+ ctx->Viewport.WindowMap.m[MAT_SZ] = 0.5 * ctx->Visual.DepthMaxF;
+ ctx->Viewport.WindowMap.m[MAT_TZ] = 0.5 * ctx->Visual.DepthMaxF;
ctx->Viewport.WindowMap.flags = MAT_FLAG_GENERAL_SCALE|MAT_FLAG_TRANSLATION;
ctx->Viewport.WindowMap.type = MATRIX_3D_NO_ROT;
-
- ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
- ctx->NewState |= NEW_VIEWPORT;
+ ctx->NewState |= _NEW_VIEWPORT;
/* Check if window/buffer has been resized and if so, reallocate the
* ancillary buffers.
*/
- gl_ResizeBuffersMESA(ctx);
+ _mesa_ResizeBuffersMESA();
ctx->RasterMask &= ~WINCLIP_BIT;
if ( ctx->Viewport.X<0
- || ctx->Viewport.X + ctx->Viewport.Width > ctx->Buffer->Width
+ || ctx->Viewport.X + ctx->Viewport.Width > ctx->DrawBuffer->Width
|| ctx->Viewport.Y<0
- || ctx->Viewport.Y + ctx->Viewport.Height > ctx->Buffer->Height) {
+ || ctx->Viewport.Y + ctx->Viewport.Height > ctx->DrawBuffer->Height) {
ctx->RasterMask |= WINCLIP_BIT;
}
-void gl_DepthRange( GLcontext *ctx, GLclampd nearval, GLclampd farval )
+void
+_mesa_DepthRange( GLclampd nearval, GLclampd farval )
{
/*
* nearval - specifies mapping of the near clipping plane to window
* this range to window z coords.
*/
GLfloat n, f;
-
+ GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glDepthRange");
if (MESA_VERBOSE&VERBOSE_API)
ctx->Viewport.Near = n;
ctx->Viewport.Far = f;
- ctx->Viewport.WindowMap.m[MAT_SZ] = DEPTH_SCALE * ((f - n) / 2.0);
- ctx->Viewport.WindowMap.m[MAT_TZ] = DEPTH_SCALE * ((f - n) / 2.0 + n);
-
- ctx->ModelProjectWinMatrixUptodate = GL_FALSE;
+ ctx->Viewport.WindowMap.m[MAT_SZ] = ctx->Visual.DepthMaxF * ((f - n) / 2.0);
+ ctx->Viewport.WindowMap.m[MAT_TZ] = ctx->Visual.DepthMaxF * ((f - n) / 2.0 + n);
+ ctx->NewState |= _NEW_VIEWPORT;
if (ctx->Driver.DepthRange) {
(*ctx->Driver.DepthRange)( ctx, nearval, farval );
}
}
-
-
-void gl_calculate_model_project_matrix( GLcontext *ctx )
-{
- gl_matrix_mul( &ctx->ModelProjectMatrix,
- &ctx->ProjectionMatrix,
- &ctx->ModelView );
-
- gl_matrix_analyze( &ctx->ModelProjectMatrix );
-}
-
-
-void gl_matrix_ctr( GLmatrix *m )
-{
- m->inv = 0;
- MEMCPY( m->m, Identity, sizeof(Identity));
- m->type = MATRIX_IDENTITY;
- m->flags = MAT_DIRTY_DEPENDENTS;
-}
-
-void gl_matrix_dtr( GLmatrix *m )
-{
- if (m->inv != 0) {
- free(m->inv);
- m->inv = 0;
- }
-}
-
-void gl_matrix_set_identity( GLmatrix *m )
-{
- MEMCPY( m->m, Identity, sizeof(Identity));
- m->type = MATRIX_IDENTITY;
- m->flags = MAT_DIRTY_DEPENDENTS;
-}
-
-
-void gl_matrix_alloc_inv( GLmatrix *m )
-{
- if (m->inv == 0) {
- m->inv = (GLfloat *)malloc(16*sizeof(GLfloat));
- MEMCPY( m->inv, Identity, 16 * sizeof(GLfloat) );
- }
-}
-
-void gl_matrix_copy( GLmatrix *to, const GLmatrix *from )
-{
- MEMCPY( to->m, from->m, sizeof(Identity));
- to->flags = from->flags | MAT_DIRTY_DEPENDENTS;
- to->type = from->type;
-
- if (to->inv != 0) {
- if (from->inv == 0) {
- gl_matrix_invert( to );
- } else {
- MEMCPY(to->inv, from->inv, sizeof(GLfloat)*16);
- }
- }
-}
-
-void gl_matrix_mul( GLmatrix *dest, const GLmatrix *a, const GLmatrix *b )
-{
- dest->flags = (a->flags |
- b->flags |
- MAT_DIRTY_TYPE |
- MAT_DIRTY_INVERSE |
- MAT_DIRTY_DEPENDENTS);
-
- if (TEST_MAT_FLAGS(dest, MAT_FLAGS_3D))
- matmul34( dest->m, a->m, b->m );
- else
- matmul4( dest->m, a->m, b->m );
-}