blob: e5159253e6aacc4ceb13790aca601320446e40ee [file] [log] [blame]
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001/* $Id: light.c,v 1.24 2000/11/13 20:02:56 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
jtgafb833d1999-08-19 00:55:39 +00006 *
Brian Paul16a9efe2000-01-13 00:29:02 +00007 * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
jtgafb833d1999-08-19 00:55:39 +00008 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27
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"
37#include "matrix.h"
Brian Paulfbd8f211999-11-11 01:22:25 +000038#include "mem.h"
jtgafb833d1999-08-19 00:55:39 +000039#include "mmath.h"
40#include "simple_list.h"
41#include "types.h"
42#include "vb.h"
43#include "xform.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);
jtgafb833d1999-08-19 00:55:39 +000057 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
58
59 if (MESA_VERBOSE & VERBOSE_API)
60 fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
61
Brian Paulfbd8f211999-11-11 01:22:25 +000062 if (mode == GL_FLAT || mode == GL_SMOOTH) {
Brian Paul8acb3a11999-11-22 18:58:53 +000063 if (ctx->Light.ShadeModel != mode) {
Brian Paulfbd8f211999-11-11 01:22:25 +000064 ctx->Light.ShadeModel = mode;
Brian Paul8acb3a11999-11-22 18:58:53 +000065 if (ctx->Light.ShadeModel == GL_FLAT)
Keith Whitwell14940c42000-11-05 18:40:57 +000066 SET_BITS(ctx->_TriangleCaps, DD_FLATSHADE);
Brian Paul8acb3a11999-11-22 18:58:53 +000067 else
Keith Whitwell14940c42000-11-05 18:40:57 +000068 CLEAR_BITS(ctx->_TriangleCaps, DD_FLATSHADE);
Keith Whitwella96308c2000-10-30 13:31:59 +000069
70 ctx->NewState |= _NEW_LIGHT;
71
Brian Paulfbd8f211999-11-11 01:22:25 +000072 if (ctx->Driver.ShadeModel)
73 (*ctx->Driver.ShadeModel)( ctx, mode );
Keith Whitwell1bf9dfa1999-09-18 20:41:22 +000074 }
Brian Paulfbd8f211999-11-11 01:22:25 +000075 }
76 else {
Keith Whitwell1bf9dfa1999-09-18 20:41:22 +000077 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
jtgafb833d1999-08-19 00:55:39 +000078 }
jtgafb833d1999-08-19 00:55:39 +000079}
80
81
82
Brian Paulfbd8f211999-11-11 01:22:25 +000083void
84_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
jtgafb833d1999-08-19 00:55:39 +000085{
Brian Paulfbd8f211999-11-11 01:22:25 +000086 _mesa_Lightfv( light, pname, &param );
87}
jtgafb833d1999-08-19 00:55:39 +000088
Brian Paulfbd8f211999-11-11 01:22:25 +000089
90void
91_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
92{
93 GET_CURRENT_CONTEXT(ctx);
Keith Whitwell1e1aac02000-11-13 20:02:56 +000094 GLint i = (GLint) (light - GL_LIGHT0);
95 struct gl_light *l = &ctx->Light.Light[i];
jtgafb833d1999-08-19 00:55:39 +000096
97 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
98
Keith Whitwell1e1aac02000-11-13 20:02:56 +000099 if (i < 0 || i >= MAX_LIGHTS) {
jtgafb833d1999-08-19 00:55:39 +0000100 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
101 return;
102 }
103
104 switch (pname) {
105 case GL_AMBIENT:
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000106 COPY_4V( l->Ambient, params );
jtgafb833d1999-08-19 00:55:39 +0000107 break;
108 case GL_DIFFUSE:
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000109 COPY_4V( l->Diffuse, params );
jtgafb833d1999-08-19 00:55:39 +0000110 break;
111 case GL_SPECULAR:
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000112 COPY_4V( l->Specular, params );
jtgafb833d1999-08-19 00:55:39 +0000113 break;
114 case GL_POSITION:
115 /* transform position by ModelView matrix */
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000116 TRANSFORM_POINT( l->EyePosition, ctx->ModelView.m, params );
117 if (l->EyePosition[3] != 0.0F)
118 l->_Flags |= LIGHT_POSITIONAL;
119 else
120 l->_Flags &= ~LIGHT_POSITIONAL;
jtgafb833d1999-08-19 00:55:39 +0000121 break;
122 case GL_SPOT_DIRECTION:
123 /* transform direction by inverse modelview */
124 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
125 gl_matrix_analyze( &ctx->ModelView );
126 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000127 TRANSFORM_NORMAL( l->EyeDirection, params, ctx->ModelView.inv );
jtgafb833d1999-08-19 00:55:39 +0000128 break;
129 case GL_SPOT_EXPONENT:
130 if (params[0]<0.0 || params[0]>128.0) {
131 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
132 return;
133 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000134 if (l->SpotExponent != params[0]) {
135 l->SpotExponent = params[0];
136 gl_compute_spot_exp_table( l );
jtgafb833d1999-08-19 00:55:39 +0000137 }
138 break;
139 case GL_SPOT_CUTOFF:
140 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
141 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
142 return;
143 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000144 l->SpotCutoff = params[0];
145 l->_CosCutoff = cos(params[0]*DEG2RAD);
146 if (l->_CosCutoff < 0)
147 l->_CosCutoff = 0;
148 if (l->SpotCutoff != 180.0F)
149 l->_Flags |= LIGHT_SPOT;
150 else
151 l->_Flags &= ~LIGHT_SPOT;
jtgafb833d1999-08-19 00:55:39 +0000152 break;
153 case GL_CONSTANT_ATTENUATION:
154 if (params[0]<0.0) {
155 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
156 return;
157 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000158 l->ConstantAttenuation = params[0];
jtgafb833d1999-08-19 00:55:39 +0000159 break;
160 case GL_LINEAR_ATTENUATION:
161 if (params[0]<0.0) {
162 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
163 return;
164 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000165 l->LinearAttenuation = params[0];
jtgafb833d1999-08-19 00:55:39 +0000166 break;
167 case GL_QUADRATIC_ATTENUATION:
168 if (params[0]<0.0) {
169 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
170 return;
171 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000172 l->QuadraticAttenuation = params[0];
jtgafb833d1999-08-19 00:55:39 +0000173 break;
174 default:
175 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
Brian Paulfbd8f211999-11-11 01:22:25 +0000176 return;
jtgafb833d1999-08-19 00:55:39 +0000177 }
178
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000179 if (ctx->Driver.Lightfv)
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000180 ctx->Driver.Lightfv( ctx, light, pname, params );
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000181
Keith Whitwella96308c2000-10-30 13:31:59 +0000182 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000183}
184
185
Brian Paulfbd8f211999-11-11 01:22:25 +0000186void
187_mesa_Lighti( GLenum light, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000188{
Brian Paulfbd8f211999-11-11 01:22:25 +0000189 _mesa_Lightiv( light, pname, &param );
190}
191
192
193void
194_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
195{
196 GLfloat fparam[4];
197
198 switch (pname) {
199 case GL_AMBIENT:
200 case GL_DIFFUSE:
201 case GL_SPECULAR:
202 fparam[0] = INT_TO_FLOAT( params[0] );
203 fparam[1] = INT_TO_FLOAT( params[1] );
204 fparam[2] = INT_TO_FLOAT( params[2] );
205 fparam[3] = INT_TO_FLOAT( params[3] );
206 break;
207 case GL_POSITION:
208 fparam[0] = (GLfloat) params[0];
209 fparam[1] = (GLfloat) params[1];
210 fparam[2] = (GLfloat) params[2];
211 fparam[3] = (GLfloat) params[3];
212 break;
213 case GL_SPOT_DIRECTION:
214 fparam[0] = (GLfloat) params[0];
215 fparam[1] = (GLfloat) params[1];
216 fparam[2] = (GLfloat) params[2];
217 break;
218 case GL_SPOT_EXPONENT:
219 case GL_SPOT_CUTOFF:
220 case GL_CONSTANT_ATTENUATION:
221 case GL_LINEAR_ATTENUATION:
222 case GL_QUADRATIC_ATTENUATION:
223 fparam[0] = (GLfloat) params[0];
224 break;
225 default:
226 /* error will be caught later in gl_Lightfv */
227 ;
228 }
229
230 _mesa_Lightfv( light, pname, fparam );
231}
232
233
234
235void
236_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
237{
238 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000239 GLint l = (GLint) (light - GL_LIGHT0);
240
241 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
242
243 if (l<0 || l>=MAX_LIGHTS) {
244 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
245 return;
246 }
247
248 switch (pname) {
249 case GL_AMBIENT:
250 COPY_4V( params, ctx->Light.Light[l].Ambient );
251 break;
252 case GL_DIFFUSE:
253 COPY_4V( params, ctx->Light.Light[l].Diffuse );
254 break;
255 case GL_SPECULAR:
256 COPY_4V( params, ctx->Light.Light[l].Specular );
257 break;
258 case GL_POSITION:
259 COPY_4V( params, ctx->Light.Light[l].EyePosition );
260 break;
261 case GL_SPOT_DIRECTION:
262 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
263 break;
264 case GL_SPOT_EXPONENT:
265 params[0] = ctx->Light.Light[l].SpotExponent;
266 break;
267 case GL_SPOT_CUTOFF:
268 params[0] = ctx->Light.Light[l].SpotCutoff;
269 break;
270 case GL_CONSTANT_ATTENUATION:
271 params[0] = ctx->Light.Light[l].ConstantAttenuation;
272 break;
273 case GL_LINEAR_ATTENUATION:
274 params[0] = ctx->Light.Light[l].LinearAttenuation;
275 break;
276 case GL_QUADRATIC_ATTENUATION:
277 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
278 break;
279 default:
280 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
281 break;
282 }
283}
284
285
286
Brian Paulfbd8f211999-11-11 01:22:25 +0000287void
288_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +0000289{
Brian Paulfbd8f211999-11-11 01:22:25 +0000290 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000291 GLint l = (GLint) (light - GL_LIGHT0);
292
293 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
294
295 if (l<0 || l>=MAX_LIGHTS) {
296 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
297 return;
298 }
299
300 switch (pname) {
301 case GL_AMBIENT:
302 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
303 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
304 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
305 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
306 break;
307 case GL_DIFFUSE:
308 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
309 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
310 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
311 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
312 break;
313 case GL_SPECULAR:
314 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
315 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
316 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
317 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
318 break;
319 case GL_POSITION:
320 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
321 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
322 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
323 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
324 break;
325 case GL_SPOT_DIRECTION:
326 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
327 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
328 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
329 break;
330 case GL_SPOT_EXPONENT:
331 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
332 break;
333 case GL_SPOT_CUTOFF:
334 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
335 break;
336 case GL_CONSTANT_ATTENUATION:
337 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
338 break;
339 case GL_LINEAR_ATTENUATION:
340 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
341 break;
342 case GL_QUADRATIC_ATTENUATION:
343 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
344 break;
345 default:
346 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
347 break;
348 }
349}
350
351
352
353/**********************************************************************/
354/*** Light Model ***/
355/**********************************************************************/
356
357
Brian Paulfbd8f211999-11-11 01:22:25 +0000358void
359_mesa_LightModelfv( GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000360{
Brian Paulfbd8f211999-11-11 01:22:25 +0000361 GET_CURRENT_CONTEXT(ctx);
362 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
jtgafb833d1999-08-19 00:55:39 +0000363
364 switch (pname) {
365 case GL_LIGHT_MODEL_AMBIENT:
366 COPY_4V( ctx->Light.Model.Ambient, params );
367 break;
368 case GL_LIGHT_MODEL_LOCAL_VIEWER:
369 if (params[0]==0.0)
370 ctx->Light.Model.LocalViewer = GL_FALSE;
371 else
372 ctx->Light.Model.LocalViewer = GL_TRUE;
373 break;
374 case GL_LIGHT_MODEL_TWO_SIDE:
375 if (params[0]==0.0)
376 ctx->Light.Model.TwoSide = GL_FALSE;
377 else
378 ctx->Light.Model.TwoSide = GL_TRUE;
379 break;
380 case GL_LIGHT_MODEL_COLOR_CONTROL:
Brian Paulf3f9b771999-10-19 20:32:40 +0000381 if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
jtgafb833d1999-08-19 00:55:39 +0000382 ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
Keith Whitwellfe5d67d2000-10-27 16:44:40 +0000383 if (!ctx->Fog.ColorSumEnabled)
Keith Whitwell14940c42000-11-05 18:40:57 +0000384 CLEAR_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000385 }
jtgafb833d1999-08-19 00:55:39 +0000386 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
387 ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
Keith Whitwell14940c42000-11-05 18:40:57 +0000388 SET_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000389 }
390 else {
jtgafb833d1999-08-19 00:55:39 +0000391 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
Brian Paulf3f9b771999-10-19 20:32:40 +0000392 }
jtgafb833d1999-08-19 00:55:39 +0000393 break;
394 default:
395 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
396 break;
397 }
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000398
399 if (ctx->Driver.LightModelfv)
400 ctx->Driver.LightModelfv( ctx, pname, params );
401
Keith Whitwella96308c2000-10-30 13:31:59 +0000402 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000403}
404
405
Brian Paulfbd8f211999-11-11 01:22:25 +0000406void
407_mesa_LightModeliv( GLenum pname, const GLint *params )
408{
409 GLfloat fparam[4];
410 GET_CURRENT_CONTEXT(ctx);
411 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
412
413 switch (pname) {
414 case GL_LIGHT_MODEL_AMBIENT:
415 fparam[0] = INT_TO_FLOAT( params[0] );
416 fparam[1] = INT_TO_FLOAT( params[1] );
417 fparam[2] = INT_TO_FLOAT( params[2] );
418 fparam[3] = INT_TO_FLOAT( params[3] );
419 break;
420 case GL_LIGHT_MODEL_LOCAL_VIEWER:
421 case GL_LIGHT_MODEL_TWO_SIDE:
422 case GL_LIGHT_MODEL_COLOR_CONTROL:
423 fparam[0] = (GLfloat) params[0];
424 break;
425 default:
426 /* Error will be caught later in gl_LightModelfv */
427 ;
428 }
429 _mesa_LightModelfv( pname, fparam );
430}
431
432
433void
434_mesa_LightModeli( GLenum pname, GLint param )
435{
436 _mesa_LightModeliv( pname, &param );
437}
438
439
440void
441_mesa_LightModelf( GLenum pname, GLfloat param )
442{
443 _mesa_LightModelfv( pname, &param );
444}
445
jtgafb833d1999-08-19 00:55:39 +0000446
447
448/********** MATERIAL **********/
449
450
451/*
452 * Given a face and pname value (ala glColorMaterial), compute a bitmask
453 * of the targeted material values.
454 */
455GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
456 GLuint legal,
457 const char *where )
458{
459 GLuint bitmask = 0;
460
461 /* Make a bitmask indicating what material attribute(s) we're updating */
462 switch (pname) {
463 case GL_EMISSION:
464 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
465 break;
466 case GL_AMBIENT:
467 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
468 break;
469 case GL_DIFFUSE:
470 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
471 break;
472 case GL_SPECULAR:
473 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
474 break;
475 case GL_SHININESS:
476 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
477 break;
478 case GL_AMBIENT_AND_DIFFUSE:
479 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
480 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
481 break;
482 case GL_COLOR_INDEXES:
483 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
484 break;
485 default:
486 gl_error( ctx, GL_INVALID_ENUM, where );
487 return 0;
488 }
489
490 if (face==GL_FRONT) {
491 bitmask &= FRONT_MATERIAL_BITS;
492 }
493 else if (face==GL_BACK) {
494 bitmask &= BACK_MATERIAL_BITS;
495 }
496 else if (face != GL_FRONT_AND_BACK) {
497 gl_error( ctx, GL_INVALID_ENUM, where );
498 return 0;
499 }
500
501 if (bitmask & ~legal) {
502 gl_error( ctx, GL_INVALID_ENUM, where );
503 return 0;
504 }
505
506 return bitmask;
507}
508
509
510
jtgafb833d1999-08-19 00:55:39 +0000511/*
512 * Check if the global material has to be updated with info that was
513 * associated with a vertex via glMaterial.
514 * This function is used when any material values get changed between
515 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
516 * when GL_COLOR_MATERIAL is enabled.
517 *
Brian Paulde82d062000-06-26 23:37:46 +0000518 * src[0] is front material, src[1] is back material
519 *
jtgafb833d1999-08-19 00:55:39 +0000520 * KW: Added code here to keep the precomputed variables uptodate.
521 * This means we can use the faster shade functions when using
522 * GL_COLOR_MATERIAL, and we can also now use the precomputed
523 * values in the slower shading functions, which further offsets
524 * the cost of doing this here.
525 */
526void gl_update_material( GLcontext *ctx,
Brian Paulde82d062000-06-26 23:37:46 +0000527 const struct gl_material src[2],
jtgafb833d1999-08-19 00:55:39 +0000528 GLuint bitmask )
529{
530 struct gl_light *light, *list = &ctx->Light.EnabledList;
jtgafb833d1999-08-19 00:55:39 +0000531
532 if (ctx->Light.ColorMaterialEnabled)
533 bitmask &= ~ctx->Light.ColorMaterialBitmask;
534
Keith Whitwell06ac5921999-11-10 06:29:44 +0000535 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000536 fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000537
jtgafb833d1999-08-19 00:55:39 +0000538 if (!bitmask)
539 return;
540
Brian Paulde82d062000-06-26 23:37:46 +0000541 /* update material emission */
542 if (bitmask & FRONT_EMISSION_BIT) {
543 struct gl_material *mat = &ctx->Light.Material[0];
544 COPY_4FV( mat->Emission, src[0].Emission );
545 }
546 if (bitmask & BACK_EMISSION_BIT) {
547 struct gl_material *mat = &ctx->Light.Material[1];
548 COPY_4FV( mat->Emission, src[1].Emission );
549 }
550
551 /* update material ambience */
jtgafb833d1999-08-19 00:55:39 +0000552 if (bitmask & FRONT_AMBIENT_BIT) {
553 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000554 COPY_4FV( mat->Ambient, src[0].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000555 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000556 SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000557 }
jtgafb833d1999-08-19 00:55:39 +0000558 }
559 if (bitmask & BACK_AMBIENT_BIT) {
560 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000561 COPY_4FV( mat->Ambient, src[1].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000562 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000563 SCALE_3V( light->_MatAmbient[1], light->Ambient, src[1].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000564 }
jtgafb833d1999-08-19 00:55:39 +0000565 }
Brian Paulde82d062000-06-26 23:37:46 +0000566
567 /* update BaseColor = emission + scene's ambience * material's ambience */
568 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
569 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000570 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
571 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000572 }
573 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
574 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000575 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
576 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000577 }
578
579 /* update material diffuse values */
jtgafb833d1999-08-19 00:55:39 +0000580 if (bitmask & FRONT_DIFFUSE_BIT) {
581 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000582 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000583 SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
584 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000585 ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000586 }
587 COPY_4FV( mat->Diffuse, src[0].Diffuse );
Keith Whitwell14940c42000-11-05 18:40:57 +0000588 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000589 }
590 if (bitmask & BACK_DIFFUSE_BIT) {
591 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000592 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000593 SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
594 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000595 ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000596 }
597 COPY_4FV( mat->Diffuse, src[1].Diffuse );
Keith Whitwell14940c42000-11-05 18:40:57 +0000598 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000599 }
Brian Paulde82d062000-06-26 23:37:46 +0000600
601 /* update material specular values */
jtgafb833d1999-08-19 00:55:39 +0000602 if (bitmask & FRONT_SPECULAR_BIT) {
603 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000604 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000605 SUB_3V( tmp, src[0].Specular, mat->Specular );
606 foreach (light, list) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000607 ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
608 light->_IsMatSpecular[0] =
609 (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000610 }
611 COPY_4FV( mat->Specular, src[0].Specular );
612 }
613 if (bitmask & BACK_SPECULAR_BIT) {
614 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000615 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000616 SUB_3V( tmp, src[1].Specular, mat->Specular );
617 foreach (light, list) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000618 ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
619 light->_IsMatSpecular[1] =
620 (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000621 }
622 COPY_4FV( mat->Specular, src[1].Specular );
623 }
Brian Paulde82d062000-06-26 23:37:46 +0000624
jtgafb833d1999-08-19 00:55:39 +0000625 if (bitmask & FRONT_SHININESS_BIT) {
626 GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
627 gl_compute_shine_table( ctx, 0, shininess );
628 gl_compute_shine_table( ctx, 2, shininess * .5 );
629 }
630 if (bitmask & BACK_SHININESS_BIT) {
631 GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
632 gl_compute_shine_table( ctx, 1, shininess );
633 gl_compute_shine_table( ctx, 3, shininess * .5 );
634 }
Brian Paulde82d062000-06-26 23:37:46 +0000635
jtgafb833d1999-08-19 00:55:39 +0000636 if (bitmask & FRONT_INDEXES_BIT) {
637 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
638 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
639 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
640 }
641 if (bitmask & BACK_INDEXES_BIT) {
642 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
643 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
644 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
645 }
646
Keith Whitwell06ac5921999-11-10 06:29:44 +0000647 if (0)
648 {
649 struct gl_material *mat = &ctx->Light.Material[0];
650 fprintf(stderr, "update_mat emission : %f %f %f\n",
651 mat->Emission[0],
652 mat->Emission[1],
653 mat->Emission[2]);
654 fprintf(stderr, "update_mat specular : %f %f %f\n",
655 mat->Specular[0],
656 mat->Specular[1],
657 mat->Specular[2]);
658 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
659 mat->Diffuse[0],
660 mat->Diffuse[1],
661 mat->Diffuse[2]);
662 fprintf(stderr, "update_mat ambient : %f %f %f\n",
663 mat->Ambient[0],
664 mat->Ambient[1],
665 mat->Ambient[2]);
666 }
jtgafb833d1999-08-19 00:55:39 +0000667}
668
669
670
671
Brian Paulde82d062000-06-26 23:37:46 +0000672/*
673 * Update the current materials from the given rgba color
674 * according to the bitmask in ColorMaterialBitmask, which is
675 * set by glColorMaterial().
676 */
jtgafb833d1999-08-19 00:55:39 +0000677void gl_update_color_material( GLcontext *ctx,
Brian Paulba643a22000-10-28 18:34:48 +0000678 const GLchan rgba[4] )
jtgafb833d1999-08-19 00:55:39 +0000679{
680 struct gl_light *light, *list = &ctx->Light.EnabledList;
681 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
Brian Paulde82d062000-06-26 23:37:46 +0000682 GLfloat color[4];
jtgafb833d1999-08-19 00:55:39 +0000683
Brian Paulc893a012000-10-28 20:41:13 +0000684 color[0] = CHAN_TO_FLOAT(rgba[0]);
685 color[1] = CHAN_TO_FLOAT(rgba[1]);
686 color[2] = CHAN_TO_FLOAT(rgba[2]);
687 color[3] = CHAN_TO_FLOAT(rgba[3]);
688
Keith Whitwell06ac5921999-11-10 06:29:44 +0000689 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000690 fprintf(stderr, "gl_update_color_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000691
Brian Paulde82d062000-06-26 23:37:46 +0000692 /* update emissive colors */
693 if (bitmask & FRONT_EMISSION_BIT) {
694 struct gl_material *mat = &ctx->Light.Material[0];
695 COPY_4FV( mat->Emission, color );
696 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000697
Brian Paulde82d062000-06-26 23:37:46 +0000698 if (bitmask & BACK_EMISSION_BIT) {
699 struct gl_material *mat = &ctx->Light.Material[1];
700 COPY_4FV( mat->Emission, color );
701 }
702
Keith Whitwell14940c42000-11-05 18:40:57 +0000703 /* update light->_MatAmbient = light's ambient * material's ambient */
jtgafb833d1999-08-19 00:55:39 +0000704 if (bitmask & FRONT_AMBIENT_BIT) {
705 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000706 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000707 SCALE_3V( light->_MatAmbient[0], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000708 }
709 COPY_4FV( mat->Ambient, color );
710 }
711
712 if (bitmask & BACK_AMBIENT_BIT) {
713 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000714 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000715 SCALE_3V( light->_MatAmbient[1], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000716 }
717 COPY_4FV( mat->Ambient, color );
718 }
719
Brian Paulde82d062000-06-26 23:37:46 +0000720 /* update BaseColor = emission + scene's ambience * material's ambience */
721 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
722 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000723 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
724 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000725 }
726
727 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
728 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000729 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
730 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000731 }
732
Keith Whitwell14940c42000-11-05 18:40:57 +0000733 /* update light->_MatDiffuse = light's diffuse * material's diffuse */
jtgafb833d1999-08-19 00:55:39 +0000734 if (bitmask & FRONT_DIFFUSE_BIT) {
735 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000736 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000737 SUB_3V( tmp, color, mat->Diffuse );
738 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000739 ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000740 }
741 COPY_4FV( mat->Diffuse, color );
Keith Whitwell14940c42000-11-05 18:40:57 +0000742 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000743 }
744
745 if (bitmask & BACK_DIFFUSE_BIT) {
746 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000747 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000748 SUB_3V( tmp, color, mat->Diffuse );
749 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000750 ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000751 }
752 COPY_4FV( mat->Diffuse, color );
Keith Whitwell14940c42000-11-05 18:40:57 +0000753 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000754 }
755
Keith Whitwell14940c42000-11-05 18:40:57 +0000756 /* update light->_MatSpecular = light's specular * material's specular */
jtgafb833d1999-08-19 00:55:39 +0000757 if (bitmask & FRONT_SPECULAR_BIT) {
758 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000759 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000760 SUB_3V( tmp, color, mat->Specular );
761 foreach (light, list) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000762 ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
763 light->_IsMatSpecular[0] =
764 (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000765 }
766 COPY_4FV( mat->Specular, color );
767 }
Brian Paulde82d062000-06-26 23:37:46 +0000768
jtgafb833d1999-08-19 00:55:39 +0000769 if (bitmask & BACK_SPECULAR_BIT) {
770 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000771 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000772 SUB_3V( tmp, color, mat->Specular );
773 foreach (light, list) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +0000774 ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
775 light->_IsMatSpecular[1] =
776 (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000777 }
778 COPY_4FV( mat->Specular, color );
779 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000780
781 if (0)
782 {
783 struct gl_material *mat = &ctx->Light.Material[0];
784 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
785 mat->Emission[0],
786 mat->Emission[1],
787 mat->Emission[2]);
788 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
789 mat->Specular[0],
790 mat->Specular[1],
791 mat->Specular[2]);
792 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
793 mat->Diffuse[0],
794 mat->Diffuse[1],
795 mat->Diffuse[2]);
796 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
797 mat->Ambient[0],
798 mat->Ambient[1],
799 mat->Ambient[2]);
800 }
jtgafb833d1999-08-19 00:55:39 +0000801}
802
803
804
805
Brian Paulfbd8f211999-11-11 01:22:25 +0000806void
807_mesa_ColorMaterial( GLenum face, GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000808{
Brian Paulfbd8f211999-11-11 01:22:25 +0000809 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000810 GLuint bitmask;
811 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
812 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
813 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
814 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
815
816 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
817
Keith Whitwell06ac5921999-11-10 06:29:44 +0000818 if (MESA_VERBOSE&VERBOSE_API)
819 fprintf(stderr, "glColorMaterial %s %s\n",
820 gl_lookup_enum_by_nr(face),
821 gl_lookup_enum_by_nr(mode));
822
jtgafb833d1999-08-19 00:55:39 +0000823 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
824
825 if (bitmask != 0) {
826 ctx->Light.ColorMaterialBitmask = bitmask;
827 ctx->Light.ColorMaterialFace = face;
828 ctx->Light.ColorMaterialMode = mode;
829 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000830
831 if (ctx->Light.ColorMaterialEnabled)
Brian Paul19300532000-10-29 19:02:23 +0000832 gl_update_color_material( ctx, ctx->Current.Color );
Keith Whitwella96308c2000-10-30 13:31:59 +0000833
834 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000835}
836
837
838
Brian Paulfbd8f211999-11-11 01:22:25 +0000839
840void
841_mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
842{
843 _mesa_Materialfv( face, pname, &param );
844}
845
846
jtgafb833d1999-08-19 00:55:39 +0000847/* KW: This is now called directly (ie by name) from the glMaterial*
848 * API functions.
849 */
Brian Paulfbd8f211999-11-11 01:22:25 +0000850void
851_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000852{
Brian Paulfbd8f211999-11-11 01:22:25 +0000853 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000854 struct immediate *IM;
855 struct gl_material *mat;
856 GLuint bitmask;
857 GLuint count;
858
859 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
860 if (bitmask == 0)
861 return;
862
863 IM = ctx->input;
864 count = IM->Count;
865
Keith Whitwelld4714731999-10-19 18:37:02 +0000866 if (!IM->Material) {
867 IM->Material =
868 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
869 VB_SIZE * 2 );
870 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
871 }
872
873
jtgafb833d1999-08-19 00:55:39 +0000874 if (!(IM->Flag[count] & VERT_MATERIAL)) {
875 IM->Flag[count] |= VERT_MATERIAL;
Keith Whitwelld4714731999-10-19 18:37:02 +0000876 IM->MaterialMask[count] = 0;
jtgafb833d1999-08-19 00:55:39 +0000877 }
878
Brian Paulfbd8f211999-11-11 01:22:25 +0000879
jtgafb833d1999-08-19 00:55:39 +0000880 IM->MaterialMask[count] |= bitmask;
881 mat = IM->Material[count];
jtgafb833d1999-08-19 00:55:39 +0000882
883 if (bitmask & FRONT_AMBIENT_BIT) {
884 COPY_4FV( mat[0].Ambient, params );
885 }
886 if (bitmask & BACK_AMBIENT_BIT) {
887 COPY_4FV( mat[1].Ambient, params );
888 }
889 if (bitmask & FRONT_DIFFUSE_BIT) {
890 COPY_4FV( mat[0].Diffuse, params );
891 }
892 if (bitmask & BACK_DIFFUSE_BIT) {
893 COPY_4FV( mat[1].Diffuse, params );
894 }
895 if (bitmask & FRONT_SPECULAR_BIT) {
896 COPY_4FV( mat[0].Specular, params );
897 }
898 if (bitmask & BACK_SPECULAR_BIT) {
899 COPY_4FV( mat[1].Specular, params );
900 }
901 if (bitmask & FRONT_EMISSION_BIT) {
902 COPY_4FV( mat[0].Emission, params );
903 }
904 if (bitmask & BACK_EMISSION_BIT) {
905 COPY_4FV( mat[1].Emission, params );
906 }
907 if (bitmask & FRONT_SHININESS_BIT) {
908 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
909 mat[0].Shininess = shininess;
910 }
911 if (bitmask & BACK_SHININESS_BIT) {
912 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
913 mat[1].Shininess = shininess;
914 }
915 if (bitmask & FRONT_INDEXES_BIT) {
916 mat[0].AmbientIndex = params[0];
917 mat[0].DiffuseIndex = params[1];
918 mat[0].SpecularIndex = params[2];
919 }
920 if (bitmask & BACK_INDEXES_BIT) {
921 mat[1].AmbientIndex = params[0];
922 mat[1].DiffuseIndex = params[1];
923 mat[1].SpecularIndex = params[2];
924 }
925}
926
927
Brian Paulfbd8f211999-11-11 01:22:25 +0000928void
929_mesa_Materiali(GLenum face, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000930{
Brian Paulfbd8f211999-11-11 01:22:25 +0000931 _mesa_Materialiv(face, pname, &param);
932}
933
934
935void
936_mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
937{
938 GLfloat fparam[4];
939 switch (pname) {
940 case GL_AMBIENT:
941 case GL_DIFFUSE:
942 case GL_SPECULAR:
943 case GL_EMISSION:
944 case GL_AMBIENT_AND_DIFFUSE:
945 fparam[0] = INT_TO_FLOAT( params[0] );
946 fparam[1] = INT_TO_FLOAT( params[1] );
947 fparam[2] = INT_TO_FLOAT( params[2] );
948 fparam[3] = INT_TO_FLOAT( params[3] );
949 break;
950 case GL_SHININESS:
951 fparam[0] = (GLfloat) params[0];
952 break;
953 case GL_COLOR_INDEXES:
954 fparam[0] = (GLfloat) params[0];
955 fparam[1] = (GLfloat) params[1];
956 fparam[2] = (GLfloat) params[2];
957 break;
958 default:
959 /* Error will be caught later in gl_Materialfv */
960 ;
961 }
962 _mesa_Materialfv(face, pname, fparam);
963}
964
965
966void
967_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
968{
969 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000970 GLuint f;
971
972 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
973
974 if (face==GL_FRONT) {
975 f = 0;
976 }
977 else if (face==GL_BACK) {
978 f = 1;
979 }
980 else {
981 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
982 return;
983 }
984 switch (pname) {
985 case GL_AMBIENT:
986 COPY_4FV( params, ctx->Light.Material[f].Ambient );
987 break;
988 case GL_DIFFUSE:
989 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
990 break;
991 case GL_SPECULAR:
992 COPY_4FV( params, ctx->Light.Material[f].Specular );
993 break;
994 case GL_EMISSION:
995 COPY_4FV( params, ctx->Light.Material[f].Emission );
996 break;
997 case GL_SHININESS:
998 *params = ctx->Light.Material[f].Shininess;
999 break;
1000 case GL_COLOR_INDEXES:
1001 params[0] = ctx->Light.Material[f].AmbientIndex;
1002 params[1] = ctx->Light.Material[f].DiffuseIndex;
1003 params[2] = ctx->Light.Material[f].SpecularIndex;
1004 break;
1005 default:
1006 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1007 }
1008}
1009
1010
1011
Brian Paulfbd8f211999-11-11 01:22:25 +00001012void
1013_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +00001014{
Brian Paulfbd8f211999-11-11 01:22:25 +00001015 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +00001016 GLuint f;
1017
1018 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
1019
1020 if (face==GL_FRONT) {
1021 f = 0;
1022 }
1023 else if (face==GL_BACK) {
1024 f = 1;
1025 }
1026 else {
1027 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
1028 return;
1029 }
1030 switch (pname) {
1031 case GL_AMBIENT:
1032 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
1033 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
1034 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
1035 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
1036 break;
1037 case GL_DIFFUSE:
1038 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
1039 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
1040 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
1041 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
1042 break;
1043 case GL_SPECULAR:
1044 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
1045 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
1046 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
1047 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
1048 break;
1049 case GL_EMISSION:
1050 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
1051 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
1052 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
1053 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
1054 break;
1055 case GL_SHININESS:
1056 *params = ROUNDF( ctx->Light.Material[f].Shininess );
1057 break;
1058 case GL_COLOR_INDEXES:
1059 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
1060 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
1061 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
1062 break;
1063 default:
1064 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1065 }
1066}
1067
1068
1069
1070
1071/**********************************************************************/
1072/***** Lighting computation *****/
1073/**********************************************************************/
1074
1075
1076/*
1077 * Notes:
1078 * When two-sided lighting is enabled we compute the color (or index)
1079 * for both the front and back side of the primitive. Then, when the
1080 * orientation of the facet is later learned, we can determine which
1081 * color (or index) to use for rendering.
1082 *
1083 * KW: We now know orientation in advance and only shade for
1084 * the side or sides which are actually required.
1085 *
1086 * Variables:
1087 * n = normal vector
1088 * V = vertex position
1089 * P = light source position
1090 * Pe = (0,0,0,1)
1091 *
1092 * Precomputed:
1093 * IF P[3]==0 THEN
1094 * // light at infinity
1095 * IF local_viewer THEN
Keith Whitwell14940c42000-11-05 18:40:57 +00001096 * _VP_inf_norm = unit vector from V to P // Precompute
jtgafb833d1999-08-19 00:55:39 +00001097 * ELSE
1098 * // eye at infinity
Keith Whitwell14940c42000-11-05 18:40:57 +00001099 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
jtgafb833d1999-08-19 00:55:39 +00001100 * ENDIF
1101 * ENDIF
1102 *
1103 * Functions:
1104 * Normalize( v ) = normalized vector v
1105 * Magnitude( v ) = length of vector v
1106 */
1107
1108
1109
1110/*
1111 * Whenever the spotlight exponent for a light changes we must call
1112 * this function to recompute the exponent lookup table.
1113 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001114void
1115gl_compute_spot_exp_table( struct gl_light *l )
jtgafb833d1999-08-19 00:55:39 +00001116{
Brian Paula0faa7f2000-07-18 16:55:56 +00001117 GLint i;
1118 GLdouble exponent = l->SpotExponent;
1119 GLdouble tmp = 0;
1120 GLint clamp = 0;
jtgafb833d1999-08-19 00:55:39 +00001121
Keith Whitwell14940c42000-11-05 18:40:57 +00001122 l->_SpotExpTable[0][0] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001123
Brian Paula0faa7f2000-07-18 16:55:56 +00001124 for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
jtgafb833d1999-08-19 00:55:39 +00001125 if (clamp == 0) {
Brian Paula0faa7f2000-07-18 16:55:56 +00001126 tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
1127 if (tmp < FLT_MIN * 100.0) {
jtgafb833d1999-08-19 00:55:39 +00001128 tmp = 0.0;
1129 clamp = 1;
1130 }
1131 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001132 l->_SpotExpTable[i][0] = tmp;
jtgafb833d1999-08-19 00:55:39 +00001133 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001134 for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001135 l->_SpotExpTable[i][1] = l->_SpotExpTable[i+1][0] - l->_SpotExpTable[i][0];
jtgafb833d1999-08-19 00:55:39 +00001136 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001137 l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001138}
1139
1140
1141
1142
1143/* Calculate a new shine table. Doing this here saves a branch in
1144 * lighting, and the cost of doing it early may be partially offset
1145 * by keeping a MRU cache of shine tables for various shine values.
1146 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001147static void
1148compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001149{
Brian Paula0faa7f2000-07-18 16:55:56 +00001150 GLint i;
jtgafb833d1999-08-19 00:55:39 +00001151 GLfloat *m = tab->tab;
1152
Brian Paula0faa7f2000-07-18 16:55:56 +00001153 m[0] = 0.0;
1154 if (shininess == 0.0) {
jtgafb833d1999-08-19 00:55:39 +00001155 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
Brian Paula0faa7f2000-07-18 16:55:56 +00001156 m[i] = 1.0;
1157 }
1158 else {
1159 for (i = 1 ; i < SHINE_TABLE_SIZE ; i++) {
1160 GLdouble t = pow(i / (GLfloat) (SHINE_TABLE_SIZE - 1), shininess);
1161 if (t > 1e-20)
1162 m[i] = t;
1163 else
1164 m[i] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001165 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001166 m[SHINE_TABLE_SIZE] = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001167 }
1168
1169 tab->shininess = shininess;
1170}
1171
jtgafb833d1999-08-19 00:55:39 +00001172
Brian Paula0faa7f2000-07-18 16:55:56 +00001173void
1174gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001175{
Brian Paula0faa7f2000-07-18 16:55:56 +00001176#define DISTSQR(a,b) ((a-b)*(a-b))
Keith Whitwell14940c42000-11-05 18:40:57 +00001177 struct gl_shine_tab *list = ctx->_ShineTabList;
jtgafb833d1999-08-19 00:55:39 +00001178 struct gl_shine_tab *s;
1179
1180 foreach(s, list)
1181 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
1182 break;
1183
Brian Paula0faa7f2000-07-18 16:55:56 +00001184 if (s == list) {
jtgafb833d1999-08-19 00:55:39 +00001185 foreach(s, list)
Brian Paula0faa7f2000-07-18 16:55:56 +00001186 if (s->refcount == 0)
1187 break;
jtgafb833d1999-08-19 00:55:39 +00001188
1189 compute_shine_table( s, shininess );
1190 }
1191
Keith Whitwell14940c42000-11-05 18:40:57 +00001192 ctx->_ShineTable[i]->refcount--;
1193 ctx->_ShineTable[i] = s;
jtgafb833d1999-08-19 00:55:39 +00001194 move_to_tail( list, s );
1195 s->refcount++;
Brian Paula0faa7f2000-07-18 16:55:56 +00001196#undef DISTSQR
jtgafb833d1999-08-19 00:55:39 +00001197}
1198
1199
1200
jtgafb833d1999-08-19 00:55:39 +00001201
1202/*
1203 * Examine current lighting parameters to determine if the optimized lighting
1204 * function can be used.
1205 * Also, precompute some lighting values such as the products of light
1206 * source and material ambient, diffuse and specular coefficients.
1207 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001208void
1209gl_update_lighting( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001210{
1211 struct gl_light *light;
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001212 ctx->_TriangleCaps &= ~(DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
1213 ctx->_NeedEyeCoords &= ~NEED_EYE_LIGHT;
1214 ctx->_NeedNormals &= ~NEED_NORMALS_LIGHT;
Keith Whitwell14940c42000-11-05 18:40:57 +00001215 ctx->Light._Flags = 0;
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001216
1217 if (!ctx->Light.Enabled)
1218 return;
1219
1220 ctx->_NeedNormals |= NEED_NORMALS_LIGHT;
1221
1222 if (ctx->Light.Model.TwoSide)
1223 ctx->_TriangleCaps |= (DD_TRI_LIGHT_TWOSIDE|DD_LIGHTING_CULL);
jtgafb833d1999-08-19 00:55:39 +00001224
1225 foreach(light, &ctx->Light.EnabledList) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001226 ctx->Light._Flags |= light->_Flags;
jtgafb833d1999-08-19 00:55:39 +00001227 }
1228
Keith Whitwell14940c42000-11-05 18:40:57 +00001229 ctx->Light._NeedVertices =
1230 ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001231 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
1232 ctx->Light.Model.LocalViewer);
1233
1234 if ((ctx->Light._Flags & LIGHT_POSITIONAL) ||
1235 ctx->Light.Model.LocalViewer)
1236 ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
1237
1238
1239 /* XXX: This test is overkill & needs to be fixed both for software and
1240 * hardware t&l drivers. The above should be sufficient & should
1241 * be tested to verify this.
1242 */
1243 if (ctx->Light._NeedVertices)
1244 ctx->_NeedEyeCoords |= NEED_EYE_LIGHT;
1245
jtgafb833d1999-08-19 00:55:39 +00001246
1247 /* Precompute some shading values.
1248 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001249 if (ctx->Visual.RGBAflag) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001250 GLuint sides = ctx->Light.Model.TwoSide ? 2 : 1;
jtgafb833d1999-08-19 00:55:39 +00001251 GLuint side;
1252 for (side=0; side < sides; side++) {
1253 struct gl_material *mat = &ctx->Light.Material[side];
Brian Paulc535ba52000-06-29 04:56:30 +00001254
Keith Whitwell14940c42000-11-05 18:40:57 +00001255 COPY_3V(ctx->Light._BaseColor[side], mat->Emission);
1256 ACC_SCALE_3V(ctx->Light._BaseColor[side],
jtgafb833d1999-08-19 00:55:39 +00001257 ctx->Light.Model.Ambient,
1258 mat->Ambient);
1259
Keith Whitwell14940c42000-11-05 18:40:57 +00001260 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[side],
Brian Paulc893a012000-10-28 20:41:13 +00001261 ctx->Light.Material[side].Diffuse[3] );
jtgafb833d1999-08-19 00:55:39 +00001262 }
1263
1264 foreach (light, &ctx->Light.EnabledList) {
1265 for (side=0; side< sides; side++) {
Brian Paulc535ba52000-06-29 04:56:30 +00001266 const struct gl_material *mat = &ctx->Light.Material[side];
Keith Whitwell14940c42000-11-05 18:40:57 +00001267 SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse );
1268 SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient );
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001269 SCALE_3V( light->_MatSpecular[side], light->Specular,
1270 mat->Specular);
1271 light->_IsMatSpecular[side] =
1272 (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +00001273 }
1274 }
1275 }
Brian Paulc535ba52000-06-29 04:56:30 +00001276 else {
1277 static const GLfloat ci[3] = { .30, .59, .11 };
jtgafb833d1999-08-19 00:55:39 +00001278 foreach(light, &ctx->Light.EnabledList) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001279 light->_dli = DOT3(ci, light->Diffuse);
1280 light->_sli = DOT3(ci, light->Specular);
jtgafb833d1999-08-19 00:55:39 +00001281 }
1282 }
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001283
1284 gl_update_lighting_function(ctx);
jtgafb833d1999-08-19 00:55:39 +00001285}
1286
Brian Paulc535ba52000-06-29 04:56:30 +00001287
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001288/* _NEW_MODELVIEW
1289 * _NEW_LIGHT
1290 * _TNL_NEW_NEED_EYE_COORDS
1291 *
1292 * Update on (_NEW_MODELVIEW | _NEW_LIGHT) when lighting is enabled.
1293 * Also update on lighting space changes.
jtgafb833d1999-08-19 00:55:39 +00001294 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001295void
1296gl_compute_light_positions( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001297{
1298 struct gl_light *light;
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001299 static const GLfloat eye_z[3] = { 0, 0, 1 };
jtgafb833d1999-08-19 00:55:39 +00001300
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001301 if (!ctx->Light.Enabled)
1302 return;
1303
1304 if (ctx->_NeedEyeCoords) {
1305 COPY_3V( ctx->_EyeZDir, eye_z );
1306 }
1307 else {
1308 TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m );
1309 }
1310
jtgafb833d1999-08-19 00:55:39 +00001311 foreach (light, &ctx->Light.EnabledList) {
1312
Keith Whitwell14940c42000-11-05 18:40:57 +00001313 if (ctx->_NeedEyeCoords) {
1314 COPY_4FV( light->_Position, light->EyePosition );
jtgafb833d1999-08-19 00:55:39 +00001315 }
Brian Paulde82d062000-06-26 23:37:46 +00001316 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001317 TRANSFORM_POINT( light->_Position, ctx->ModelView.inv,
Brian Paulde82d062000-06-26 23:37:46 +00001318 light->EyePosition );
1319 }
jtgafb833d1999-08-19 00:55:39 +00001320
Keith Whitwell14940c42000-11-05 18:40:57 +00001321 if (!(light->_Flags & LIGHT_POSITIONAL)) {
jtgafb833d1999-08-19 00:55:39 +00001322 /* VP (VP) = Normalize( Position ) */
Keith Whitwell14940c42000-11-05 18:40:57 +00001323 COPY_3V( light->_VP_inf_norm, light->_Position );
1324 NORMALIZE_3FV( light->_VP_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001325
Brian Paulde82d062000-06-26 23:37:46 +00001326 if (!ctx->Light.Model.LocalViewer) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001327 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1328 ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
1329 NORMALIZE_3FV( light->_h_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001330 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001331 light->_VP_inf_spot_attenuation = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001332 }
1333
Keith Whitwell14940c42000-11-05 18:40:57 +00001334 if (light->_Flags & LIGHT_SPOT) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001335 if (ctx->_NeedEyeCoords) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001336 COPY_3V( light->_NormDirection, light->EyeDirection );
Brian Paulde82d062000-06-26 23:37:46 +00001337 }
1338 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001339 TRANSFORM_NORMAL( light->_NormDirection,
jtgafb833d1999-08-19 00:55:39 +00001340 light->EyeDirection,
1341 ctx->ModelView.m);
1342 }
1343
Keith Whitwell14940c42000-11-05 18:40:57 +00001344 NORMALIZE_3FV( light->_NormDirection );
jtgafb833d1999-08-19 00:55:39 +00001345
Keith Whitwell14940c42000-11-05 18:40:57 +00001346 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1347 GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
1348 light->_NormDirection);
jtgafb833d1999-08-19 00:55:39 +00001349
Keith Whitwell14940c42000-11-05 18:40:57 +00001350 if (PV_dot_dir > light->_CosCutoff) {
jtgafb833d1999-08-19 00:55:39 +00001351 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1352 int k = (int) x;
Keith Whitwell14940c42000-11-05 18:40:57 +00001353 light->_VP_inf_spot_attenuation =
1354 (light->_SpotExpTable[k][0] +
1355 (x-k)*light->_SpotExpTable[k][1]);
jtgafb833d1999-08-19 00:55:39 +00001356 }
Brian Paulde82d062000-06-26 23:37:46 +00001357 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001358 light->_VP_inf_spot_attenuation = 0;
Brian Paulde82d062000-06-26 23:37:46 +00001359 }
jtgafb833d1999-08-19 00:55:39 +00001360 }
1361 }
1362 }
1363}
1364
1365
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001366/* _NEW_TRANSFORM
1367 * _NEW_MODELVIEW
1368 * _TNL_NEW_NEED_NORMALS
1369 * _TNL_NEW_NEED_EYE_COORDS
1370 *
1371 * Update on (_NEW_TRANSFORM|_NEW_MODELVIEW)
1372 * And also on NewLightingSpaces() callback.
1373 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001374void
1375gl_update_normal_transform( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001376{
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001377
1378 if (!ctx->_NeedNormals) {
1379 ctx->_NormalTransform = 0;
1380 return;
1381 }
jtgafb833d1999-08-19 00:55:39 +00001382
Keith Whitwell14940c42000-11-05 18:40:57 +00001383 if (ctx->_NeedEyeCoords) {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001384 GLuint transform = NORM_TRANSFORM_NO_ROT;
jtgafb833d1999-08-19 00:55:39 +00001385
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001386 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1387 MAT_FLAG_ROTATION |
1388 MAT_FLAG_GENERAL_3D |
1389 MAT_FLAG_PERSPECTIVE))
1390 transform = NORM_TRANSFORM;
jtgafb833d1999-08-19 00:55:39 +00001391
jtgafb833d1999-08-19 00:55:39 +00001392
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001393 if (ctx->Transform.Normalize) {
1394 ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
1395 }
1396 else if (ctx->Transform.RescaleNormals &&
1397 ctx->_ModelViewInvScale != 1.0) {
1398 ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
Brian Paula0faa7f2000-07-18 16:55:56 +00001399 }
1400 else {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001401 ctx->_NormalTransform = gl_normal_tab[transform];
jtgafb833d1999-08-19 00:55:39 +00001402 }
1403 }
1404 else {
Keith Whitwell1e1aac02000-11-13 20:02:56 +00001405 if (ctx->Transform.Normalize) {
1406 ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE];
1407 }
1408 else if (!ctx->Transform.RescaleNormals &&
1409 ctx->_ModelViewInvScale != 1.0) {
1410 ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE];
Brian Paula0faa7f2000-07-18 16:55:56 +00001411 }
1412 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001413 ctx->_NormalTransform = 0;
jtgafb833d1999-08-19 00:55:39 +00001414 }
1415 }
jtgafb833d1999-08-19 00:55:39 +00001416}