attrib.c revision 9a33a11d714c90162d32781ebbd2c1dfab52cfd1
1/* $Id: attrib.c,v 1.66 2002/06/13 04:28:29 brianp Exp $ */ 2 3/* 4 * Mesa 3-D graphics library 5 * Version: 4.1 6 * 7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included 17 * in all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27 28#ifdef PC_HEADER 29#include "all.h" 30#else 31#include "glheader.h" 32#include "accum.h" 33#include "attrib.h" 34#include "blend.h" 35#include "buffers.h" 36#include "colormac.h" 37#include "context.h" 38#include "depth.h" 39#include "enable.h" 40#include "enums.h" 41#include "fog.h" 42#include "hint.h" 43#include "light.h" 44#include "lines.h" 45#include "matrix.h" 46#include "mem.h" 47#include "points.h" 48#include "polygon.h" 49#include "simple_list.h" 50#include "stencil.h" 51#include "texobj.h" 52#include "texstate.h" 53#include "mtypes.h" 54#include "math/m_xform.h" 55#endif 56 57 58 59 60/* 61 * Allocate a new attribute state node. These nodes have a 62 * "kind" value and a pointer to a struct of state data. 63 */ 64static struct gl_attrib_node * 65new_attrib_node( GLbitfield kind ) 66{ 67 struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node); 68 if (an) { 69 an->kind = kind; 70 } 71 return an; 72} 73 74 75 76/* 77 * Copy texture object state from one texture object to another. 78 */ 79static void 80copy_texobj_state( struct gl_texture_object *dest, 81 const struct gl_texture_object *src ) 82{ 83 dest->Name = src->Name; 84 /* 85 dest->Dimensions = src->Dimensions; 86 */ 87 dest->Priority = src->Priority; 88 dest->BorderColor[0] = src->BorderColor[0]; 89 dest->BorderColor[1] = src->BorderColor[1]; 90 dest->BorderColor[2] = src->BorderColor[2]; 91 dest->BorderColor[3] = src->BorderColor[3]; 92 dest->WrapS = src->WrapS; 93 dest->WrapT = src->WrapT; 94 dest->WrapR = src->WrapR; 95 dest->MinFilter = src->MinFilter; 96 dest->MagFilter = src->MagFilter; 97 dest->MinLod = src->MinLod; 98 dest->MaxLod = src->MaxLod; 99 dest->BaseLevel = src->BaseLevel; 100 dest->MaxLevel = src->MaxLevel; 101 dest->MaxAnisotropy = src->MaxAnisotropy; 102 dest->CompareFlag = src->CompareFlag; 103 dest->CompareOperator = src->CompareOperator; 104 dest->ShadowAmbient = src->ShadowAmbient; 105 dest->_MaxLevel = src->_MaxLevel; 106 dest->_MaxLambda = src->_MaxLambda; 107 dest->Palette = src->Palette; 108 dest->Complete = src->Complete; 109} 110 111 112 113void 114_mesa_PushAttrib(GLbitfield mask) 115{ 116 struct gl_attrib_node *newnode; 117 struct gl_attrib_node *head; 118 119 GET_CURRENT_CONTEXT(ctx); 120 ASSERT_OUTSIDE_BEGIN_END(ctx); 121 122 if (MESA_VERBOSE & VERBOSE_API) 123 _mesa_debug("glPushAttrib %x\n", (int) mask); 124 125 if (ctx->AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) { 126 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushAttrib" ); 127 return; 128 } 129 130 /* Build linked list of attribute nodes which save all attribute */ 131 /* groups specified by the mask. */ 132 head = NULL; 133 134 if (mask & GL_ACCUM_BUFFER_BIT) { 135 struct gl_accum_attrib *attr; 136 attr = MALLOC_STRUCT( gl_accum_attrib ); 137 MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) ); 138 newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT ); 139 newnode->data = attr; 140 newnode->next = head; 141 head = newnode; 142 } 143 144 if (mask & GL_COLOR_BUFFER_BIT) { 145 struct gl_colorbuffer_attrib *attr; 146 attr = MALLOC_STRUCT( gl_colorbuffer_attrib ); 147 MEMCPY( attr, &ctx->Color, sizeof(struct gl_colorbuffer_attrib) ); 148 newnode = new_attrib_node( GL_COLOR_BUFFER_BIT ); 149 newnode->data = attr; 150 newnode->next = head; 151 head = newnode; 152 } 153 154 if (mask & GL_CURRENT_BIT) { 155 struct gl_current_attrib *attr; 156 FLUSH_CURRENT( ctx, 0 ); 157 attr = MALLOC_STRUCT( gl_current_attrib ); 158 MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) ); 159 newnode = new_attrib_node( GL_CURRENT_BIT ); 160 newnode->data = attr; 161 newnode->next = head; 162 head = newnode; 163 } 164 165 if (mask & GL_DEPTH_BUFFER_BIT) { 166 struct gl_depthbuffer_attrib *attr; 167 attr = MALLOC_STRUCT( gl_depthbuffer_attrib ); 168 MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) ); 169 newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT ); 170 newnode->data = attr; 171 newnode->next = head; 172 head = newnode; 173 } 174 175 if (mask & GL_ENABLE_BIT) { 176 struct gl_enable_attrib *attr; 177 GLuint i; 178 attr = MALLOC_STRUCT( gl_enable_attrib ); 179 /* Copy enable flags from all other attributes into the enable struct. */ 180 attr->AlphaTest = ctx->Color.AlphaEnabled; 181 attr->AutoNormal = ctx->Eval.AutoNormal; 182 attr->Blend = ctx->Color.BlendEnabled; 183 attr->ClipPlanes = ctx->Transform.ClipPlanesEnabled; 184 attr->ColorMaterial = ctx->Light.ColorMaterialEnabled; 185 attr->Convolution1D = ctx->Pixel.Convolution1DEnabled; 186 attr->Convolution2D = ctx->Pixel.Convolution2DEnabled; 187 attr->Separable2D = ctx->Pixel.Separable2DEnabled; 188 attr->CullFace = ctx->Polygon.CullFlag; 189 attr->DepthTest = ctx->Depth.Test; 190 attr->Dither = ctx->Color.DitherFlag; 191 attr->Fog = ctx->Fog.Enabled; 192 for (i=0;i<MAX_LIGHTS;i++) { 193 attr->Light[i] = ctx->Light.Light[i].Enabled; 194 } 195 attr->Lighting = ctx->Light.Enabled; 196 attr->LineSmooth = ctx->Line.SmoothFlag; 197 attr->LineStipple = ctx->Line.StippleFlag; 198 attr->Histogram = ctx->Pixel.HistogramEnabled; 199 attr->MinMax = ctx->Pixel.MinMaxEnabled; 200 attr->IndexLogicOp = ctx->Color.IndexLogicOpEnabled; 201 attr->ColorLogicOp = ctx->Color.ColorLogicOpEnabled; 202 attr->Map1Color4 = ctx->Eval.Map1Color4; 203 attr->Map1Index = ctx->Eval.Map1Index; 204 attr->Map1Normal = ctx->Eval.Map1Normal; 205 attr->Map1TextureCoord1 = ctx->Eval.Map1TextureCoord1; 206 attr->Map1TextureCoord2 = ctx->Eval.Map1TextureCoord2; 207 attr->Map1TextureCoord3 = ctx->Eval.Map1TextureCoord3; 208 attr->Map1TextureCoord4 = ctx->Eval.Map1TextureCoord4; 209 attr->Map1Vertex3 = ctx->Eval.Map1Vertex3; 210 attr->Map1Vertex4 = ctx->Eval.Map1Vertex4; 211 MEMCPY(attr->Map1Attrib, ctx->Eval.Map1Attrib, sizeof(ctx->Eval.Map1Attrib)); 212 attr->Map2Color4 = ctx->Eval.Map2Color4; 213 attr->Map2Index = ctx->Eval.Map2Index; 214 attr->Map2Normal = ctx->Eval.Map2Normal; 215 attr->Map2TextureCoord1 = ctx->Eval.Map2TextureCoord1; 216 attr->Map2TextureCoord2 = ctx->Eval.Map2TextureCoord2; 217 attr->Map2TextureCoord3 = ctx->Eval.Map2TextureCoord3; 218 attr->Map2TextureCoord4 = ctx->Eval.Map2TextureCoord4; 219 attr->Map2Vertex3 = ctx->Eval.Map2Vertex3; 220 attr->Map2Vertex4 = ctx->Eval.Map2Vertex4; 221 MEMCPY(attr->Map2Attrib, ctx->Eval.Map2Attrib, sizeof(ctx->Eval.Map2Attrib)); 222 attr->Normalize = ctx->Transform.Normalize; 223 attr->RasterPositionUnclipped = ctx->Transform.RasterPositionUnclipped; 224 attr->PixelTexture = ctx->Pixel.PixelTextureEnabled; 225 attr->PointSmooth = ctx->Point.SmoothFlag; 226 attr->PointSprite = ctx->Point.PointSprite; 227 attr->PolygonOffsetPoint = ctx->Polygon.OffsetPoint; 228 attr->PolygonOffsetLine = ctx->Polygon.OffsetLine; 229 attr->PolygonOffsetFill = ctx->Polygon.OffsetFill; 230 attr->PolygonSmooth = ctx->Polygon.SmoothFlag; 231 attr->PolygonStipple = ctx->Polygon.StippleFlag; 232 attr->RescaleNormals = ctx->Transform.RescaleNormals; 233 attr->Scissor = ctx->Scissor.Enabled; 234 attr->Stencil = ctx->Stencil.Enabled; 235 attr->MultisampleEnabled = ctx->Multisample.Enabled; 236 attr->SampleAlphaToCoverage = ctx->Multisample.SampleAlphaToCoverage; 237 attr->SampleAlphaToOne = ctx->Multisample.SampleAlphaToOne; 238 attr->SampleCoverage = ctx->Multisample.SampleCoverage; 239 attr->SampleCoverageInvert = ctx->Multisample.SampleCoverageInvert; 240 for (i=0; i<MAX_TEXTURE_UNITS; i++) { 241 attr->Texture[i] = ctx->Texture.Unit[i].Enabled; 242 attr->TexGen[i] = ctx->Texture.Unit[i].TexGenEnabled; 243 } 244 /* GL_NV_vertex_program */ 245 attr->VertexProgram = ctx->VertexProgram.Enabled; 246 attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled; 247 attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled; 248 newnode = new_attrib_node( GL_ENABLE_BIT ); 249 newnode->data = attr; 250 newnode->next = head; 251 head = newnode; 252 } 253 254 if (mask & GL_EVAL_BIT) { 255 struct gl_eval_attrib *attr; 256 attr = MALLOC_STRUCT( gl_eval_attrib ); 257 MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) ); 258 newnode = new_attrib_node( GL_EVAL_BIT ); 259 newnode->data = attr; 260 newnode->next = head; 261 head = newnode; 262 } 263 264 if (mask & GL_FOG_BIT) { 265 struct gl_fog_attrib *attr; 266 attr = MALLOC_STRUCT( gl_fog_attrib ); 267 MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) ); 268 newnode = new_attrib_node( GL_FOG_BIT ); 269 newnode->data = attr; 270 newnode->next = head; 271 head = newnode; 272 } 273 274 if (mask & GL_HINT_BIT) { 275 struct gl_hint_attrib *attr; 276 attr = MALLOC_STRUCT( gl_hint_attrib ); 277 MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) ); 278 newnode = new_attrib_node( GL_HINT_BIT ); 279 newnode->data = attr; 280 newnode->next = head; 281 head = newnode; 282 } 283 284 if (mask & GL_LIGHTING_BIT) { 285 struct gl_light_attrib *attr; 286 FLUSH_CURRENT(ctx, 0); /* flush material changes */ 287 attr = MALLOC_STRUCT( gl_light_attrib ); 288 MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) ); 289 newnode = new_attrib_node( GL_LIGHTING_BIT ); 290 newnode->data = attr; 291 newnode->next = head; 292 head = newnode; 293 } 294 295 if (mask & GL_LINE_BIT) { 296 struct gl_line_attrib *attr; 297 attr = MALLOC_STRUCT( gl_line_attrib ); 298 MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) ); 299 newnode = new_attrib_node( GL_LINE_BIT ); 300 newnode->data = attr; 301 newnode->next = head; 302 head = newnode; 303 } 304 305 if (mask & GL_LIST_BIT) { 306 struct gl_list_attrib *attr; 307 attr = MALLOC_STRUCT( gl_list_attrib ); 308 MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) ); 309 newnode = new_attrib_node( GL_LIST_BIT ); 310 newnode->data = attr; 311 newnode->next = head; 312 head = newnode; 313 } 314 315 if (mask & GL_PIXEL_MODE_BIT) { 316 struct gl_pixel_attrib *attr; 317 attr = MALLOC_STRUCT( gl_pixel_attrib ); 318 MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) ); 319 newnode = new_attrib_node( GL_PIXEL_MODE_BIT ); 320 newnode->data = attr; 321 newnode->next = head; 322 head = newnode; 323 } 324 325 if (mask & GL_POINT_BIT) { 326 struct gl_point_attrib *attr; 327 attr = MALLOC_STRUCT( gl_point_attrib ); 328 MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) ); 329 newnode = new_attrib_node( GL_POINT_BIT ); 330 newnode->data = attr; 331 newnode->next = head; 332 head = newnode; 333 } 334 335 if (mask & GL_POLYGON_BIT) { 336 struct gl_polygon_attrib *attr; 337 attr = MALLOC_STRUCT( gl_polygon_attrib ); 338 MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) ); 339 newnode = new_attrib_node( GL_POLYGON_BIT ); 340 newnode->data = attr; 341 newnode->next = head; 342 head = newnode; 343 } 344 345 if (mask & GL_POLYGON_STIPPLE_BIT) { 346 GLuint *stipple; 347 stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) ); 348 MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) ); 349 newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT ); 350 newnode->data = stipple; 351 newnode->next = head; 352 head = newnode; 353 } 354 355 if (mask & GL_SCISSOR_BIT) { 356 struct gl_scissor_attrib *attr; 357 attr = MALLOC_STRUCT( gl_scissor_attrib ); 358 MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) ); 359 newnode = new_attrib_node( GL_SCISSOR_BIT ); 360 newnode->data = attr; 361 newnode->next = head; 362 head = newnode; 363 } 364 365 if (mask & GL_STENCIL_BUFFER_BIT) { 366 struct gl_stencil_attrib *attr; 367 attr = MALLOC_STRUCT( gl_stencil_attrib ); 368 MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) ); 369 newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT ); 370 newnode->data = attr; 371 newnode->next = head; 372 head = newnode; 373 } 374 375 if (mask & GL_TEXTURE_BIT) { 376 struct gl_texture_attrib *attr; 377 GLuint u; 378 /* Bump the texture object reference counts so that they don't 379 * inadvertantly get deleted. 380 */ 381 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 382 ctx->Texture.Unit[u].Current1D->RefCount++; 383 ctx->Texture.Unit[u].Current2D->RefCount++; 384 ctx->Texture.Unit[u].Current3D->RefCount++; 385 ctx->Texture.Unit[u].CurrentCubeMap->RefCount++; 386 } 387 attr = MALLOC_STRUCT( gl_texture_attrib ); 388 MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); 389 /* copy state of the currently bound texture objects */ 390 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 391 copy_texobj_state(&attr->Unit[u].Saved1D, attr->Unit[u].Current1D); 392 copy_texobj_state(&attr->Unit[u].Saved2D, attr->Unit[u].Current2D); 393 copy_texobj_state(&attr->Unit[u].Saved3D, attr->Unit[u].Current3D); 394 copy_texobj_state(&attr->Unit[u].SavedCubeMap, attr->Unit[u].CurrentCubeMap); 395 } 396 newnode = new_attrib_node( GL_TEXTURE_BIT ); 397 newnode->data = attr; 398 newnode->next = head; 399 head = newnode; 400 } 401 402 if (mask & GL_TRANSFORM_BIT) { 403 struct gl_transform_attrib *attr; 404 attr = MALLOC_STRUCT( gl_transform_attrib ); 405 MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) ); 406 newnode = new_attrib_node( GL_TRANSFORM_BIT ); 407 newnode->data = attr; 408 newnode->next = head; 409 head = newnode; 410 } 411 412 if (mask & GL_VIEWPORT_BIT) { 413 struct gl_viewport_attrib *attr; 414 attr = MALLOC_STRUCT( gl_viewport_attrib ); 415 MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) ); 416 newnode = new_attrib_node( GL_VIEWPORT_BIT ); 417 newnode->data = attr; 418 newnode->next = head; 419 head = newnode; 420 } 421 422 /* GL_ARB_multisample */ 423 if (mask & GL_MULTISAMPLE_BIT_ARB) { 424 struct gl_multisample_attrib *attr; 425 attr = MALLOC_STRUCT( gl_multisample_attrib ); 426 MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) ); 427 newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB ); 428 newnode->data = attr; 429 newnode->next = head; 430 head = newnode; 431 } 432 433 ctx->AttribStack[ctx->AttribStackDepth] = head; 434 ctx->AttribStackDepth++; 435} 436 437 438 439static void 440pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable) 441{ 442 GLuint i; 443 444#define TEST_AND_UPDATE(VALUE, NEWVALUE, ENUM) \ 445 if ((VALUE) != (NEWVALUE)) { \ 446 _mesa_set_enable( ctx, ENUM, (NEWVALUE) ); \ 447 } 448 449 TEST_AND_UPDATE(ctx->Color.AlphaEnabled, enable->AlphaTest, GL_ALPHA_TEST); 450 TEST_AND_UPDATE(ctx->Color.BlendEnabled, enable->Blend, GL_BLEND); 451 452 for (i=0;i<MAX_CLIP_PLANES;i++) { 453 const GLuint mask = 1 << i; 454 if ((ctx->Transform.ClipPlanesEnabled & mask) != (enable->ClipPlanes & mask)) 455 _mesa_set_enable(ctx, (GLenum) (GL_CLIP_PLANE0 + i), 456 (enable->ClipPlanes & mask) ? GL_TRUE : GL_FALSE); 457 } 458 459 TEST_AND_UPDATE(ctx->Light.ColorMaterialEnabled, enable->ColorMaterial, 460 GL_COLOR_MATERIAL); 461 TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE); 462 TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST); 463 TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER); 464 TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D, 465 GL_CONVOLUTION_1D); 466 TEST_AND_UPDATE(ctx->Pixel.Convolution2DEnabled, enable->Convolution2D, 467 GL_CONVOLUTION_2D); 468 TEST_AND_UPDATE(ctx->Pixel.Separable2DEnabled, enable->Separable2D, 469 GL_SEPARABLE_2D); 470 TEST_AND_UPDATE(ctx->Fog.Enabled, enable->Fog, GL_FOG); 471 TEST_AND_UPDATE(ctx->Light.Enabled, enable->Lighting, GL_LIGHTING); 472 TEST_AND_UPDATE(ctx->Line.SmoothFlag, enable->LineSmooth, GL_LINE_SMOOTH); 473 TEST_AND_UPDATE(ctx->Line.StippleFlag, enable->LineStipple, 474 GL_LINE_STIPPLE); 475 TEST_AND_UPDATE(ctx->Color.IndexLogicOpEnabled, enable->IndexLogicOp, 476 GL_INDEX_LOGIC_OP); 477 TEST_AND_UPDATE(ctx->Color.ColorLogicOpEnabled, enable->ColorLogicOp, 478 GL_COLOR_LOGIC_OP); 479 480 TEST_AND_UPDATE(ctx->Eval.Map1Color4, enable->Map1Color4, GL_MAP1_COLOR_4); 481 TEST_AND_UPDATE(ctx->Eval.Map1Index, enable->Map1Index, GL_MAP1_INDEX); 482 TEST_AND_UPDATE(ctx->Eval.Map1Normal, enable->Map1Normal, GL_MAP1_NORMAL); 483 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord1, enable->Map1TextureCoord1, 484 GL_MAP1_TEXTURE_COORD_1); 485 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord2, enable->Map1TextureCoord2, 486 GL_MAP1_TEXTURE_COORD_2); 487 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord3, enable->Map1TextureCoord3, 488 GL_MAP1_TEXTURE_COORD_3); 489 TEST_AND_UPDATE(ctx->Eval.Map1TextureCoord4, enable->Map1TextureCoord4, 490 GL_MAP1_TEXTURE_COORD_4); 491 TEST_AND_UPDATE(ctx->Eval.Map1Vertex3, enable->Map1Vertex3, 492 GL_MAP1_VERTEX_3); 493 TEST_AND_UPDATE(ctx->Eval.Map1Vertex4, enable->Map1Vertex4, 494 GL_MAP1_VERTEX_4); 495 for (i = 0; i < 16; i++) { 496 TEST_AND_UPDATE(ctx->Eval.Map1Attrib[i], enable->Map1Attrib[i], 497 GL_MAP1_VERTEX_ATTRIB0_4_NV + i); 498 } 499 500 TEST_AND_UPDATE(ctx->Eval.Map2Color4, enable->Map2Color4, GL_MAP2_COLOR_4); 501 TEST_AND_UPDATE(ctx->Eval.Map2Index, enable->Map2Index, GL_MAP2_INDEX); 502 TEST_AND_UPDATE(ctx->Eval.Map2Normal, enable->Map2Normal, GL_MAP2_NORMAL); 503 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord1, enable->Map2TextureCoord1, 504 GL_MAP2_TEXTURE_COORD_1); 505 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord2, enable->Map2TextureCoord2, 506 GL_MAP2_TEXTURE_COORD_2); 507 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord3, enable->Map2TextureCoord3, 508 GL_MAP2_TEXTURE_COORD_3); 509 TEST_AND_UPDATE(ctx->Eval.Map2TextureCoord4, enable->Map2TextureCoord4, 510 GL_MAP2_TEXTURE_COORD_4); 511 TEST_AND_UPDATE(ctx->Eval.Map2Vertex3, enable->Map2Vertex3, 512 GL_MAP2_VERTEX_3); 513 TEST_AND_UPDATE(ctx->Eval.Map2Vertex4, enable->Map2Vertex4, 514 GL_MAP2_VERTEX_4); 515 for (i = 0; i < 16; i++) { 516 TEST_AND_UPDATE(ctx->Eval.Map2Attrib[i], enable->Map2Attrib[i], 517 GL_MAP2_VERTEX_ATTRIB0_4_NV + i); 518 } 519 520 TEST_AND_UPDATE(ctx->Eval.AutoNormal, enable->AutoNormal, GL_AUTO_NORMAL); 521 TEST_AND_UPDATE(ctx->Transform.Normalize, enable->Normalize, GL_NORMALIZE); 522 TEST_AND_UPDATE(ctx->Transform.RescaleNormals, enable->RescaleNormals, 523 GL_RESCALE_NORMAL_EXT); 524 TEST_AND_UPDATE(ctx->Transform.RasterPositionUnclipped, 525 enable->RasterPositionUnclipped, 526 GL_RASTER_POSITION_UNCLIPPED_IBM); 527 TEST_AND_UPDATE(ctx->Pixel.PixelTextureEnabled, enable->PixelTexture, 528 GL_POINT_SMOOTH); 529 TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, 530 GL_POINT_SMOOTH); 531 if (ctx->Extensions.NV_point_sprite) { 532 TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, 533 GL_POINT_SPRITE_NV); 534 } 535 TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, 536 GL_POLYGON_OFFSET_POINT); 537 TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, 538 GL_POLYGON_OFFSET_LINE); 539 TEST_AND_UPDATE(ctx->Polygon.OffsetFill, enable->PolygonOffsetFill, 540 GL_POLYGON_OFFSET_FILL); 541 TEST_AND_UPDATE(ctx->Polygon.SmoothFlag, enable->PolygonSmooth, 542 GL_POLYGON_SMOOTH); 543 TEST_AND_UPDATE(ctx->Polygon.StippleFlag, enable->PolygonStipple, 544 GL_POLYGON_STIPPLE); 545 TEST_AND_UPDATE(ctx->Scissor.Enabled, enable->Scissor, GL_SCISSOR_TEST); 546 TEST_AND_UPDATE(ctx->Stencil.Enabled, enable->Stencil, GL_STENCIL_TEST); 547 TEST_AND_UPDATE(ctx->Multisample.Enabled, enable->MultisampleEnabled, 548 GL_MULTISAMPLE_ARB); 549 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToCoverage, 550 enable->SampleAlphaToCoverage, 551 GL_SAMPLE_ALPHA_TO_COVERAGE_ARB); 552 TEST_AND_UPDATE(ctx->Multisample.SampleAlphaToOne, 553 enable->SampleAlphaToOne, 554 GL_SAMPLE_ALPHA_TO_ONE_ARB); 555 TEST_AND_UPDATE(ctx->Multisample.SampleCoverage, 556 enable->SampleCoverage, 557 GL_SAMPLE_COVERAGE_ARB); 558 TEST_AND_UPDATE(ctx->Multisample.SampleCoverageInvert, 559 enable->SampleCoverageInvert, 560 GL_SAMPLE_COVERAGE_INVERT_ARB); 561 /* GL_NV_vertex_program */ 562 TEST_AND_UPDATE(ctx->VertexProgram.Enabled, 563 enable->VertexProgram, 564 GL_VERTEX_PROGRAM_NV); 565 TEST_AND_UPDATE(ctx->VertexProgram.PointSizeEnabled, 566 enable->VertexProgramPointSize, 567 GL_VERTEX_PROGRAM_POINT_SIZE_NV); 568 TEST_AND_UPDATE(ctx->VertexProgram.TwoSideEnabled, 569 enable->VertexProgramTwoSide, 570 GL_VERTEX_PROGRAM_TWO_SIDE_NV); 571 572#undef TEST_AND_UPDATE 573 574 /* texture unit enables */ 575 for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { 576 if (ctx->Texture.Unit[i].Enabled != enable->Texture[i]) { 577 ctx->Texture.Unit[i].Enabled = enable->Texture[i]; 578 if (ctx->Driver.Enable) { 579 if (ctx->Driver.ActiveTexture) { 580 (*ctx->Driver.ActiveTexture)(ctx, i); 581 } 582 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_1D, 583 (GLboolean) (enable->Texture[i] & TEXTURE0_1D) ); 584 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_2D, 585 (GLboolean) (enable->Texture[i] & TEXTURE0_2D) ); 586 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_3D, 587 (GLboolean) (enable->Texture[i] & TEXTURE0_3D) ); 588 } 589 } 590 591 if (ctx->Texture.Unit[i].TexGenEnabled != enable->TexGen[i]) { 592 ctx->Texture.Unit[i].TexGenEnabled = enable->TexGen[i]; 593 if (ctx->Driver.Enable) { 594 if (ctx->Driver.ActiveTexture) { 595 (*ctx->Driver.ActiveTexture)(ctx, i); 596 } 597 if (enable->TexGen[i] & S_BIT) 598 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_TRUE); 599 else 600 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_S, GL_FALSE); 601 if (enable->TexGen[i] & T_BIT) 602 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_TRUE); 603 else 604 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_T, GL_FALSE); 605 if (enable->TexGen[i] & R_BIT) 606 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_TRUE); 607 else 608 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_R, GL_FALSE); 609 if (enable->TexGen[i] & Q_BIT) 610 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_TRUE); 611 else 612 (*ctx->Driver.Enable)( ctx, GL_TEXTURE_GEN_Q, GL_FALSE); 613 } 614 } 615 } 616 617 if (ctx->Driver.ActiveTexture) { 618 (*ctx->Driver.ActiveTexture)(ctx, ctx->Texture.CurrentUnit); 619 } 620} 621 622 623static void 624pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) 625{ 626 GLuint u; 627 628 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 629 const struct gl_texture_unit *unit = &texAttrib->Unit[u]; 630 GLuint numObjs, i; 631 632 _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + u); 633 _mesa_set_enable(ctx, GL_TEXTURE_1D, 634 (GLboolean) (unit->Enabled & TEXTURE0_1D ? GL_TRUE : GL_FALSE)); 635 _mesa_set_enable(ctx, GL_TEXTURE_2D, 636 (GLboolean) (unit->Enabled & TEXTURE0_2D ? GL_TRUE : GL_FALSE)); 637 _mesa_set_enable(ctx, GL_TEXTURE_3D, 638 (GLboolean) (unit->Enabled & TEXTURE0_3D ? GL_TRUE : GL_FALSE)); 639 if (ctx->Extensions.ARB_texture_cube_map) { 640 _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP_ARB, 641 (GLboolean) (unit->Enabled & TEXTURE0_CUBE ? GL_TRUE : GL_FALSE)); 642 } 643 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); 644 _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); 645 _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenModeS); 646 _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenModeT); 647 _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenModeR); 648 _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenModeQ); 649 _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlaneS); 650 _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlaneT); 651 _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlaneR); 652 _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlaneQ); 653 _mesa_TexGenfv(GL_S, GL_EYE_PLANE, unit->EyePlaneS); 654 _mesa_TexGenfv(GL_T, GL_EYE_PLANE, unit->EyePlaneT); 655 _mesa_TexGenfv(GL_R, GL_EYE_PLANE, unit->EyePlaneR); 656 _mesa_TexGenfv(GL_Q, GL_EYE_PLANE, unit->EyePlaneQ); 657 if (ctx->Extensions.EXT_texture_lod_bias) { 658 _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL_EXT, 659 GL_TEXTURE_LOD_BIAS_EXT, unit->LodBias); 660 } 661 if (ctx->Extensions.EXT_texture_env_combine || 662 ctx->Extensions.ARB_texture_env_combine) { 663 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, 664 unit->CombineModeRGB); 665 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, 666 unit->CombineModeA); 667 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, 668 unit->CombineSourceRGB[0]); 669 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, 670 unit->CombineSourceRGB[1]); 671 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_EXT, 672 unit->CombineSourceRGB[2]); 673 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, 674 unit->CombineSourceA[0]); 675 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, 676 unit->CombineSourceA[1]); 677 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA_EXT, 678 unit->CombineSourceA[2]); 679 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_EXT, 680 unit->CombineOperandRGB[0]); 681 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_EXT, 682 unit->CombineOperandRGB[1]); 683 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_EXT, 684 unit->CombineOperandRGB[2]); 685 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA_EXT, 686 unit->CombineOperandA[0]); 687 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_EXT, 688 unit->CombineOperandA[1]); 689 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_EXT, 690 unit->CombineOperandA[2]); 691 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 692 1 << unit->CombineScaleShiftRGB); 693 _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 694 1 << unit->CombineScaleShiftA); 695 } 696 697 /* Restore texture object state */ 698 numObjs = ctx->Extensions.ARB_texture_cube_map ? 4 : 3; 699 700 for (i = 0; i < numObjs; i++) { 701 GLenum target = 0; 702 const struct gl_texture_object *obj = NULL; 703 GLfloat bordColor[4]; 704 705 switch (i) { 706 case 0: 707 target = GL_TEXTURE_1D; 708 obj = &unit->Saved1D; 709 break; 710 case 1: 711 target = GL_TEXTURE_2D; 712 obj = &unit->Saved2D; 713 break; 714 case 2: 715 target = GL_TEXTURE_3D; 716 obj = &unit->Saved3D; 717 break; 718 case 3: 719 target = GL_TEXTURE_CUBE_MAP_ARB; 720 obj = &unit->SavedCubeMap; 721 break; 722 default: 723 ; /* silence warnings */ 724 } 725 726 _mesa_BindTexture(target, obj->Name); 727 728 bordColor[0] = CHAN_TO_FLOAT(obj->BorderColor[0]); 729 bordColor[1] = CHAN_TO_FLOAT(obj->BorderColor[1]); 730 bordColor[2] = CHAN_TO_FLOAT(obj->BorderColor[2]); 731 bordColor[3] = CHAN_TO_FLOAT(obj->BorderColor[3]); 732 733 _mesa_TexParameterf(target, GL_TEXTURE_PRIORITY, obj->Priority); 734 _mesa_TexParameterfv(target, GL_TEXTURE_BORDER_COLOR, bordColor); 735 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, obj->WrapS); 736 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, obj->WrapT); 737 _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, obj->WrapR); 738 _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, obj->MinFilter); 739 _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter); 740 _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod); 741 _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod); 742 _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel); 743 _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel); 744 if (ctx->Extensions.EXT_texture_filter_anisotropic) { 745 _mesa_TexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, 746 obj->MaxAnisotropy); 747 } 748 if (ctx->Extensions.SGIX_shadow) { 749 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_SGIX, 750 obj->CompareFlag); 751 _mesa_TexParameteri(target, GL_TEXTURE_COMPARE_OPERATOR_SGIX, 752 obj->CompareOperator); 753 } 754 if (ctx->Extensions.SGIX_shadow_ambient) { 755 _mesa_TexParameterf(target, GL_SHADOW_AMBIENT_SGIX, 756 CHAN_TO_FLOAT(obj->ShadowAmbient)); 757 } 758 759 } 760 } 761 _mesa_ActiveTextureARB(GL_TEXTURE0_ARB 762 + texAttrib->CurrentUnit); 763 764 /* "un-bump" the texture object reference counts. We did that so they 765 * wouldn't inadvertantly get deleted while they were still referenced 766 * inside the attribute state stack. 767 */ 768 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 769 ctx->Texture.Unit[u].Current1D->RefCount--; 770 ctx->Texture.Unit[u].Current2D->RefCount--; 771 ctx->Texture.Unit[u].Current3D->RefCount--; 772 ctx->Texture.Unit[u].CurrentCubeMap->RefCount--; 773 } 774} 775 776 777/* 778 * This function is kind of long just because we have to call a lot 779 * of device driver functions to update device driver state. 780 * 781 * XXX As it is now, most of the pop-code calls immediate-mode Mesa functions 782 * in order to restore GL state. This isn't terribly efficient but it 783 * ensures that dirty flags and any derived state gets updated correctly. 784 * We could at least check if the value to restore equals the current value 785 * and then skip the Mesa call. 786 */ 787void 788_mesa_PopAttrib(void) 789{ 790 struct gl_attrib_node *attr, *next; 791 GET_CURRENT_CONTEXT(ctx); 792 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 793 794 if (ctx->AttribStackDepth == 0) { 795 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopAttrib" ); 796 return; 797 } 798 799 ctx->AttribStackDepth--; 800 attr = ctx->AttribStack[ctx->AttribStackDepth]; 801 802 while (attr) { 803 804 if (MESA_VERBOSE & VERBOSE_API) { 805 _mesa_debug("glPopAttrib %s\n", _mesa_lookup_enum_by_nr(attr->kind)); 806 } 807 808 switch (attr->kind) { 809 case GL_ACCUM_BUFFER_BIT: 810 { 811 const struct gl_accum_attrib *accum; 812 accum = (const struct gl_accum_attrib *) attr->data; 813 _mesa_ClearAccum(accum->ClearColor[0], 814 accum->ClearColor[1], 815 accum->ClearColor[2], 816 accum->ClearColor[3]); 817 } 818 break; 819 case GL_COLOR_BUFFER_BIT: 820 { 821 const struct gl_colorbuffer_attrib *color; 822 color = (const struct gl_colorbuffer_attrib *) attr->data; 823 _mesa_ClearIndex((GLfloat) color->ClearIndex); 824 _mesa_ClearColor(CHAN_TO_FLOAT(color->ClearColor[0]), 825 CHAN_TO_FLOAT(color->ClearColor[1]), 826 CHAN_TO_FLOAT(color->ClearColor[2]), 827 CHAN_TO_FLOAT(color->ClearColor[3])); 828 _mesa_IndexMask(color->IndexMask); 829 _mesa_ColorMask((GLboolean) (color->ColorMask[0] != 0), 830 (GLboolean) (color->ColorMask[1] != 0), 831 (GLboolean) (color->ColorMask[2] != 0), 832 (GLboolean) (color->ColorMask[3] != 0)); 833 _mesa_DrawBuffer(color->DrawBuffer); 834 _mesa_set_enable(ctx, GL_ALPHA_TEST, color->AlphaEnabled); 835 _mesa_AlphaFunc(color->AlphaFunc, 836 CHAN_TO_FLOAT(color->AlphaRef)); 837 _mesa_set_enable(ctx, GL_BLEND, color->BlendEnabled); 838 _mesa_BlendFuncSeparateEXT(color->BlendSrcRGB, 839 color->BlendDstRGB, 840 color->BlendSrcA, 841 color->BlendDstA); 842 _mesa_BlendEquation(color->BlendEquation); 843 _mesa_BlendColor(color->BlendColor[0], 844 color->BlendColor[1], 845 color->BlendColor[2], 846 color->BlendColor[3]); 847 _mesa_LogicOp(color->LogicOp); 848 _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, 849 color->ColorLogicOpEnabled); 850 _mesa_set_enable(ctx, GL_INDEX_LOGIC_OP, 851 color->IndexLogicOpEnabled); 852 _mesa_set_enable(ctx, GL_DITHER, color->DitherFlag); 853 } 854 break; 855 case GL_CURRENT_BIT: 856 FLUSH_CURRENT( ctx, 0 ); 857 MEMCPY( &ctx->Current, attr->data, 858 sizeof(struct gl_current_attrib) ); 859 break; 860 case GL_DEPTH_BUFFER_BIT: 861 { 862 const struct gl_depthbuffer_attrib *depth; 863 depth = (const struct gl_depthbuffer_attrib *) attr->data; 864 _mesa_DepthFunc(depth->Func); 865 _mesa_ClearDepth(depth->Clear); 866 _mesa_set_enable(ctx, GL_DEPTH_TEST, depth->Test); 867 _mesa_DepthMask(depth->Mask); 868 if (ctx->Extensions.HP_occlusion_test) 869 _mesa_set_enable(ctx, GL_OCCLUSION_TEST_HP, 870 depth->OcclusionTest); 871 } 872 break; 873 case GL_ENABLE_BIT: 874 { 875 const struct gl_enable_attrib *enable; 876 enable = (const struct gl_enable_attrib *) attr->data; 877 pop_enable_group(ctx, enable); 878 ctx->NewState |= _NEW_ALL; 879 } 880 break; 881 case GL_EVAL_BIT: 882 MEMCPY( &ctx->Eval, attr->data, sizeof(struct gl_eval_attrib) ); 883 ctx->NewState |= _NEW_EVAL; 884 break; 885 case GL_FOG_BIT: 886 { 887 const struct gl_fog_attrib *fog; 888 fog = (const struct gl_fog_attrib *) attr->data; 889 _mesa_set_enable(ctx, GL_FOG, fog->Enabled); 890 _mesa_Fogfv(GL_FOG_COLOR, fog->Color); 891 _mesa_Fogf(GL_FOG_DENSITY, fog->Density); 892 _mesa_Fogf(GL_FOG_START, fog->Start); 893 _mesa_Fogf(GL_FOG_END, fog->End); 894 _mesa_Fogf(GL_FOG_INDEX, fog->Index); 895 _mesa_Fogi(GL_FOG_MODE, fog->Mode); 896 } 897 break; 898 case GL_HINT_BIT: 899 { 900 const struct gl_hint_attrib *hint; 901 hint = (const struct gl_hint_attrib *) attr->data; 902 _mesa_Hint(GL_PERSPECTIVE_CORRECTION_HINT, 903 hint->PerspectiveCorrection ); 904 _mesa_Hint(GL_POINT_SMOOTH_HINT, hint->PointSmooth); 905 _mesa_Hint(GL_LINE_SMOOTH_HINT, hint->LineSmooth); 906 _mesa_Hint(GL_POLYGON_SMOOTH_HINT, hint->PolygonSmooth); 907 _mesa_Hint(GL_FOG_HINT, hint->Fog); 908 _mesa_Hint(GL_CLIP_VOLUME_CLIPPING_HINT_EXT, 909 hint->ClipVolumeClipping); 910 if (ctx->Extensions.ARB_texture_compression) 911 _mesa_Hint(GL_TEXTURE_COMPRESSION_HINT_ARB, 912 hint->TextureCompression); 913 } 914 break; 915 case GL_LIGHTING_BIT: 916 { 917 GLuint i; 918 const struct gl_light_attrib *light; 919 light = (const struct gl_light_attrib *) attr->data; 920 /* lighting enable */ 921 _mesa_set_enable(ctx, GL_LIGHTING, light->Enabled); 922 /* per-light state */ 923 924 if (ctx->ModelviewMatrixStack.Top->flags & MAT_DIRTY_INVERSE) 925 _math_matrix_analyse( ctx->ModelviewMatrixStack.Top ); 926 927 for (i = 0; i < MAX_LIGHTS; i++) { 928 GLenum lgt = (GLenum) (GL_LIGHT0 + i); 929 const struct gl_light *l = &light->Light[i]; 930 GLfloat tmp[4]; 931 _mesa_set_enable(ctx, lgt, l->Enabled); 932 _mesa_Lightfv( lgt, GL_AMBIENT, l->Ambient ); 933 _mesa_Lightfv( lgt, GL_DIFFUSE, l->Diffuse ); 934 _mesa_Lightfv( lgt, GL_SPECULAR, l->Specular ); 935 TRANSFORM_POINT( tmp, ctx->ModelviewMatrixStack.Top->inv, l->EyePosition ); 936 _mesa_Lightfv( lgt, GL_POSITION, tmp ); 937 TRANSFORM_POINT( tmp, ctx->ModelviewMatrixStack.Top->m, l->EyeDirection ); 938 _mesa_Lightfv( lgt, GL_SPOT_DIRECTION, tmp ); 939 _mesa_Lightfv( lgt, GL_SPOT_EXPONENT, &l->SpotExponent ); 940 _mesa_Lightfv( lgt, GL_SPOT_CUTOFF, &l->SpotCutoff ); 941 _mesa_Lightfv( lgt, GL_CONSTANT_ATTENUATION, 942 &l->ConstantAttenuation ); 943 _mesa_Lightfv( lgt, GL_LINEAR_ATTENUATION, 944 &l->LinearAttenuation ); 945 _mesa_Lightfv( lgt, GL_QUADRATIC_ATTENUATION, 946 &l->QuadraticAttenuation ); 947 } 948 /* light model */ 949 _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, 950 light->Model.Ambient); 951 _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 952 (GLfloat) light->Model.LocalViewer); 953 _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, 954 (GLfloat) light->Model.TwoSide); 955 _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, 956 (GLfloat) light->Model.ColorControl); 957 /* materials */ 958 MEMCPY(ctx->Light.Material, light->Material, 959 2 * sizeof(struct gl_material)); 960 /* shade model */ 961 _mesa_ShadeModel(light->ShadeModel); 962 /* color material */ 963 _mesa_ColorMaterial(light->ColorMaterialFace, 964 light->ColorMaterialMode); 965 _mesa_set_enable(ctx, GL_COLOR_MATERIAL, 966 light->ColorMaterialEnabled); 967 } 968 break; 969 case GL_LINE_BIT: 970 { 971 const struct gl_line_attrib *line; 972 line = (const struct gl_line_attrib *) attr->data; 973 _mesa_set_enable(ctx, GL_LINE_SMOOTH, line->SmoothFlag); 974 _mesa_set_enable(ctx, GL_LINE_STIPPLE, line->StippleFlag); 975 _mesa_LineStipple(line->StippleFactor, line->StipplePattern); 976 _mesa_LineWidth(line->Width); 977 } 978 break; 979 case GL_LIST_BIT: 980 MEMCPY( &ctx->List, attr->data, sizeof(struct gl_list_attrib) ); 981 break; 982 case GL_PIXEL_MODE_BIT: 983 MEMCPY( &ctx->Pixel, attr->data, sizeof(struct gl_pixel_attrib) ); 984 ctx->NewState |= _NEW_PIXEL; 985 break; 986 case GL_POINT_BIT: 987 { 988 const struct gl_point_attrib *point; 989 point = (const struct gl_point_attrib *) attr->data; 990 _mesa_PointSize(point->Size); 991 _mesa_set_enable(ctx, GL_POINT_SMOOTH, point->SmoothFlag); 992 _mesa_PointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, 993 point->Params); 994 _mesa_PointParameterfEXT(GL_POINT_SIZE_MIN_EXT, point->MinSize); 995 _mesa_PointParameterfEXT(GL_POINT_SIZE_MAX_EXT, point->MaxSize); 996 _mesa_PointParameterfEXT(GL_POINT_FADE_THRESHOLD_SIZE_EXT, 997 point->Threshold); 998 if (ctx->Extensions.NV_point_sprite) { 999 GLuint u; 1000 for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { 1001 _mesa_TexEnvi(GL_POINT_SPRITE_NV, GL_COORD_REPLACE_NV, 1002 (GLint) point->CoordReplace[u]); 1003 } 1004 _mesa_set_enable(ctx, GL_POINT_SPRITE_NV,point->PointSprite); 1005 _mesa_PointParameteriNV(GL_POINT_SPRITE_R_MODE_NV, 1006 ctx->Point.SpriteRMode); 1007 } 1008 } 1009 break; 1010 case GL_POLYGON_BIT: 1011 { 1012 const struct gl_polygon_attrib *polygon; 1013 polygon = (const struct gl_polygon_attrib *) attr->data; 1014 _mesa_CullFace(polygon->CullFaceMode); 1015 _mesa_FrontFace(polygon->FrontFace); 1016 _mesa_PolygonMode(GL_FRONT, polygon->FrontMode); 1017 _mesa_PolygonMode(GL_BACK, polygon->BackMode); 1018 _mesa_PolygonOffset(polygon->OffsetFactor, 1019 polygon->OffsetUnits); 1020 _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, polygon->SmoothFlag); 1021 _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, polygon->StippleFlag); 1022 _mesa_set_enable(ctx, GL_CULL_FACE, polygon->CullFlag); 1023 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_POINT, 1024 polygon->OffsetPoint); 1025 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_LINE, 1026 polygon->OffsetLine); 1027 _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, 1028 polygon->OffsetFill); 1029 } 1030 break; 1031 case GL_POLYGON_STIPPLE_BIT: 1032 MEMCPY( ctx->PolygonStipple, attr->data, 32*sizeof(GLuint) ); 1033 ctx->NewState |= _NEW_POLYGONSTIPPLE; 1034 if (ctx->Driver.PolygonStipple) 1035 ctx->Driver.PolygonStipple( ctx, (const GLubyte *) attr->data ); 1036 break; 1037 case GL_SCISSOR_BIT: 1038 { 1039 const struct gl_scissor_attrib *scissor; 1040 scissor = (const struct gl_scissor_attrib *) attr->data; 1041 _mesa_Scissor(scissor->X, scissor->Y, 1042 scissor->Width, scissor->Height); 1043 _mesa_set_enable(ctx, GL_SCISSOR_TEST, scissor->Enabled); 1044 } 1045 break; 1046 case GL_STENCIL_BUFFER_BIT: 1047 { 1048 const struct gl_stencil_attrib *stencil; 1049 stencil = (const struct gl_stencil_attrib *) attr->data; 1050 _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled); 1051 _mesa_ClearStencil(stencil->Clear); 1052 _mesa_StencilFunc(stencil->Function, stencil->Ref, 1053 stencil->ValueMask); 1054 _mesa_StencilMask(stencil->WriteMask); 1055 _mesa_StencilOp(stencil->FailFunc, stencil->ZFailFunc, 1056 stencil->ZPassFunc); 1057 } 1058 break; 1059 case GL_TRANSFORM_BIT: 1060 { 1061 GLuint i; 1062 const struct gl_transform_attrib *xform; 1063 xform = (const struct gl_transform_attrib *) attr->data; 1064 _mesa_MatrixMode(xform->MatrixMode); 1065 1066 if (ctx->ProjectionMatrixStack.Top->flags & MAT_DIRTY) 1067 _math_matrix_analyse( ctx->ProjectionMatrixStack.Top ); 1068 1069 /* restore clip planes */ 1070 for (i = 0; i < MAX_CLIP_PLANES; i++) { 1071 const GLuint mask = 1 << 1; 1072 const GLfloat *eyePlane = xform->EyeUserPlane[i]; 1073 COPY_4V(ctx->Transform.EyeUserPlane[i], eyePlane); 1074 if (xform->ClipPlanesEnabled & mask) { 1075 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE); 1076 } 1077 else { 1078 _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE); 1079 } 1080 if (ctx->Driver.ClipPlane) 1081 ctx->Driver.ClipPlane( ctx, i, eyePlane ); 1082 } 1083 1084 /* normalize/rescale */ 1085 if (xform->Normalize != ctx->Transform.Normalize) 1086 _mesa_set_enable(ctx, GL_NORMALIZE,ctx->Transform.Normalize); 1087 if (xform->RescaleNormals != ctx->Transform.RescaleNormals) 1088 _mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT, 1089 ctx->Transform.RescaleNormals); 1090 } 1091 break; 1092 case GL_TEXTURE_BIT: 1093 /* Take care of texture object reference counters */ 1094 { 1095 const struct gl_texture_attrib *texture; 1096 texture = (const struct gl_texture_attrib *) attr->data; 1097 pop_texture_group(ctx, texture); 1098 ctx->NewState |= _NEW_TEXTURE; 1099 } 1100 break; 1101 case GL_VIEWPORT_BIT: 1102 { 1103 const struct gl_viewport_attrib *vp; 1104 vp = (const struct gl_viewport_attrib *) attr->data; 1105 _mesa_Viewport(vp->X, vp->Y, vp->Width, vp->Height); 1106 _mesa_DepthRange(vp->Near, vp->Far); 1107 } 1108 break; 1109 case GL_MULTISAMPLE_BIT_ARB: 1110 { 1111 const struct gl_multisample_attrib *ms; 1112 ms = (const struct gl_multisample_attrib *) attr->data; 1113 _mesa_SampleCoverageARB(ms->SampleCoverageValue, 1114 ms->SampleCoverageInvert); 1115 } 1116 break; 1117 1118 default: 1119 _mesa_problem( ctx, "Bad attrib flag in PopAttrib"); 1120 break; 1121 } 1122 1123 next = attr->next; 1124 FREE( attr->data ); 1125 FREE( attr ); 1126 attr = next; 1127 } 1128} 1129 1130 1131#define GL_CLIENT_PACK_BIT (1<<20) 1132#define GL_CLIENT_UNPACK_BIT (1<<21) 1133 1134 1135void 1136_mesa_PushClientAttrib(GLbitfield mask) 1137{ 1138 struct gl_attrib_node *newnode; 1139 struct gl_attrib_node *head; 1140 1141 GET_CURRENT_CONTEXT(ctx); 1142 ASSERT_OUTSIDE_BEGIN_END(ctx); 1143 1144 if (ctx->ClientAttribStackDepth >= MAX_CLIENT_ATTRIB_STACK_DEPTH) { 1145 _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushClientAttrib" ); 1146 return; 1147 } 1148 1149 /* Build linked list of attribute nodes which save all attribute */ 1150 /* groups specified by the mask. */ 1151 head = NULL; 1152 1153 if (mask & GL_CLIENT_PIXEL_STORE_BIT) { 1154 struct gl_pixelstore_attrib *attr; 1155 /* packing attribs */ 1156 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 1157 MEMCPY( attr, &ctx->Pack, sizeof(struct gl_pixelstore_attrib) ); 1158 newnode = new_attrib_node( GL_CLIENT_PACK_BIT ); 1159 newnode->data = attr; 1160 newnode->next = head; 1161 head = newnode; 1162 /* unpacking attribs */ 1163 attr = MALLOC_STRUCT( gl_pixelstore_attrib ); 1164 MEMCPY( attr, &ctx->Unpack, sizeof(struct gl_pixelstore_attrib) ); 1165 newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT ); 1166 newnode->data = attr; 1167 newnode->next = head; 1168 head = newnode; 1169 } 1170 if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { 1171 struct gl_array_attrib *attr; 1172 attr = MALLOC_STRUCT( gl_array_attrib ); 1173 MEMCPY( attr, &ctx->Array, sizeof(struct gl_array_attrib) ); 1174 newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT ); 1175 newnode->data = attr; 1176 newnode->next = head; 1177 head = newnode; 1178 } 1179 1180 ctx->ClientAttribStack[ctx->ClientAttribStackDepth] = head; 1181 ctx->ClientAttribStackDepth++; 1182} 1183 1184 1185 1186 1187void 1188_mesa_PopClientAttrib(void) 1189{ 1190 struct gl_attrib_node *attr, *next; 1191 1192 GET_CURRENT_CONTEXT(ctx); 1193 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); 1194 1195 if (ctx->ClientAttribStackDepth == 0) { 1196 _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopClientAttrib" ); 1197 return; 1198 } 1199 1200 ctx->ClientAttribStackDepth--; 1201 attr = ctx->ClientAttribStack[ctx->ClientAttribStackDepth]; 1202 1203 while (attr) { 1204 switch (attr->kind) { 1205 case GL_CLIENT_PACK_BIT: 1206 MEMCPY( &ctx->Pack, attr->data, 1207 sizeof(struct gl_pixelstore_attrib) ); 1208 ctx->NewState |= _NEW_PACKUNPACK; 1209 break; 1210 case GL_CLIENT_UNPACK_BIT: 1211 MEMCPY( &ctx->Unpack, attr->data, 1212 sizeof(struct gl_pixelstore_attrib) ); 1213 ctx->NewState |= _NEW_PACKUNPACK; 1214 break; 1215 case GL_CLIENT_VERTEX_ARRAY_BIT: 1216 MEMCPY( &ctx->Array, attr->data, 1217 sizeof(struct gl_array_attrib) ); 1218 ctx->NewState |= _NEW_ARRAY; 1219 break; 1220 default: 1221 _mesa_problem( ctx, "Bad attrib flag in PopClientAttrib"); 1222 break; 1223 } 1224 1225 next = attr->next; 1226 FREE( attr->data ); 1227 FREE( attr ); 1228 attr = next; 1229 } 1230} 1231