1 /* 2 * Mesa 3-D graphics library 3 * Version: 7.5 4 * 5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. 6 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included 16 * in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 */ 25 26 27 #include "glheader.h" 28 #include "imports.h" 29 #include "context.h" 30 #include "enums.h" 31 #include "light.h" 32 #include "macros.h" 33 #include "simple_list.h" 34 #include "mtypes.h" 35 #include "math/m_matrix.h" 36 37 38 void GLAPIENTRY 39 _mesa_ShadeModel( GLenum mode ) 40 { 41 GET_CURRENT_CONTEXT(ctx); 42 ASSERT_OUTSIDE_BEGIN_END(ctx); 43 44 if (MESA_VERBOSE & VERBOSE_API) 45 _mesa_debug(ctx, "glShadeModel %s\n", _mesa_lookup_enum_by_nr(mode)); 46 47 if (mode != GL_FLAT && mode != GL_SMOOTH) { 48 _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel"); 49 return; 50 } 51 52 if (ctx->Light.ShadeModel == mode) 53 return; 54 55 FLUSH_VERTICES(ctx, _NEW_LIGHT); 56 ctx->Light.ShadeModel = mode; 57 58 if (ctx->Driver.ShadeModel) 59 ctx->Driver.ShadeModel( ctx, mode ); 60 } 61 62 63 /** 64 * Set the provoking vertex (the vertex which specifies the prim's 65 * color when flat shading) to either the first or last vertex of the 66 * triangle or line. 67 */ 68 void GLAPIENTRY 69 _mesa_ProvokingVertexEXT(GLenum mode) 70 { 71 GET_CURRENT_CONTEXT(ctx); 72 ASSERT_OUTSIDE_BEGIN_END(ctx); 73 74 if (MESA_VERBOSE&VERBOSE_API) 75 _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode); 76 77 switch (mode) { 78 case GL_FIRST_VERTEX_CONVENTION_EXT: 79 case GL_LAST_VERTEX_CONVENTION_EXT: 80 break; 81 default: 82 _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode); 83 return; 84 } 85 86 if (ctx->Light.ProvokingVertex == mode) 87 return; 88 89 FLUSH_VERTICES(ctx, _NEW_LIGHT); 90 ctx->Light.ProvokingVertex = mode; 91 } 92 93 94 /** 95 * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set 96 * per-light state. 97 * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction 98 * will have already been transformed by the modelview matrix! 99 * Also, all error checking should have already been done. 100 */ 101 void 102 _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params) 103 { 104 struct gl_light *light; 105 106 ASSERT(lnum < MAX_LIGHTS); 107 light = &ctx->Light.Light[lnum]; 108 109 switch (pname) { 110 case GL_AMBIENT: 111 if (TEST_EQ_4V(light->Ambient, params)) 112 return; 113 FLUSH_VERTICES(ctx, _NEW_LIGHT); 114 COPY_4V( light->Ambient, params ); 115 break; 116 case GL_DIFFUSE: 117 if (TEST_EQ_4V(light->Diffuse, params)) 118 return; 119 FLUSH_VERTICES(ctx, _NEW_LIGHT); 120 COPY_4V( light->Diffuse, params ); 121 break; 122 case GL_SPECULAR: 123 if (TEST_EQ_4V(light->Specular, params)) 124 return; 125 FLUSH_VERTICES(ctx, _NEW_LIGHT); 126 COPY_4V( light->Specular, params ); 127 break; 128 case GL_POSITION: 129 /* NOTE: position has already been transformed by ModelView! */ 130 if (TEST_EQ_4V(light->EyePosition, params)) 131 return; 132 FLUSH_VERTICES(ctx, _NEW_LIGHT); 133 COPY_4V(light->EyePosition, params); 134 if (light->EyePosition[3] != 0.0F) 135 light->_Flags |= LIGHT_POSITIONAL; 136 else 137 light->_Flags &= ~LIGHT_POSITIONAL; 138 break; 139 case GL_SPOT_DIRECTION: 140 /* NOTE: Direction already transformed by inverse ModelView! */ 141 if (TEST_EQ_3V(light->SpotDirection, params)) 142 return; 143 FLUSH_VERTICES(ctx, _NEW_LIGHT); 144 COPY_3V(light->SpotDirection, params); 145 break; 146 case GL_SPOT_EXPONENT: 147 ASSERT(params[0] >= 0.0); 148 ASSERT(params[0] <= ctx->Const.MaxSpotExponent); 149 if (light->SpotExponent == params[0]) 150 return; 151 FLUSH_VERTICES(ctx, _NEW_LIGHT); 152 light->SpotExponent = params[0]; 153 break; 154 case GL_SPOT_CUTOFF: 155 ASSERT(params[0] == 180.0 || (params[0] >= 0.0 && params[0] <= 90.0)); 156 if (light->SpotCutoff == params[0]) 157 return; 158 FLUSH_VERTICES(ctx, _NEW_LIGHT); 159 light->SpotCutoff = params[0]; 160 light->_CosCutoff = (GLfloat) (cos(light->SpotCutoff * DEG2RAD)); 161 if (light->_CosCutoff < 0) 162 light->_CosCutoff = 0; 163 if (light->SpotCutoff != 180.0F) 164 light->_Flags |= LIGHT_SPOT; 165 else 166 light->_Flags &= ~LIGHT_SPOT; 167 break; 168 case GL_CONSTANT_ATTENUATION: 169 ASSERT(params[0] >= 0.0); 170 if (light->ConstantAttenuation == params[0]) 171 return; 172 FLUSH_VERTICES(ctx, _NEW_LIGHT); 173 light->ConstantAttenuation = params[0]; 174 break; 175 case GL_LINEAR_ATTENUATION: 176 ASSERT(params[0] >= 0.0); 177 if (light->LinearAttenuation == params[0]) 178 return; 179 FLUSH_VERTICES(ctx, _NEW_LIGHT); 180 light->LinearAttenuation = params[0]; 181 break; 182 case GL_QUADRATIC_ATTENUATION: 183 ASSERT(params[0] >= 0.0); 184 if (light->QuadraticAttenuation == params[0]) 185 return; 186 FLUSH_VERTICES(ctx, _NEW_LIGHT); 187 light->QuadraticAttenuation = params[0]; 188 break; 189 default: 190 _mesa_problem(ctx, "Unexpected pname in _mesa_light()"); 191 return; 192 } 193 194 if (ctx->Driver.Lightfv) 195 ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params ); 196 } 197 198 199 void GLAPIENTRY 200 _mesa_Lightf( GLenum light, GLenum pname, GLfloat param ) 201 { 202 GLfloat fparam[4]; 203 fparam[0] = param; 204 fparam[1] = fparam[2] = fparam[3] = 0.0F; 205 _mesa_Lightfv( light, pname, fparam ); 206 } 207 208 209 void GLAPIENTRY 210 _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) 211 { 212 GET_CURRENT_CONTEXT(ctx); 213 GLint i = (GLint) (light - GL_LIGHT0); 214 GLfloat temp[4]; 215 ASSERT_OUTSIDE_BEGIN_END(ctx); 216 217 if (i < 0 || i >= (GLint) ctx->Const.MaxLights) { 218 _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light ); 219 return; 220 } 221 222 /* do particular error checks, transformations */ 223 switch (pname) { 224 case GL_AMBIENT: 225 case GL_DIFFUSE: 226 case GL_SPECULAR: 227 /* nothing */ 228 break; 229 case GL_POSITION: 230 /* transform position by ModelView matrix */ 231 TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params); 232 params = temp; 233 break; 234 case GL_SPOT_DIRECTION: 235 /* transform direction by inverse modelview */ 236 if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) { 237 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); 238 } 239 TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m); 240 params = temp; 241 break; 242 case GL_SPOT_EXPONENT: 243 if (params[0] < 0.0 || params[0] > ctx->Const.MaxSpotExponent) { 244 _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); 245 return; 246 } 247 break; 248 case GL_SPOT_CUTOFF: 249 if ((params[0] < 0.0 || params[0] > 90.0) && params[0] != 180.0) { 250 _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); 251 return; 252 } 253 break; 254 case GL_CONSTANT_ATTENUATION: 255 if (params[0] < 0.0) { 256 _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); 257 return; 258 } 259 break; 260 case GL_LINEAR_ATTENUATION: 261 if (params[0] < 0.0) { 262 _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); 263 return; 264 } 265 break; 266 case GL_QUADRATIC_ATTENUATION: 267 if (params[0] < 0.0) { 268 _mesa_error(ctx, GL_INVALID_VALUE, "glLight"); 269 return; 270 } 271 break; 272 default: 273 _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname); 274 return; 275 } 276 277 _mesa_light(ctx, i, pname, params); 278 } 279 280 281 void GLAPIENTRY 282 _mesa_Lighti( GLenum light, GLenum pname, GLint param ) 283 { 284 GLint iparam[4]; 285 iparam[0] = param; 286 iparam[1] = iparam[2] = iparam[3] = 0; 287 _mesa_Lightiv( light, pname, iparam ); 288 } 289 290 291 void GLAPIENTRY 292 _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params ) 293 { 294 GLfloat fparam[4]; 295 296 switch (pname) { 297 case GL_AMBIENT: 298 case GL_DIFFUSE: 299 case GL_SPECULAR: 300 fparam[0] = INT_TO_FLOAT( params[0] ); 301 fparam[1] = INT_TO_FLOAT( params[1] ); 302 fparam[2] = INT_TO_FLOAT( params[2] ); 303 fparam[3] = INT_TO_FLOAT( params[3] ); 304 break; 305 case GL_POSITION: 306 fparam[0] = (GLfloat) params[0]; 307 fparam[1] = (GLfloat) params[1]; 308 fparam[2] = (GLfloat) params[2]; 309 fparam[3] = (GLfloat) params[3]; 310 break; 311 case GL_SPOT_DIRECTION: 312 fparam[0] = (GLfloat) params[0]; 313 fparam[1] = (GLfloat) params[1]; 314 fparam[2] = (GLfloat) params[2]; 315 break; 316 case GL_SPOT_EXPONENT: 317 case GL_SPOT_CUTOFF: 318 case GL_CONSTANT_ATTENUATION: 319 case GL_LINEAR_ATTENUATION: 320 case GL_QUADRATIC_ATTENUATION: 321 fparam[0] = (GLfloat) params[0]; 322 break; 323 default: 324 /* error will be caught later in gl_Lightfv */ 325 ; 326 } 327 328 _mesa_Lightfv( light, pname, fparam ); 329 } 330 331 332 333 void GLAPIENTRY 334 _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params ) 335 { 336 GET_CURRENT_CONTEXT(ctx); 337 GLint l = (GLint) (light - GL_LIGHT0); 338 ASSERT_OUTSIDE_BEGIN_END(ctx); 339 340 if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { 341 _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" ); 342 return; 343 } 344 345 switch (pname) { 346 case GL_AMBIENT: 347 COPY_4V( params, ctx->Light.Light[l].Ambient ); 348 break; 349 case GL_DIFFUSE: 350 COPY_4V( params, ctx->Light.Light[l].Diffuse ); 351 break; 352 case GL_SPECULAR: 353 COPY_4V( params, ctx->Light.Light[l].Specular ); 354 break; 355 case GL_POSITION: 356 COPY_4V( params, ctx->Light.Light[l].EyePosition ); 357 break; 358 case GL_SPOT_DIRECTION: 359 COPY_3V( params, ctx->Light.Light[l].SpotDirection ); 360 break; 361 case GL_SPOT_EXPONENT: 362 params[0] = ctx->Light.Light[l].SpotExponent; 363 break; 364 case GL_SPOT_CUTOFF: 365 params[0] = ctx->Light.Light[l].SpotCutoff; 366 break; 367 case GL_CONSTANT_ATTENUATION: 368 params[0] = ctx->Light.Light[l].ConstantAttenuation; 369 break; 370 case GL_LINEAR_ATTENUATION: 371 params[0] = ctx->Light.Light[l].LinearAttenuation; 372 break; 373 case GL_QUADRATIC_ATTENUATION: 374 params[0] = ctx->Light.Light[l].QuadraticAttenuation; 375 break; 376 default: 377 _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" ); 378 break; 379 } 380 } 381 382 383 void GLAPIENTRY 384 _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params ) 385 { 386 GET_CURRENT_CONTEXT(ctx); 387 GLint l = (GLint) (light - GL_LIGHT0); 388 ASSERT_OUTSIDE_BEGIN_END(ctx); 389 390 if (l < 0 || l >= (GLint) ctx->Const.MaxLights) { 391 _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" ); 392 return; 393 } 394 395 switch (pname) { 396 case GL_AMBIENT: 397 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]); 398 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]); 399 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]); 400 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]); 401 break; 402 case GL_DIFFUSE: 403 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]); 404 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]); 405 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]); 406 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]); 407 break; 408 case GL_SPECULAR: 409 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]); 410 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]); 411 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]); 412 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]); 413 break; 414 case GL_POSITION: 415 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0]; 416 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1]; 417 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2]; 418 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3]; 419 break; 420 case GL_SPOT_DIRECTION: 421 params[0] = (GLint) ctx->Light.Light[l].SpotDirection[0]; 422 params[1] = (GLint) ctx->Light.Light[l].SpotDirection[1]; 423 params[2] = (GLint) ctx->Light.Light[l].SpotDirection[2]; 424 break; 425 case GL_SPOT_EXPONENT: 426 params[0] = (GLint) ctx->Light.Light[l].SpotExponent; 427 break; 428 case GL_SPOT_CUTOFF: 429 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff; 430 break; 431 case GL_CONSTANT_ATTENUATION: 432 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation; 433 break; 434 case GL_LINEAR_ATTENUATION: 435 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation; 436 break; 437 case GL_QUADRATIC_ATTENUATION: 438 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation; 439 break; 440 default: 441 _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" ); 442 break; 443 } 444 } 445 446 447 448 /**********************************************************************/ 449 /*** Light Model ***/ 450 /**********************************************************************/ 451 452 453 void GLAPIENTRY 454 _mesa_LightModelfv( GLenum pname, const GLfloat *params ) 455 { 456 GLenum newenum; 457 GLboolean newbool; 458 GET_CURRENT_CONTEXT(ctx); 459 ASSERT_OUTSIDE_BEGIN_END(ctx); 460 461 switch (pname) { 462 case GL_LIGHT_MODEL_AMBIENT: 463 if (TEST_EQ_4V( ctx->Light.Model.Ambient, params )) 464 return; 465 FLUSH_VERTICES(ctx, _NEW_LIGHT); 466 COPY_4V( ctx->Light.Model.Ambient, params ); 467 break; 468 case GL_LIGHT_MODEL_LOCAL_VIEWER: 469 if (ctx->API != API_OPENGL) 470 goto invalid_pname; 471 newbool = (params[0]!=0.0); 472 if (ctx->Light.Model.LocalViewer == newbool) 473 return; 474 FLUSH_VERTICES(ctx, _NEW_LIGHT); 475 ctx->Light.Model.LocalViewer = newbool; 476 break; 477 case GL_LIGHT_MODEL_TWO_SIDE: 478 newbool = (params[0]!=0.0); 479 if (ctx->Light.Model.TwoSide == newbool) 480 return; 481 FLUSH_VERTICES(ctx, _NEW_LIGHT); 482 ctx->Light.Model.TwoSide = newbool; 483 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 484 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; 485 else 486 ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; 487 break; 488 case GL_LIGHT_MODEL_COLOR_CONTROL: 489 if (ctx->API != API_OPENGL) 490 goto invalid_pname; 491 if (params[0] == (GLfloat) GL_SINGLE_COLOR) 492 newenum = GL_SINGLE_COLOR; 493 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) 494 newenum = GL_SEPARATE_SPECULAR_COLOR; 495 else { 496 _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)", 497 (GLint) params[0] ); 498 return; 499 } 500 if (ctx->Light.Model.ColorControl == newenum) 501 return; 502 FLUSH_VERTICES(ctx, _NEW_LIGHT); 503 ctx->Light.Model.ColorControl = newenum; 504 break; 505 default: 506 goto invalid_pname; 507 } 508 509 if (ctx->Driver.LightModelfv) 510 ctx->Driver.LightModelfv( ctx, pname, params ); 511 512 return; 513 514 invalid_pname: 515 _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname ); 516 return; 517 } 518 519 520 void GLAPIENTRY 521 _mesa_LightModeliv( GLenum pname, const GLint *params ) 522 { 523 GLfloat fparam[4]; 524 525 switch (pname) { 526 case GL_LIGHT_MODEL_AMBIENT: 527 fparam[0] = INT_TO_FLOAT( params[0] ); 528 fparam[1] = INT_TO_FLOAT( params[1] ); 529 fparam[2] = INT_TO_FLOAT( params[2] ); 530 fparam[3] = INT_TO_FLOAT( params[3] ); 531 break; 532 case GL_LIGHT_MODEL_LOCAL_VIEWER: 533 case GL_LIGHT_MODEL_TWO_SIDE: 534 case GL_LIGHT_MODEL_COLOR_CONTROL: 535 fparam[0] = (GLfloat) params[0]; 536 break; 537 default: 538 /* Error will be caught later in gl_LightModelfv */ 539 ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F); 540 } 541 _mesa_LightModelfv( pname, fparam ); 542 } 543 544 545 void GLAPIENTRY 546 _mesa_LightModeli( GLenum pname, GLint param ) 547 { 548 GLint iparam[4]; 549 iparam[0] = param; 550 iparam[1] = iparam[2] = iparam[3] = 0; 551 _mesa_LightModeliv( pname, iparam ); 552 } 553 554 555 void GLAPIENTRY 556 _mesa_LightModelf( GLenum pname, GLfloat param ) 557 { 558 GLfloat fparam[4]; 559 fparam[0] = param; 560 fparam[1] = fparam[2] = fparam[3] = 0.0F; 561 _mesa_LightModelfv( pname, fparam ); 562 } 563 564 565 566 /********** MATERIAL **********/ 567 568 569 /* 570 * Given a face and pname value (ala glColorMaterial), compute a bitmask 571 * of the targeted material values. 572 */ 573 GLuint 574 _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname, 575 GLuint legal, const char *where ) 576 { 577 GLuint bitmask = 0; 578 579 /* Make a bitmask indicating what material attribute(s) we're updating */ 580 switch (pname) { 581 case GL_EMISSION: 582 bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION; 583 break; 584 case GL_AMBIENT: 585 bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT; 586 break; 587 case GL_DIFFUSE: 588 bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE; 589 break; 590 case GL_SPECULAR: 591 bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR; 592 break; 593 case GL_SHININESS: 594 bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS; 595 break; 596 case GL_AMBIENT_AND_DIFFUSE: 597 bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT; 598 bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE; 599 break; 600 case GL_COLOR_INDEXES: 601 bitmask |= MAT_BIT_FRONT_INDEXES | MAT_BIT_BACK_INDEXES; 602 break; 603 default: 604 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 605 return 0; 606 } 607 608 if (face==GL_FRONT) { 609 bitmask &= FRONT_MATERIAL_BITS; 610 } 611 else if (face==GL_BACK) { 612 bitmask &= BACK_MATERIAL_BITS; 613 } 614 else if (face != GL_FRONT_AND_BACK) { 615 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 616 return 0; 617 } 618 619 if (bitmask & ~legal) { 620 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 621 return 0; 622 } 623 624 return bitmask; 625 } 626 627 628 629 /* Update derived values following a change in ctx->Light.Material 630 */ 631 void 632 _mesa_update_material( struct gl_context *ctx, GLuint bitmask ) 633 { 634 struct gl_light *light, *list = &ctx->Light.EnabledList; 635 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 636 637 if (MESA_VERBOSE & VERBOSE_MATERIAL) 638 _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask); 639 640 if (!bitmask) 641 return; 642 643 /* update material ambience */ 644 if (bitmask & MAT_BIT_FRONT_AMBIENT) { 645 foreach (light, list) { 646 SCALE_3V( light->_MatAmbient[0], light->Ambient, 647 mat[MAT_ATTRIB_FRONT_AMBIENT]); 648 } 649 } 650 651 if (bitmask & MAT_BIT_BACK_AMBIENT) { 652 foreach (light, list) { 653 SCALE_3V( light->_MatAmbient[1], light->Ambient, 654 mat[MAT_ATTRIB_BACK_AMBIENT]); 655 } 656 } 657 658 /* update BaseColor = emission + scene's ambience * material's ambience */ 659 if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) { 660 COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] ); 661 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT], 662 ctx->Light.Model.Ambient ); 663 } 664 665 if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) { 666 COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] ); 667 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT], 668 ctx->Light.Model.Ambient ); 669 } 670 671 /* update material diffuse values */ 672 if (bitmask & MAT_BIT_FRONT_DIFFUSE) { 673 foreach (light, list) { 674 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, 675 mat[MAT_ATTRIB_FRONT_DIFFUSE] ); 676 } 677 } 678 679 if (bitmask & MAT_BIT_BACK_DIFFUSE) { 680 foreach (light, list) { 681 SCALE_3V( light->_MatDiffuse[1], light->Diffuse, 682 mat[MAT_ATTRIB_BACK_DIFFUSE] ); 683 } 684 } 685 686 /* update material specular values */ 687 if (bitmask & MAT_BIT_FRONT_SPECULAR) { 688 foreach (light, list) { 689 SCALE_3V( light->_MatSpecular[0], light->Specular, 690 mat[MAT_ATTRIB_FRONT_SPECULAR]); 691 } 692 } 693 694 if (bitmask & MAT_BIT_BACK_SPECULAR) { 695 foreach (light, list) { 696 SCALE_3V( light->_MatSpecular[1], light->Specular, 697 mat[MAT_ATTRIB_BACK_SPECULAR]); 698 } 699 } 700 } 701 702 703 /* 704 * Update the current materials from the given rgba color 705 * according to the bitmask in _ColorMaterialBitmask, which is 706 * set by glColorMaterial(). 707 */ 708 void 709 _mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] ) 710 { 711 const GLbitfield bitmask = ctx->Light._ColorMaterialBitmask; 712 struct gl_material *mat = &ctx->Light.Material; 713 int i; 714 715 for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) 716 if (bitmask & (1<<i)) 717 COPY_4FV( mat->Attrib[i], color ); 718 719 _mesa_update_material( ctx, bitmask ); 720 } 721 722 723 void GLAPIENTRY 724 _mesa_ColorMaterial( GLenum face, GLenum mode ) 725 { 726 GET_CURRENT_CONTEXT(ctx); 727 GLuint bitmask; 728 GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION | 729 MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR | 730 MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE | 731 MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT); 732 ASSERT_OUTSIDE_BEGIN_END(ctx); 733 734 if (MESA_VERBOSE&VERBOSE_API) 735 _mesa_debug(ctx, "glColorMaterial %s %s\n", 736 _mesa_lookup_enum_by_nr(face), 737 _mesa_lookup_enum_by_nr(mode)); 738 739 bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial"); 740 if (bitmask == 0) 741 return; /* error was recorded */ 742 743 if (ctx->Light._ColorMaterialBitmask == bitmask && 744 ctx->Light.ColorMaterialFace == face && 745 ctx->Light.ColorMaterialMode == mode) 746 return; 747 748 FLUSH_VERTICES(ctx, _NEW_LIGHT); 749 ctx->Light._ColorMaterialBitmask = bitmask; 750 ctx->Light.ColorMaterialFace = face; 751 ctx->Light.ColorMaterialMode = mode; 752 753 if (ctx->Light.ColorMaterialEnabled) { 754 FLUSH_CURRENT( ctx, 0 ); 755 _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); 756 } 757 758 if (ctx->Driver.ColorMaterial) 759 ctx->Driver.ColorMaterial( ctx, face, mode ); 760 } 761 762 763 void GLAPIENTRY 764 _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) 765 { 766 GET_CURRENT_CONTEXT(ctx); 767 GLuint f; 768 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 769 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ 770 771 FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ 772 773 if (face==GL_FRONT) { 774 f = 0; 775 } 776 else if (face==GL_BACK) { 777 f = 1; 778 } 779 else { 780 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" ); 781 return; 782 } 783 784 switch (pname) { 785 case GL_AMBIENT: 786 COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] ); 787 break; 788 case GL_DIFFUSE: 789 COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] ); 790 break; 791 case GL_SPECULAR: 792 COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] ); 793 break; 794 case GL_EMISSION: 795 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] ); 796 break; 797 case GL_SHININESS: 798 *params = mat[MAT_ATTRIB_SHININESS(f)][0]; 799 break; 800 case GL_COLOR_INDEXES: 801 if (ctx->API != API_OPENGL) { 802 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 803 return; 804 } 805 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0]; 806 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1]; 807 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2]; 808 break; 809 default: 810 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 811 } 812 } 813 814 815 void GLAPIENTRY 816 _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) 817 { 818 GET_CURRENT_CONTEXT(ctx); 819 GLuint f; 820 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 821 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ 822 823 ASSERT(ctx->API == API_OPENGL); 824 825 FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ 826 827 if (face==GL_FRONT) { 828 f = 0; 829 } 830 else if (face==GL_BACK) { 831 f = 1; 832 } 833 else { 834 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" ); 835 return; 836 } 837 switch (pname) { 838 case GL_AMBIENT: 839 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] ); 840 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] ); 841 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] ); 842 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] ); 843 break; 844 case GL_DIFFUSE: 845 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] ); 846 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] ); 847 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] ); 848 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] ); 849 break; 850 case GL_SPECULAR: 851 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] ); 852 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] ); 853 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] ); 854 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] ); 855 break; 856 case GL_EMISSION: 857 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] ); 858 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] ); 859 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] ); 860 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] ); 861 break; 862 case GL_SHININESS: 863 *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] ); 864 break; 865 case GL_COLOR_INDEXES: 866 params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] ); 867 params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] ); 868 params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] ); 869 break; 870 default: 871 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 872 } 873 } 874 875 876 877 /** 878 * Examine current lighting parameters to determine if the optimized lighting 879 * function can be used. 880 * Also, precompute some lighting values such as the products of light 881 * source and material ambient, diffuse and specular coefficients. 882 */ 883 void 884 _mesa_update_lighting( struct gl_context *ctx ) 885 { 886 GLbitfield flags = 0; 887 struct gl_light *light; 888 ctx->Light._NeedEyeCoords = GL_FALSE; 889 890 if (!ctx->Light.Enabled) 891 return; 892 893 foreach(light, &ctx->Light.EnabledList) { 894 flags |= light->_Flags; 895 } 896 897 ctx->Light._NeedVertices = 898 ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || 899 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || 900 ctx->Light.Model.LocalViewer); 901 902 ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) || 903 ctx->Light.Model.LocalViewer); 904 905 /* XXX: This test is overkill & needs to be fixed both for software and 906 * hardware t&l drivers. The above should be sufficient & should 907 * be tested to verify this. 908 */ 909 if (ctx->Light._NeedVertices) 910 ctx->Light._NeedEyeCoords = GL_TRUE; 911 912 /* Precompute some shading values. Although we reference 913 * Light.Material here, we can get away without flushing 914 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes 915 * are flushed, they will update the derived state at that time. 916 */ 917 if (ctx->Light.Model.TwoSide) 918 _mesa_update_material(ctx, 919 MAT_BIT_FRONT_EMISSION | 920 MAT_BIT_FRONT_AMBIENT | 921 MAT_BIT_FRONT_DIFFUSE | 922 MAT_BIT_FRONT_SPECULAR | 923 MAT_BIT_BACK_EMISSION | 924 MAT_BIT_BACK_AMBIENT | 925 MAT_BIT_BACK_DIFFUSE | 926 MAT_BIT_BACK_SPECULAR); 927 else 928 _mesa_update_material(ctx, 929 MAT_BIT_FRONT_EMISSION | 930 MAT_BIT_FRONT_AMBIENT | 931 MAT_BIT_FRONT_DIFFUSE | 932 MAT_BIT_FRONT_SPECULAR); 933 } 934 935 936 /** 937 * Update state derived from light position, spot direction. 938 * Called upon: 939 * _NEW_MODELVIEW 940 * _NEW_LIGHT 941 * _TNL_NEW_NEED_EYE_COORDS 942 * 943 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled. 944 * Also update on lighting space changes. 945 */ 946 static void 947 compute_light_positions( struct gl_context *ctx ) 948 { 949 struct gl_light *light; 950 static const GLfloat eye_z[3] = { 0, 0, 1 }; 951 952 if (!ctx->Light.Enabled) 953 return; 954 955 if (ctx->_NeedEyeCoords) { 956 COPY_3V( ctx->_EyeZDir, eye_z ); 957 } 958 else { 959 TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m ); 960 } 961 962 foreach (light, &ctx->Light.EnabledList) { 963 964 if (ctx->_NeedEyeCoords) { 965 /* _Position is in eye coordinate space */ 966 COPY_4FV( light->_Position, light->EyePosition ); 967 } 968 else { 969 /* _Position is in object coordinate space */ 970 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv, 971 light->EyePosition ); 972 } 973 974 if (!(light->_Flags & LIGHT_POSITIONAL)) { 975 /* VP (VP) = Normalize( Position ) */ 976 COPY_3V( light->_VP_inf_norm, light->_Position ); 977 NORMALIZE_3FV( light->_VP_inf_norm ); 978 979 if (!ctx->Light.Model.LocalViewer) { 980 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */ 981 ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir); 982 NORMALIZE_3FV( light->_h_inf_norm ); 983 } 984 light->_VP_inf_spot_attenuation = 1.0; 985 } 986 else { 987 /* positional light w/ homogeneous coordinate, divide by W */ 988 GLfloat wInv = (GLfloat)1.0 / light->_Position[3]; 989 light->_Position[0] *= wInv; 990 light->_Position[1] *= wInv; 991 light->_Position[2] *= wInv; 992 } 993 994 if (light->_Flags & LIGHT_SPOT) { 995 /* Note: we normalize the spot direction now */ 996 997 if (ctx->_NeedEyeCoords) { 998 COPY_3V( light->_NormSpotDirection, light->SpotDirection ); 999 NORMALIZE_3FV( light->_NormSpotDirection ); 1000 } 1001 else { 1002 GLfloat spotDir[3]; 1003 COPY_3V(spotDir, light->SpotDirection); 1004 NORMALIZE_3FV(spotDir); 1005 TRANSFORM_NORMAL( light->_NormSpotDirection, 1006 spotDir, 1007 ctx->ModelviewMatrixStack.Top->m); 1008 } 1009 1010 NORMALIZE_3FV( light->_NormSpotDirection ); 1011 1012 if (!(light->_Flags & LIGHT_POSITIONAL)) { 1013 GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm, 1014 light->_NormSpotDirection); 1015 1016 if (PV_dot_dir > light->_CosCutoff) { 1017 light->_VP_inf_spot_attenuation = 1018 powf(PV_dot_dir, light->SpotExponent); 1019 } 1020 else { 1021 light->_VP_inf_spot_attenuation = 0; 1022 } 1023 } 1024 } 1025 } 1026 } 1027 1028 1029 1030 static void 1031 update_modelview_scale( struct gl_context *ctx ) 1032 { 1033 ctx->_ModelViewInvScale = 1.0F; 1034 if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) { 1035 const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv; 1036 GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; 1037 if (f < 1e-12) f = 1.0; 1038 if (ctx->_NeedEyeCoords) 1039 ctx->_ModelViewInvScale = (GLfloat) INV_SQRTF(f); 1040 else 1041 ctx->_ModelViewInvScale = (GLfloat) SQRTF(f); 1042 } 1043 } 1044 1045 1046 /** 1047 * Bring up to date any state that relies on _NeedEyeCoords. 1048 */ 1049 void 1050 _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ) 1051 { 1052 const GLuint oldneedeyecoords = ctx->_NeedEyeCoords; 1053 1054 (void) new_state; 1055 ctx->_NeedEyeCoords = GL_FALSE; 1056 1057 if (ctx->_ForceEyeCoords || 1058 (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) || 1059 ctx->Point._Attenuated || 1060 ctx->Light._NeedEyeCoords) 1061 ctx->_NeedEyeCoords = GL_TRUE; 1062 1063 if (ctx->Light.Enabled && 1064 !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) 1065 ctx->_NeedEyeCoords = GL_TRUE; 1066 1067 /* Check if the truth-value interpretations of the bitfields have 1068 * changed: 1069 */ 1070 if (oldneedeyecoords != ctx->_NeedEyeCoords) { 1071 /* Recalculate all state that depends on _NeedEyeCoords. 1072 */ 1073 update_modelview_scale(ctx); 1074 compute_light_positions( ctx ); 1075 1076 if (ctx->Driver.LightingSpaceChange) 1077 ctx->Driver.LightingSpaceChange( ctx ); 1078 } 1079 else { 1080 GLuint new_state2 = ctx->NewState; 1081 1082 /* Recalculate that same state only if it has been invalidated 1083 * by other statechanges. 1084 */ 1085 if (new_state2 & _NEW_MODELVIEW) 1086 update_modelview_scale(ctx); 1087 1088 if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW)) 1089 compute_light_positions( ctx ); 1090 } 1091 } 1092 1093 1094 /** 1095 * Drivers may need this if the hardware tnl unit doesn't support the 1096 * light-in-modelspace optimization. It's also useful for debugging. 1097 */ 1098 void 1099 _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ) 1100 { 1101 ctx->_ForceEyeCoords = !flag; 1102 ctx->NewState |= _NEW_POINT; /* one of the bits from 1103 * _MESA_NEW_NEED_EYE_COORDS. 1104 */ 1105 } 1106 1107 1108 1109 /**********************************************************************/ 1110 /***** Initialization *****/ 1111 /**********************************************************************/ 1112 1113 /** 1114 * Initialize the n-th light data structure. 1115 * 1116 * \param l pointer to the gl_light structure to be initialized. 1117 * \param n number of the light. 1118 * \note The defaults for light 0 are different than the other lights. 1119 */ 1120 static void 1121 init_light( struct gl_light *l, GLuint n ) 1122 { 1123 make_empty_list( l ); 1124 1125 ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 ); 1126 if (n==0) { 1127 ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 ); 1128 ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 ); 1129 } 1130 else { 1131 ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 ); 1132 ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 ); 1133 } 1134 ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 ); 1135 ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 ); 1136 l->SpotExponent = 0.0; 1137 l->SpotCutoff = 180.0; 1138 l->_CosCutoff = 0.0; /* KW: -ve values not admitted */ 1139 l->ConstantAttenuation = 1.0; 1140 l->LinearAttenuation = 0.0; 1141 l->QuadraticAttenuation = 0.0; 1142 l->Enabled = GL_FALSE; 1143 } 1144 1145 1146 /** 1147 * Initialize the light model data structure. 1148 * 1149 * \param lm pointer to the gl_lightmodel structure to be initialized. 1150 */ 1151 static void 1152 init_lightmodel( struct gl_lightmodel *lm ) 1153 { 1154 ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F ); 1155 lm->LocalViewer = GL_FALSE; 1156 lm->TwoSide = GL_FALSE; 1157 lm->ColorControl = GL_SINGLE_COLOR; 1158 } 1159 1160 1161 /** 1162 * Initialize the material data structure. 1163 * 1164 * \param m pointer to the gl_material structure to be initialized. 1165 */ 1166 static void 1167 init_material( struct gl_material *m ) 1168 { 1169 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F ); 1170 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F ); 1171 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F ); 1172 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F ); 1173 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F ); 1174 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F ); 1175 1176 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F ); 1177 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F ); 1178 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F ); 1179 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F ); 1180 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F ); 1181 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F ); 1182 } 1183 1184 1185 /** 1186 * Initialize all lighting state for the given context. 1187 */ 1188 void 1189 _mesa_init_lighting( struct gl_context *ctx ) 1190 { 1191 GLuint i; 1192 1193 /* Lighting group */ 1194 for (i = 0; i < MAX_LIGHTS; i++) { 1195 init_light( &ctx->Light.Light[i], i ); 1196 } 1197 make_empty_list( &ctx->Light.EnabledList ); 1198 1199 init_lightmodel( &ctx->Light.Model ); 1200 init_material( &ctx->Light.Material ); 1201 ctx->Light.ShadeModel = GL_SMOOTH; 1202 ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT; 1203 ctx->Light.Enabled = GL_FALSE; 1204 ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK; 1205 ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE; 1206 ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx, 1207 GL_FRONT_AND_BACK, 1208 GL_AMBIENT_AND_DIFFUSE, ~0, 1209 NULL ); 1210 1211 ctx->Light.ColorMaterialEnabled = GL_FALSE; 1212 ctx->Light.ClampVertexColor = GL_TRUE; 1213 1214 /* Miscellaneous */ 1215 ctx->Light._NeedEyeCoords = GL_FALSE; 1216 ctx->_NeedEyeCoords = GL_FALSE; 1217 ctx->_ForceEyeCoords = GL_FALSE; 1218 ctx->_ModelViewInvScale = 1.0; 1219 } 1220 1221 1222 /** 1223 * Deallocate malloc'd lighting state attached to given context. 1224 */ 1225 void 1226 _mesa_free_lighting_data( struct gl_context *ctx ) 1227 { 1228 } 1229