1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 6bf215546Sopenharmony_ci * 7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 16bf215546Sopenharmony_ci * 17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 24bf215546Sopenharmony_ci */ 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci 27bf215546Sopenharmony_ci/** 28bf215546Sopenharmony_ci * \file matrix.c 29bf215546Sopenharmony_ci * Matrix operations. 30bf215546Sopenharmony_ci * 31bf215546Sopenharmony_ci * \note 32bf215546Sopenharmony_ci * -# 4x4 transformation matrices are stored in memory in column major order. 33bf215546Sopenharmony_ci * -# Points/vertices are to be thought of as column vectors. 34bf215546Sopenharmony_ci * -# Transformation of a point p by a matrix M is: p' = M * p 35bf215546Sopenharmony_ci */ 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci 38bf215546Sopenharmony_ci#include "glheader.h" 39bf215546Sopenharmony_ci 40bf215546Sopenharmony_ci#include "context.h" 41bf215546Sopenharmony_ci#include "enums.h" 42bf215546Sopenharmony_ci#include "macros.h" 43bf215546Sopenharmony_ci#include "matrix.h" 44bf215546Sopenharmony_ci#include "mtypes.h" 45bf215546Sopenharmony_ci#include "math/m_matrix.h" 46bf215546Sopenharmony_ci#include "util/bitscan.h" 47bf215546Sopenharmony_ci#include "api_exec_decl.h" 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci 50bf215546Sopenharmony_cistatic struct gl_matrix_stack * 51bf215546Sopenharmony_ciget_named_matrix_stack(struct gl_context *ctx, GLenum mode, const char* caller) 52bf215546Sopenharmony_ci{ 53bf215546Sopenharmony_ci switch (mode) { 54bf215546Sopenharmony_ci case GL_MODELVIEW: 55bf215546Sopenharmony_ci return &ctx->ModelviewMatrixStack; 56bf215546Sopenharmony_ci case GL_PROJECTION: 57bf215546Sopenharmony_ci return &ctx->ProjectionMatrixStack; 58bf215546Sopenharmony_ci case GL_TEXTURE: 59bf215546Sopenharmony_ci /* This error check is disabled because if we're called from 60bf215546Sopenharmony_ci * glPopAttrib() when the active texture unit is >= MaxTextureCoordUnits 61bf215546Sopenharmony_ci * we'll generate an unexpected error. 62bf215546Sopenharmony_ci * From the GL_ARB_vertex_shader spec it sounds like we should instead 63bf215546Sopenharmony_ci * do error checking in other places when we actually try to access 64bf215546Sopenharmony_ci * texture matrices beyond MaxTextureCoordUnits. 65bf215546Sopenharmony_ci */ 66bf215546Sopenharmony_ci#if 0 67bf215546Sopenharmony_ci if (ctx->Texture.CurrentUnit >= ctx->Const.MaxTextureCoordUnits) { 68bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_OPERATION, 69bf215546Sopenharmony_ci "glMatrixMode(invalid tex unit %d)", 70bf215546Sopenharmony_ci ctx->Texture.CurrentUnit); 71bf215546Sopenharmony_ci return; 72bf215546Sopenharmony_ci } 73bf215546Sopenharmony_ci#endif 74bf215546Sopenharmony_ci assert(ctx->Texture.CurrentUnit < ARRAY_SIZE(ctx->TextureMatrixStack)); 75bf215546Sopenharmony_ci return &ctx->TextureMatrixStack[ctx->Texture.CurrentUnit]; 76bf215546Sopenharmony_ci case GL_MATRIX0_ARB: 77bf215546Sopenharmony_ci case GL_MATRIX1_ARB: 78bf215546Sopenharmony_ci case GL_MATRIX2_ARB: 79bf215546Sopenharmony_ci case GL_MATRIX3_ARB: 80bf215546Sopenharmony_ci case GL_MATRIX4_ARB: 81bf215546Sopenharmony_ci case GL_MATRIX5_ARB: 82bf215546Sopenharmony_ci case GL_MATRIX6_ARB: 83bf215546Sopenharmony_ci case GL_MATRIX7_ARB: 84bf215546Sopenharmony_ci if (ctx->API == API_OPENGL_COMPAT 85bf215546Sopenharmony_ci && (ctx->Extensions.ARB_vertex_program || 86bf215546Sopenharmony_ci ctx->Extensions.ARB_fragment_program)) { 87bf215546Sopenharmony_ci const GLuint m = mode - GL_MATRIX0_ARB; 88bf215546Sopenharmony_ci if (m <= ctx->Const.MaxProgramMatrices) 89bf215546Sopenharmony_ci return &ctx->ProgramMatrixStack[m]; 90bf215546Sopenharmony_ci } 91bf215546Sopenharmony_ci FALLTHROUGH; 92bf215546Sopenharmony_ci default: 93bf215546Sopenharmony_ci break; 94bf215546Sopenharmony_ci } 95bf215546Sopenharmony_ci if (mode >= GL_TEXTURE0 && mode < (GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits)) { 96bf215546Sopenharmony_ci return &ctx->TextureMatrixStack[mode - GL_TEXTURE0]; 97bf215546Sopenharmony_ci } 98bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_ENUM, "%s", caller); 99bf215546Sopenharmony_ci return NULL; 100bf215546Sopenharmony_ci} 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci 103bf215546Sopenharmony_cistatic void matrix_frustum(struct gl_matrix_stack* stack, 104bf215546Sopenharmony_ci GLdouble left, GLdouble right, 105bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 106bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval, 107bf215546Sopenharmony_ci const char* caller) 108bf215546Sopenharmony_ci{ 109bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 110bf215546Sopenharmony_ci if (nearval <= 0.0 || 111bf215546Sopenharmony_ci farval <= 0.0 || 112bf215546Sopenharmony_ci nearval == farval || 113bf215546Sopenharmony_ci left == right || 114bf215546Sopenharmony_ci top == bottom) { 115bf215546Sopenharmony_ci _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); 116bf215546Sopenharmony_ci return; 117bf215546Sopenharmony_ci } 118bf215546Sopenharmony_ci 119bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci _math_matrix_frustum(stack->Top, 122bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 123bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 124bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval); 125bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 126bf215546Sopenharmony_ci} 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci 129bf215546Sopenharmony_ci/** 130bf215546Sopenharmony_ci * Apply a perspective projection matrix. 131bf215546Sopenharmony_ci * 132bf215546Sopenharmony_ci * \param left left clipping plane coordinate. 133bf215546Sopenharmony_ci * \param right right clipping plane coordinate. 134bf215546Sopenharmony_ci * \param bottom bottom clipping plane coordinate. 135bf215546Sopenharmony_ci * \param top top clipping plane coordinate. 136bf215546Sopenharmony_ci * \param nearval distance to the near clipping plane. 137bf215546Sopenharmony_ci * \param farval distance to the far clipping plane. 138bf215546Sopenharmony_ci * 139bf215546Sopenharmony_ci * \sa glFrustum(). 140bf215546Sopenharmony_ci * 141bf215546Sopenharmony_ci * Flushes vertices and validates parameters. Calls _math_matrix_frustum() with 142bf215546Sopenharmony_ci * the top matrix of the current matrix stack and sets 143bf215546Sopenharmony_ci * __struct gl_contextRec::NewState. 144bf215546Sopenharmony_ci */ 145bf215546Sopenharmony_civoid GLAPIENTRY 146bf215546Sopenharmony_ci_mesa_Frustum( GLdouble left, GLdouble right, 147bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 148bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval ) 149bf215546Sopenharmony_ci{ 150bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 151bf215546Sopenharmony_ci matrix_frustum(ctx->CurrentStack, 152bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 153bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 154bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval, 155bf215546Sopenharmony_ci "glFrustum"); 156bf215546Sopenharmony_ci} 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci 159bf215546Sopenharmony_civoid GLAPIENTRY 160bf215546Sopenharmony_ci_mesa_MatrixFrustumEXT( GLenum matrixMode, 161bf215546Sopenharmony_ci GLdouble left, GLdouble right, 162bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 163bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval ) 164bf215546Sopenharmony_ci{ 165bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 166bf215546Sopenharmony_ci struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, 167bf215546Sopenharmony_ci "glMatrixFrustumEXT"); 168bf215546Sopenharmony_ci if (!stack) 169bf215546Sopenharmony_ci return; 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ci matrix_frustum(stack, 172bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 173bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 174bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval, 175bf215546Sopenharmony_ci "glMatrixFrustumEXT"); 176bf215546Sopenharmony_ci} 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci 179bf215546Sopenharmony_cistatic void 180bf215546Sopenharmony_cimatrix_ortho(struct gl_matrix_stack* stack, 181bf215546Sopenharmony_ci GLdouble left, GLdouble right, 182bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 183bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval, 184bf215546Sopenharmony_ci const char* caller) 185bf215546Sopenharmony_ci{ 186bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 187bf215546Sopenharmony_ci 188bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 189bf215546Sopenharmony_ci _mesa_debug(ctx, "%s(%f, %f, %f, %f, %f, %f)\n", caller, 190bf215546Sopenharmony_ci left, right, bottom, top, nearval, farval); 191bf215546Sopenharmony_ci 192bf215546Sopenharmony_ci if (left == right || 193bf215546Sopenharmony_ci bottom == top || 194bf215546Sopenharmony_ci nearval == farval) 195bf215546Sopenharmony_ci { 196bf215546Sopenharmony_ci _mesa_error( ctx, GL_INVALID_VALUE, "%s", caller ); 197bf215546Sopenharmony_ci return; 198bf215546Sopenharmony_ci } 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ci _math_matrix_ortho( stack->Top, 203bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 204bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 205bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval ); 206bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 207bf215546Sopenharmony_ci} 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci 210bf215546Sopenharmony_ci/** 211bf215546Sopenharmony_ci * Apply an orthographic projection matrix. 212bf215546Sopenharmony_ci * 213bf215546Sopenharmony_ci * \param left left clipping plane coordinate. 214bf215546Sopenharmony_ci * \param right right clipping plane coordinate. 215bf215546Sopenharmony_ci * \param bottom bottom clipping plane coordinate. 216bf215546Sopenharmony_ci * \param top top clipping plane coordinate. 217bf215546Sopenharmony_ci * \param nearval distance to the near clipping plane. 218bf215546Sopenharmony_ci * \param farval distance to the far clipping plane. 219bf215546Sopenharmony_ci * 220bf215546Sopenharmony_ci * \sa glOrtho(). 221bf215546Sopenharmony_ci * 222bf215546Sopenharmony_ci * Flushes vertices and validates parameters. Calls _math_matrix_ortho() with 223bf215546Sopenharmony_ci * the top matrix of the current matrix stack and sets 224bf215546Sopenharmony_ci * __struct gl_contextRec::NewState. 225bf215546Sopenharmony_ci */ 226bf215546Sopenharmony_civoid GLAPIENTRY 227bf215546Sopenharmony_ci_mesa_Ortho( GLdouble left, GLdouble right, 228bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 229bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval ) 230bf215546Sopenharmony_ci{ 231bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 232bf215546Sopenharmony_ci matrix_ortho(ctx->CurrentStack, 233bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 234bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 235bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval, 236bf215546Sopenharmony_ci "glOrtho"); 237bf215546Sopenharmony_ci} 238bf215546Sopenharmony_ci 239bf215546Sopenharmony_ci 240bf215546Sopenharmony_civoid GLAPIENTRY 241bf215546Sopenharmony_ci_mesa_MatrixOrthoEXT( GLenum matrixMode, 242bf215546Sopenharmony_ci GLdouble left, GLdouble right, 243bf215546Sopenharmony_ci GLdouble bottom, GLdouble top, 244bf215546Sopenharmony_ci GLdouble nearval, GLdouble farval ) 245bf215546Sopenharmony_ci{ 246bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 247bf215546Sopenharmony_ci struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, 248bf215546Sopenharmony_ci "glMatrixOrthoEXT"); 249bf215546Sopenharmony_ci if (!stack) 250bf215546Sopenharmony_ci return; 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci matrix_ortho(stack, 253bf215546Sopenharmony_ci (GLfloat) left, (GLfloat) right, 254bf215546Sopenharmony_ci (GLfloat) bottom, (GLfloat) top, 255bf215546Sopenharmony_ci (GLfloat) nearval, (GLfloat) farval, 256bf215546Sopenharmony_ci "glMatrixOrthoEXT"); 257bf215546Sopenharmony_ci} 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci 260bf215546Sopenharmony_ci/** 261bf215546Sopenharmony_ci * Set the current matrix stack. 262bf215546Sopenharmony_ci * 263bf215546Sopenharmony_ci * \param mode matrix stack. 264bf215546Sopenharmony_ci * 265bf215546Sopenharmony_ci * \sa glMatrixMode(). 266bf215546Sopenharmony_ci * 267bf215546Sopenharmony_ci * Flushes the vertices, validates the parameter and updates 268bf215546Sopenharmony_ci * __struct gl_contextRec::CurrentStack and gl_transform_attrib::MatrixMode 269bf215546Sopenharmony_ci * with the specified matrix stack. 270bf215546Sopenharmony_ci */ 271bf215546Sopenharmony_civoid GLAPIENTRY 272bf215546Sopenharmony_ci_mesa_MatrixMode( GLenum mode ) 273bf215546Sopenharmony_ci{ 274bf215546Sopenharmony_ci struct gl_matrix_stack * stack; 275bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci if (ctx->Transform.MatrixMode == mode && mode != GL_TEXTURE) 278bf215546Sopenharmony_ci return; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci if (mode >= GL_TEXTURE0 && mode < (GL_TEXTURE0 + ctx->Const.MaxTextureCoordUnits)) { 281bf215546Sopenharmony_ci stack = NULL; 282bf215546Sopenharmony_ci } else { 283bf215546Sopenharmony_ci stack = get_named_matrix_stack(ctx, mode, "glMatrixMode"); 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci if (stack) { 287bf215546Sopenharmony_ci ctx->CurrentStack = stack; 288bf215546Sopenharmony_ci ctx->Transform.MatrixMode = mode; 289bf215546Sopenharmony_ci ctx->PopAttribState |= GL_TRANSFORM_BIT; 290bf215546Sopenharmony_ci } 291bf215546Sopenharmony_ci} 292bf215546Sopenharmony_ci 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_cistatic void 295bf215546Sopenharmony_cipush_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, 296bf215546Sopenharmony_ci GLenum matrixMode, const char *func) 297bf215546Sopenharmony_ci{ 298bf215546Sopenharmony_ci if (stack->Depth + 1 >= stack->MaxDepth) { 299bf215546Sopenharmony_ci if (ctx->Transform.MatrixMode == GL_TEXTURE) { 300bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=GL_TEXTURE, unit=%d)", 301bf215546Sopenharmony_ci func, ctx->Texture.CurrentUnit); 302bf215546Sopenharmony_ci } else { 303bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_OVERFLOW, "%s(mode=%s)", 304bf215546Sopenharmony_ci func, _mesa_enum_to_string(matrixMode)); 305bf215546Sopenharmony_ci } 306bf215546Sopenharmony_ci return; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci 309bf215546Sopenharmony_ci if (stack->Depth + 1 >= stack->StackSize) { 310bf215546Sopenharmony_ci unsigned new_stack_size = stack->StackSize * 2; 311bf215546Sopenharmony_ci unsigned i; 312bf215546Sopenharmony_ci GLmatrix *new_stack = realloc(stack->Stack, 313bf215546Sopenharmony_ci sizeof(*new_stack) * new_stack_size); 314bf215546Sopenharmony_ci 315bf215546Sopenharmony_ci if (!new_stack) { 316bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); 317bf215546Sopenharmony_ci return; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci 320bf215546Sopenharmony_ci for (i = stack->StackSize; i < new_stack_size; i++) 321bf215546Sopenharmony_ci _math_matrix_ctr(&new_stack[i]); 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci stack->Stack = new_stack; 324bf215546Sopenharmony_ci stack->StackSize = new_stack_size; 325bf215546Sopenharmony_ci } 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ci _math_matrix_push_copy(&stack->Stack[stack->Depth + 1], 328bf215546Sopenharmony_ci &stack->Stack[stack->Depth]); 329bf215546Sopenharmony_ci stack->Depth++; 330bf215546Sopenharmony_ci stack->Top = &(stack->Stack[stack->Depth]); 331bf215546Sopenharmony_ci} 332bf215546Sopenharmony_ci 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci/** 335bf215546Sopenharmony_ci * Push the current matrix stack. 336bf215546Sopenharmony_ci * 337bf215546Sopenharmony_ci * \sa glPushMatrix(). 338bf215546Sopenharmony_ci * 339bf215546Sopenharmony_ci * Verifies the current matrix stack is not full, and duplicates the top-most 340bf215546Sopenharmony_ci * matrix in the stack. 341bf215546Sopenharmony_ci * Marks __struct gl_contextRec::NewState with the stack dirty flag. 342bf215546Sopenharmony_ci */ 343bf215546Sopenharmony_civoid GLAPIENTRY 344bf215546Sopenharmony_ci_mesa_PushMatrix( void ) 345bf215546Sopenharmony_ci{ 346bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 347bf215546Sopenharmony_ci struct gl_matrix_stack *stack = ctx->CurrentStack; 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci if (MESA_VERBOSE&VERBOSE_API) 350bf215546Sopenharmony_ci _mesa_debug(ctx, "glPushMatrix %s\n", 351bf215546Sopenharmony_ci _mesa_enum_to_string(ctx->Transform.MatrixMode)); 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci push_matrix(ctx, stack, ctx->Transform.MatrixMode, "glPushMatrix"); 354bf215546Sopenharmony_ci} 355bf215546Sopenharmony_ci 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_civoid GLAPIENTRY 358bf215546Sopenharmony_ci_mesa_MatrixPushEXT( GLenum matrixMode ) 359bf215546Sopenharmony_ci{ 360bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 361bf215546Sopenharmony_ci struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, 362bf215546Sopenharmony_ci "glMatrixPushEXT"); 363bf215546Sopenharmony_ci ASSERT_OUTSIDE_BEGIN_END(ctx); 364bf215546Sopenharmony_ci if (stack) 365bf215546Sopenharmony_ci push_matrix(ctx, stack, matrixMode, "glMatrixPushEXT"); 366bf215546Sopenharmony_ci} 367bf215546Sopenharmony_ci 368bf215546Sopenharmony_ci 369bf215546Sopenharmony_cistatic GLboolean 370bf215546Sopenharmony_cipop_matrix( struct gl_context *ctx, struct gl_matrix_stack *stack ) 371bf215546Sopenharmony_ci{ 372bf215546Sopenharmony_ci if (stack->Depth == 0) 373bf215546Sopenharmony_ci return GL_FALSE; 374bf215546Sopenharmony_ci 375bf215546Sopenharmony_ci stack->Depth--; 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci /* If the popped matrix is the same as the current one, treat it as 378bf215546Sopenharmony_ci * a no-op change. 379bf215546Sopenharmony_ci */ 380bf215546Sopenharmony_ci if (memcmp(stack->Top, &stack->Stack[stack->Depth], 381bf215546Sopenharmony_ci sizeof(GLmatrix))) { 382bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 383bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 384bf215546Sopenharmony_ci } 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci stack->Top = &(stack->Stack[stack->Depth]); 387bf215546Sopenharmony_ci return GL_TRUE; 388bf215546Sopenharmony_ci} 389bf215546Sopenharmony_ci 390bf215546Sopenharmony_ci 391bf215546Sopenharmony_ci/** 392bf215546Sopenharmony_ci * Pop the current matrix stack. 393bf215546Sopenharmony_ci * 394bf215546Sopenharmony_ci * \sa glPopMatrix(). 395bf215546Sopenharmony_ci * 396bf215546Sopenharmony_ci * Flushes the vertices, verifies the current matrix stack is not empty, and 397bf215546Sopenharmony_ci * moves the stack head down. 398bf215546Sopenharmony_ci * Marks __struct gl_contextRec::NewState with the dirty stack flag. 399bf215546Sopenharmony_ci */ 400bf215546Sopenharmony_civoid GLAPIENTRY 401bf215546Sopenharmony_ci_mesa_PopMatrix( void ) 402bf215546Sopenharmony_ci{ 403bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 404bf215546Sopenharmony_ci struct gl_matrix_stack *stack = ctx->CurrentStack; 405bf215546Sopenharmony_ci 406bf215546Sopenharmony_ci if (MESA_VERBOSE&VERBOSE_API) 407bf215546Sopenharmony_ci _mesa_debug(ctx, "glPopMatrix %s\n", 408bf215546Sopenharmony_ci _mesa_enum_to_string(ctx->Transform.MatrixMode)); 409bf215546Sopenharmony_ci 410bf215546Sopenharmony_ci if (!pop_matrix(ctx, stack)) { 411bf215546Sopenharmony_ci if (ctx->Transform.MatrixMode == GL_TEXTURE) { 412bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, 413bf215546Sopenharmony_ci "glPopMatrix(mode=GL_TEXTURE, unit=%d)", 414bf215546Sopenharmony_ci ctx->Texture.CurrentUnit); 415bf215546Sopenharmony_ci } 416bf215546Sopenharmony_ci else { 417bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, "glPopMatrix(mode=%s)", 418bf215546Sopenharmony_ci _mesa_enum_to_string(ctx->Transform.MatrixMode)); 419bf215546Sopenharmony_ci } 420bf215546Sopenharmony_ci } 421bf215546Sopenharmony_ci} 422bf215546Sopenharmony_ci 423bf215546Sopenharmony_ci 424bf215546Sopenharmony_civoid GLAPIENTRY 425bf215546Sopenharmony_ci_mesa_MatrixPopEXT( GLenum matrixMode ) 426bf215546Sopenharmony_ci{ 427bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 428bf215546Sopenharmony_ci struct gl_matrix_stack *stack = get_named_matrix_stack(ctx, matrixMode, 429bf215546Sopenharmony_ci "glMatrixPopEXT"); 430bf215546Sopenharmony_ci if (!stack) 431bf215546Sopenharmony_ci return; 432bf215546Sopenharmony_ci 433bf215546Sopenharmony_ci if (!pop_matrix(ctx, stack)) { 434bf215546Sopenharmony_ci if (matrixMode == GL_TEXTURE) { 435bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, 436bf215546Sopenharmony_ci "glMatrixPopEXT(mode=GL_TEXTURE, unit=%d)", 437bf215546Sopenharmony_ci ctx->Texture.CurrentUnit); 438bf215546Sopenharmony_ci } 439bf215546Sopenharmony_ci else { 440bf215546Sopenharmony_ci _mesa_error(ctx, GL_STACK_UNDERFLOW, "glMatrixPopEXT(mode=%s)", 441bf215546Sopenharmony_ci _mesa_enum_to_string(matrixMode)); 442bf215546Sopenharmony_ci } 443bf215546Sopenharmony_ci } 444bf215546Sopenharmony_ci} 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ci 447bf215546Sopenharmony_civoid 448bf215546Sopenharmony_ci_mesa_load_identity_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack) 449bf215546Sopenharmony_ci{ 450bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci _math_matrix_set_identity(stack->Top); 453bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 454bf215546Sopenharmony_ci} 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_ci 457bf215546Sopenharmony_ci/** 458bf215546Sopenharmony_ci * Replace the current matrix with the identity matrix. 459bf215546Sopenharmony_ci * 460bf215546Sopenharmony_ci * \sa glLoadIdentity(). 461bf215546Sopenharmony_ci * 462bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_set_identity() with the 463bf215546Sopenharmony_ci * top-most matrix in the current stack. 464bf215546Sopenharmony_ci * Marks __struct gl_contextRec::NewState with the stack dirty flag. 465bf215546Sopenharmony_ci */ 466bf215546Sopenharmony_civoid GLAPIENTRY 467bf215546Sopenharmony_ci_mesa_LoadIdentity( void ) 468bf215546Sopenharmony_ci{ 469bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 470bf215546Sopenharmony_ci 471bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 472bf215546Sopenharmony_ci _mesa_debug(ctx, "glLoadIdentity()\n"); 473bf215546Sopenharmony_ci 474bf215546Sopenharmony_ci _mesa_load_identity_matrix(ctx, ctx->CurrentStack); 475bf215546Sopenharmony_ci} 476bf215546Sopenharmony_ci 477bf215546Sopenharmony_ci 478bf215546Sopenharmony_civoid GLAPIENTRY 479bf215546Sopenharmony_ci_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ) 480bf215546Sopenharmony_ci{ 481bf215546Sopenharmony_ci struct gl_matrix_stack *stack; 482bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 483bf215546Sopenharmony_ci stack = get_named_matrix_stack(ctx, matrixMode, "glMatrixLoadIdentityEXT"); 484bf215546Sopenharmony_ci if (!stack) 485bf215546Sopenharmony_ci return; 486bf215546Sopenharmony_ci 487bf215546Sopenharmony_ci _mesa_load_identity_matrix(ctx, stack); 488bf215546Sopenharmony_ci} 489bf215546Sopenharmony_ci 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_civoid 492bf215546Sopenharmony_ci_mesa_load_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, 493bf215546Sopenharmony_ci const GLfloat *m) 494bf215546Sopenharmony_ci{ 495bf215546Sopenharmony_ci if (memcmp(m, stack->Top->m, 16 * sizeof(GLfloat)) != 0) { 496bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 497bf215546Sopenharmony_ci _math_matrix_loadf(stack->Top, m); 498bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci} 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci 503bf215546Sopenharmony_cistatic void 504bf215546Sopenharmony_cimatrix_load(struct gl_context *ctx, struct gl_matrix_stack *stack, 505bf215546Sopenharmony_ci const GLfloat *m, const char* caller) 506bf215546Sopenharmony_ci{ 507bf215546Sopenharmony_ci if (!m) return; 508bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 509bf215546Sopenharmony_ci _mesa_debug(ctx, 510bf215546Sopenharmony_ci "%s(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", 511bf215546Sopenharmony_ci caller, 512bf215546Sopenharmony_ci m[0], m[4], m[8], m[12], 513bf215546Sopenharmony_ci m[1], m[5], m[9], m[13], 514bf215546Sopenharmony_ci m[2], m[6], m[10], m[14], 515bf215546Sopenharmony_ci m[3], m[7], m[11], m[15]); 516bf215546Sopenharmony_ci 517bf215546Sopenharmony_ci _mesa_load_matrix(ctx, stack, m); 518bf215546Sopenharmony_ci} 519bf215546Sopenharmony_ci 520bf215546Sopenharmony_ci 521bf215546Sopenharmony_ci/** 522bf215546Sopenharmony_ci * Replace the current matrix with a given matrix. 523bf215546Sopenharmony_ci * 524bf215546Sopenharmony_ci * \param m matrix. 525bf215546Sopenharmony_ci * 526bf215546Sopenharmony_ci * \sa glLoadMatrixf(). 527bf215546Sopenharmony_ci * 528bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_loadf() with the top-most 529bf215546Sopenharmony_ci * matrix in the current stack and the given matrix. 530bf215546Sopenharmony_ci * Marks __struct gl_contextRec::NewState with the dirty stack flag. 531bf215546Sopenharmony_ci */ 532bf215546Sopenharmony_civoid GLAPIENTRY 533bf215546Sopenharmony_ci_mesa_LoadMatrixf( const GLfloat *m ) 534bf215546Sopenharmony_ci{ 535bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 536bf215546Sopenharmony_ci matrix_load(ctx, ctx->CurrentStack, m, "glLoadMatrix"); 537bf215546Sopenharmony_ci} 538bf215546Sopenharmony_ci 539bf215546Sopenharmony_ci 540bf215546Sopenharmony_ci/** 541bf215546Sopenharmony_ci * Replace the named matrix with a given matrix. 542bf215546Sopenharmony_ci * 543bf215546Sopenharmony_ci * \param matrixMode matrix to replace 544bf215546Sopenharmony_ci * \param m matrix 545bf215546Sopenharmony_ci * 546bf215546Sopenharmony_ci * \sa glLoadMatrixf(). 547bf215546Sopenharmony_ci */ 548bf215546Sopenharmony_civoid GLAPIENTRY 549bf215546Sopenharmony_ci_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ) 550bf215546Sopenharmony_ci{ 551bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 552bf215546Sopenharmony_ci struct gl_matrix_stack * stack = 553bf215546Sopenharmony_ci get_named_matrix_stack(ctx, matrixMode, "glMatrixLoadfEXT"); 554bf215546Sopenharmony_ci if (!stack) 555bf215546Sopenharmony_ci return; 556bf215546Sopenharmony_ci 557bf215546Sopenharmony_ci matrix_load(ctx, stack, m, "glMatrixLoadfEXT"); 558bf215546Sopenharmony_ci} 559bf215546Sopenharmony_ci 560bf215546Sopenharmony_ci 561bf215546Sopenharmony_cistatic void 562bf215546Sopenharmony_cimatrix_mult(struct gl_matrix_stack *stack, const GLfloat *m, const char* caller) 563bf215546Sopenharmony_ci{ 564bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 565bf215546Sopenharmony_ci if (!m || 566bf215546Sopenharmony_ci (m[0] == 1 && m[1] == 0 && m[2] == 0 && m[3] == 0 && 567bf215546Sopenharmony_ci m[4] == 0 && m[5] == 1 && m[6] == 0 && m[7] == 0 && 568bf215546Sopenharmony_ci m[8] == 0 && m[9] == 0 && m[10] == 1 && m[11] == 0 && 569bf215546Sopenharmony_ci m[12] == 0 && m[13] == 0 && m[14] == 0 && m[15] == 1)) 570bf215546Sopenharmony_ci return; 571bf215546Sopenharmony_ci if (MESA_VERBOSE & VERBOSE_API) 572bf215546Sopenharmony_ci _mesa_debug(ctx, 573bf215546Sopenharmony_ci "%s(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", 574bf215546Sopenharmony_ci caller, 575bf215546Sopenharmony_ci m[0], m[4], m[8], m[12], 576bf215546Sopenharmony_ci m[1], m[5], m[9], m[13], 577bf215546Sopenharmony_ci m[2], m[6], m[10], m[14], 578bf215546Sopenharmony_ci m[3], m[7], m[11], m[15]); 579bf215546Sopenharmony_ci 580bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 581bf215546Sopenharmony_ci _math_matrix_mul_floats(stack->Top, m); 582bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 583bf215546Sopenharmony_ci} 584bf215546Sopenharmony_ci 585bf215546Sopenharmony_ci 586bf215546Sopenharmony_ci/** 587bf215546Sopenharmony_ci * Multiply the current matrix with a given matrix. 588bf215546Sopenharmony_ci * 589bf215546Sopenharmony_ci * \param m matrix. 590bf215546Sopenharmony_ci * 591bf215546Sopenharmony_ci * \sa glMultMatrixf(). 592bf215546Sopenharmony_ci * 593bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_mul_floats() with the top-most 594bf215546Sopenharmony_ci * matrix in the current stack and the given matrix. Marks 595bf215546Sopenharmony_ci * __struct gl_contextRec::NewState with the dirty stack flag. 596bf215546Sopenharmony_ci */ 597bf215546Sopenharmony_civoid GLAPIENTRY 598bf215546Sopenharmony_ci_mesa_MultMatrixf( const GLfloat *m ) 599bf215546Sopenharmony_ci{ 600bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 601bf215546Sopenharmony_ci matrix_mult(ctx->CurrentStack, m, "glMultMatrix"); 602bf215546Sopenharmony_ci} 603bf215546Sopenharmony_ci 604bf215546Sopenharmony_ci 605bf215546Sopenharmony_civoid GLAPIENTRY 606bf215546Sopenharmony_ci_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ) 607bf215546Sopenharmony_ci{ 608bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 609bf215546Sopenharmony_ci struct gl_matrix_stack * stack = 610bf215546Sopenharmony_ci get_named_matrix_stack(ctx, matrixMode, "glMatrixMultfEXT"); 611bf215546Sopenharmony_ci if (!stack) 612bf215546Sopenharmony_ci return; 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci matrix_mult(stack, m, "glMultMatrix"); 615bf215546Sopenharmony_ci} 616bf215546Sopenharmony_ci 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_cistatic void 619bf215546Sopenharmony_cimatrix_rotate(struct gl_matrix_stack *stack, GLfloat angle, 620bf215546Sopenharmony_ci GLfloat x, GLfloat y, GLfloat z, const char* caller) 621bf215546Sopenharmony_ci{ 622bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 625bf215546Sopenharmony_ci if (angle != 0.0F) { 626bf215546Sopenharmony_ci _math_matrix_rotate(stack->Top, angle, x, y, z); 627bf215546Sopenharmony_ci ctx->NewState |=stack->DirtyFlag; 628bf215546Sopenharmony_ci } 629bf215546Sopenharmony_ci} 630bf215546Sopenharmony_ci 631bf215546Sopenharmony_ci 632bf215546Sopenharmony_ci/** 633bf215546Sopenharmony_ci * Multiply the current matrix with a rotation matrix. 634bf215546Sopenharmony_ci * 635bf215546Sopenharmony_ci * \param angle angle of rotation, in degrees. 636bf215546Sopenharmony_ci * \param x rotation vector x coordinate. 637bf215546Sopenharmony_ci * \param y rotation vector y coordinate. 638bf215546Sopenharmony_ci * \param z rotation vector z coordinate. 639bf215546Sopenharmony_ci * 640bf215546Sopenharmony_ci * \sa glRotatef(). 641bf215546Sopenharmony_ci * 642bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_rotate() with the top-most 643bf215546Sopenharmony_ci * matrix in the current stack and the given parameters. Marks 644bf215546Sopenharmony_ci * __struct gl_contextRec::NewState with the dirty stack flag. 645bf215546Sopenharmony_ci */ 646bf215546Sopenharmony_civoid GLAPIENTRY 647bf215546Sopenharmony_ci_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) 648bf215546Sopenharmony_ci{ 649bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 650bf215546Sopenharmony_ci matrix_rotate(ctx->CurrentStack, angle, x, y, z, "glRotatef"); 651bf215546Sopenharmony_ci} 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_civoid GLAPIENTRY 655bf215546Sopenharmony_ci_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) 656bf215546Sopenharmony_ci{ 657bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 658bf215546Sopenharmony_ci struct gl_matrix_stack *stack = 659bf215546Sopenharmony_ci get_named_matrix_stack(ctx, matrixMode, "glMatrixRotatefEXT"); 660bf215546Sopenharmony_ci if (!stack) 661bf215546Sopenharmony_ci return; 662bf215546Sopenharmony_ci 663bf215546Sopenharmony_ci matrix_rotate(stack, angle, x, y, z, "glMatrixRotatefEXT"); 664bf215546Sopenharmony_ci} 665bf215546Sopenharmony_ci 666bf215546Sopenharmony_ci 667bf215546Sopenharmony_ci/** 668bf215546Sopenharmony_ci * Multiply the current matrix with a general scaling matrix. 669bf215546Sopenharmony_ci * 670bf215546Sopenharmony_ci * \param x x axis scale factor. 671bf215546Sopenharmony_ci * \param y y axis scale factor. 672bf215546Sopenharmony_ci * \param z z axis scale factor. 673bf215546Sopenharmony_ci * 674bf215546Sopenharmony_ci * \sa glScalef(). 675bf215546Sopenharmony_ci * 676bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_scale() with the top-most 677bf215546Sopenharmony_ci * matrix in the current stack and the given parameters. Marks 678bf215546Sopenharmony_ci * __struct gl_contextRec::NewState with the dirty stack flag. 679bf215546Sopenharmony_ci */ 680bf215546Sopenharmony_civoid GLAPIENTRY 681bf215546Sopenharmony_ci_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) 682bf215546Sopenharmony_ci{ 683bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 684bf215546Sopenharmony_ci 685bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 686bf215546Sopenharmony_ci _math_matrix_scale( ctx->CurrentStack->Top, x, y, z); 687bf215546Sopenharmony_ci ctx->NewState |= ctx->CurrentStack->DirtyFlag; 688bf215546Sopenharmony_ci} 689bf215546Sopenharmony_ci 690bf215546Sopenharmony_ci 691bf215546Sopenharmony_civoid GLAPIENTRY 692bf215546Sopenharmony_ci_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) 693bf215546Sopenharmony_ci{ 694bf215546Sopenharmony_ci struct gl_matrix_stack *stack; 695bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 696bf215546Sopenharmony_ci 697bf215546Sopenharmony_ci stack = get_named_matrix_stack(ctx, matrixMode, "glMatrixScalefEXT"); 698bf215546Sopenharmony_ci if (!stack) 699bf215546Sopenharmony_ci return; 700bf215546Sopenharmony_ci 701bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 702bf215546Sopenharmony_ci _math_matrix_scale(stack->Top, x, y, z); 703bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 704bf215546Sopenharmony_ci} 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci 707bf215546Sopenharmony_ci/** 708bf215546Sopenharmony_ci * Multiply the current matrix with a translation matrix. 709bf215546Sopenharmony_ci * 710bf215546Sopenharmony_ci * \param x translation vector x coordinate. 711bf215546Sopenharmony_ci * \param y translation vector y coordinate. 712bf215546Sopenharmony_ci * \param z translation vector z coordinate. 713bf215546Sopenharmony_ci * 714bf215546Sopenharmony_ci * \sa glTranslatef(). 715bf215546Sopenharmony_ci * 716bf215546Sopenharmony_ci * Flushes the vertices and calls _math_matrix_translate() with the top-most 717bf215546Sopenharmony_ci * matrix in the current stack and the given parameters. Marks 718bf215546Sopenharmony_ci * __struct gl_contextRec::NewState with the dirty stack flag. 719bf215546Sopenharmony_ci */ 720bf215546Sopenharmony_civoid GLAPIENTRY 721bf215546Sopenharmony_ci_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) 722bf215546Sopenharmony_ci{ 723bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 726bf215546Sopenharmony_ci _math_matrix_translate( ctx->CurrentStack->Top, x, y, z); 727bf215546Sopenharmony_ci ctx->NewState |= ctx->CurrentStack->DirtyFlag; 728bf215546Sopenharmony_ci} 729bf215546Sopenharmony_ci 730bf215546Sopenharmony_ci 731bf215546Sopenharmony_civoid GLAPIENTRY 732bf215546Sopenharmony_ci_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) 733bf215546Sopenharmony_ci{ 734bf215546Sopenharmony_ci GET_CURRENT_CONTEXT(ctx); 735bf215546Sopenharmony_ci struct gl_matrix_stack *stack = 736bf215546Sopenharmony_ci get_named_matrix_stack(ctx, matrixMode, "glMatrixTranslatefEXT"); 737bf215546Sopenharmony_ci if (!stack) 738bf215546Sopenharmony_ci return; 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci FLUSH_VERTICES(ctx, 0, 0); 741bf215546Sopenharmony_ci _math_matrix_translate(stack->Top, x, y, z); 742bf215546Sopenharmony_ci ctx->NewState |= stack->DirtyFlag; 743bf215546Sopenharmony_ci} 744bf215546Sopenharmony_ci 745bf215546Sopenharmony_ci 746bf215546Sopenharmony_civoid GLAPIENTRY 747bf215546Sopenharmony_ci_mesa_LoadMatrixd( const GLdouble *m ) 748bf215546Sopenharmony_ci{ 749bf215546Sopenharmony_ci GLint i; 750bf215546Sopenharmony_ci GLfloat f[16]; 751bf215546Sopenharmony_ci if (!m) return; 752bf215546Sopenharmony_ci for (i = 0; i < 16; i++) 753bf215546Sopenharmony_ci f[i] = (GLfloat) m[i]; 754bf215546Sopenharmony_ci _mesa_LoadMatrixf(f); 755bf215546Sopenharmony_ci} 756bf215546Sopenharmony_ci 757bf215546Sopenharmony_ci 758bf215546Sopenharmony_civoid GLAPIENTRY 759bf215546Sopenharmony_ci_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ) 760bf215546Sopenharmony_ci{ 761bf215546Sopenharmony_ci GLfloat f[16]; 762bf215546Sopenharmony_ci if (!m) return; 763bf215546Sopenharmony_ci for (unsigned i = 0; i < 16; i++) 764bf215546Sopenharmony_ci f[i] = (GLfloat) m[i]; 765bf215546Sopenharmony_ci _mesa_MatrixLoadfEXT(matrixMode, f); 766bf215546Sopenharmony_ci} 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci 769bf215546Sopenharmony_civoid GLAPIENTRY 770bf215546Sopenharmony_ci_mesa_MultMatrixd( const GLdouble *m ) 771bf215546Sopenharmony_ci{ 772bf215546Sopenharmony_ci GLint i; 773bf215546Sopenharmony_ci GLfloat f[16]; 774bf215546Sopenharmony_ci if (!m) return; 775bf215546Sopenharmony_ci for (i = 0; i < 16; i++) 776bf215546Sopenharmony_ci f[i] = (GLfloat) m[i]; 777bf215546Sopenharmony_ci _mesa_MultMatrixf( f ); 778bf215546Sopenharmony_ci} 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci 781bf215546Sopenharmony_civoid GLAPIENTRY 782bf215546Sopenharmony_ci_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ) 783bf215546Sopenharmony_ci{ 784bf215546Sopenharmony_ci GLfloat f[16]; 785bf215546Sopenharmony_ci if (!m) return; 786bf215546Sopenharmony_ci for (unsigned i = 0; i < 16; i++) 787bf215546Sopenharmony_ci f[i] = (GLfloat) m[i]; 788bf215546Sopenharmony_ci _mesa_MatrixMultfEXT(matrixMode, f); 789bf215546Sopenharmony_ci} 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_civoid GLAPIENTRY 793bf215546Sopenharmony_ci_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) 794bf215546Sopenharmony_ci{ 795bf215546Sopenharmony_ci _mesa_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); 796bf215546Sopenharmony_ci} 797bf215546Sopenharmony_ci 798bf215546Sopenharmony_ci 799bf215546Sopenharmony_civoid GLAPIENTRY 800bf215546Sopenharmony_ci_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, 801bf215546Sopenharmony_ci GLdouble x, GLdouble y, GLdouble z ) 802bf215546Sopenharmony_ci{ 803bf215546Sopenharmony_ci _mesa_MatrixRotatefEXT(matrixMode, (GLfloat) angle, 804bf215546Sopenharmony_ci (GLfloat) x, (GLfloat) y, (GLfloat) z); 805bf215546Sopenharmony_ci} 806bf215546Sopenharmony_ci 807bf215546Sopenharmony_ci 808bf215546Sopenharmony_civoid GLAPIENTRY 809bf215546Sopenharmony_ci_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ) 810bf215546Sopenharmony_ci{ 811bf215546Sopenharmony_ci _mesa_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z); 812bf215546Sopenharmony_ci} 813bf215546Sopenharmony_ci 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_civoid GLAPIENTRY 816bf215546Sopenharmony_ci_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) 817bf215546Sopenharmony_ci{ 818bf215546Sopenharmony_ci _mesa_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); 819bf215546Sopenharmony_ci} 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci 822bf215546Sopenharmony_civoid GLAPIENTRY 823bf215546Sopenharmony_ci_mesa_Translated( GLdouble x, GLdouble y, GLdouble z ) 824bf215546Sopenharmony_ci{ 825bf215546Sopenharmony_ci _mesa_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z); 826bf215546Sopenharmony_ci} 827bf215546Sopenharmony_ci 828bf215546Sopenharmony_ci 829bf215546Sopenharmony_civoid GLAPIENTRY 830bf215546Sopenharmony_ci_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ) 831bf215546Sopenharmony_ci{ 832bf215546Sopenharmony_ci _mesa_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); 833bf215546Sopenharmony_ci} 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci 836bf215546Sopenharmony_civoid GLAPIENTRY 837bf215546Sopenharmony_ci_mesa_LoadTransposeMatrixf( const GLfloat *m ) 838bf215546Sopenharmony_ci{ 839bf215546Sopenharmony_ci GLfloat tm[16]; 840bf215546Sopenharmony_ci if (!m) return; 841bf215546Sopenharmony_ci _math_transposef(tm, m); 842bf215546Sopenharmony_ci _mesa_LoadMatrixf(tm); 843bf215546Sopenharmony_ci} 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_civoid GLAPIENTRY 846bf215546Sopenharmony_ci_mesa_MatrixLoadTransposefEXT( GLenum matrixMode, const GLfloat *m ) 847bf215546Sopenharmony_ci{ 848bf215546Sopenharmony_ci GLfloat tm[16]; 849bf215546Sopenharmony_ci if (!m) return; 850bf215546Sopenharmony_ci _math_transposef(tm, m); 851bf215546Sopenharmony_ci _mesa_MatrixLoadfEXT(matrixMode, tm); 852bf215546Sopenharmony_ci} 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_civoid GLAPIENTRY 855bf215546Sopenharmony_ci_mesa_LoadTransposeMatrixd( const GLdouble *m ) 856bf215546Sopenharmony_ci{ 857bf215546Sopenharmony_ci GLfloat tm[16]; 858bf215546Sopenharmony_ci if (!m) return; 859bf215546Sopenharmony_ci _math_transposefd(tm, m); 860bf215546Sopenharmony_ci _mesa_LoadMatrixf(tm); 861bf215546Sopenharmony_ci} 862bf215546Sopenharmony_ci 863bf215546Sopenharmony_civoid GLAPIENTRY 864bf215546Sopenharmony_ci_mesa_MatrixLoadTransposedEXT( GLenum matrixMode, const GLdouble *m ) 865bf215546Sopenharmony_ci{ 866bf215546Sopenharmony_ci GLfloat tm[16]; 867bf215546Sopenharmony_ci if (!m) return; 868bf215546Sopenharmony_ci _math_transposefd(tm, m); 869bf215546Sopenharmony_ci _mesa_MatrixLoadfEXT(matrixMode, tm); 870bf215546Sopenharmony_ci} 871bf215546Sopenharmony_ci 872bf215546Sopenharmony_civoid GLAPIENTRY 873bf215546Sopenharmony_ci_mesa_MultTransposeMatrixf( const GLfloat *m ) 874bf215546Sopenharmony_ci{ 875bf215546Sopenharmony_ci GLfloat tm[16]; 876bf215546Sopenharmony_ci if (!m) return; 877bf215546Sopenharmony_ci _math_transposef(tm, m); 878bf215546Sopenharmony_ci _mesa_MultMatrixf(tm); 879bf215546Sopenharmony_ci} 880bf215546Sopenharmony_ci 881bf215546Sopenharmony_civoid GLAPIENTRY 882bf215546Sopenharmony_ci_mesa_MatrixMultTransposefEXT( GLenum matrixMode, const GLfloat *m ) 883bf215546Sopenharmony_ci{ 884bf215546Sopenharmony_ci GLfloat tm[16]; 885bf215546Sopenharmony_ci if (!m) return; 886bf215546Sopenharmony_ci _math_transposef(tm, m); 887bf215546Sopenharmony_ci _mesa_MatrixMultfEXT(matrixMode, tm); 888bf215546Sopenharmony_ci} 889bf215546Sopenharmony_ci 890bf215546Sopenharmony_civoid GLAPIENTRY 891bf215546Sopenharmony_ci_mesa_MultTransposeMatrixd( const GLdouble *m ) 892bf215546Sopenharmony_ci{ 893bf215546Sopenharmony_ci GLfloat tm[16]; 894bf215546Sopenharmony_ci if (!m) return; 895bf215546Sopenharmony_ci _math_transposefd(tm, m); 896bf215546Sopenharmony_ci _mesa_MultMatrixf(tm); 897bf215546Sopenharmony_ci} 898bf215546Sopenharmony_ci 899bf215546Sopenharmony_civoid GLAPIENTRY 900bf215546Sopenharmony_ci_mesa_MatrixMultTransposedEXT( GLenum matrixMode, const GLdouble *m ) 901bf215546Sopenharmony_ci{ 902bf215546Sopenharmony_ci GLfloat tm[16]; 903bf215546Sopenharmony_ci if (!m) return; 904bf215546Sopenharmony_ci _math_transposefd(tm, m); 905bf215546Sopenharmony_ci _mesa_MatrixMultfEXT(matrixMode, tm); 906bf215546Sopenharmony_ci} 907bf215546Sopenharmony_ci 908bf215546Sopenharmony_ci/**********************************************************************/ 909bf215546Sopenharmony_ci/** \name State management */ 910bf215546Sopenharmony_ci/*@{*/ 911bf215546Sopenharmony_ci 912bf215546Sopenharmony_ci 913bf215546Sopenharmony_ci/** 914bf215546Sopenharmony_ci * Update the projection matrix stack. 915bf215546Sopenharmony_ci * 916bf215546Sopenharmony_ci * \param ctx GL context. 917bf215546Sopenharmony_ci * 918bf215546Sopenharmony_ci * Recomputes user clip positions if necessary. 919bf215546Sopenharmony_ci * 920bf215546Sopenharmony_ci * \note This routine references __struct gl_contextRec::Tranform attribute 921bf215546Sopenharmony_ci * values to compute userclip positions in clip space, but is only called on 922bf215546Sopenharmony_ci * _NEW_PROJECTION. The _mesa_ClipPlane() function keeps these values up to 923bf215546Sopenharmony_ci * date across changes to the __struct gl_contextRec::Transform attributes. 924bf215546Sopenharmony_ci */ 925bf215546Sopenharmony_cistatic void 926bf215546Sopenharmony_ciupdate_projection( struct gl_context *ctx ) 927bf215546Sopenharmony_ci{ 928bf215546Sopenharmony_ci /* Recompute clip plane positions in clipspace. This is also done 929bf215546Sopenharmony_ci * in _mesa_ClipPlane(). 930bf215546Sopenharmony_ci */ 931bf215546Sopenharmony_ci GLbitfield mask = ctx->Transform.ClipPlanesEnabled; 932bf215546Sopenharmony_ci 933bf215546Sopenharmony_ci if (mask) { 934bf215546Sopenharmony_ci /* make sure the inverse is up to date */ 935bf215546Sopenharmony_ci _math_matrix_analyse(ctx->ProjectionMatrixStack.Top); 936bf215546Sopenharmony_ci 937bf215546Sopenharmony_ci do { 938bf215546Sopenharmony_ci const int p = u_bit_scan(&mask); 939bf215546Sopenharmony_ci 940bf215546Sopenharmony_ci _mesa_transform_vector(ctx->Transform._ClipUserPlane[p], 941bf215546Sopenharmony_ci ctx->Transform.EyeUserPlane[p], 942bf215546Sopenharmony_ci ctx->ProjectionMatrixStack.Top->inv); 943bf215546Sopenharmony_ci } while (mask); 944bf215546Sopenharmony_ci } 945bf215546Sopenharmony_ci} 946bf215546Sopenharmony_ci 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci/** 949bf215546Sopenharmony_ci * Updates the combined modelview-projection matrix. 950bf215546Sopenharmony_ci * 951bf215546Sopenharmony_ci * \param ctx GL context. 952bf215546Sopenharmony_ci * \param new_state new state bit mask. 953bf215546Sopenharmony_ci * 954bf215546Sopenharmony_ci * If there is a new model view matrix then analyzes it. If there is a new 955bf215546Sopenharmony_ci * projection matrix, updates it. Finally calls 956bf215546Sopenharmony_ci * calculate_model_project_matrix() to recalculate the modelview-projection 957bf215546Sopenharmony_ci * matrix. 958bf215546Sopenharmony_ci */ 959bf215546Sopenharmony_civoid _mesa_update_modelview_project( struct gl_context *ctx, GLuint new_state ) 960bf215546Sopenharmony_ci{ 961bf215546Sopenharmony_ci if (new_state & _NEW_MODELVIEW) 962bf215546Sopenharmony_ci _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 963bf215546Sopenharmony_ci 964bf215546Sopenharmony_ci if (new_state & _NEW_PROJECTION) 965bf215546Sopenharmony_ci update_projection( ctx ); 966bf215546Sopenharmony_ci 967bf215546Sopenharmony_ci /* Calculate ModelViewMatrix * ProjectionMatrix. */ 968bf215546Sopenharmony_ci _math_matrix_mul_matrix(&ctx->_ModelProjectMatrix, 969bf215546Sopenharmony_ci ctx->ProjectionMatrixStack.Top, 970bf215546Sopenharmony_ci ctx->ModelviewMatrixStack.Top); 971bf215546Sopenharmony_ci} 972bf215546Sopenharmony_ci 973bf215546Sopenharmony_ci/*@}*/ 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci/**********************************************************************/ 977bf215546Sopenharmony_ci/** Matrix stack initialization */ 978bf215546Sopenharmony_ci/*@{*/ 979bf215546Sopenharmony_ci 980bf215546Sopenharmony_ci 981bf215546Sopenharmony_ci/** 982bf215546Sopenharmony_ci * Initialize a matrix stack. 983bf215546Sopenharmony_ci * 984bf215546Sopenharmony_ci * \param stack matrix stack. 985bf215546Sopenharmony_ci * \param maxDepth maximum stack depth. 986bf215546Sopenharmony_ci * \param dirtyFlag dirty flag. 987bf215546Sopenharmony_ci * 988bf215546Sopenharmony_ci * Allocates an array of \p maxDepth elements for the matrix stack and calls 989bf215546Sopenharmony_ci * _math_matrix_ctr() for each element to initialize it. 990bf215546Sopenharmony_ci */ 991bf215546Sopenharmony_cistatic void 992bf215546Sopenharmony_ciinit_matrix_stack(struct gl_matrix_stack *stack, 993bf215546Sopenharmony_ci GLuint maxDepth, GLuint dirtyFlag) 994bf215546Sopenharmony_ci{ 995bf215546Sopenharmony_ci stack->Depth = 0; 996bf215546Sopenharmony_ci stack->MaxDepth = maxDepth; 997bf215546Sopenharmony_ci stack->DirtyFlag = dirtyFlag; 998bf215546Sopenharmony_ci /* The stack will be dynamically resized at glPushMatrix() time */ 999bf215546Sopenharmony_ci stack->Stack = calloc(1, sizeof(GLmatrix)); 1000bf215546Sopenharmony_ci stack->StackSize = 1; 1001bf215546Sopenharmony_ci _math_matrix_ctr(&stack->Stack[0]); 1002bf215546Sopenharmony_ci stack->Top = stack->Stack; 1003bf215546Sopenharmony_ci} 1004bf215546Sopenharmony_ci 1005bf215546Sopenharmony_ci/** 1006bf215546Sopenharmony_ci * Free matrix stack. 1007bf215546Sopenharmony_ci * 1008bf215546Sopenharmony_ci * \param stack matrix stack. 1009bf215546Sopenharmony_ci */ 1010bf215546Sopenharmony_cistatic void 1011bf215546Sopenharmony_cifree_matrix_stack( struct gl_matrix_stack *stack ) 1012bf215546Sopenharmony_ci{ 1013bf215546Sopenharmony_ci free(stack->Stack); 1014bf215546Sopenharmony_ci stack->Stack = stack->Top = NULL; 1015bf215546Sopenharmony_ci stack->StackSize = 0; 1016bf215546Sopenharmony_ci} 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ci/*@}*/ 1019bf215546Sopenharmony_ci 1020bf215546Sopenharmony_ci 1021bf215546Sopenharmony_ci/**********************************************************************/ 1022bf215546Sopenharmony_ci/** \name Initialization */ 1023bf215546Sopenharmony_ci/*@{*/ 1024bf215546Sopenharmony_ci 1025bf215546Sopenharmony_ci 1026bf215546Sopenharmony_ci/** 1027bf215546Sopenharmony_ci * Initialize the context matrix data. 1028bf215546Sopenharmony_ci * 1029bf215546Sopenharmony_ci * \param ctx GL context. 1030bf215546Sopenharmony_ci * 1031bf215546Sopenharmony_ci * Initializes each of the matrix stacks and the combined modelview-projection 1032bf215546Sopenharmony_ci * matrix. 1033bf215546Sopenharmony_ci */ 1034bf215546Sopenharmony_civoid _mesa_init_matrix( struct gl_context * ctx ) 1035bf215546Sopenharmony_ci{ 1036bf215546Sopenharmony_ci GLuint i; 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci /* Initialize matrix stacks */ 1039bf215546Sopenharmony_ci init_matrix_stack(&ctx->ModelviewMatrixStack, MAX_MODELVIEW_STACK_DEPTH, 1040bf215546Sopenharmony_ci _NEW_MODELVIEW); 1041bf215546Sopenharmony_ci init_matrix_stack(&ctx->ProjectionMatrixStack, MAX_PROJECTION_STACK_DEPTH, 1042bf215546Sopenharmony_ci _NEW_PROJECTION); 1043bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->TextureMatrixStack); i++) 1044bf215546Sopenharmony_ci init_matrix_stack(&ctx->TextureMatrixStack[i], MAX_TEXTURE_STACK_DEPTH, 1045bf215546Sopenharmony_ci _NEW_TEXTURE_MATRIX); 1046bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->ProgramMatrixStack); i++) 1047bf215546Sopenharmony_ci init_matrix_stack(&ctx->ProgramMatrixStack[i], 1048bf215546Sopenharmony_ci MAX_PROGRAM_MATRIX_STACK_DEPTH, _NEW_TRACK_MATRIX); 1049bf215546Sopenharmony_ci ctx->CurrentStack = &ctx->ModelviewMatrixStack; 1050bf215546Sopenharmony_ci 1051bf215546Sopenharmony_ci /* Init combined Modelview*Projection matrix */ 1052bf215546Sopenharmony_ci _math_matrix_ctr( &ctx->_ModelProjectMatrix ); 1053bf215546Sopenharmony_ci} 1054bf215546Sopenharmony_ci 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci/** 1057bf215546Sopenharmony_ci * Free the context matrix data. 1058bf215546Sopenharmony_ci * 1059bf215546Sopenharmony_ci * \param ctx GL context. 1060bf215546Sopenharmony_ci * 1061bf215546Sopenharmony_ci * Frees each of the matrix stacks. 1062bf215546Sopenharmony_ci */ 1063bf215546Sopenharmony_civoid _mesa_free_matrix_data( struct gl_context *ctx ) 1064bf215546Sopenharmony_ci{ 1065bf215546Sopenharmony_ci GLuint i; 1066bf215546Sopenharmony_ci 1067bf215546Sopenharmony_ci free_matrix_stack(&ctx->ModelviewMatrixStack); 1068bf215546Sopenharmony_ci free_matrix_stack(&ctx->ProjectionMatrixStack); 1069bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->TextureMatrixStack); i++) 1070bf215546Sopenharmony_ci free_matrix_stack(&ctx->TextureMatrixStack[i]); 1071bf215546Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ctx->ProgramMatrixStack); i++) 1072bf215546Sopenharmony_ci free_matrix_stack(&ctx->ProgramMatrixStack[i]); 1073bf215546Sopenharmony_ci 1074bf215546Sopenharmony_ci} 1075bf215546Sopenharmony_ci 1076bf215546Sopenharmony_ci 1077bf215546Sopenharmony_ci/** 1078bf215546Sopenharmony_ci * Initialize the context transform attribute group. 1079bf215546Sopenharmony_ci * 1080bf215546Sopenharmony_ci * \param ctx GL context. 1081bf215546Sopenharmony_ci * 1082bf215546Sopenharmony_ci * \todo Move this to a new file with other 'transform' routines. 1083bf215546Sopenharmony_ci */ 1084bf215546Sopenharmony_civoid _mesa_init_transform( struct gl_context *ctx ) 1085bf215546Sopenharmony_ci{ 1086bf215546Sopenharmony_ci GLuint i; 1087bf215546Sopenharmony_ci 1088bf215546Sopenharmony_ci /* Transformation group */ 1089bf215546Sopenharmony_ci ctx->Transform.MatrixMode = GL_MODELVIEW; 1090bf215546Sopenharmony_ci ctx->Transform.Normalize = GL_FALSE; 1091bf215546Sopenharmony_ci ctx->Transform.RescaleNormals = GL_FALSE; 1092bf215546Sopenharmony_ci ctx->Transform.RasterPositionUnclipped = GL_FALSE; 1093bf215546Sopenharmony_ci for (i=0;i<ctx->Const.MaxClipPlanes;i++) { 1094bf215546Sopenharmony_ci ASSIGN_4V( ctx->Transform.EyeUserPlane[i], 0.0, 0.0, 0.0, 0.0 ); 1095bf215546Sopenharmony_ci } 1096bf215546Sopenharmony_ci ctx->Transform.ClipPlanesEnabled = 0; 1097bf215546Sopenharmony_ci} 1098bf215546Sopenharmony_ci 1099bf215546Sopenharmony_ci 1100bf215546Sopenharmony_ci/*@}*/ 1101