From: Chris Forbes <chr...@ijw.co.nz> Allows the legacy matrix stacks to be manipulated without disturbing the matrix mode selector.
Signed-off-by: Chris Forbes <chr...@ijw.co.nz> --- src/mesa/main/matrix.c | 370 +++++++++++++++++++++++++++++++++++------ src/mesa/main/matrix.h | 46 +++++ 2 files changed, 363 insertions(+), 53 deletions(-) diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index bd38c1d8496..ea0a3bd537f 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -116,25 +116,53 @@ _mesa_Frustum( GLdouble left, GLdouble right, { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (nearval <= 0.0 || farval <= 0.0 || nearval == farval || left == right || - top == bottom) - { + top == bottom) { _mesa_error( ctx, GL_INVALID_VALUE, "glFrustum" ); return; } + FLUSH_VERTICES(ctx, 0); _math_matrix_frustum( ctx->CurrentStack->Top, - (GLfloat) left, (GLfloat) right, - (GLfloat) bottom, (GLfloat) top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, (GLfloat) nearval, (GLfloat) farval ); ctx->NewState |= ctx->CurrentStack->DirtyFlag; } +void GLAPIENTRY +_mesa_MatrixFrustumEXT( GLenum matrixMode, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode); + + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMatrixFrustumEXT(mode)"); + return; + } + + if (nearval <= 0.0 || + farval <= 0.0 || + nearval == farval || + left == right || + top == bottom) { + _mesa_error(ctx, GL_INVALID_VALUE, "glMatrixFrustumEXT"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_frustum(stack->Top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval); + ctx->NewState |= stack->DirtyFlag; +} /** * Apply an orthographic projection matrix. @@ -159,27 +187,54 @@ _mesa_Ortho( GLdouble left, GLdouble right, { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0); - if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glOrtho(%f, %f, %f, %f, %f, %f)\n", left, right, bottom, top, nearval, farval); if (left == right || bottom == top || - nearval == farval) - { + nearval == farval) { _mesa_error( ctx, GL_INVALID_VALUE, "glOrtho" ); return; } + FLUSH_VERTICES(ctx, 0); _math_matrix_ortho( ctx->CurrentStack->Top, - (GLfloat) left, (GLfloat) right, - (GLfloat) bottom, (GLfloat) top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, (GLfloat) nearval, (GLfloat) farval ); ctx->NewState |= ctx->CurrentStack->DirtyFlag; } +void GLAPIENTRY +_mesa_MatrixOrthoEXT( GLenum matrixMode, + GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode); + + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMatrixOrthoEXT(mode)"); + return; + } + + if (left == right || + bottom == top || + nearval == farval) { + _mesa_error(ctx, GL_INVALID_VALUE, "glMatrixOrthoEXT"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_ortho(stack->Top, + (GLfloat) left, (GLfloat) right, + (GLfloat) bottom, (GLfloat) top, + (GLfloat) nearval, (GLfloat) farval); + ctx->NewState |= stack->DirtyFlag; +} + /** * Set the current matrix stack. * @@ -211,38 +266,21 @@ _mesa_MatrixMode( GLenum mode ) } } - -/** - * Push the current matrix stack. - * - * \sa glPushMatrix(). - * - * Verifies the current matrix stack is not full, and duplicates the top-most - * matrix in the stack. - * Marks __struct gl_contextRec::NewState with the stack dirty flag. - */ -void GLAPIENTRY -_mesa_PushMatrix( void ) +static void +push_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, + GLenum matrixMode, const char *func) { - GET_CURRENT_CONTEXT(ctx); - struct gl_matrix_stack *stack = ctx->CurrentStack; - - if (MESA_VERBOSE&VERBOSE_API) - _mesa_debug(ctx, "glPushMatrix %s\n", - _mesa_enum_to_string(ctx->Transform.MatrixMode)); - if (stack->Depth + 1 >= stack->MaxDepth) { if (ctx->Transform.MatrixMode == GL_TEXTURE) { - _mesa_error(ctx, GL_STACK_OVERFLOW, - "glPushMatrix(mode=GL_TEXTURE, unit=%d)", - ctx->Texture.CurrentUnit); - } - else { - _mesa_error(ctx, GL_STACK_OVERFLOW, "glPushMatrix(mode=%s)", - _mesa_enum_to_string(ctx->Transform.MatrixMode)); + _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=GL_TEXTURE, unit=%d)", + func, ctx->Texture.CurrentUnit); + } else { + _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=%s)", + func, _mesa_enum_to_string(matrixMode)); } return; } + if (stack->Depth + 1 >= stack->StackSize) { unsigned new_stack_size = stack->StackSize * 2; unsigned i; @@ -250,7 +288,7 @@ _mesa_PushMatrix( void ) sizeof(*new_stack) * new_stack_size); if (!new_stack) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glPushMatrix()"); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } @@ -268,12 +306,60 @@ _mesa_PushMatrix( void ) ctx->NewState |= stack->DirtyFlag; } +/** + * Push the current matrix stack. + * + * \sa glPushMatrix(). + * + * Verifies the current matrix stack is not full, and duplicates the top-most + * matrix in the stack. + * Marks __struct gl_contextRec::NewState with the stack dirty flag. + */ +void GLAPIENTRY +_mesa_PushMatrix( void ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = ctx->CurrentStack; + + if (MESA_VERBOSE&VERBOSE_API) + _mesa_debug(ctx, "glPushMatrix %s\n", + _mesa_enum_to_string(ctx->Transform.MatrixMode)); + + push_matrix(ctx, stack, ctx->Transform.MatrixMode, "glPushMatrix"); +} + +void GLAPIENTRY +_mesa_MatrixPushEXT( GLenum matrixMode ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode); + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMatrixPushEXT(mode)"); + return; + } + + push_matrix(ctx, stack, matrixMode, "glMatrixPushEXT"); +} + +static GLboolean +pop_matrix( struct gl_context *ctx, struct gl_matrix_stack *stack ) +{ + if (stack->Depth == 0) + return GL_FALSE; + + stack->Depth--; + stack->Top = &(stack->Stack[stack->Depth]); + ctx->NewState |= stack->DirtyFlag; + return GL_TRUE; +} /** * Pop the current matrix stack. * * \sa glPopMatrix(). - * + * * Flushes the vertices, verifies the current matrix stack is not empty, and * moves the stack head down. * Marks __struct gl_contextRec::NewState with the dirty stack flag. @@ -290,21 +376,41 @@ _mesa_PopMatrix( void ) _mesa_debug(ctx, "glPopMatrix %s\n", _mesa_enum_to_string(ctx->Transform.MatrixMode)); - if (stack->Depth == 0) { + if (!pop_matrix(ctx, stack)) { if (ctx->Transform.MatrixMode == GL_TEXTURE) { - _mesa_error(ctx, GL_STACK_UNDERFLOW, + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=GL_TEXTURE, unit=%d)", ctx->Texture.CurrentUnit); } else { - _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)", + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)", _mesa_enum_to_string(ctx->Transform.MatrixMode)); } + } +} + +void GLAPIENTRY +_mesa_MatrixPopEXT( GLenum matrixMode ) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode); + + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, "glMatrixPopEXT(mode)"); return; } - stack->Depth--; - stack->Top = &(stack->Stack[stack->Depth]); - ctx->NewState |= stack->DirtyFlag; + + if (!pop_matrix(ctx, stack)) { + if (matrixMode == GL_TEXTURE) { + _mesa_error(ctx, GL_STACK_UNDERFLOW, + "glMatrixPopEXT(mode=GL_TEXTURE, unit=%d)", + ctx->Texture.CurrentUnit); + } + else { + _mesa_error(ctx, GL_STACK_UNDERFLOW, "glMatrixPopEXT(mode=%s)", + _mesa_enum_to_string(matrixMode)); + } + } } @@ -331,6 +437,24 @@ _mesa_LoadIdentity( void ) ctx->NewState |= ctx->CurrentStack->DirtyFlag; } +void GLAPIENTRY +_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + stack = get_named_matrix_stack(ctx, matrixMode); + + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixLoadIdentityEXT(mode)\n"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_set_identity( stack->Top ); + ctx->NewState |= stack->DirtyFlag; +} + /** * Replace the current matrix with a given matrix. @@ -364,6 +488,33 @@ _mesa_LoadMatrixf( const GLfloat *m ) } +/** + * Replace the named matrix with a given matrix. + * + * \param matrixMode matrix to replace + * \param m matrix + * + * \sa glLoadMatrixf(). + */ +void GLAPIENTRY +_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + if (!m) return; + + stack = get_named_matrix_stack(ctx, matrixMode); + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixLoadfEXT(matrixMode)"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_loadf(stack->Top, m); + ctx->NewState |= stack->DirtyFlag; +} + /** * Multiply the current matrix with a given matrix. * @@ -393,6 +544,24 @@ _mesa_MultMatrixf( const GLfloat *m ) ctx->NewState |= ctx->CurrentStack->DirtyFlag; } +void GLAPIENTRY +_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + if (!m) return; + + stack = get_named_matrix_stack(ctx, matrixMode); + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixMultfEXT(matrixMode)"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_mul_floats(stack->Top, m); + ctx->NewState |= stack->DirtyFlag; +} /** * Multiply the current matrix with a rotation matrix. @@ -420,6 +589,25 @@ _mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) } } +void GLAPIENTRY +_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + if (angle == 0.0f) return; + + stack = get_named_matrix_stack(ctx, matrixMode); + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixRotatefEXT(matrixMode)"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_rotate(stack->Top, angle, x, y, z); + ctx->NewState |= stack->DirtyFlag; +} + /** * Multiply the current matrix with a general scaling matrix. @@ -444,6 +632,24 @@ _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) ctx->NewState |= ctx->CurrentStack->DirtyFlag; } +void GLAPIENTRY +_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + + stack = get_named_matrix_stack(ctx, matrixMode); + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixScalefEXT(matrixMode)"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_scale(stack->Top, x, y, z); + ctx->NewState |= stack->DirtyFlag; +} + /** * Multiply the current matrix with a translation matrix. @@ -468,7 +674,25 @@ _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) ctx->NewState |= ctx->CurrentStack->DirtyFlag; } - +void GLAPIENTRY +_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) +{ + struct gl_matrix_stack *stack; + GET_CURRENT_CONTEXT(ctx); + + stack = get_named_matrix_stack(ctx, matrixMode); + if (!stack) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glMatrixTranslatefEXT(matrixMode)"); + return; + } + + FLUSH_VERTICES(ctx, 0); + _math_matrix_translate(stack->Top, x, y, z); + ctx->NewState |= stack->DirtyFlag; +} + + void GLAPIENTRY _mesa_LoadMatrixd( const GLdouble *m ) { @@ -480,6 +704,17 @@ _mesa_LoadMatrixd( const GLdouble *m ) _mesa_LoadMatrixf(f); } +void GLAPIENTRY +_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLint i; + GLfloat f[16]; + if (!m) return; + for (i = 0; i < 16; i++) + f[i] = (GLfloat) m[i]; + _mesa_MatrixLoadfEXT(matrixMode, f); +} + void GLAPIENTRY _mesa_MultMatrixd( const GLdouble *m ) { @@ -491,6 +726,16 @@ _mesa_MultMatrixd( const GLdouble *m ) _mesa_MultMatrixf( f ); } +void GLAPIENTRY +_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ) +{ + GLint i; + GLfloat f[16]; + if (!m) return; + for (i = 0; i < 16; i++) + f[i] = (GLfloat) m[i]; + _mesa_MatrixMultfEXT(matrixMode, f); +} void GLAPIENTRY _mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) @@ -498,6 +743,14 @@ _mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) _mesa_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); } +void GLAPIENTRY +_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, + GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixRotatefEXT(matrixMode, (GLfloat) angle, + (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + void GLAPIENTRY _mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) @@ -505,6 +758,12 @@ _mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) _mesa_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z); } +void GLAPIENTRY +_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} + void GLAPIENTRY _mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) @@ -512,6 +771,11 @@ _mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) _mesa_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z); } +void GLAPIENTRY +_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) +{ + _mesa_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); +} void GLAPIENTRY _mesa_LoadTransposeMatrixf( const GLfloat *m ) @@ -566,7 +830,7 @@ _mesa_MultTransposeMatrixd( const GLdouble *m ) * * Calls _math_matrix_analyse() with the top-matrix of the projection matrix * stack, and recomputes user clip positions if necessary. - * + * * \note This routine references __struct gl_contextRec::Tranform attribute * values to compute userclip positions in clip space, but is only called on * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values up to @@ -652,7 +916,7 @@ void _mesa_update_modelview_project( struct gl_context *ctx, GLuint new_state ) * \param stack matrix stack. * \param maxDepth maximum stack depth. * \param dirtyFlag dirty flag. - * + * * Allocates an array of \p maxDepth elements for the matrix stack and calls * _math_matrix_ctr() for each element to initialize it. */ @@ -676,9 +940,9 @@ init_matrix_stack( struct gl_matrix_stack *stack, /** * Free matrix stack. - * + * * \param stack matrix stack. - * + * * Calls _math_matrix_dtr() for each element of the matrix stack and * frees the array. */ @@ -734,7 +998,7 @@ void _mesa_init_matrix( struct gl_context * ctx ) /** * Free the context matrix data. - * + * * \param ctx GL context. * * Frees each of the matrix stacks and the combined modelview-projection @@ -756,7 +1020,7 @@ void _mesa_free_matrix_data( struct gl_context *ctx ) } -/** +/** * Initialize the context transform attribute group. * * \param ctx GL context. diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h index 8eee67ca386..78f4cb5a6dc 100644 --- a/src/mesa/main/matrix.h +++ b/src/mesa/main/matrix.h @@ -96,6 +96,52 @@ _mesa_MultTransposeMatrixf( const GLfloat *m ); extern void GLAPIENTRY _mesa_MultTransposeMatrixd( const GLdouble *m ); +extern void GLAPIENTRY +_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ); + +extern void GLAPIENTRY +_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ); + +extern void GLAPIENTRY +_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ); + +extern void GLAPIENTRY +_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ); + +extern void GLAPIENTRY +_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ); + +extern void GLAPIENTRY +_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); + +extern void GLAPIENTRY +_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); + +extern void GLAPIENTRY +_mesa_MatrixOrthoEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, + GLdouble n, GLdouble f ); + +extern void GLAPIENTRY +_mesa_MatrixFrustumEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, + GLdouble n, GLdouble f ); + +extern void GLAPIENTRY +_mesa_MatrixPushEXT( GLenum matrixMode ); + +extern void GLAPIENTRY +_mesa_MatrixPopEXT( GLenum matrixMode ); extern void _mesa_init_matrix( struct gl_context * ctx ); -- 2.17.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev