blob: 123ae89adeeea1a4727020f6fe7e880330dcd60e [file] [log] [blame]
Keith Whitwell14940c42000-11-05 18:40:57 +00001/* $Id: light.c,v 1.23 2000/11/05 18:40:58 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);
94 GLint l;
95 GLint nParams;
jtgafb833d1999-08-19 00:55:39 +000096
97 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
98
99 l = (GLint) (light - GL_LIGHT0);
100
Brian Paulfbd8f211999-11-11 01:22:25 +0000101 if (l < 0 || l >= MAX_LIGHTS) {
jtgafb833d1999-08-19 00:55:39 +0000102 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
103 return;
104 }
105
106 switch (pname) {
107 case GL_AMBIENT:
108 COPY_4V( ctx->Light.Light[l].Ambient, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000109 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000110 break;
111 case GL_DIFFUSE:
112 COPY_4V( ctx->Light.Light[l].Diffuse, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000113 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000114 break;
115 case GL_SPECULAR:
116 COPY_4V( ctx->Light.Light[l].Specular, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000117 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000118 break;
119 case GL_POSITION:
120 /* transform position by ModelView matrix */
121 TRANSFORM_POINT( ctx->Light.Light[l].EyePosition,
122 ctx->ModelView.m,
123 params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000124 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000125 break;
126 case GL_SPOT_DIRECTION:
127 /* transform direction by inverse modelview */
128 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
129 gl_matrix_analyze( &ctx->ModelView );
130 }
131 TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
132 params,
133 ctx->ModelView.inv );
Brian Paulfbd8f211999-11-11 01:22:25 +0000134 nParams = 3;
jtgafb833d1999-08-19 00:55:39 +0000135 break;
136 case GL_SPOT_EXPONENT:
137 if (params[0]<0.0 || params[0]>128.0) {
138 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
139 return;
140 }
141 if (ctx->Light.Light[l].SpotExponent != params[0]) {
142 ctx->Light.Light[l].SpotExponent = params[0];
143 gl_compute_spot_exp_table( &ctx->Light.Light[l] );
144 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000145 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000146 break;
147 case GL_SPOT_CUTOFF:
148 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
149 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
150 return;
151 }
152 ctx->Light.Light[l].SpotCutoff = params[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000153 ctx->Light.Light[l]._CosCutoff = cos(params[0]*DEG2RAD);
154 if (ctx->Light.Light[l]._CosCutoff < 0)
155 ctx->Light.Light[l]._CosCutoff = 0;
Brian Paulfbd8f211999-11-11 01:22:25 +0000156 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000157 break;
158 case GL_CONSTANT_ATTENUATION:
159 if (params[0]<0.0) {
160 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
161 return;
162 }
163 ctx->Light.Light[l].ConstantAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000164 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000165 break;
166 case GL_LINEAR_ATTENUATION:
167 if (params[0]<0.0) {
168 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
169 return;
170 }
171 ctx->Light.Light[l].LinearAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000172 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000173 break;
174 case GL_QUADRATIC_ATTENUATION:
175 if (params[0]<0.0) {
176 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
177 return;
178 }
179 ctx->Light.Light[l].QuadraticAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000180 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000181 break;
182 default:
183 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
Brian Paulfbd8f211999-11-11 01:22:25 +0000184 return;
jtgafb833d1999-08-19 00:55:39 +0000185 }
186
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000187 if (ctx->Driver.Lightfv)
Brian Paulfbd8f211999-11-11 01:22:25 +0000188 ctx->Driver.Lightfv( ctx, light, pname, params, nParams );
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000189
Keith Whitwella96308c2000-10-30 13:31:59 +0000190 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000191}
192
193
Brian Paulfbd8f211999-11-11 01:22:25 +0000194void
195_mesa_Lighti( GLenum light, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000196{
Brian Paulfbd8f211999-11-11 01:22:25 +0000197 _mesa_Lightiv( light, pname, &param );
198}
199
200
201void
202_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
203{
204 GLfloat fparam[4];
205
206 switch (pname) {
207 case GL_AMBIENT:
208 case GL_DIFFUSE:
209 case GL_SPECULAR:
210 fparam[0] = INT_TO_FLOAT( params[0] );
211 fparam[1] = INT_TO_FLOAT( params[1] );
212 fparam[2] = INT_TO_FLOAT( params[2] );
213 fparam[3] = INT_TO_FLOAT( params[3] );
214 break;
215 case GL_POSITION:
216 fparam[0] = (GLfloat) params[0];
217 fparam[1] = (GLfloat) params[1];
218 fparam[2] = (GLfloat) params[2];
219 fparam[3] = (GLfloat) params[3];
220 break;
221 case GL_SPOT_DIRECTION:
222 fparam[0] = (GLfloat) params[0];
223 fparam[1] = (GLfloat) params[1];
224 fparam[2] = (GLfloat) params[2];
225 break;
226 case GL_SPOT_EXPONENT:
227 case GL_SPOT_CUTOFF:
228 case GL_CONSTANT_ATTENUATION:
229 case GL_LINEAR_ATTENUATION:
230 case GL_QUADRATIC_ATTENUATION:
231 fparam[0] = (GLfloat) params[0];
232 break;
233 default:
234 /* error will be caught later in gl_Lightfv */
235 ;
236 }
237
238 _mesa_Lightfv( light, pname, fparam );
239}
240
241
242
243void
244_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
245{
246 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000247 GLint l = (GLint) (light - GL_LIGHT0);
248
249 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
250
251 if (l<0 || l>=MAX_LIGHTS) {
252 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
253 return;
254 }
255
256 switch (pname) {
257 case GL_AMBIENT:
258 COPY_4V( params, ctx->Light.Light[l].Ambient );
259 break;
260 case GL_DIFFUSE:
261 COPY_4V( params, ctx->Light.Light[l].Diffuse );
262 break;
263 case GL_SPECULAR:
264 COPY_4V( params, ctx->Light.Light[l].Specular );
265 break;
266 case GL_POSITION:
267 COPY_4V( params, ctx->Light.Light[l].EyePosition );
268 break;
269 case GL_SPOT_DIRECTION:
270 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
271 break;
272 case GL_SPOT_EXPONENT:
273 params[0] = ctx->Light.Light[l].SpotExponent;
274 break;
275 case GL_SPOT_CUTOFF:
276 params[0] = ctx->Light.Light[l].SpotCutoff;
277 break;
278 case GL_CONSTANT_ATTENUATION:
279 params[0] = ctx->Light.Light[l].ConstantAttenuation;
280 break;
281 case GL_LINEAR_ATTENUATION:
282 params[0] = ctx->Light.Light[l].LinearAttenuation;
283 break;
284 case GL_QUADRATIC_ATTENUATION:
285 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
286 break;
287 default:
288 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
289 break;
290 }
291}
292
293
294
Brian Paulfbd8f211999-11-11 01:22:25 +0000295void
296_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +0000297{
Brian Paulfbd8f211999-11-11 01:22:25 +0000298 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000299 GLint l = (GLint) (light - GL_LIGHT0);
300
301 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
302
303 if (l<0 || l>=MAX_LIGHTS) {
304 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
305 return;
306 }
307
308 switch (pname) {
309 case GL_AMBIENT:
310 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
311 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
312 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
313 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
314 break;
315 case GL_DIFFUSE:
316 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
317 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
318 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
319 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
320 break;
321 case GL_SPECULAR:
322 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
323 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
324 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
325 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
326 break;
327 case GL_POSITION:
328 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
329 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
330 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
331 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
332 break;
333 case GL_SPOT_DIRECTION:
334 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
335 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
336 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
337 break;
338 case GL_SPOT_EXPONENT:
339 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
340 break;
341 case GL_SPOT_CUTOFF:
342 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
343 break;
344 case GL_CONSTANT_ATTENUATION:
345 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
346 break;
347 case GL_LINEAR_ATTENUATION:
348 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
349 break;
350 case GL_QUADRATIC_ATTENUATION:
351 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
352 break;
353 default:
354 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
355 break;
356 }
357}
358
359
360
361/**********************************************************************/
362/*** Light Model ***/
363/**********************************************************************/
364
365
Brian Paulfbd8f211999-11-11 01:22:25 +0000366void
367_mesa_LightModelfv( GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000368{
Brian Paulfbd8f211999-11-11 01:22:25 +0000369 GET_CURRENT_CONTEXT(ctx);
370 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
jtgafb833d1999-08-19 00:55:39 +0000371
372 switch (pname) {
373 case GL_LIGHT_MODEL_AMBIENT:
374 COPY_4V( ctx->Light.Model.Ambient, params );
375 break;
376 case GL_LIGHT_MODEL_LOCAL_VIEWER:
377 if (params[0]==0.0)
378 ctx->Light.Model.LocalViewer = GL_FALSE;
379 else
380 ctx->Light.Model.LocalViewer = GL_TRUE;
381 break;
382 case GL_LIGHT_MODEL_TWO_SIDE:
383 if (params[0]==0.0)
384 ctx->Light.Model.TwoSide = GL_FALSE;
385 else
386 ctx->Light.Model.TwoSide = GL_TRUE;
387 break;
388 case GL_LIGHT_MODEL_COLOR_CONTROL:
Brian Paulf3f9b771999-10-19 20:32:40 +0000389 if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
jtgafb833d1999-08-19 00:55:39 +0000390 ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
Keith Whitwellfe5d67d2000-10-27 16:44:40 +0000391 if (!ctx->Fog.ColorSumEnabled)
Keith Whitwell14940c42000-11-05 18:40:57 +0000392 CLEAR_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000393 }
jtgafb833d1999-08-19 00:55:39 +0000394 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
395 ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
Keith Whitwell14940c42000-11-05 18:40:57 +0000396 SET_BITS(ctx->_TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000397 }
398 else {
jtgafb833d1999-08-19 00:55:39 +0000399 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
Brian Paulf3f9b771999-10-19 20:32:40 +0000400 }
jtgafb833d1999-08-19 00:55:39 +0000401 break;
402 default:
403 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
404 break;
405 }
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000406
407 if (ctx->Driver.LightModelfv)
408 ctx->Driver.LightModelfv( ctx, pname, params );
409
Keith Whitwella96308c2000-10-30 13:31:59 +0000410 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000411}
412
413
Brian Paulfbd8f211999-11-11 01:22:25 +0000414void
415_mesa_LightModeliv( GLenum pname, const GLint *params )
416{
417 GLfloat fparam[4];
418 GET_CURRENT_CONTEXT(ctx);
419 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
420
421 switch (pname) {
422 case GL_LIGHT_MODEL_AMBIENT:
423 fparam[0] = INT_TO_FLOAT( params[0] );
424 fparam[1] = INT_TO_FLOAT( params[1] );
425 fparam[2] = INT_TO_FLOAT( params[2] );
426 fparam[3] = INT_TO_FLOAT( params[3] );
427 break;
428 case GL_LIGHT_MODEL_LOCAL_VIEWER:
429 case GL_LIGHT_MODEL_TWO_SIDE:
430 case GL_LIGHT_MODEL_COLOR_CONTROL:
431 fparam[0] = (GLfloat) params[0];
432 break;
433 default:
434 /* Error will be caught later in gl_LightModelfv */
435 ;
436 }
437 _mesa_LightModelfv( pname, fparam );
438}
439
440
441void
442_mesa_LightModeli( GLenum pname, GLint param )
443{
444 _mesa_LightModeliv( pname, &param );
445}
446
447
448void
449_mesa_LightModelf( GLenum pname, GLfloat param )
450{
451 _mesa_LightModelfv( pname, &param );
452}
453
jtgafb833d1999-08-19 00:55:39 +0000454
455
456/********** MATERIAL **********/
457
458
459/*
460 * Given a face and pname value (ala glColorMaterial), compute a bitmask
461 * of the targeted material values.
462 */
463GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
464 GLuint legal,
465 const char *where )
466{
467 GLuint bitmask = 0;
468
469 /* Make a bitmask indicating what material attribute(s) we're updating */
470 switch (pname) {
471 case GL_EMISSION:
472 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
473 break;
474 case GL_AMBIENT:
475 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
476 break;
477 case GL_DIFFUSE:
478 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
479 break;
480 case GL_SPECULAR:
481 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
482 break;
483 case GL_SHININESS:
484 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
485 break;
486 case GL_AMBIENT_AND_DIFFUSE:
487 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
488 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
489 break;
490 case GL_COLOR_INDEXES:
491 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
492 break;
493 default:
494 gl_error( ctx, GL_INVALID_ENUM, where );
495 return 0;
496 }
497
498 if (face==GL_FRONT) {
499 bitmask &= FRONT_MATERIAL_BITS;
500 }
501 else if (face==GL_BACK) {
502 bitmask &= BACK_MATERIAL_BITS;
503 }
504 else if (face != GL_FRONT_AND_BACK) {
505 gl_error( ctx, GL_INVALID_ENUM, where );
506 return 0;
507 }
508
509 if (bitmask & ~legal) {
510 gl_error( ctx, GL_INVALID_ENUM, where );
511 return 0;
512 }
513
514 return bitmask;
515}
516
517
518
jtgafb833d1999-08-19 00:55:39 +0000519/*
520 * Check if the global material has to be updated with info that was
521 * associated with a vertex via glMaterial.
522 * This function is used when any material values get changed between
523 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
524 * when GL_COLOR_MATERIAL is enabled.
525 *
Brian Paulde82d062000-06-26 23:37:46 +0000526 * src[0] is front material, src[1] is back material
527 *
jtgafb833d1999-08-19 00:55:39 +0000528 * KW: Added code here to keep the precomputed variables uptodate.
529 * This means we can use the faster shade functions when using
530 * GL_COLOR_MATERIAL, and we can also now use the precomputed
531 * values in the slower shading functions, which further offsets
532 * the cost of doing this here.
533 */
534void gl_update_material( GLcontext *ctx,
Brian Paulde82d062000-06-26 23:37:46 +0000535 const struct gl_material src[2],
jtgafb833d1999-08-19 00:55:39 +0000536 GLuint bitmask )
537{
538 struct gl_light *light, *list = &ctx->Light.EnabledList;
jtgafb833d1999-08-19 00:55:39 +0000539
540 if (ctx->Light.ColorMaterialEnabled)
541 bitmask &= ~ctx->Light.ColorMaterialBitmask;
542
Keith Whitwell06ac5921999-11-10 06:29:44 +0000543 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000544 fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000545
jtgafb833d1999-08-19 00:55:39 +0000546 if (!bitmask)
547 return;
548
Brian Paulde82d062000-06-26 23:37:46 +0000549 /* update material emission */
550 if (bitmask & FRONT_EMISSION_BIT) {
551 struct gl_material *mat = &ctx->Light.Material[0];
552 COPY_4FV( mat->Emission, src[0].Emission );
553 }
554 if (bitmask & BACK_EMISSION_BIT) {
555 struct gl_material *mat = &ctx->Light.Material[1];
556 COPY_4FV( mat->Emission, src[1].Emission );
557 }
558
559 /* update material ambience */
jtgafb833d1999-08-19 00:55:39 +0000560 if (bitmask & FRONT_AMBIENT_BIT) {
561 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000562 COPY_4FV( mat->Ambient, src[0].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000563 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000564 SCALE_3V( light->_MatAmbient[0], light->Ambient, src[0].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000565 }
jtgafb833d1999-08-19 00:55:39 +0000566 }
567 if (bitmask & BACK_AMBIENT_BIT) {
568 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000569 COPY_4FV( mat->Ambient, src[1].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000570 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000571 SCALE_3V( light->_MatAmbient[1], light->Ambient, src[1].Ambient);
Brian Paulde82d062000-06-26 23:37:46 +0000572 }
jtgafb833d1999-08-19 00:55:39 +0000573 }
Brian Paulde82d062000-06-26 23:37:46 +0000574
575 /* update BaseColor = emission + scene's ambience * material's ambience */
576 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
577 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000578 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
579 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000580 }
581 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
582 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000583 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
584 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000585 }
586
587 /* update material diffuse values */
jtgafb833d1999-08-19 00:55:39 +0000588 if (bitmask & FRONT_DIFFUSE_BIT) {
589 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000590 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000591 SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
592 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000593 ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000594 }
595 COPY_4FV( mat->Diffuse, src[0].Diffuse );
Keith Whitwell14940c42000-11-05 18:40:57 +0000596 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000597 }
598 if (bitmask & BACK_DIFFUSE_BIT) {
599 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000600 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000601 SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
602 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000603 ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000604 }
605 COPY_4FV( mat->Diffuse, src[1].Diffuse );
Keith Whitwell14940c42000-11-05 18:40:57 +0000606 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000607 }
Brian Paulde82d062000-06-26 23:37:46 +0000608
609 /* update material specular values */
jtgafb833d1999-08-19 00:55:39 +0000610 if (bitmask & FRONT_SPECULAR_BIT) {
611 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000612 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000613 SUB_3V( tmp, src[0].Specular, mat->Specular );
614 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000615 if (light->_Flags & LIGHT_SPECULAR) {
616 ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
617 light->_IsMatSpecular[0] =
618 (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000619 }
620 }
621 COPY_4FV( mat->Specular, src[0].Specular );
622 }
623 if (bitmask & BACK_SPECULAR_BIT) {
624 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000625 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000626 SUB_3V( tmp, src[1].Specular, mat->Specular );
627 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000628 if (light->_Flags & LIGHT_SPECULAR) {
629 ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
630 light->_IsMatSpecular[1] =
631 (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000632 }
633 }
634 COPY_4FV( mat->Specular, src[1].Specular );
635 }
Brian Paulde82d062000-06-26 23:37:46 +0000636
jtgafb833d1999-08-19 00:55:39 +0000637 if (bitmask & FRONT_SHININESS_BIT) {
638 GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
639 gl_compute_shine_table( ctx, 0, shininess );
640 gl_compute_shine_table( ctx, 2, shininess * .5 );
641 }
642 if (bitmask & BACK_SHININESS_BIT) {
643 GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
644 gl_compute_shine_table( ctx, 1, shininess );
645 gl_compute_shine_table( ctx, 3, shininess * .5 );
646 }
Brian Paulde82d062000-06-26 23:37:46 +0000647
jtgafb833d1999-08-19 00:55:39 +0000648 if (bitmask & FRONT_INDEXES_BIT) {
649 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
650 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
651 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
652 }
653 if (bitmask & BACK_INDEXES_BIT) {
654 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
655 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
656 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
657 }
658
Keith Whitwell06ac5921999-11-10 06:29:44 +0000659 if (0)
660 {
661 struct gl_material *mat = &ctx->Light.Material[0];
662 fprintf(stderr, "update_mat emission : %f %f %f\n",
663 mat->Emission[0],
664 mat->Emission[1],
665 mat->Emission[2]);
666 fprintf(stderr, "update_mat specular : %f %f %f\n",
667 mat->Specular[0],
668 mat->Specular[1],
669 mat->Specular[2]);
670 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
671 mat->Diffuse[0],
672 mat->Diffuse[1],
673 mat->Diffuse[2]);
674 fprintf(stderr, "update_mat ambient : %f %f %f\n",
675 mat->Ambient[0],
676 mat->Ambient[1],
677 mat->Ambient[2]);
678 }
jtgafb833d1999-08-19 00:55:39 +0000679}
680
681
682
683
Brian Paulde82d062000-06-26 23:37:46 +0000684/*
685 * Update the current materials from the given rgba color
686 * according to the bitmask in ColorMaterialBitmask, which is
687 * set by glColorMaterial().
688 */
jtgafb833d1999-08-19 00:55:39 +0000689void gl_update_color_material( GLcontext *ctx,
Brian Paulba643a22000-10-28 18:34:48 +0000690 const GLchan rgba[4] )
jtgafb833d1999-08-19 00:55:39 +0000691{
692 struct gl_light *light, *list = &ctx->Light.EnabledList;
693 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
Brian Paulde82d062000-06-26 23:37:46 +0000694 GLfloat color[4];
jtgafb833d1999-08-19 00:55:39 +0000695
Brian Paulc893a012000-10-28 20:41:13 +0000696 color[0] = CHAN_TO_FLOAT(rgba[0]);
697 color[1] = CHAN_TO_FLOAT(rgba[1]);
698 color[2] = CHAN_TO_FLOAT(rgba[2]);
699 color[3] = CHAN_TO_FLOAT(rgba[3]);
700
Keith Whitwell06ac5921999-11-10 06:29:44 +0000701 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000702 fprintf(stderr, "gl_update_color_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000703
Brian Paulde82d062000-06-26 23:37:46 +0000704 /* update emissive colors */
705 if (bitmask & FRONT_EMISSION_BIT) {
706 struct gl_material *mat = &ctx->Light.Material[0];
707 COPY_4FV( mat->Emission, color );
708 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000709
Brian Paulde82d062000-06-26 23:37:46 +0000710 if (bitmask & BACK_EMISSION_BIT) {
711 struct gl_material *mat = &ctx->Light.Material[1];
712 COPY_4FV( mat->Emission, color );
713 }
714
Keith Whitwell14940c42000-11-05 18:40:57 +0000715 /* update light->_MatAmbient = light's ambient * material's ambient */
jtgafb833d1999-08-19 00:55:39 +0000716 if (bitmask & FRONT_AMBIENT_BIT) {
717 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000718 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000719 SCALE_3V( light->_MatAmbient[0], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000720 }
721 COPY_4FV( mat->Ambient, color );
722 }
723
724 if (bitmask & BACK_AMBIENT_BIT) {
725 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000726 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000727 SCALE_3V( light->_MatAmbient[1], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000728 }
729 COPY_4FV( mat->Ambient, color );
730 }
731
Brian Paulde82d062000-06-26 23:37:46 +0000732 /* update BaseColor = emission + scene's ambience * material's ambience */
733 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
734 struct gl_material *mat = &ctx->Light.Material[0];
Keith Whitwell14940c42000-11-05 18:40:57 +0000735 COPY_3V( ctx->Light._BaseColor[0], mat->Emission );
736 ACC_SCALE_3V( ctx->Light._BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000737 }
738
739 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
740 struct gl_material *mat = &ctx->Light.Material[1];
Keith Whitwell14940c42000-11-05 18:40:57 +0000741 COPY_3V( ctx->Light._BaseColor[1], mat->Emission );
742 ACC_SCALE_3V( ctx->Light._BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000743 }
744
Keith Whitwell14940c42000-11-05 18:40:57 +0000745 /* update light->_MatDiffuse = light's diffuse * material's diffuse */
jtgafb833d1999-08-19 00:55:39 +0000746 if (bitmask & FRONT_DIFFUSE_BIT) {
747 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000748 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000749 SUB_3V( tmp, color, mat->Diffuse );
750 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000751 ACC_SCALE_3V( light->_MatDiffuse[0], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000752 }
753 COPY_4FV( mat->Diffuse, color );
Keith Whitwell14940c42000-11-05 18:40:57 +0000754 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000755 }
756
757 if (bitmask & BACK_DIFFUSE_BIT) {
758 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000759 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000760 SUB_3V( tmp, color, mat->Diffuse );
761 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000762 ACC_SCALE_3V( light->_MatDiffuse[1], light->Diffuse, tmp );
jtgafb833d1999-08-19 00:55:39 +0000763 }
764 COPY_4FV( mat->Diffuse, color );
Keith Whitwell14940c42000-11-05 18:40:57 +0000765 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000766 }
767
Keith Whitwell14940c42000-11-05 18:40:57 +0000768 /* update light->_MatSpecular = light's specular * material's specular */
jtgafb833d1999-08-19 00:55:39 +0000769 if (bitmask & FRONT_SPECULAR_BIT) {
770 struct gl_material *mat = &ctx->Light.Material[0];
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 Whitwell14940c42000-11-05 18:40:57 +0000774 if (light->_Flags & LIGHT_SPECULAR) {
775 ACC_SCALE_3V( light->_MatSpecular[0], light->Specular, tmp );
776 light->_IsMatSpecular[0] =
777 (LEN_SQUARED_3FV(light->_MatSpecular[0]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000778 }
779 }
780 COPY_4FV( mat->Specular, color );
781 }
Brian Paulde82d062000-06-26 23:37:46 +0000782
jtgafb833d1999-08-19 00:55:39 +0000783 if (bitmask & BACK_SPECULAR_BIT) {
784 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000785 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000786 SUB_3V( tmp, color, mat->Specular );
787 foreach (light, list) {
Keith Whitwell14940c42000-11-05 18:40:57 +0000788 if (light->_Flags & LIGHT_SPECULAR) {
789 ACC_SCALE_3V( light->_MatSpecular[1], light->Specular, tmp );
790 light->_IsMatSpecular[1] =
791 (LEN_SQUARED_3FV(light->_MatSpecular[1]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +0000792 }
793 }
794 COPY_4FV( mat->Specular, color );
795 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000796
797 if (0)
798 {
799 struct gl_material *mat = &ctx->Light.Material[0];
800 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
801 mat->Emission[0],
802 mat->Emission[1],
803 mat->Emission[2]);
804 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
805 mat->Specular[0],
806 mat->Specular[1],
807 mat->Specular[2]);
808 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
809 mat->Diffuse[0],
810 mat->Diffuse[1],
811 mat->Diffuse[2]);
812 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
813 mat->Ambient[0],
814 mat->Ambient[1],
815 mat->Ambient[2]);
816 }
jtgafb833d1999-08-19 00:55:39 +0000817}
818
819
820
821
Brian Paulfbd8f211999-11-11 01:22:25 +0000822void
823_mesa_ColorMaterial( GLenum face, GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000824{
Brian Paulfbd8f211999-11-11 01:22:25 +0000825 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000826 GLuint bitmask;
827 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
828 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
829 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
830 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
831
832 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
833
Keith Whitwell06ac5921999-11-10 06:29:44 +0000834 if (MESA_VERBOSE&VERBOSE_API)
835 fprintf(stderr, "glColorMaterial %s %s\n",
836 gl_lookup_enum_by_nr(face),
837 gl_lookup_enum_by_nr(mode));
838
jtgafb833d1999-08-19 00:55:39 +0000839 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
840
841 if (bitmask != 0) {
842 ctx->Light.ColorMaterialBitmask = bitmask;
843 ctx->Light.ColorMaterialFace = face;
844 ctx->Light.ColorMaterialMode = mode;
845 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000846
847 if (ctx->Light.ColorMaterialEnabled)
Brian Paul19300532000-10-29 19:02:23 +0000848 gl_update_color_material( ctx, ctx->Current.Color );
Keith Whitwella96308c2000-10-30 13:31:59 +0000849
850 ctx->NewState |= _NEW_LIGHT;
jtgafb833d1999-08-19 00:55:39 +0000851}
852
853
854
Brian Paulfbd8f211999-11-11 01:22:25 +0000855
856void
857_mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
858{
859 _mesa_Materialfv( face, pname, &param );
860}
861
862
jtgafb833d1999-08-19 00:55:39 +0000863/* KW: This is now called directly (ie by name) from the glMaterial*
864 * API functions.
865 */
Brian Paulfbd8f211999-11-11 01:22:25 +0000866void
867_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000868{
Brian Paulfbd8f211999-11-11 01:22:25 +0000869 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000870 struct immediate *IM;
871 struct gl_material *mat;
872 GLuint bitmask;
873 GLuint count;
874
875 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
876 if (bitmask == 0)
877 return;
878
879 IM = ctx->input;
880 count = IM->Count;
881
Keith Whitwelld4714731999-10-19 18:37:02 +0000882 if (!IM->Material) {
883 IM->Material =
884 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
885 VB_SIZE * 2 );
886 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
887 }
888
889
jtgafb833d1999-08-19 00:55:39 +0000890 if (!(IM->Flag[count] & VERT_MATERIAL)) {
891 IM->Flag[count] |= VERT_MATERIAL;
Keith Whitwelld4714731999-10-19 18:37:02 +0000892 IM->MaterialMask[count] = 0;
jtgafb833d1999-08-19 00:55:39 +0000893 }
894
Brian Paulfbd8f211999-11-11 01:22:25 +0000895
jtgafb833d1999-08-19 00:55:39 +0000896 IM->MaterialMask[count] |= bitmask;
897 mat = IM->Material[count];
jtgafb833d1999-08-19 00:55:39 +0000898
899 if (bitmask & FRONT_AMBIENT_BIT) {
900 COPY_4FV( mat[0].Ambient, params );
901 }
902 if (bitmask & BACK_AMBIENT_BIT) {
903 COPY_4FV( mat[1].Ambient, params );
904 }
905 if (bitmask & FRONT_DIFFUSE_BIT) {
906 COPY_4FV( mat[0].Diffuse, params );
907 }
908 if (bitmask & BACK_DIFFUSE_BIT) {
909 COPY_4FV( mat[1].Diffuse, params );
910 }
911 if (bitmask & FRONT_SPECULAR_BIT) {
912 COPY_4FV( mat[0].Specular, params );
913 }
914 if (bitmask & BACK_SPECULAR_BIT) {
915 COPY_4FV( mat[1].Specular, params );
916 }
917 if (bitmask & FRONT_EMISSION_BIT) {
918 COPY_4FV( mat[0].Emission, params );
919 }
920 if (bitmask & BACK_EMISSION_BIT) {
921 COPY_4FV( mat[1].Emission, params );
922 }
923 if (bitmask & FRONT_SHININESS_BIT) {
924 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
925 mat[0].Shininess = shininess;
926 }
927 if (bitmask & BACK_SHININESS_BIT) {
928 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
929 mat[1].Shininess = shininess;
930 }
931 if (bitmask & FRONT_INDEXES_BIT) {
932 mat[0].AmbientIndex = params[0];
933 mat[0].DiffuseIndex = params[1];
934 mat[0].SpecularIndex = params[2];
935 }
936 if (bitmask & BACK_INDEXES_BIT) {
937 mat[1].AmbientIndex = params[0];
938 mat[1].DiffuseIndex = params[1];
939 mat[1].SpecularIndex = params[2];
940 }
941}
942
943
Brian Paulfbd8f211999-11-11 01:22:25 +0000944void
945_mesa_Materiali(GLenum face, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000946{
Brian Paulfbd8f211999-11-11 01:22:25 +0000947 _mesa_Materialiv(face, pname, &param);
948}
949
950
951void
952_mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
953{
954 GLfloat fparam[4];
955 switch (pname) {
956 case GL_AMBIENT:
957 case GL_DIFFUSE:
958 case GL_SPECULAR:
959 case GL_EMISSION:
960 case GL_AMBIENT_AND_DIFFUSE:
961 fparam[0] = INT_TO_FLOAT( params[0] );
962 fparam[1] = INT_TO_FLOAT( params[1] );
963 fparam[2] = INT_TO_FLOAT( params[2] );
964 fparam[3] = INT_TO_FLOAT( params[3] );
965 break;
966 case GL_SHININESS:
967 fparam[0] = (GLfloat) params[0];
968 break;
969 case GL_COLOR_INDEXES:
970 fparam[0] = (GLfloat) params[0];
971 fparam[1] = (GLfloat) params[1];
972 fparam[2] = (GLfloat) params[2];
973 break;
974 default:
975 /* Error will be caught later in gl_Materialfv */
976 ;
977 }
978 _mesa_Materialfv(face, pname, fparam);
979}
980
981
982void
983_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
984{
985 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000986 GLuint f;
987
988 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
989
990 if (face==GL_FRONT) {
991 f = 0;
992 }
993 else if (face==GL_BACK) {
994 f = 1;
995 }
996 else {
997 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
998 return;
999 }
1000 switch (pname) {
1001 case GL_AMBIENT:
1002 COPY_4FV( params, ctx->Light.Material[f].Ambient );
1003 break;
1004 case GL_DIFFUSE:
1005 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
1006 break;
1007 case GL_SPECULAR:
1008 COPY_4FV( params, ctx->Light.Material[f].Specular );
1009 break;
1010 case GL_EMISSION:
1011 COPY_4FV( params, ctx->Light.Material[f].Emission );
1012 break;
1013 case GL_SHININESS:
1014 *params = ctx->Light.Material[f].Shininess;
1015 break;
1016 case GL_COLOR_INDEXES:
1017 params[0] = ctx->Light.Material[f].AmbientIndex;
1018 params[1] = ctx->Light.Material[f].DiffuseIndex;
1019 params[2] = ctx->Light.Material[f].SpecularIndex;
1020 break;
1021 default:
1022 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1023 }
1024}
1025
1026
1027
Brian Paulfbd8f211999-11-11 01:22:25 +00001028void
1029_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +00001030{
Brian Paulfbd8f211999-11-11 01:22:25 +00001031 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +00001032 GLuint f;
1033
1034 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
1035
1036 if (face==GL_FRONT) {
1037 f = 0;
1038 }
1039 else if (face==GL_BACK) {
1040 f = 1;
1041 }
1042 else {
1043 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
1044 return;
1045 }
1046 switch (pname) {
1047 case GL_AMBIENT:
1048 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
1049 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
1050 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
1051 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
1052 break;
1053 case GL_DIFFUSE:
1054 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
1055 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
1056 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
1057 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
1058 break;
1059 case GL_SPECULAR:
1060 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
1061 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
1062 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
1063 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
1064 break;
1065 case GL_EMISSION:
1066 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
1067 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
1068 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
1069 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
1070 break;
1071 case GL_SHININESS:
1072 *params = ROUNDF( ctx->Light.Material[f].Shininess );
1073 break;
1074 case GL_COLOR_INDEXES:
1075 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
1076 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
1077 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
1078 break;
1079 default:
1080 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1081 }
1082}
1083
1084
1085
1086
1087/**********************************************************************/
1088/***** Lighting computation *****/
1089/**********************************************************************/
1090
1091
1092/*
1093 * Notes:
1094 * When two-sided lighting is enabled we compute the color (or index)
1095 * for both the front and back side of the primitive. Then, when the
1096 * orientation of the facet is later learned, we can determine which
1097 * color (or index) to use for rendering.
1098 *
1099 * KW: We now know orientation in advance and only shade for
1100 * the side or sides which are actually required.
1101 *
1102 * Variables:
1103 * n = normal vector
1104 * V = vertex position
1105 * P = light source position
1106 * Pe = (0,0,0,1)
1107 *
1108 * Precomputed:
1109 * IF P[3]==0 THEN
1110 * // light at infinity
1111 * IF local_viewer THEN
Keith Whitwell14940c42000-11-05 18:40:57 +00001112 * _VP_inf_norm = unit vector from V to P // Precompute
jtgafb833d1999-08-19 00:55:39 +00001113 * ELSE
1114 * // eye at infinity
Keith Whitwell14940c42000-11-05 18:40:57 +00001115 * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
jtgafb833d1999-08-19 00:55:39 +00001116 * ENDIF
1117 * ENDIF
1118 *
1119 * Functions:
1120 * Normalize( v ) = normalized vector v
1121 * Magnitude( v ) = length of vector v
1122 */
1123
1124
1125
1126/*
1127 * Whenever the spotlight exponent for a light changes we must call
1128 * this function to recompute the exponent lookup table.
1129 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001130void
1131gl_compute_spot_exp_table( struct gl_light *l )
jtgafb833d1999-08-19 00:55:39 +00001132{
Brian Paula0faa7f2000-07-18 16:55:56 +00001133 GLint i;
1134 GLdouble exponent = l->SpotExponent;
1135 GLdouble tmp = 0;
1136 GLint clamp = 0;
jtgafb833d1999-08-19 00:55:39 +00001137
Keith Whitwell14940c42000-11-05 18:40:57 +00001138 l->_SpotExpTable[0][0] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001139
Brian Paula0faa7f2000-07-18 16:55:56 +00001140 for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
jtgafb833d1999-08-19 00:55:39 +00001141 if (clamp == 0) {
Brian Paula0faa7f2000-07-18 16:55:56 +00001142 tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
1143 if (tmp < FLT_MIN * 100.0) {
jtgafb833d1999-08-19 00:55:39 +00001144 tmp = 0.0;
1145 clamp = 1;
1146 }
1147 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001148 l->_SpotExpTable[i][0] = tmp;
jtgafb833d1999-08-19 00:55:39 +00001149 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001150 for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001151 l->_SpotExpTable[i][1] = l->_SpotExpTable[i+1][0] - l->_SpotExpTable[i][0];
jtgafb833d1999-08-19 00:55:39 +00001152 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001153 l->_SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001154}
1155
1156
1157
1158
1159/* Calculate a new shine table. Doing this here saves a branch in
1160 * lighting, and the cost of doing it early may be partially offset
1161 * by keeping a MRU cache of shine tables for various shine values.
1162 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001163static void
1164compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001165{
Brian Paula0faa7f2000-07-18 16:55:56 +00001166 GLint i;
jtgafb833d1999-08-19 00:55:39 +00001167 GLfloat *m = tab->tab;
1168
Brian Paula0faa7f2000-07-18 16:55:56 +00001169 m[0] = 0.0;
1170 if (shininess == 0.0) {
jtgafb833d1999-08-19 00:55:39 +00001171 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
Brian Paula0faa7f2000-07-18 16:55:56 +00001172 m[i] = 1.0;
1173 }
1174 else {
1175 for (i = 1 ; i < SHINE_TABLE_SIZE ; i++) {
1176 GLdouble t = pow(i / (GLfloat) (SHINE_TABLE_SIZE - 1), shininess);
1177 if (t > 1e-20)
1178 m[i] = t;
1179 else
1180 m[i] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001181 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001182 m[SHINE_TABLE_SIZE] = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001183 }
1184
1185 tab->shininess = shininess;
1186}
1187
jtgafb833d1999-08-19 00:55:39 +00001188
Brian Paula0faa7f2000-07-18 16:55:56 +00001189void
1190gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001191{
Brian Paula0faa7f2000-07-18 16:55:56 +00001192#define DISTSQR(a,b) ((a-b)*(a-b))
Keith Whitwell14940c42000-11-05 18:40:57 +00001193 struct gl_shine_tab *list = ctx->_ShineTabList;
jtgafb833d1999-08-19 00:55:39 +00001194 struct gl_shine_tab *s;
1195
1196 foreach(s, list)
1197 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
1198 break;
1199
Brian Paula0faa7f2000-07-18 16:55:56 +00001200 if (s == list) {
jtgafb833d1999-08-19 00:55:39 +00001201 foreach(s, list)
Brian Paula0faa7f2000-07-18 16:55:56 +00001202 if (s->refcount == 0)
1203 break;
jtgafb833d1999-08-19 00:55:39 +00001204
1205 compute_shine_table( s, shininess );
1206 }
1207
Keith Whitwell14940c42000-11-05 18:40:57 +00001208 ctx->_ShineTable[i]->refcount--;
1209 ctx->_ShineTable[i] = s;
jtgafb833d1999-08-19 00:55:39 +00001210 move_to_tail( list, s );
1211 s->refcount++;
Brian Paula0faa7f2000-07-18 16:55:56 +00001212#undef DISTSQR
jtgafb833d1999-08-19 00:55:39 +00001213}
1214
1215
1216
jtgafb833d1999-08-19 00:55:39 +00001217
1218/*
1219 * Examine current lighting parameters to determine if the optimized lighting
1220 * function can be used.
1221 * Also, precompute some lighting values such as the products of light
1222 * source and material ambient, diffuse and specular coefficients.
1223 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001224void
1225gl_update_lighting( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001226{
1227 struct gl_light *light;
1228
Keith Whitwell14940c42000-11-05 18:40:57 +00001229 ctx->Light._Flags = 0;
jtgafb833d1999-08-19 00:55:39 +00001230
1231 foreach(light, &ctx->Light.EnabledList) {
1232
Keith Whitwell14940c42000-11-05 18:40:57 +00001233 light->_Flags = 0;
jtgafb833d1999-08-19 00:55:39 +00001234
1235 if (light->EyePosition[3] != 0.0F)
Keith Whitwell14940c42000-11-05 18:40:57 +00001236 light->_Flags |= LIGHT_POSITIONAL;
jtgafb833d1999-08-19 00:55:39 +00001237
1238 if (LEN_SQUARED_3FV(light->Specular) > 1e-16)
Keith Whitwell14940c42000-11-05 18:40:57 +00001239 light->_Flags |= LIGHT_SPECULAR;
jtgafb833d1999-08-19 00:55:39 +00001240
1241 if (light->SpotCutoff != 180.0F)
Keith Whitwell14940c42000-11-05 18:40:57 +00001242 light->_Flags |= LIGHT_SPOT;
jtgafb833d1999-08-19 00:55:39 +00001243
Keith Whitwell14940c42000-11-05 18:40:57 +00001244 ctx->Light._Flags |= light->_Flags;
jtgafb833d1999-08-19 00:55:39 +00001245 }
1246
Keith Whitwell14940c42000-11-05 18:40:57 +00001247 ctx->Light._NeedVertices =
1248 ((ctx->Light._Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
jtgafb833d1999-08-19 00:55:39 +00001249 (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
Keith Whitwell14940c42000-11-05 18:40:57 +00001250 (ctx->Light.Model.LocalViewer && (ctx->Light._Flags & LIGHT_SPECULAR)));
jtgafb833d1999-08-19 00:55:39 +00001251
1252
1253 /* Precompute some shading values.
1254 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001255 if (ctx->Visual.RGBAflag) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001256 GLuint sides = ((ctx->_TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
jtgafb833d1999-08-19 00:55:39 +00001257 GLuint side;
1258 for (side=0; side < sides; side++) {
1259 struct gl_material *mat = &ctx->Light.Material[side];
Brian Paulc535ba52000-06-29 04:56:30 +00001260
Keith Whitwell14940c42000-11-05 18:40:57 +00001261 COPY_3V(ctx->Light._BaseColor[side], mat->Emission);
1262 ACC_SCALE_3V(ctx->Light._BaseColor[side],
jtgafb833d1999-08-19 00:55:39 +00001263 ctx->Light.Model.Ambient,
1264 mat->Ambient);
1265
Keith Whitwell14940c42000-11-05 18:40:57 +00001266 FLOAT_COLOR_TO_CHAN(ctx->Light._BaseAlpha[side],
Brian Paulc893a012000-10-28 20:41:13 +00001267 ctx->Light.Material[side].Diffuse[3] );
jtgafb833d1999-08-19 00:55:39 +00001268 }
1269
1270 foreach (light, &ctx->Light.EnabledList) {
1271 for (side=0; side< sides; side++) {
Brian Paulc535ba52000-06-29 04:56:30 +00001272 const struct gl_material *mat = &ctx->Light.Material[side];
Keith Whitwell14940c42000-11-05 18:40:57 +00001273 SCALE_3V( light->_MatDiffuse[side], light->Diffuse, mat->Diffuse );
1274 SCALE_3V( light->_MatAmbient[side], light->Ambient, mat->Ambient );
1275 if (light->_Flags & LIGHT_SPECULAR) {
1276 SCALE_3V( light->_MatSpecular[side], light->Specular,
jtgafb833d1999-08-19 00:55:39 +00001277 mat->Specular);
Keith Whitwell14940c42000-11-05 18:40:57 +00001278 light->_IsMatSpecular[side] =
1279 (LEN_SQUARED_3FV(light->_MatSpecular[side]) > 1e-16);
jtgafb833d1999-08-19 00:55:39 +00001280 }
1281 else
Keith Whitwell14940c42000-11-05 18:40:57 +00001282 light->_IsMatSpecular[side] = 0;
jtgafb833d1999-08-19 00:55:39 +00001283 }
1284 }
1285 }
Brian Paulc535ba52000-06-29 04:56:30 +00001286 else {
1287 static const GLfloat ci[3] = { .30, .59, .11 };
jtgafb833d1999-08-19 00:55:39 +00001288 foreach(light, &ctx->Light.EnabledList) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001289 light->_dli = DOT3(ci, light->Diffuse);
1290 light->_sli = DOT3(ci, light->Specular);
jtgafb833d1999-08-19 00:55:39 +00001291 }
1292 }
1293}
1294
Brian Paulc535ba52000-06-29 04:56:30 +00001295
1296
jtgafb833d1999-08-19 00:55:39 +00001297/* Need to seriously restrict the circumstances under which these
1298 * calc's are performed.
1299 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001300void
1301gl_compute_light_positions( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001302{
1303 struct gl_light *light;
1304
Brian Paulde82d062000-06-26 23:37:46 +00001305 if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) {
1306 static const GLfloat eye_z[3] = { 0, 0, 1 };
Keith Whitwell14940c42000-11-05 18:40:57 +00001307 if (ctx->_NeedEyeCoords) {
1308 COPY_3V( ctx->_EyeZDir, eye_z );
jtgafb833d1999-08-19 00:55:39 +00001309 }
Brian Paulde82d062000-06-26 23:37:46 +00001310 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001311 TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelView.m );
Brian Paulde82d062000-06-26 23:37:46 +00001312 }
jtgafb833d1999-08-19 00:55:39 +00001313 }
1314
1315 foreach (light, &ctx->Light.EnabledList) {
1316
Keith Whitwell14940c42000-11-05 18:40:57 +00001317 if (ctx->_NeedEyeCoords) {
1318 COPY_4FV( light->_Position, light->EyePosition );
jtgafb833d1999-08-19 00:55:39 +00001319 }
Brian Paulde82d062000-06-26 23:37:46 +00001320 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001321 TRANSFORM_POINT( light->_Position, ctx->ModelView.inv,
Brian Paulde82d062000-06-26 23:37:46 +00001322 light->EyePosition );
1323 }
jtgafb833d1999-08-19 00:55:39 +00001324
Keith Whitwell14940c42000-11-05 18:40:57 +00001325 if (!(light->_Flags & LIGHT_POSITIONAL)) {
jtgafb833d1999-08-19 00:55:39 +00001326 /* VP (VP) = Normalize( Position ) */
Keith Whitwell14940c42000-11-05 18:40:57 +00001327 COPY_3V( light->_VP_inf_norm, light->_Position );
1328 NORMALIZE_3FV( light->_VP_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001329
Brian Paulde82d062000-06-26 23:37:46 +00001330 if (!ctx->Light.Model.LocalViewer) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001331 /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1332 ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
1333 NORMALIZE_3FV( light->_h_inf_norm );
jtgafb833d1999-08-19 00:55:39 +00001334 }
Keith Whitwell14940c42000-11-05 18:40:57 +00001335 light->_VP_inf_spot_attenuation = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001336 }
1337
Keith Whitwell14940c42000-11-05 18:40:57 +00001338 if (light->_Flags & LIGHT_SPOT) {
1339 if (ctx->_NeedEyeNormals) {
1340 COPY_3V( light->_NormDirection, light->EyeDirection );
Brian Paulde82d062000-06-26 23:37:46 +00001341 }
1342 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001343 TRANSFORM_NORMAL( light->_NormDirection,
jtgafb833d1999-08-19 00:55:39 +00001344 light->EyeDirection,
1345 ctx->ModelView.m);
1346 }
1347
Keith Whitwell14940c42000-11-05 18:40:57 +00001348 NORMALIZE_3FV( light->_NormDirection );
jtgafb833d1999-08-19 00:55:39 +00001349
1350
1351 /* Unlikely occurrance?
1352 */
Keith Whitwell14940c42000-11-05 18:40:57 +00001353 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1354 GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
1355 light->_NormDirection);
jtgafb833d1999-08-19 00:55:39 +00001356
Keith Whitwell14940c42000-11-05 18:40:57 +00001357 if (PV_dot_dir > light->_CosCutoff) {
jtgafb833d1999-08-19 00:55:39 +00001358 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1359 int k = (int) x;
Keith Whitwell14940c42000-11-05 18:40:57 +00001360 light->_VP_inf_spot_attenuation =
1361 (light->_SpotExpTable[k][0] +
1362 (x-k)*light->_SpotExpTable[k][1]);
jtgafb833d1999-08-19 00:55:39 +00001363 }
Brian Paulde82d062000-06-26 23:37:46 +00001364 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001365 light->_VP_inf_spot_attenuation = 0;
Brian Paulde82d062000-06-26 23:37:46 +00001366 }
jtgafb833d1999-08-19 00:55:39 +00001367 }
1368 }
1369 }
1370}
1371
1372
Brian Paula0faa7f2000-07-18 16:55:56 +00001373void
1374gl_update_normal_transform( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001375{
Keith Whitwell14940c42000-11-05 18:40:57 +00001376 ctx->_vb_rescale_factor = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001377
Keith Whitwell14940c42000-11-05 18:40:57 +00001378 if (ctx->_NeedEyeCoords) {
1379 if (ctx->_NeedNormals) {
jtgafb833d1999-08-19 00:55:39 +00001380 GLuint transform = NORM_TRANSFORM_NO_ROT;
1381
1382 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1383 MAT_FLAG_ROTATION |
1384 MAT_FLAG_GENERAL_3D |
1385 MAT_FLAG_PERSPECTIVE))
1386 transform = NORM_TRANSFORM;
jtgafb833d1999-08-19 00:55:39 +00001387
Keith Whitwell14940c42000-11-05 18:40:57 +00001388 ctx->_vb_rescale_factor = ctx->_rescale_factor;
jtgafb833d1999-08-19 00:55:39 +00001389
Brian Paula0faa7f2000-07-18 16:55:56 +00001390 if (ctx->Transform.Normalize) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001391 ctx->_NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
jtgafb833d1999-08-19 00:55:39 +00001392 }
1393 else if (ctx->Transform.RescaleNormals &&
Keith Whitwell14940c42000-11-05 18:40:57 +00001394 ctx->_rescale_factor != 1.0) {
1395 ctx->_NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
jtgafb833d1999-08-19 00:55:39 +00001396 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001397 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001398 ctx->_NormalTransform = gl_normal_tab[transform];
jtgafb833d1999-08-19 00:55:39 +00001399 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001400 }
1401 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001402 ctx->_NormalTransform = 0;
jtgafb833d1999-08-19 00:55:39 +00001403 }
1404 }
1405 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001406 if (ctx->_NeedNormals) {
1407 ctx->_vb_rescale_factor = 1.0/ctx->_rescale_factor;
jtgafb833d1999-08-19 00:55:39 +00001408
Brian Paula0faa7f2000-07-18 16:55:56 +00001409 if (ctx->Transform.Normalize) {
Keith Whitwell14940c42000-11-05 18:40:57 +00001410 ctx->_NormalTransform = gl_normal_tab[NORM_NORMALIZE];
jtgafb833d1999-08-19 00:55:39 +00001411 }
1412 else if (!ctx->Transform.RescaleNormals &&
Keith Whitwell14940c42000-11-05 18:40:57 +00001413 ctx->_rescale_factor != 1.0) {
1414 ctx->_NormalTransform = gl_normal_tab[NORM_RESCALE];
jtgafb833d1999-08-19 00:55:39 +00001415 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001416 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001417 ctx->_NormalTransform = 0;
jtgafb833d1999-08-19 00:55:39 +00001418 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001419 }
1420 else {
Keith Whitwell14940c42000-11-05 18:40:57 +00001421 ctx->_NormalTransform = 0;
jtgafb833d1999-08-19 00:55:39 +00001422 }
1423 }
jtgafb833d1999-08-19 00:55:39 +00001424}