light.c revision 8df3f9bd5f7626a4548e9901c0b7af33a21af8a6
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 38void 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 */ 68void 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 */ 101void 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 199void 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 209void 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 281void 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 291void 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 333void 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 383void 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 453void 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 newbool = (params[0]!=0.0); 470 if (ctx->Light.Model.LocalViewer == newbool) 471 return; 472 FLUSH_VERTICES(ctx, _NEW_LIGHT); 473 ctx->Light.Model.LocalViewer = newbool; 474 break; 475 case GL_LIGHT_MODEL_TWO_SIDE: 476 newbool = (params[0]!=0.0); 477 if (ctx->Light.Model.TwoSide == newbool) 478 return; 479 FLUSH_VERTICES(ctx, _NEW_LIGHT); 480 ctx->Light.Model.TwoSide = newbool; 481 if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) 482 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE; 483 else 484 ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE; 485 break; 486 case GL_LIGHT_MODEL_COLOR_CONTROL: 487 if (params[0] == (GLfloat) GL_SINGLE_COLOR) 488 newenum = GL_SINGLE_COLOR; 489 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) 490 newenum = GL_SEPARATE_SPECULAR_COLOR; 491 else { 492 _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)", 493 (GLint) params[0] ); 494 return; 495 } 496 if (ctx->Light.Model.ColorControl == newenum) 497 return; 498 FLUSH_VERTICES(ctx, _NEW_LIGHT); 499 ctx->Light.Model.ColorControl = newenum; 500 break; 501 default: 502 _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname ); 503 break; 504 } 505 506 if (ctx->Driver.LightModelfv) 507 ctx->Driver.LightModelfv( ctx, pname, params ); 508} 509 510 511void GLAPIENTRY 512_mesa_LightModeliv( GLenum pname, const GLint *params ) 513{ 514 GLfloat fparam[4]; 515 516 switch (pname) { 517 case GL_LIGHT_MODEL_AMBIENT: 518 fparam[0] = INT_TO_FLOAT( params[0] ); 519 fparam[1] = INT_TO_FLOAT( params[1] ); 520 fparam[2] = INT_TO_FLOAT( params[2] ); 521 fparam[3] = INT_TO_FLOAT( params[3] ); 522 break; 523 case GL_LIGHT_MODEL_LOCAL_VIEWER: 524 case GL_LIGHT_MODEL_TWO_SIDE: 525 case GL_LIGHT_MODEL_COLOR_CONTROL: 526 fparam[0] = (GLfloat) params[0]; 527 break; 528 default: 529 /* Error will be caught later in gl_LightModelfv */ 530 ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F); 531 } 532 _mesa_LightModelfv( pname, fparam ); 533} 534 535 536void GLAPIENTRY 537_mesa_LightModeli( GLenum pname, GLint param ) 538{ 539 GLint iparam[4]; 540 iparam[0] = param; 541 iparam[1] = iparam[2] = iparam[3] = 0; 542 _mesa_LightModeliv( pname, iparam ); 543} 544 545 546void GLAPIENTRY 547_mesa_LightModelf( GLenum pname, GLfloat param ) 548{ 549 GLfloat fparam[4]; 550 fparam[0] = param; 551 fparam[1] = fparam[2] = fparam[3] = 0.0F; 552 _mesa_LightModelfv( pname, fparam ); 553} 554 555 556 557/********** MATERIAL **********/ 558 559 560/* 561 * Given a face and pname value (ala glColorMaterial), compute a bitmask 562 * of the targeted material values. 563 */ 564GLuint 565_mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname, 566 GLuint legal, const char *where ) 567{ 568 GLuint bitmask = 0; 569 570 /* Make a bitmask indicating what material attribute(s) we're updating */ 571 switch (pname) { 572 case GL_EMISSION: 573 bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION; 574 break; 575 case GL_AMBIENT: 576 bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT; 577 break; 578 case GL_DIFFUSE: 579 bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE; 580 break; 581 case GL_SPECULAR: 582 bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR; 583 break; 584 case GL_SHININESS: 585 bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS; 586 break; 587 case GL_AMBIENT_AND_DIFFUSE: 588 bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT; 589 bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE; 590 break; 591 case GL_COLOR_INDEXES: 592 bitmask |= MAT_BIT_FRONT_INDEXES | MAT_BIT_BACK_INDEXES; 593 break; 594 default: 595 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 596 return 0; 597 } 598 599 if (face==GL_FRONT) { 600 bitmask &= FRONT_MATERIAL_BITS; 601 } 602 else if (face==GL_BACK) { 603 bitmask &= BACK_MATERIAL_BITS; 604 } 605 else if (face != GL_FRONT_AND_BACK) { 606 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 607 return 0; 608 } 609 610 if (bitmask & ~legal) { 611 _mesa_error( ctx, GL_INVALID_ENUM, "%s", where ); 612 return 0; 613 } 614 615 return bitmask; 616} 617 618 619 620/* Update derived values following a change in ctx->Light.Material 621 */ 622void 623_mesa_update_material( struct gl_context *ctx, GLuint bitmask ) 624{ 625 struct gl_light *light, *list = &ctx->Light.EnabledList; 626 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 627 628 if (MESA_VERBOSE & VERBOSE_MATERIAL) 629 _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask); 630 631 if (!bitmask) 632 return; 633 634 /* update material ambience */ 635 if (bitmask & MAT_BIT_FRONT_AMBIENT) { 636 foreach (light, list) { 637 SCALE_3V( light->_MatAmbient[0], light->Ambient, 638 mat[MAT_ATTRIB_FRONT_AMBIENT]); 639 } 640 } 641 642 if (bitmask & MAT_BIT_BACK_AMBIENT) { 643 foreach (light, list) { 644 SCALE_3V( light->_MatAmbient[1], light->Ambient, 645 mat[MAT_ATTRIB_BACK_AMBIENT]); 646 } 647 } 648 649 /* update BaseColor = emission + scene's ambience * material's ambience */ 650 if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) { 651 COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] ); 652 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT], 653 ctx->Light.Model.Ambient ); 654 } 655 656 if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) { 657 COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] ); 658 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT], 659 ctx->Light.Model.Ambient ); 660 } 661 662 /* update material diffuse values */ 663 if (bitmask & MAT_BIT_FRONT_DIFFUSE) { 664 foreach (light, list) { 665 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, 666 mat[MAT_ATTRIB_FRONT_DIFFUSE] ); 667 } 668 } 669 670 if (bitmask & MAT_BIT_BACK_DIFFUSE) { 671 foreach (light, list) { 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 foreach (light, list) { 680 SCALE_3V( light->_MatSpecular[0], light->Specular, 681 mat[MAT_ATTRIB_FRONT_SPECULAR]); 682 } 683 } 684 685 if (bitmask & MAT_BIT_BACK_SPECULAR) { 686 foreach (light, list) { 687 SCALE_3V( light->_MatSpecular[1], light->Specular, 688 mat[MAT_ATTRIB_BACK_SPECULAR]); 689 } 690 } 691} 692 693 694/* 695 * Update the current materials from the given rgba color 696 * according to the bitmask in _ColorMaterialBitmask, which is 697 * set by glColorMaterial(). 698 */ 699void 700_mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] ) 701{ 702 const GLbitfield bitmask = ctx->Light._ColorMaterialBitmask; 703 struct gl_material *mat = &ctx->Light.Material; 704 int i; 705 706 for (i = 0 ; i < MAT_ATTRIB_MAX ; i++) 707 if (bitmask & (1<<i)) 708 COPY_4FV( mat->Attrib[i], color ); 709 710 _mesa_update_material( ctx, bitmask ); 711} 712 713 714void GLAPIENTRY 715_mesa_ColorMaterial( GLenum face, GLenum mode ) 716{ 717 GET_CURRENT_CONTEXT(ctx); 718 GLuint bitmask; 719 GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION | 720 MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR | 721 MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE | 722 MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT); 723 ASSERT_OUTSIDE_BEGIN_END(ctx); 724 725 if (MESA_VERBOSE&VERBOSE_API) 726 _mesa_debug(ctx, "glColorMaterial %s %s\n", 727 _mesa_lookup_enum_by_nr(face), 728 _mesa_lookup_enum_by_nr(mode)); 729 730 bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial"); 731 if (bitmask == 0) 732 return; /* error was recorded */ 733 734 if (ctx->Light._ColorMaterialBitmask == bitmask && 735 ctx->Light.ColorMaterialFace == face && 736 ctx->Light.ColorMaterialMode == mode) 737 return; 738 739 FLUSH_VERTICES(ctx, _NEW_LIGHT); 740 ctx->Light._ColorMaterialBitmask = bitmask; 741 ctx->Light.ColorMaterialFace = face; 742 ctx->Light.ColorMaterialMode = mode; 743 744 if (ctx->Light.ColorMaterialEnabled) { 745 FLUSH_CURRENT( ctx, 0 ); 746 _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); 747 } 748 749 if (ctx->Driver.ColorMaterial) 750 ctx->Driver.ColorMaterial( ctx, face, mode ); 751} 752 753 754void GLAPIENTRY 755_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ) 756{ 757 GET_CURRENT_CONTEXT(ctx); 758 GLuint f; 759 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 760 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ 761 762 FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ 763 764 if (face==GL_FRONT) { 765 f = 0; 766 } 767 else if (face==GL_BACK) { 768 f = 1; 769 } 770 else { 771 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" ); 772 return; 773 } 774 775 switch (pname) { 776 case GL_AMBIENT: 777 COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] ); 778 break; 779 case GL_DIFFUSE: 780 COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] ); 781 break; 782 case GL_SPECULAR: 783 COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] ); 784 break; 785 case GL_EMISSION: 786 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] ); 787 break; 788 case GL_SHININESS: 789 *params = mat[MAT_ATTRIB_SHININESS(f)][0]; 790 break; 791 case GL_COLOR_INDEXES: 792 if (ctx->API != API_OPENGL) { 793 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 794 return; 795 } 796 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0]; 797 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1]; 798 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2]; 799 break; 800 default: 801 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 802 } 803} 804 805 806void GLAPIENTRY 807_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) 808{ 809 GET_CURRENT_CONTEXT(ctx); 810 GLuint f; 811 GLfloat (*mat)[4] = ctx->Light.Material.Attrib; 812 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */ 813 814 ASSERT(ctx->API == API_OPENGL); 815 816 FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ 817 818 if (face==GL_FRONT) { 819 f = 0; 820 } 821 else if (face==GL_BACK) { 822 f = 1; 823 } 824 else { 825 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" ); 826 return; 827 } 828 switch (pname) { 829 case GL_AMBIENT: 830 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] ); 831 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] ); 832 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] ); 833 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] ); 834 break; 835 case GL_DIFFUSE: 836 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] ); 837 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] ); 838 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] ); 839 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] ); 840 break; 841 case GL_SPECULAR: 842 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] ); 843 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] ); 844 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] ); 845 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] ); 846 break; 847 case GL_EMISSION: 848 params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] ); 849 params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] ); 850 params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] ); 851 params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] ); 852 break; 853 case GL_SHININESS: 854 *params = IROUND( mat[MAT_ATTRIB_SHININESS(f)][0] ); 855 break; 856 case GL_COLOR_INDEXES: 857 params[0] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][0] ); 858 params[1] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][1] ); 859 params[2] = IROUND( mat[MAT_ATTRIB_INDEXES(f)][2] ); 860 break; 861 default: 862 _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" ); 863 } 864} 865 866 867 868/** 869 * Examine current lighting parameters to determine if the optimized lighting 870 * function can be used. 871 * Also, precompute some lighting values such as the products of light 872 * source and material ambient, diffuse and specular coefficients. 873 */ 874void 875_mesa_update_lighting( struct gl_context *ctx ) 876{ 877 GLbitfield flags = 0; 878 struct gl_light *light; 879 ctx->Light._NeedEyeCoords = GL_FALSE; 880 881 if (!ctx->Light.Enabled) 882 return; 883 884 foreach(light, &ctx->Light.EnabledList) { 885 flags |= light->_Flags; 886 } 887 888 ctx->Light._NeedVertices = 889 ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) || 890 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR || 891 ctx->Light.Model.LocalViewer); 892 893 ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) || 894 ctx->Light.Model.LocalViewer); 895 896 /* XXX: This test is overkill & needs to be fixed both for software and 897 * hardware t&l drivers. The above should be sufficient & should 898 * be tested to verify this. 899 */ 900 if (ctx->Light._NeedVertices) 901 ctx->Light._NeedEyeCoords = GL_TRUE; 902 903 /* Precompute some shading values. Although we reference 904 * Light.Material here, we can get away without flushing 905 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes 906 * are flushed, they will update the derived state at that time. 907 */ 908 if (ctx->Light.Model.TwoSide) 909 _mesa_update_material(ctx, 910 MAT_BIT_FRONT_EMISSION | 911 MAT_BIT_FRONT_AMBIENT | 912 MAT_BIT_FRONT_DIFFUSE | 913 MAT_BIT_FRONT_SPECULAR | 914 MAT_BIT_BACK_EMISSION | 915 MAT_BIT_BACK_AMBIENT | 916 MAT_BIT_BACK_DIFFUSE | 917 MAT_BIT_BACK_SPECULAR); 918 else 919 _mesa_update_material(ctx, 920 MAT_BIT_FRONT_EMISSION | 921 MAT_BIT_FRONT_AMBIENT | 922 MAT_BIT_FRONT_DIFFUSE | 923 MAT_BIT_FRONT_SPECULAR); 924} 925 926 927/** 928 * Update state derived from light position, spot direction. 929 * Called upon: 930 * _NEW_MODELVIEW 931 * _NEW_LIGHT 932 * _TNL_NEW_NEED_EYE_COORDS 933 * 934 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled. 935 * Also update on lighting space changes. 936 */ 937static void 938compute_light_positions( struct gl_context *ctx ) 939{ 940 struct gl_light *light; 941 static const GLfloat eye_z[3] = { 0, 0, 1 }; 942 943 if (!ctx->Light.Enabled) 944 return; 945 946 if (ctx->_NeedEyeCoords) { 947 COPY_3V( ctx->_EyeZDir, eye_z ); 948 } 949 else { 950 TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m ); 951 } 952 953 foreach (light, &ctx->Light.EnabledList) { 954 955 if (ctx->_NeedEyeCoords) { 956 /* _Position is in eye coordinate space */ 957 COPY_4FV( light->_Position, light->EyePosition ); 958 } 959 else { 960 /* _Position is in object coordinate space */ 961 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv, 962 light->EyePosition ); 963 } 964 965 if (!(light->_Flags & LIGHT_POSITIONAL)) { 966 /* VP (VP) = Normalize( Position ) */ 967 COPY_3V( light->_VP_inf_norm, light->_Position ); 968 NORMALIZE_3FV( light->_VP_inf_norm ); 969 970 if (!ctx->Light.Model.LocalViewer) { 971 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */ 972 ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir); 973 NORMALIZE_3FV( light->_h_inf_norm ); 974 } 975 light->_VP_inf_spot_attenuation = 1.0; 976 } 977 else { 978 /* positional light w/ homogeneous coordinate, divide by W */ 979 GLfloat wInv = (GLfloat)1.0 / light->_Position[3]; 980 light->_Position[0] *= wInv; 981 light->_Position[1] *= wInv; 982 light->_Position[2] *= wInv; 983 } 984 985 if (light->_Flags & LIGHT_SPOT) { 986 /* Note: we normalize the spot direction now */ 987 988 if (ctx->_NeedEyeCoords) { 989 COPY_3V( light->_NormSpotDirection, light->SpotDirection ); 990 NORMALIZE_3FV( light->_NormSpotDirection ); 991 } 992 else { 993 GLfloat spotDir[3]; 994 COPY_3V(spotDir, light->SpotDirection); 995 NORMALIZE_3FV(spotDir); 996 TRANSFORM_NORMAL( light->_NormSpotDirection, 997 spotDir, 998 ctx->ModelviewMatrixStack.Top->m); 999 } 1000 1001 NORMALIZE_3FV( light->_NormSpotDirection ); 1002 1003 if (!(light->_Flags & LIGHT_POSITIONAL)) { 1004 GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm, 1005 light->_NormSpotDirection); 1006 1007 if (PV_dot_dir > light->_CosCutoff) { 1008 light->_VP_inf_spot_attenuation = 1009 powf(PV_dot_dir, light->SpotExponent); 1010 } 1011 else { 1012 light->_VP_inf_spot_attenuation = 0; 1013 } 1014 } 1015 } 1016 } 1017} 1018 1019 1020 1021static void 1022update_modelview_scale( struct gl_context *ctx ) 1023{ 1024 ctx->_ModelViewInvScale = 1.0F; 1025 if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) { 1026 const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv; 1027 GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10]; 1028 if (f < 1e-12) f = 1.0; 1029 if (ctx->_NeedEyeCoords) 1030 ctx->_ModelViewInvScale = (GLfloat) INV_SQRTF(f); 1031 else 1032 ctx->_ModelViewInvScale = (GLfloat) SQRTF(f); 1033 } 1034} 1035 1036 1037/** 1038 * Bring up to date any state that relies on _NeedEyeCoords. 1039 */ 1040void 1041_mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ) 1042{ 1043 const GLuint oldneedeyecoords = ctx->_NeedEyeCoords; 1044 1045 (void) new_state; 1046 ctx->_NeedEyeCoords = GL_FALSE; 1047 1048 if (ctx->_ForceEyeCoords || 1049 (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) || 1050 ctx->Point._Attenuated || 1051 ctx->Light._NeedEyeCoords) 1052 ctx->_NeedEyeCoords = GL_TRUE; 1053 1054 if (ctx->Light.Enabled && 1055 !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) 1056 ctx->_NeedEyeCoords = GL_TRUE; 1057 1058 /* Check if the truth-value interpretations of the bitfields have 1059 * changed: 1060 */ 1061 if (oldneedeyecoords != ctx->_NeedEyeCoords) { 1062 /* Recalculate all state that depends on _NeedEyeCoords. 1063 */ 1064 update_modelview_scale(ctx); 1065 compute_light_positions( ctx ); 1066 1067 if (ctx->Driver.LightingSpaceChange) 1068 ctx->Driver.LightingSpaceChange( ctx ); 1069 } 1070 else { 1071 GLuint new_state2 = ctx->NewState; 1072 1073 /* Recalculate that same state only if it has been invalidated 1074 * by other statechanges. 1075 */ 1076 if (new_state2 & _NEW_MODELVIEW) 1077 update_modelview_scale(ctx); 1078 1079 if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW)) 1080 compute_light_positions( ctx ); 1081 } 1082} 1083 1084 1085/** 1086 * Drivers may need this if the hardware tnl unit doesn't support the 1087 * light-in-modelspace optimization. It's also useful for debugging. 1088 */ 1089void 1090_mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ) 1091{ 1092 ctx->_ForceEyeCoords = !flag; 1093 ctx->NewState |= _NEW_POINT; /* one of the bits from 1094 * _MESA_NEW_NEED_EYE_COORDS. 1095 */ 1096} 1097 1098 1099 1100/**********************************************************************/ 1101/***** Initialization *****/ 1102/**********************************************************************/ 1103 1104/** 1105 * Initialize the n-th light data structure. 1106 * 1107 * \param l pointer to the gl_light structure to be initialized. 1108 * \param n number of the light. 1109 * \note The defaults for light 0 are different than the other lights. 1110 */ 1111static void 1112init_light( struct gl_light *l, GLuint n ) 1113{ 1114 make_empty_list( l ); 1115 1116 ASSIGN_4V( l->Ambient, 0.0, 0.0, 0.0, 1.0 ); 1117 if (n==0) { 1118 ASSIGN_4V( l->Diffuse, 1.0, 1.0, 1.0, 1.0 ); 1119 ASSIGN_4V( l->Specular, 1.0, 1.0, 1.0, 1.0 ); 1120 } 1121 else { 1122 ASSIGN_4V( l->Diffuse, 0.0, 0.0, 0.0, 1.0 ); 1123 ASSIGN_4V( l->Specular, 0.0, 0.0, 0.0, 1.0 ); 1124 } 1125 ASSIGN_4V( l->EyePosition, 0.0, 0.0, 1.0, 0.0 ); 1126 ASSIGN_3V( l->SpotDirection, 0.0, 0.0, -1.0 ); 1127 l->SpotExponent = 0.0; 1128 l->SpotCutoff = 180.0; 1129 l->_CosCutoff = 0.0; /* KW: -ve values not admitted */ 1130 l->ConstantAttenuation = 1.0; 1131 l->LinearAttenuation = 0.0; 1132 l->QuadraticAttenuation = 0.0; 1133 l->Enabled = GL_FALSE; 1134} 1135 1136 1137/** 1138 * Initialize the light model data structure. 1139 * 1140 * \param lm pointer to the gl_lightmodel structure to be initialized. 1141 */ 1142static void 1143init_lightmodel( struct gl_lightmodel *lm ) 1144{ 1145 ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F ); 1146 lm->LocalViewer = GL_FALSE; 1147 lm->TwoSide = GL_FALSE; 1148 lm->ColorControl = GL_SINGLE_COLOR; 1149} 1150 1151 1152/** 1153 * Initialize the material data structure. 1154 * 1155 * \param m pointer to the gl_material structure to be initialized. 1156 */ 1157static void 1158init_material( struct gl_material *m ) 1159{ 1160 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F ); 1161 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F ); 1162 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F ); 1163 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F ); 1164 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F ); 1165 ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F ); 1166 1167 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT], 0.2F, 0.2F, 0.2F, 1.0F ); 1168 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE], 0.8F, 0.8F, 0.8F, 1.0F ); 1169 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F ); 1170 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F ); 1171 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F ); 1172 ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F ); 1173} 1174 1175 1176/** 1177 * Initialize all lighting state for the given context. 1178 */ 1179void 1180_mesa_init_lighting( struct gl_context *ctx ) 1181{ 1182 GLuint i; 1183 1184 /* Lighting group */ 1185 for (i = 0; i < MAX_LIGHTS; i++) { 1186 init_light( &ctx->Light.Light[i], i ); 1187 } 1188 make_empty_list( &ctx->Light.EnabledList ); 1189 1190 init_lightmodel( &ctx->Light.Model ); 1191 init_material( &ctx->Light.Material ); 1192 ctx->Light.ShadeModel = GL_SMOOTH; 1193 ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT; 1194 ctx->Light.Enabled = GL_FALSE; 1195 ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK; 1196 ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE; 1197 ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx, 1198 GL_FRONT_AND_BACK, 1199 GL_AMBIENT_AND_DIFFUSE, ~0, 1200 NULL ); 1201 1202 ctx->Light.ColorMaterialEnabled = GL_FALSE; 1203 ctx->Light.ClampVertexColor = GL_TRUE; 1204 1205 /* Miscellaneous */ 1206 ctx->Light._NeedEyeCoords = GL_FALSE; 1207 ctx->_NeedEyeCoords = GL_FALSE; 1208 ctx->_ForceEyeCoords = GL_FALSE; 1209 ctx->_ModelViewInvScale = 1.0; 1210} 1211 1212 1213/** 1214 * Deallocate malloc'd lighting state attached to given context. 1215 */ 1216void 1217_mesa_free_lighting_data( struct gl_context *ctx ) 1218{ 1219} 1220