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