blob: 155792af52bdf9609f4125be67e552f3023203cb [file] [log] [blame]
Keith Whitwellc6b2a922001-02-15 01:33:52 +00001/* $Id: light.c,v 1.37 2001/02/15 01:33:52 keithw Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
4 * Mesa 3-D graphics library
Brian Paulba643a22000-10-28 18:34:48 +00005 * Version: 3.5
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00006 *
Brian Paul16a9efe2000-01-13 00:29:02 +00007 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00008 *
jtgafb833d1999-08-19 00:55:39 +00009 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000015 *
jtgafb833d1999-08-19 00:55:39 +000016 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000018 *
jtgafb833d1999-08-19 00:55:39 +000019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
jtgafb833d1999-08-19 00:55:39 +000028#ifdef PC_HEADER
29#include "all.h"
30#else
Brian Paulfbd8f211999-11-11 01:22:25 +000031#include "glheader.h"
Brian Paulc893a012000-10-28 20:41:13 +000032#include "colormac.h"
jtgafb833d1999-08-19 00:55:39 +000033#include "context.h"
34#include "enums.h"
35#include "light.h"
36#include "macros.h"
Brian Paulfbd8f211999-11-11 01:22:25 +000037#include "mem.h"
jtgafb833d1999-08-19 00:55:39 +000038#include "mmath.h"
39#include "simple_list.h"
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +000040#include "mtypes.h"
Keith Whitwell23caf202000-11-16 21:05:34 +000041
42#include "math/m_xform.h"
43#include "math/m_matrix.h"
jtgafb833d1999-08-19 00:55:39 +000044#endif
45
46
Brian Paul075398b2000-01-31 23:33:53 +000047/* XXX this is a bit of a hack needed for compilation within XFree86 */
48#ifndef FLT_MIN
49#define FLT_MIN 1e-37
50#endif
51
jtgafb833d1999-08-19 00:55:39 +000052
Brian Paulfbd8f211999-11-11 01:22:25 +000053void
54_mesa_ShadeModel( GLenum mode )
jtgafb833d1999-08-19 00:55:39 +000055{
Brian Paulfbd8f211999-11-11 01:22:25 +000056 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +000057 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +000058
59 if (MESA_VERBOSE & VERBOSE_API)
60 fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
61
Keith Whitwellcab974c2000-12-26 05:09:27 +000062 if (mode != GL_FLAT && mode != GL_SMOOTH) {
Keith Whitwell1bf9dfa1999-09-18 20:41:22 +000063 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
Keith Whitwellcab974c2000-12-26 05:09:27 +000064 return;
jtgafb833d1999-08-19 00:55:39 +000065 }
Keith Whitwellcab974c2000-12-26 05:09:27 +000066
67 if (ctx->Light.ShadeModel == mode)
68 return;
69
70 FLUSH_VERTICES(ctx, _NEW_LIGHT);
71 ctx->Light.ShadeModel = mode;
72 ctx->_TriangleCaps ^= DD_FLATSHADE;
73 if (ctx->Driver.ShadeModel)
74 (*ctx->Driver.ShadeModel)( ctx, mode );
jtgafb833d1999-08-19 00:55:39 +000075}
76
77
78
Brian Paulfbd8f211999-11-11 01:22:25 +000079void
80_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
jtgafb833d1999-08-19 00:55:39 +000081{
Brian Paulfbd8f211999-11-11 01:22:25 +000082 _mesa_Lightfv( light, pname, &param );
83}
jtgafb833d1999-08-19 00:55:39 +000084
Brian Paulfbd8f211999-11-11 01:22:25 +000085
86void
87_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
88{
89 GET_CURRENT_CONTEXT(ctx);
Keith Whitwell1e1aac02000-11-13 20:02:56 +000090 GLint i = (GLint) (light - GL_LIGHT0);
91 struct gl_light *l = &ctx->Light.Light[i];
jtgafb833d1999-08-19 00:55:39 +000092
Brian Paula8644322000-11-27 18:22:13 +000093 if (i < 0 || i >= ctx->Const.MaxLights) {
jtgafb833d1999-08-19 00:55:39 +000094 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
95 return;
96 }
97
98 switch (pname) {
Keith Whitwellcab974c2000-12-26 05:09:27 +000099 case GL_AMBIENT:
100 if (TEST_EQ_4V(l->Ambient, params))
101 return;
102 FLUSH_VERTICES(ctx, _NEW_LIGHT);
103 COPY_4V( l->Ambient, params );
104 break;
105 case GL_DIFFUSE:
106 if (TEST_EQ_4V(l->Diffuse, params))
107 return;
108 FLUSH_VERTICES(ctx, _NEW_LIGHT);
109 COPY_4V( l->Diffuse, params );
110 break;
111 case GL_SPECULAR:
112 if (TEST_EQ_4V(l->Specular, params))
113 return;
114 FLUSH_VERTICES(ctx, _NEW_LIGHT);
115 COPY_4V( l->Specular, params );
116 break;
117 case GL_POSITION: {
118 GLfloat tmp[4];
119 /* transform position by ModelView matrix */
120 TRANSFORM_POINT( tmp, ctx->ModelView.m, params );
121 if (TEST_EQ_4V(l->EyePosition, tmp))
122 return;
123 FLUSH_VERTICES(ctx, _NEW_LIGHT);
124 COPY_4V(l->EyePosition, tmp);
125 if (l->EyePosition[3] != 0.0F)
126 l->_Flags |= LIGHT_POSITIONAL;
127 else
128 l->_Flags &= ~LIGHT_POSITIONAL;
129 break;
130 }
131 case GL_SPOT_DIRECTION: {
132 GLfloat tmp[4];
133 /* transform direction by inverse modelview */
134 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
135 _math_matrix_analyse( &ctx->ModelView );
136 }
137 TRANSFORM_NORMAL( tmp, params, ctx->ModelView.inv );
138 if (TEST_EQ_3V(l->EyeDirection, tmp))
139 return;
140 FLUSH_VERTICES(ctx, _NEW_LIGHT);
141 COPY_3V(l->EyeDirection, tmp);
142 break;
143 }
144 case GL_SPOT_EXPONENT:
145 if (params[0]<0.0 || params[0]>128.0) {
146 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
147 return;
148 }
149 if (l->SpotExponent == params[0])
150 return;
151 FLUSH_VERTICES(ctx, _NEW_LIGHT);
152 l->SpotExponent = params[0];
153 gl_invalidate_spot_exp_table( l );
154 break;
155 case GL_SPOT_CUTOFF:
156 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
157 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
158 return;
159 }
160 if (l->SpotCutoff == params[0])
161 return;
162 FLUSH_VERTICES(ctx, _NEW_LIGHT);
163 l->SpotCutoff = params[0];
164 l->_CosCutoff = cos(params[0]*DEG2RAD);
165 if (l->_CosCutoff < 0)
166 l->_CosCutoff = 0;
167 if (l->SpotCutoff != 180.0F)
168 l->_Flags |= LIGHT_SPOT;
169 else
170 l->_Flags &= ~LIGHT_SPOT;
171 break;
172 case GL_CONSTANT_ATTENUATION:
173 if (params[0]<0.0) {
174 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
175 return;
176 }
177 if (l->ConstantAttenuation == params[0])
178 return;
179 FLUSH_VERTICES(ctx, _NEW_LIGHT);
180 l->ConstantAttenuation = params[0];
181 break;
182 case GL_LINEAR_ATTENUATION:
183 if (params[0]<0.0) {
184 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
185 return;
186 }
187 if (l->LinearAttenuation == params[0])
188 return;
189 FLUSH_VERTICES(ctx, _NEW_LIGHT);
190 l->LinearAttenuation = params[0];
191 break;
192 case GL_QUADRATIC_ATTENUATION:
193 if (params[0]<0.0) {
194 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
195 return;
196 }
197 if (l->QuadraticAttenuation == params[0])
198 return;
199 FLUSH_VERTICES(ctx, _NEW_LIGHT);
200 l->QuadraticAttenuation = params[0];
201 break;
202 default:
203 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
204 return;
jtgafb833d1999-08-19 00:55:39 +0000205 }
206
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000207 if (ctx->Driver.Lightfv)
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000208 ctx->Driver.Lightfv( ctx, light, pname, params );
jtgafb833d1999-08-19 00:55:39 +0000209}
210
211
Brian Paulfbd8f211999-11-11 01:22:25 +0000212void
213_mesa_Lighti( GLenum light, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000214{
Brian Paulfbd8f211999-11-11 01:22:25 +0000215 _mesa_Lightiv( light, pname, &param );
216}
217
218
219void
220_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
221{
222 GLfloat fparam[4];
223
224 switch (pname) {
225 case GL_AMBIENT:
226 case GL_DIFFUSE:
227 case GL_SPECULAR:
228 fparam[0] = INT_TO_FLOAT( params[0] );
229 fparam[1] = INT_TO_FLOAT( params[1] );
230 fparam[2] = INT_TO_FLOAT( params[2] );
231 fparam[3] = INT_TO_FLOAT( params[3] );
232 break;
233 case GL_POSITION:
234 fparam[0] = (GLfloat) params[0];
235 fparam[1] = (GLfloat) params[1];
236 fparam[2] = (GLfloat) params[2];
237 fparam[3] = (GLfloat) params[3];
238 break;
239 case GL_SPOT_DIRECTION:
240 fparam[0] = (GLfloat) params[0];
241 fparam[1] = (GLfloat) params[1];
242 fparam[2] = (GLfloat) params[2];
243 break;
244 case GL_SPOT_EXPONENT:
245 case GL_SPOT_CUTOFF:
246 case GL_CONSTANT_ATTENUATION:
247 case GL_LINEAR_ATTENUATION:
248 case GL_QUADRATIC_ATTENUATION:
249 fparam[0] = (GLfloat) params[0];
250 break;
251 default:
252 /* error will be caught later in gl_Lightfv */
253 ;
254 }
255
256 _mesa_Lightfv( light, pname, fparam );
257}
258
259
260
261void
262_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
263{
264 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000265 GLint l = (GLint) (light - GL_LIGHT0);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000266 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +0000267
Brian Paula8644322000-11-27 18:22:13 +0000268 if (l < 0 || l >= ctx->Const.MaxLights) {
jtgafb833d1999-08-19 00:55:39 +0000269 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
270 return;
271 }
272
273 switch (pname) {
274 case GL_AMBIENT:
275 COPY_4V( params, ctx->Light.Light[l].Ambient );
276 break;
277 case GL_DIFFUSE:
278 COPY_4V( params, ctx->Light.Light[l].Diffuse );
279 break;
280 case GL_SPECULAR:
281 COPY_4V( params, ctx->Light.Light[l].Specular );
282 break;
283 case GL_POSITION:
284 COPY_4V( params, ctx->Light.Light[l].EyePosition );
285 break;
286 case GL_SPOT_DIRECTION:
287 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
288 break;
289 case GL_SPOT_EXPONENT:
290 params[0] = ctx->Light.Light[l].SpotExponent;
291 break;
292 case GL_SPOT_CUTOFF:
293 params[0] = ctx->Light.Light[l].SpotCutoff;
294 break;
295 case GL_CONSTANT_ATTENUATION:
296 params[0] = ctx->Light.Light[l].ConstantAttenuation;
297 break;
298 case GL_LINEAR_ATTENUATION:
299 params[0] = ctx->Light.Light[l].LinearAttenuation;
300 break;
301 case GL_QUADRATIC_ATTENUATION:
302 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
303 break;
304 default:
305 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
306 break;
307 }
308}
309
310
311
Brian Paulfbd8f211999-11-11 01:22:25 +0000312void
313_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +0000314{
Brian Paulfbd8f211999-11-11 01:22:25 +0000315 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000316 GLint l = (GLint) (light - GL_LIGHT0);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000317 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +0000318
Brian Paula8644322000-11-27 18:22:13 +0000319 if (l < 0 || l >= ctx->Const.MaxLights) {
jtgafb833d1999-08-19 00:55:39 +0000320 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
321 return;
322 }
323
324 switch (pname) {
325 case GL_AMBIENT:
326 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
327 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
328 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
329 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
330 break;
331 case GL_DIFFUSE:
332 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
333 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
334 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
335 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
336 break;
337 case GL_SPECULAR:
338 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
339 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
340 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
341 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
342 break;
343 case GL_POSITION:
344 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
345 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
346 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
347 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
348 break;
349 case GL_SPOT_DIRECTION:
350 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
351 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
352 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
353 break;
354 case GL_SPOT_EXPONENT:
355 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
356 break;
357 case GL_SPOT_CUTOFF:
358 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
359 break;
360 case GL_CONSTANT_ATTENUATION:
361 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
362 break;
363 case GL_LINEAR_ATTENUATION:
364 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
365 break;
366 case GL_QUADRATIC_ATTENUATION:
367 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
368 break;
369 default:
370 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
371 break;
372 }
373}
374
375
376
377/**********************************************************************/
378/*** Light Model ***/
379/**********************************************************************/
380
381
Brian Paulfbd8f211999-11-11 01:22:25 +0000382void
383_mesa_LightModelfv( GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000384{
Keith Whitwellcab974c2000-12-26 05:09:27 +0000385 GLenum newenum;
386 GLboolean newbool;
Brian Paulfbd8f211999-11-11 01:22:25 +0000387 GET_CURRENT_CONTEXT(ctx);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000388 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +0000389
390 switch (pname) {
391 case GL_LIGHT_MODEL_AMBIENT:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000392 if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
393 return;
394 FLUSH_VERTICES(ctx, _NEW_LIGHT);
jtgafb833d1999-08-19 00:55:39 +0000395 COPY_4V( ctx->Light.Model.Ambient, params );
396 break;
397 case GL_LIGHT_MODEL_LOCAL_VIEWER:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000398 newbool = (params[0]!=0.0);
399 if (ctx->Light.Model.LocalViewer == newbool)
400 return;
401 FLUSH_VERTICES(ctx, _NEW_LIGHT);
402 ctx->Light.Model.LocalViewer = newbool;
jtgafb833d1999-08-19 00:55:39 +0000403 break;
404 case GL_LIGHT_MODEL_TWO_SIDE:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000405 newbool = (params[0]!=0.0);
406 if (ctx->Light.Model.TwoSide == newbool)
407 return;
408 FLUSH_VERTICES(ctx, _NEW_LIGHT);
409 ctx->Light.Model.TwoSide = newbool;
jtgafb833d1999-08-19 00:55:39 +0000410 break;
411 case GL_LIGHT_MODEL_COLOR_CONTROL:
Keith Whitwellcab974c2000-12-26 05:09:27 +0000412 if (params[0] == (GLfloat) GL_SINGLE_COLOR)
413 newenum = GL_SINGLE_COLOR;
414 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
415 newenum = GL_SEPARATE_SPECULAR_COLOR;
416 else {
jtgafb833d1999-08-19 00:55:39 +0000417 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
Keith Whitwellcab974c2000-12-26 05:09:27 +0000418 return;
Brian Paulf3f9b771999-10-19 20:32:40 +0000419 }
Keith Whitwellcab974c2000-12-26 05:09:27 +0000420 if (ctx->Light.Model.ColorControl == newenum)
421 return;
422 FLUSH_VERTICES(ctx, _NEW_LIGHT);
423 ctx->Light.Model.ColorControl = newenum;
424 ctx->_TriangleCaps ^= DD_SEPERATE_SPECULAR;
jtgafb833d1999-08-19 00:55:39 +0000425 break;
426 default:
427 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
428 break;
429 }
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000430
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000431 if (ctx->Driver.LightModelfv)
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000432 ctx->Driver.LightModelfv( ctx, pname, params );
jtgafb833d1999-08-19 00:55:39 +0000433}
434
435
Brian Paulfbd8f211999-11-11 01:22:25 +0000436void
437_mesa_LightModeliv( GLenum pname, const GLint *params )
438{
439 GLfloat fparam[4];
Brian Paulfbd8f211999-11-11 01:22:25 +0000440
441 switch (pname) {
442 case GL_LIGHT_MODEL_AMBIENT:
443 fparam[0] = INT_TO_FLOAT( params[0] );
444 fparam[1] = INT_TO_FLOAT( params[1] );
445 fparam[2] = INT_TO_FLOAT( params[2] );
446 fparam[3] = INT_TO_FLOAT( params[3] );
447 break;
448 case GL_LIGHT_MODEL_LOCAL_VIEWER:
449 case GL_LIGHT_MODEL_TWO_SIDE:
450 case GL_LIGHT_MODEL_COLOR_CONTROL:
451 fparam[0] = (GLfloat) params[0];
452 break;
453 default:
454 /* Error will be caught later in gl_LightModelfv */
455 ;
456 }
457 _mesa_LightModelfv( pname, fparam );
458}
459
460
461void
462_mesa_LightModeli( GLenum pname, GLint param )
463{
464 _mesa_LightModeliv( pname, &param );
465}
466
467
468void
469_mesa_LightModelf( GLenum pname, GLfloat param )
470{
471 _mesa_LightModelfv( pname, &param );
472}
473
jtgafb833d1999-08-19 00:55:39 +0000474
475
476/********** MATERIAL **********/
477
478
479/*
480 * Given a face and pname value (ala glColorMaterial), compute a bitmask
481 * of the targeted material values.
482 */
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000483GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
jtgafb833d1999-08-19 00:55:39 +0000484 GLuint legal,
485 const char *where )
486{
487 GLuint bitmask = 0;
488
489 /* Make a bitmask indicating what material attribute(s) we're updating */
490 switch (pname) {
491 case GL_EMISSION:
492 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
493 break;
494 case GL_AMBIENT:
495 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
496 break;
497 case GL_DIFFUSE:
498 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
499 break;
500 case GL_SPECULAR:
501 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
502 break;
503 case GL_SHININESS:
504 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
505 break;
506 case GL_AMBIENT_AND_DIFFUSE:
507 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
508 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
509 break;
510 case GL_COLOR_INDEXES:
511 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
512 break;
513 default:
514 gl_error( ctx, GL_INVALID_ENUM, where );
515 return 0;
516 }
517
518 if (face==GL_FRONT) {
519 bitmask &= FRONT_MATERIAL_BITS;
520 }
521 else if (face==GL_BACK) {
522 bitmask &= BACK_MATERIAL_BITS;
523 }
524 else if (face != GL_FRONT_AND_BACK) {
525 gl_error( ctx, GL_INVALID_ENUM, where );
526 return 0;
527 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000528
jtgafb833d1999-08-19 00:55:39 +0000529 if (bitmask & ~legal) {
530 gl_error( ctx, GL_INVALID_ENUM, where );
531 return 0;
532 }
533
534 return bitmask;
535}
536
537
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000538/* Perform a straight copy between pairs of materials.
539 */
540void gl_copy_material_pairs( struct gl_material dst[2],
541 const struct gl_material src[2],
542 GLuint bitmask )
543{
544 if (bitmask & FRONT_EMISSION_BIT) {
545 COPY_4FV( dst[0].Emission, src[0].Emission );
546 }
547 if (bitmask & BACK_EMISSION_BIT) {
548 COPY_4FV( dst[1].Emission, src[1].Emission );
549 }
550 if (bitmask & FRONT_AMBIENT_BIT) {
551 COPY_4FV( dst[0].Ambient, src[0].Ambient );
552 }
553 if (bitmask & BACK_AMBIENT_BIT) {
554 COPY_4FV( dst[1].Ambient, src[1].Ambient );
555 }
556 if (bitmask & FRONT_DIFFUSE_BIT) {
557 COPY_4FV( dst[0].Diffuse, src[0].Diffuse );
558 }
559 if (bitmask & BACK_DIFFUSE_BIT) {
560 COPY_4FV( dst[1].Diffuse, src[1].Diffuse );
561 }
562 if (bitmask & FRONT_SPECULAR_BIT) {
563 COPY_4FV( dst[0].Specular, src[0].Specular );
564 }
565 if (bitmask & BACK_SPECULAR_BIT) {
566 COPY_4FV( dst[1].Specular, src[1].Specular );
567 }
568 if (bitmask & FRONT_SHININESS_BIT) {
569 dst[0].Shininess = src[0].Shininess;
570 }
571 if (bitmask & BACK_SHININESS_BIT) {
572 dst[1].Shininess = src[1].Shininess;
573 }
574 if (bitmask & FRONT_INDEXES_BIT) {
575 dst[0].AmbientIndex = src[0].AmbientIndex;
576 dst[0].DiffuseIndex = src[0].DiffuseIndex;
577 dst[0].SpecularIndex = src[0].SpecularIndex;
578 }
579 if (bitmask & BACK_INDEXES_BIT) {
580 dst[1].AmbientIndex = src[1].AmbientIndex;
581 dst[1].DiffuseIndex = src[1].DiffuseIndex;
582 dst[1].SpecularIndex = src[1].SpecularIndex;
583 }
584}
585
jtgafb833d1999-08-19 00:55:39 +0000586
jtgafb833d1999-08-19 00:55:39 +0000587/*
588 * Check if the global material has to be updated with info that was
589 * associated with a vertex via glMaterial.
590 * This function is used when any material values get changed between
591 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
592 * when GL_COLOR_MATERIAL is enabled.
593 *
Brian Paulde82d062000-06-26 23:37:46 +0000594 * src[0] is front material, src[1] is back material
595 *
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000596 * Additionally keeps the precomputed lighting state uptodate.
jtgafb833d1999-08-19 00:55:39 +0000597 */
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000598void gl_update_material( GLcontext *ctx,
599 const struct gl_material src[2],
jtgafb833d1999-08-19 00:55:39 +0000600 GLuint bitmask )
601{
602 struct gl_light *light, *list = &ctx->Light.EnabledList;
jtgafb833d1999-08-19 00:55:39 +0000603
604 if (ctx->Light.ColorMaterialEnabled)
605 bitmask &= ~ctx->Light.ColorMaterialBitmask;
606
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000607 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000608 fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000609
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000610 if (!bitmask)
jtgafb833d1999-08-19 00:55:39 +0000611 return;
612
Brian Paulde82d062000-06-26 23:37:46 +0000613 /* update material emission */
614 if (bitmask & FRONT_EMISSION_BIT) {
615 struct gl_material *mat = &ctx->Light.Material[0];
616 COPY_4FV( mat->Emission, src[0].Emission );
617 }
618 if (bitmask & BACK_EMISSION_BIT) {
619 struct gl_material *mat = &ctx->Light.Material[1];
620 COPY_4FV( mat->Emission, src[1].Emission );
621 }
622
623 /* update material ambience */
jtgafb833d1999-08-19 00:55:39 +0000624 if (bitmask & FRONT_AMBIENT_BIT) {
625 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000626 COPY_4FV( mat->Ambient, src[0].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000627 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000628 SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000629 }
jtgafb833d1999-08-19 00:55:39 +0000630 }
631 if (bitmask & BACK_AMBIENT_BIT) {
632 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000633 COPY_4FV( mat->Ambient, src[1].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000634 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000635 SCALE_3V( light->_MatAmbient[1], light->Ambient, src[1].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000636 }
jtgafb833d1999-08-19 00:55:39 +0000637 }
Brian Paulde82d062000-06-26 23:37:46 +0000638
639 /* update BaseColor = emission + scene's ambience * material's ambience */
640 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
641 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000642 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000643 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient,
644 ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000645 }
646 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
647 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000648 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000649 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient,
650 ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000651 }
652
653 /* update material diffuse values */
jtgafb833d1999-08-19 00:55:39 +0000654 if (bitmask & FRONT_DIFFUSE_BIT) {
655 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000656 COPY_4FV( mat->Diffuse, src[0].Diffuse );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000657 foreach (light, list) {
658 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse );
659 }
Brian Paul3041d052001-01-02 22:02:51 +0000660 UNCLAMPED_FLOAT_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000661 }
662 if (bitmask & BACK_DIFFUSE_BIT) {
663 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000664 COPY_4FV( mat->Diffuse, src[1].Diffuse );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000665 foreach (light, list) {
666 SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse );
667 }
Brian Paul3041d052001-01-02 22:02:51 +0000668 UNCLAMPED_FLOAT_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000669 }
Brian Paulde82d062000-06-26 23:37:46 +0000670
671 /* update material specular values */
jtgafb833d1999-08-19 00:55:39 +0000672 if (bitmask & FRONT_SPECULAR_BIT) {
673 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000674 COPY_4FV( mat->Specular, src[0].Specular );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000675 foreach (light, list) {
Keith Whitwell9aff6cf2000-11-24 15:21:59 +0000676 SCALE_3V( light->_MatSpecular[0], light->Specular, mat->Specular);
Keith Whitwellad2ac212000-11-24 10:25:05 +0000677 }
jtgafb833d1999-08-19 00:55:39 +0000678 }
679 if (bitmask & BACK_SPECULAR_BIT) {
680 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000681 COPY_4FV( mat->Specular, src[1].Specular );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000682 foreach (light, list) {
Keith Whitwell9aff6cf2000-11-24 15:21:59 +0000683 SCALE_3V( light->_MatSpecular[1], light->Specular, mat->Specular);
Keith Whitwellad2ac212000-11-24 10:25:05 +0000684 }
jtgafb833d1999-08-19 00:55:39 +0000685 }
Brian Paulde82d062000-06-26 23:37:46 +0000686
jtgafb833d1999-08-19 00:55:39 +0000687 if (bitmask & FRONT_SHININESS_BIT) {
Keith Whitwellcab974c2000-12-26 05:09:27 +0000688 ctx->Light.Material[0].Shininess = src[0].Shininess;
689 gl_invalidate_shine_table( ctx, 0 );
jtgafb833d1999-08-19 00:55:39 +0000690 }
691 if (bitmask & BACK_SHININESS_BIT) {
Keith Whitwellcab974c2000-12-26 05:09:27 +0000692 ctx->Light.Material[1].Shininess = src[1].Shininess;
693 gl_invalidate_shine_table( ctx, 1 );
jtgafb833d1999-08-19 00:55:39 +0000694 }
Brian Paulde82d062000-06-26 23:37:46 +0000695
jtgafb833d1999-08-19 00:55:39 +0000696 if (bitmask & FRONT_INDEXES_BIT) {
697 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
698 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
699 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
700 }
701 if (bitmask & BACK_INDEXES_BIT) {
702 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
703 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
704 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
705 }
706
Keith Whitwell06ac5921999-11-10 06:29:44 +0000707 if (0)
708 {
709 struct gl_material *mat = &ctx->Light.Material[0];
710 fprintf(stderr, "update_mat emission : %f %f %f\n",
711 mat->Emission[0],
712 mat->Emission[1],
713 mat->Emission[2]);
714 fprintf(stderr, "update_mat specular : %f %f %f\n",
715 mat->Specular[0],
716 mat->Specular[1],
717 mat->Specular[2]);
718 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
719 mat->Diffuse[0],
720 mat->Diffuse[1],
721 mat->Diffuse[2]);
722 fprintf(stderr, "update_mat ambient : %f %f %f\n",
723 mat->Ambient[0],
724 mat->Ambient[1],
725 mat->Ambient[2]);
726 }
jtgafb833d1999-08-19 00:55:39 +0000727}
728
729
730
731
Keith Whitwellc6b2a922001-02-15 01:33:52 +0000732
733
734
Brian Paulde82d062000-06-26 23:37:46 +0000735/*
736 * Update the current materials from the given rgba color
737 * according to the bitmask in ColorMaterialBitmask, which is
738 * set by glColorMaterial().
739 */
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000740void gl_update_color_material( GLcontext *ctx,
Brian Paulba643a22000-10-28 18:34:48 +0000741 const GLchan rgba[4] )
jtgafb833d1999-08-19 00:55:39 +0000742{
743 struct gl_light *light, *list = &ctx->Light.EnabledList;
744 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
Brian Paulde82d062000-06-26 23:37:46 +0000745 GLfloat color[4];
jtgafb833d1999-08-19 00:55:39 +0000746
Brian Paulc893a012000-10-28 20:41:13 +0000747 color[0] = CHAN_TO_FLOAT(rgba[0]);
748 color[1] = CHAN_TO_FLOAT(rgba[1]);
749 color[2] = CHAN_TO_FLOAT(rgba[2]);
750 color[3] = CHAN_TO_FLOAT(rgba[3]);
751
Keith Whitwell06ac5921999-11-10 06:29:44 +0000752 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000753 fprintf(stderr, "gl_update_color_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000754
Brian Paulde82d062000-06-26 23:37:46 +0000755 /* update emissive colors */
756 if (bitmask & FRONT_EMISSION_BIT) {
757 struct gl_material *mat = &ctx->Light.Material[0];
758 COPY_4FV( mat->Emission, color );
759 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000760
Brian Paulde82d062000-06-26 23:37:46 +0000761 if (bitmask & BACK_EMISSION_BIT) {
762 struct gl_material *mat = &ctx->Light.Material[1];
763 COPY_4FV( mat->Emission, color );
764 }
765
Keith Whitwell14940c42000-11-05 18:40:57 +0000766 /* update light->_MatAmbient = light's ambient * material's ambient */
jtgafb833d1999-08-19 00:55:39 +0000767 if (bitmask & FRONT_AMBIENT_BIT) {
768 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000769 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000770 SCALE_3V( light->_MatAmbient[0], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000771 }
772 COPY_4FV( mat->Ambient, color );
773 }
774
775 if (bitmask & BACK_AMBIENT_BIT) {
776 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000777 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000778 SCALE_3V( light->_MatAmbient[1], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000779 }
780 COPY_4FV( mat->Ambient, color );
781 }
782
Brian Paulde82d062000-06-26 23:37:46 +0000783 /* update BaseColor = emission + scene's ambience * material's ambience */
784 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
785 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000786 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
787 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000788 }
789
790 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
791 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000792 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
793 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000794 }
795
Keith Whitwell14940c42000-11-05 18:40:57 +0000796 /* update light->_MatDiffuse = light's diffuse * material's diffuse */
jtgafb833d1999-08-19 00:55:39 +0000797 if (bitmask & FRONT_DIFFUSE_BIT) {
798 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000799 COPY_4FV( mat->Diffuse, color );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000800 foreach (light, list) {
801 SCALE_3V( light->_MatDiffuse[0], light->Diffuse, mat->Diffuse );
802 }
Brian Paul3041d052001-01-02 22:02:51 +0000803 UNCLAMPED_FLOAT_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000804 }
805
806 if (bitmask & BACK_DIFFUSE_BIT) {
807 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000808 COPY_4FV( mat->Diffuse, color );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000809 foreach (light, list) {
810 SCALE_3V( light->_MatDiffuse[1], light->Diffuse, mat->Diffuse );
811 }
Brian Paul3041d052001-01-02 22:02:51 +0000812 UNCLAMPED_FLOAT_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000813 }
814
Keith Whitwell14940c42000-11-05 18:40:57 +0000815 /* update light->_MatSpecular = light's specular * material's specular */
jtgafb833d1999-08-19 00:55:39 +0000816 if (bitmask & FRONT_SPECULAR_BIT) {
817 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000818 COPY_4FV( mat->Specular, color );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000819 foreach (light, list) {
820 ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, mat->Specular);
821 }
jtgafb833d1999-08-19 00:55:39 +0000822 }
Brian Paulde82d062000-06-26 23:37:46 +0000823
jtgafb833d1999-08-19 00:55:39 +0000824 if (bitmask & BACK_SPECULAR_BIT) {
825 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000826 COPY_4FV( mat->Specular, color );
Keith Whitwellad2ac212000-11-24 10:25:05 +0000827 foreach (light, list) {
828 ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, mat->Specular);
829 }
jtgafb833d1999-08-19 00:55:39 +0000830 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000831
832 if (0)
833 {
834 struct gl_material *mat = &ctx->Light.Material[0];
835 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
836 mat->Emission[0],
837 mat->Emission[1],
838 mat->Emission[2]);
839 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
840 mat->Specular[0],
841 mat->Specular[1],
842 mat->Specular[2]);
843 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
844 mat->Diffuse[0],
845 mat->Diffuse[1],
846 mat->Diffuse[2]);
847 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
848 mat->Ambient[0],
849 mat->Ambient[1],
850 mat->Ambient[2]);
851 }
jtgafb833d1999-08-19 00:55:39 +0000852}
853
854
855
856
Brian Paulfbd8f211999-11-11 01:22:25 +0000857void
858_mesa_ColorMaterial( GLenum face, GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000859{
Brian Paulfbd8f211999-11-11 01:22:25 +0000860 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000861 GLuint bitmask;
862 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
863 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
864 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
865 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
Keith Whitwellcab974c2000-12-26 05:09:27 +0000866 ASSERT_OUTSIDE_BEGIN_END(ctx);
jtgafb833d1999-08-19 00:55:39 +0000867
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +0000868 if (MESA_VERBOSE&VERBOSE_API)
869 fprintf(stderr, "glColorMaterial %s %s\n",
Keith Whitwell06ac5921999-11-10 06:29:44 +0000870 gl_lookup_enum_by_nr(face),
871 gl_lookup_enum_by_nr(mode));
872
jtgafb833d1999-08-19 00:55:39 +0000873 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
874
Keith Whitwellcab974c2000-12-26 05:09:27 +0000875 if (ctx->Light.ColorMaterialBitmask == bitmask &&
876 ctx->Light.ColorMaterialFace == face &&
877 ctx->Light.ColorMaterialMode == mode)
878 return;
879
880 FLUSH_VERTICES(ctx, _NEW_LIGHT);
881 ctx->Light.ColorMaterialBitmask = bitmask;
882 ctx->Light.ColorMaterialFace = face;
883 ctx->Light.ColorMaterialMode = mode;
Keith Whitwell06ac5921999-11-10 06:29:44 +0000884
Keith Whitwell23caf202000-11-16 21:05:34 +0000885 if (ctx->Light.ColorMaterialEnabled) {
Keith Whitwellcab974c2000-12-26 05:09:27 +0000886 FLUSH_CURRENT( ctx, 0 );
Brian Paul19300532000-10-29 19:02:23 +0000887 gl_update_color_material( ctx, ctx->Current.Color );
Keith Whitwell23caf202000-11-16 21:05:34 +0000888 }
jtgafb833d1999-08-19 00:55:39 +0000889}
890
891
892
Brian Paulfbd8f211999-11-11 01:22:25 +0000893
Brian Paulfbd8f211999-11-11 01:22:25 +0000894
895void
896_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
897{
898 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000899 GLuint f;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000900 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */
jtgafb833d1999-08-19 00:55:39 +0000901
902 if (face==GL_FRONT) {
903 f = 0;
904 }
905 else if (face==GL_BACK) {
906 f = 1;
907 }
908 else {
909 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
910 return;
911 }
912 switch (pname) {
913 case GL_AMBIENT:
914 COPY_4FV( params, ctx->Light.Material[f].Ambient );
915 break;
916 case GL_DIFFUSE:
917 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
918 break;
919 case GL_SPECULAR:
920 COPY_4FV( params, ctx->Light.Material[f].Specular );
921 break;
922 case GL_EMISSION:
923 COPY_4FV( params, ctx->Light.Material[f].Emission );
924 break;
925 case GL_SHININESS:
926 *params = ctx->Light.Material[f].Shininess;
927 break;
928 case GL_COLOR_INDEXES:
929 params[0] = ctx->Light.Material[f].AmbientIndex;
930 params[1] = ctx->Light.Material[f].DiffuseIndex;
931 params[2] = ctx->Light.Material[f].SpecularIndex;
932 break;
933 default:
934 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
935 }
936}
937
938
939
Brian Paulfbd8f211999-11-11 01:22:25 +0000940void
941_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +0000942{
Brian Paulfbd8f211999-11-11 01:22:25 +0000943 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000944 GLuint f;
Keith Whitwellcab974c2000-12-26 05:09:27 +0000945 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* update materials */
jtgafb833d1999-08-19 00:55:39 +0000946
947 if (face==GL_FRONT) {
948 f = 0;
949 }
950 else if (face==GL_BACK) {
951 f = 1;
952 }
953 else {
954 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
955 return;
956 }
957 switch (pname) {
958 case GL_AMBIENT:
959 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
960 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
961 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
962 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
963 break;
964 case GL_DIFFUSE:
965 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
966 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
967 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
968 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
969 break;
970 case GL_SPECULAR:
971 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
972 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
973 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
974 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
975 break;
976 case GL_EMISSION:
977 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
978 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
979 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
980 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
981 break;
982 case GL_SHININESS:
983 *params = ROUNDF( ctx->Light.Material[f].Shininess );
984 break;
985 case GL_COLOR_INDEXES:
986 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
987 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
988 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
989 break;
990 default:
991 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
992 }
993}
994
995
996
997
998/**********************************************************************/
999/***** Lighting computation *****/
1000/**********************************************************************/
1001
1002
1003/*
1004 * Notes:
1005 * When two-sided lighting is enabled we compute the color (or index)
1006 * for both the front and back side of the primitive. Then, when the
1007 * orientation of the facet is later learned, we can determine which
1008 * color (or index) to use for rendering.
1009 *
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001010 * KW: We now know orientation in advance and only shade for
jtgafb833d1999-08-19 00:55:39 +00001011 * the side or sides which are actually required.
1012 *
1013 * Variables:
1014 * n = normal vector
1015 * V = vertex position
1016 * P = light source position
1017 * Pe = (0,0,0,1)
1018 *
1019 * Precomputed:
1020 * IF P[3]==0 THEN
1021 * // light at infinity
1022 * IF local_viewer THEN
Keith Whitwell14940c42000-11-05 18:40:57 +00001023 * _VP_inf_norm = unit vector from V to P // Precompute
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001024 * ELSE
jtgafb833d1999-08-19 00:55:39 +00001025 * // eye at infinity
Keith Whitwell14940c42000-11-05 18:40:57 +00001026 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
jtgafb833d1999-08-19 00:55:39 +00001027 * ENDIF
1028 * ENDIF
1029 *
1030 * Functions:
1031 * Normalize( v ) = normalized vector v
1032 * Magnitude( v ) = length of vector v
1033 */
1034
1035
1036
1037/*
1038 * Whenever the spotlight exponent for a light changes we must call
1039 * this function to recompute the exponent lookup table.
1040 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001041void
Keith Whitwellcab974c2000-12-26 05:09:27 +00001042gl_invalidate_spot_exp_table( struct gl_light *l )
1043{
1044 l->_SpotExpTable[0][0] = -1;
1045}
1046
1047static void validate_spot_exp_table( struct gl_light *l )
jtgafb833d1999-08-19 00:55:39 +00001048{
Brian Paula0faa7f2000-07-18 16:55:56 +00001049 GLint i;
1050 GLdouble exponent = l->SpotExponent;
1051 GLdouble tmp = 0;
1052 GLint clamp = 0;
jtgafb833d1999-08-19 00:55:39 +00001053
Keith Whitwell14940c42000-11-05 18:40:57 +00001054 l->_SpotExpTable[0][0] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001055
Brian Paula0faa7f2000-07-18 16:55:56 +00001056 for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
jtgafb833d1999-08-19 00:55:39 +00001057 if (clamp == 0) {
Keith Whitwellcab974c2000-12-26 05:09:27 +00001058 tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
1059 if (tmp < FLT_MIN * 100.0) {
1060 tmp = 0.0;
1061 clamp = 1;
1062 }
jtgafb833d1999-08-19 00:55:39 +00001063 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001064 l->_SpotExpTable[i][0] = tmp;
jtgafb833d1999-08-19 00:55:39 +00001065 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001066 for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
Keith Whitwellcab974c2000-12-26 05:09:27 +00001067 l->_SpotExpTable[i][1] = (l->_SpotExpTable[i+1][0] -
1068 l->_SpotExpTable[i][0]);
jtgafb833d1999-08-19 00:55:39 +00001069 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001070 l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001071}
1072
1073
1074
1075
1076/* Calculate a new shine table. Doing this here saves a branch in
1077 * lighting, and the cost of doing it early may be partially offset
1078 * by keeping a MRU cache of shine tables for various shine values.
1079 */
Keith Whitwellcab974c2000-12-26 05:09:27 +00001080void
1081gl_invalidate_shine_table( GLcontext *ctx, GLuint i )
jtgafb833d1999-08-19 00:55:39 +00001082{
Keith Whitwellcab974c2000-12-26 05:09:27 +00001083 if (ctx->_ShineTable[i])
1084 ctx->_ShineTable[i]->refcount--;
1085 ctx->_ShineTable[i] = 0;
jtgafb833d1999-08-19 00:55:39 +00001086}
1087
Keith Whitwellcab974c2000-12-26 05:09:27 +00001088static void validate_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001089{
Keith Whitwell14940c42000-11-05 18:40:57 +00001090 struct gl_shine_tab *list = ctx->_ShineTabList;
jtgafb833d1999-08-19 00:55:39 +00001091 struct gl_shine_tab *s;
1092
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001093 foreach(s, list)
Keith Whitwellcab974c2000-12-26 05:09:27 +00001094 if ( s->shininess == shininess )
jtgafb833d1999-08-19 00:55:39 +00001095 break;
1096
Brian Paula0faa7f2000-07-18 16:55:56 +00001097 if (s == list) {
Keith Whitwell321f67c2001-01-13 05:48:25 +00001098 GLint j;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001099 GLfloat *m;
1100
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001101 foreach(s, list)
Brian Paula0faa7f2000-07-18 16:55:56 +00001102 if (s->refcount == 0)
Keith Whitwellcab974c2000-12-26 05:09:27 +00001103 break;
jtgafb833d1999-08-19 00:55:39 +00001104
Keith Whitwellcab974c2000-12-26 05:09:27 +00001105 m = s->tab;
1106 m[0] = 0.0;
1107 if (shininess == 0.0) {
Keith Whitwell321f67c2001-01-13 05:48:25 +00001108 for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++)
1109 m[j] = 1.0;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001110 }
1111 else {
Keith Whitwell321f67c2001-01-13 05:48:25 +00001112 for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) {
1113 GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1);
Brian Paulf22c04c2001-01-04 16:22:18 +00001114 if (x < 0.005) /* underflow check */
1115 x = 0.005;
1116 t = pow(x, shininess);
Keith Whitwellcab974c2000-12-26 05:09:27 +00001117 if (t > 1e-20)
Keith Whitwell321f67c2001-01-13 05:48:25 +00001118 m[j] = t;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001119 else
Keith Whitwell321f67c2001-01-13 05:48:25 +00001120 m[j] = 0.0;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001121 }
1122 m[SHINE_TABLE_SIZE] = 1.0;
1123 }
1124
1125 s->shininess = shininess;
jtgafb833d1999-08-19 00:55:39 +00001126 }
1127
Keith Whitwellcab974c2000-12-26 05:09:27 +00001128 if (ctx->_ShineTable[i])
1129 ctx->_ShineTable[i]->refcount--;
1130
Keith Whitwell14940c42000-11-05 18:40:57 +00001131 ctx->_ShineTable[i] = s;
jtgafb833d1999-08-19 00:55:39 +00001132 move_to_tail( list, s );
1133 s->refcount++;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001134}
1135
1136void
1137gl_validate_all_lighting_tables( GLcontext *ctx )
1138{
1139 GLint i;
1140 GLfloat shininess;
1141
1142 shininess = ctx->Light.Material[0].Shininess;
Brian Paul45323642001-02-13 23:55:30 +00001143 if (!ctx->_ShineTable[0] || ctx->_ShineTable[0]->shininess != shininess)
1144 validate_shine_table( ctx, 0, shininess );
Keith Whitwellcab974c2000-12-26 05:09:27 +00001145
1146 shininess = ctx->Light.Material[1].Shininess;
Brian Paul45323642001-02-13 23:55:30 +00001147 if (!ctx->_ShineTable[1] || ctx->_ShineTable[1]->shininess != shininess)
1148 validate_shine_table( ctx, 1, shininess );
Keith Whitwellcab974c2000-12-26 05:09:27 +00001149
1150 for (i = 0 ; i < MAX_LIGHTS ; i++)
1151 if (ctx->Light.Light[i]._SpotExpTable[0][0] == -1)
1152 validate_spot_exp_table( &ctx->Light.Light[i] );
jtgafb833d1999-08-19 00:55:39 +00001153}
1154
1155
1156
jtgafb833d1999-08-19 00:55:39 +00001157
1158/*
1159 * Examine current lighting parameters to determine if the optimized lighting
1160 * function can be used.
1161 * Also, precompute some lighting values such as the products of light
1162 * source and material ambient, diffuse and specular coefficients.
1163 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001164void
1165gl_update_lighting( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001166{
1167 struct gl_light *light;
Keith Whitwellcab974c2000-12-26 05:09:27 +00001168 ctx->_TriangleCaps &= ~DD_TRI_LIGHT_TWOSIDE;
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001169 ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT;
1170 ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT;
Keith Whitwell14940c42000-11-05 18:40:57 +00001171 ctx->Light._Flags = 0;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001172
1173 if (!ctx->Light.Enabled)
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001174 return;
1175
1176 ctx->_NeedNormals |= NEED_NORMALS_LIGHT;
1177
1178 if (ctx->Light.Model.TwoSide)
Keith Whitwellcab974c2000-12-26 05:09:27 +00001179 ctx->_TriangleCaps |= DD_TRI_LIGHT_TWOSIDE;
jtgafb833d1999-08-19 00:55:39 +00001180
1181 foreach(light, &ctx->Light.EnabledList) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001182 ctx->Light._Flags |= light->_Flags;
jtgafb833d1999-08-19 00:55:39 +00001183 }
1184
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001185 ctx->Light._NeedVertices =
Keith Whitwell14940c42000-11-05 18:40:57 +00001186 ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001187 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
1188 ctx->Light.Model.LocalViewer);
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001189
1190 if ((ctx->Light._Flags & LIGHT_POSITIONAL) ||
1191 ctx->Light.Model.LocalViewer)
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001192 ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001193
1194
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001195 /* XXX: This test is overkill & needs to be fixed both for software and
1196 * hardware t&l drivers. The above should be sufficient & should
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001197 * be tested to verify this.
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001198 */
1199 if (ctx->Light._NeedVertices)
1200 ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001201
jtgafb833d1999-08-19 00:55:39 +00001202
Keith Whitwellcab974c2000-12-26 05:09:27 +00001203 /* Precompute some shading values. Although we reference
1204 * Light.Material here, we can get away without flushing
1205 * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
1206 * are flushed, they will update the derived state at that time.
jtgafb833d1999-08-19 00:55:39 +00001207 */
Brian Paulb6bcae52001-01-23 23:39:36 +00001208 if (ctx->Visual.rgbMode) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001209 GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1;
jtgafb833d1999-08-19 00:55:39 +00001210 GLuint side;
1211 for (side=0; side < sides; side++) {
1212 struct gl_material *mat = &ctx->Light.Material[side];
Brian Paulc535ba52000-06-29 04:56:30 +00001213
Keith Whitwell14940c42000-11-05 18:40:57 +00001214 COPY_3V(ctx->Light._BaseColor[side], mat->Emission);
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001215 ACC_SCALE_3V(ctx->Light._BaseColor[side],
jtgafb833d1999-08-19 00:55:39 +00001216 ctx->Light.Model.Ambient,
1217 mat->Ambient);
1218
Brian Paul3041d052001-01-02 22:02:51 +00001219 UNCLAMPED_FLOAT_TO_CHAN(ctx->Light._BaseAlpha[side],
1220 ctx->Light.Material[side].Diffuse[3] );
jtgafb833d1999-08-19 00:55:39 +00001221 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001222
1223 foreach (light, &ctx->Light.EnabledList) {
jtgafb833d1999-08-19 00:55:39 +00001224 for (side=0; side< sides; side++) {
Brian Paulc535ba52000-06-29 04:56:30 +00001225 const struct gl_material *mat = &ctx->Light.Material[side];
Keith Whitwell14940c42000-11-05 18:40:57 +00001226 SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse );
1227 SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient );
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001228 SCALE_3V( light->_MatSpecular[side], light->Specular,
1229 mat->Specular);
jtgafb833d1999-08-19 00:55:39 +00001230 }
1231 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001232 }
Brian Paulc535ba52000-06-29 04:56:30 +00001233 else {
1234 static const GLfloat ci[3] = { .30, .59, .11 };
jtgafb833d1999-08-19 00:55:39 +00001235 foreach(light, &ctx->Light.EnabledList) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001236 light->_dli = DOT3(ci, light->Diffuse);
1237 light->_sli = DOT3(ci, light->Specular);
jtgafb833d1999-08-19 00:55:39 +00001238 }
1239 }
1240}
1241
Brian Paulc535ba52000-06-29 04:56:30 +00001242
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001243/* _NEW_MODELVIEW
1244 * _NEW_LIGHT
1245 * _TNL_NEW_NEED_EYE_COORDS
1246 *
1247 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
1248 * Also update on lighting space changes.
jtgafb833d1999-08-19 00:55:39 +00001249 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001250void
1251gl_compute_light_positions( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001252{
1253 struct gl_light *light;
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001254 static const GLfloat eye_z[3] = { 0, 0, 1 };
jtgafb833d1999-08-19 00:55:39 +00001255
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001256 if (!ctx->Light.Enabled)
1257 return;
1258
1259 if (ctx->_NeedEyeCoords) {
1260 COPY_3V( ctx->_EyeZDir, eye_z );
1261 }
1262 else {
1263 TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m );
1264 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001265
jtgafb833d1999-08-19 00:55:39 +00001266 foreach (light, &ctx->Light.EnabledList) {
1267
Keith Whitwell14940c42000-11-05 18:40:57 +00001268 if (ctx->_NeedEyeCoords) {
1269 COPY_4FV( light->_Position, light->EyePosition );
jtgafb833d1999-08-19 00:55:39 +00001270 }
Brian Paulde82d062000-06-26 23:37:46 +00001271 else {
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001272 TRANSFORM_POINT( light->_Position, ctx->ModelView.inv,
Brian Paulde82d062000-06-26 23:37:46 +00001273 light->EyePosition );
1274 }
jtgafb833d1999-08-19 00:55:39 +00001275
Keith Whitwell14940c42000-11-05 18:40:57 +00001276 if (!(light->_Flags & LIGHT_POSITIONAL)) {
jtgafb833d1999-08-19 00:55:39 +00001277 /* VP (VP) = Normalize( Position ) */
Keith Whitwell14940c42000-11-05 18:40:57 +00001278 COPY_3V( light->_VP_inf_norm, light->_Position );
1279 NORMALIZE_3FV( light->_VP_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001280
Brian Paulde82d062000-06-26 23:37:46 +00001281 if (!ctx->Light.Model.LocalViewer) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001282 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1283 ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
1284 NORMALIZE_3FV( light->_h_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001285 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001286 light->_VP_inf_spot_attenuation = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001287 }
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001288
Keith Whitwell14940c42000-11-05 18:40:57 +00001289 if (light->_Flags & LIGHT_SPOT) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001290 if (ctx->_NeedEyeCoords) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001291 COPY_3V( light->_NormDirection, light->EyeDirection );
Brian Paulde82d062000-06-26 23:37:46 +00001292 }
1293 else {
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001294 TRANSFORM_NORMAL( light->_NormDirection,
jtgafb833d1999-08-19 00:55:39 +00001295 light->EyeDirection,
1296 ctx->ModelView.m);
1297 }
1298
Keith Whitwell14940c42000-11-05 18:40:57 +00001299 NORMALIZE_3FV( light->_NormDirection );
jtgafb833d1999-08-19 00:55:39 +00001300
Keith Whitwell14940c42000-11-05 18:40:57 +00001301 if (!(light->_Flags & LIGHT_POSITIONAL)) {
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001302 GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
Keith Whitwell14940c42000-11-05 18:40:57 +00001303 light->_NormDirection);
jtgafb833d1999-08-19 00:55:39 +00001304
Keith Whitwell14940c42000-11-05 18:40:57 +00001305 if (PV_dot_dir > light->_CosCutoff) {
jtgafb833d1999-08-19 00:55:39 +00001306 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1307 int k = (int) x;
Jouk Jansen5e3bc0c2000-11-22 07:32:16 +00001308 light->_VP_inf_spot_attenuation =
1309 (light->_SpotExpTable[k][0] +
Keith Whitwell14940c42000-11-05 18:40:57 +00001310 (x-k)*light->_SpotExpTable[k][1]);
jtgafb833d1999-08-19 00:55:39 +00001311 }
Brian Paulde82d062000-06-26 23:37:46 +00001312 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001313 light->_VP_inf_spot_attenuation = 0;
Brian Paulde82d062000-06-26 23:37:46 +00001314 }
jtgafb833d1999-08-19 00:55:39 +00001315 }
1316 }
1317 }
1318}
1319
1320