blob: 38e74e7115228707c491ec90e0e57b2a1ccf3538 [file] [log] [blame]
Brian Paulc893a012000-10-28 20:41:13 +00001/* $Id: light.c,v 1.20 2000/10/28 20:41:14 brianp 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)
66 SET_BITS(ctx->TriangleCaps, DD_FLATSHADE);
67 else
68 CLEAR_BITS(ctx->TriangleCaps, DD_FLATSHADE);
Brian Paulfbd8f211999-11-11 01:22:25 +000069 ctx->NewState |= NEW_RASTER_OPS;
70 if (ctx->Driver.ShadeModel)
71 (*ctx->Driver.ShadeModel)( ctx, mode );
Keith Whitwell1bf9dfa1999-09-18 20:41:22 +000072 }
Brian Paulfbd8f211999-11-11 01:22:25 +000073 }
74 else {
Keith Whitwell1bf9dfa1999-09-18 20:41:22 +000075 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
jtgafb833d1999-08-19 00:55:39 +000076 }
jtgafb833d1999-08-19 00:55:39 +000077}
78
79
80
Brian Paulfbd8f211999-11-11 01:22:25 +000081void
82_mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
jtgafb833d1999-08-19 00:55:39 +000083{
Brian Paulfbd8f211999-11-11 01:22:25 +000084 _mesa_Lightfv( light, pname, &param );
85}
jtgafb833d1999-08-19 00:55:39 +000086
Brian Paulfbd8f211999-11-11 01:22:25 +000087
88void
89_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
90{
91 GET_CURRENT_CONTEXT(ctx);
92 GLint l;
93 GLint nParams;
jtgafb833d1999-08-19 00:55:39 +000094
95 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
96
97 l = (GLint) (light - GL_LIGHT0);
98
Brian Paulfbd8f211999-11-11 01:22:25 +000099 if (l < 0 || l >= 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:
106 COPY_4V( ctx->Light.Light[l].Ambient, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000107 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000108 break;
109 case GL_DIFFUSE:
110 COPY_4V( ctx->Light.Light[l].Diffuse, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000111 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000112 break;
113 case GL_SPECULAR:
114 COPY_4V( ctx->Light.Light[l].Specular, params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000115 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000116 break;
117 case GL_POSITION:
118 /* transform position by ModelView matrix */
119 TRANSFORM_POINT( ctx->Light.Light[l].EyePosition,
120 ctx->ModelView.m,
121 params );
Brian Paulfbd8f211999-11-11 01:22:25 +0000122 nParams = 4;
jtgafb833d1999-08-19 00:55:39 +0000123 break;
124 case GL_SPOT_DIRECTION:
125 /* transform direction by inverse modelview */
126 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
127 gl_matrix_analyze( &ctx->ModelView );
128 }
129 TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
130 params,
131 ctx->ModelView.inv );
Brian Paulfbd8f211999-11-11 01:22:25 +0000132 nParams = 3;
jtgafb833d1999-08-19 00:55:39 +0000133 break;
134 case GL_SPOT_EXPONENT:
135 if (params[0]<0.0 || params[0]>128.0) {
136 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
137 return;
138 }
139 if (ctx->Light.Light[l].SpotExponent != params[0]) {
140 ctx->Light.Light[l].SpotExponent = params[0];
141 gl_compute_spot_exp_table( &ctx->Light.Light[l] );
142 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000143 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000144 break;
145 case GL_SPOT_CUTOFF:
146 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
147 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
148 return;
149 }
150 ctx->Light.Light[l].SpotCutoff = params[0];
151 ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
152 if (ctx->Light.Light[l].CosCutoff < 0)
153 ctx->Light.Light[l].CosCutoff = 0;
Brian Paulfbd8f211999-11-11 01:22:25 +0000154 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000155 break;
156 case GL_CONSTANT_ATTENUATION:
157 if (params[0]<0.0) {
158 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
159 return;
160 }
161 ctx->Light.Light[l].ConstantAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000162 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000163 break;
164 case GL_LINEAR_ATTENUATION:
165 if (params[0]<0.0) {
166 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
167 return;
168 }
169 ctx->Light.Light[l].LinearAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000170 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000171 break;
172 case GL_QUADRATIC_ATTENUATION:
173 if (params[0]<0.0) {
174 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
175 return;
176 }
177 ctx->Light.Light[l].QuadraticAttenuation = params[0];
Brian Paulfbd8f211999-11-11 01:22:25 +0000178 nParams = 1;
jtgafb833d1999-08-19 00:55:39 +0000179 break;
180 default:
181 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
Brian Paulfbd8f211999-11-11 01:22:25 +0000182 return;
jtgafb833d1999-08-19 00:55:39 +0000183 }
184
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000185 if (ctx->Driver.Lightfv)
Brian Paulfbd8f211999-11-11 01:22:25 +0000186 ctx->Driver.Lightfv( ctx, light, pname, params, nParams );
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000187
jtgafb833d1999-08-19 00:55:39 +0000188 ctx->NewState |= NEW_LIGHTING;
189}
190
191
Brian Paulfbd8f211999-11-11 01:22:25 +0000192void
193_mesa_Lighti( GLenum light, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000194{
Brian Paulfbd8f211999-11-11 01:22:25 +0000195 _mesa_Lightiv( light, pname, &param );
196}
197
198
199void
200_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
201{
202 GLfloat fparam[4];
203
204 switch (pname) {
205 case GL_AMBIENT:
206 case GL_DIFFUSE:
207 case GL_SPECULAR:
208 fparam[0] = INT_TO_FLOAT( params[0] );
209 fparam[1] = INT_TO_FLOAT( params[1] );
210 fparam[2] = INT_TO_FLOAT( params[2] );
211 fparam[3] = INT_TO_FLOAT( params[3] );
212 break;
213 case GL_POSITION:
214 fparam[0] = (GLfloat) params[0];
215 fparam[1] = (GLfloat) params[1];
216 fparam[2] = (GLfloat) params[2];
217 fparam[3] = (GLfloat) params[3];
218 break;
219 case GL_SPOT_DIRECTION:
220 fparam[0] = (GLfloat) params[0];
221 fparam[1] = (GLfloat) params[1];
222 fparam[2] = (GLfloat) params[2];
223 break;
224 case GL_SPOT_EXPONENT:
225 case GL_SPOT_CUTOFF:
226 case GL_CONSTANT_ATTENUATION:
227 case GL_LINEAR_ATTENUATION:
228 case GL_QUADRATIC_ATTENUATION:
229 fparam[0] = (GLfloat) params[0];
230 break;
231 default:
232 /* error will be caught later in gl_Lightfv */
233 ;
234 }
235
236 _mesa_Lightfv( light, pname, fparam );
237}
238
239
240
241void
242_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
243{
244 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000245 GLint l = (GLint) (light - GL_LIGHT0);
246
247 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
248
249 if (l<0 || l>=MAX_LIGHTS) {
250 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
251 return;
252 }
253
254 switch (pname) {
255 case GL_AMBIENT:
256 COPY_4V( params, ctx->Light.Light[l].Ambient );
257 break;
258 case GL_DIFFUSE:
259 COPY_4V( params, ctx->Light.Light[l].Diffuse );
260 break;
261 case GL_SPECULAR:
262 COPY_4V( params, ctx->Light.Light[l].Specular );
263 break;
264 case GL_POSITION:
265 COPY_4V( params, ctx->Light.Light[l].EyePosition );
266 break;
267 case GL_SPOT_DIRECTION:
268 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
269 break;
270 case GL_SPOT_EXPONENT:
271 params[0] = ctx->Light.Light[l].SpotExponent;
272 break;
273 case GL_SPOT_CUTOFF:
274 params[0] = ctx->Light.Light[l].SpotCutoff;
275 break;
276 case GL_CONSTANT_ATTENUATION:
277 params[0] = ctx->Light.Light[l].ConstantAttenuation;
278 break;
279 case GL_LINEAR_ATTENUATION:
280 params[0] = ctx->Light.Light[l].LinearAttenuation;
281 break;
282 case GL_QUADRATIC_ATTENUATION:
283 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
284 break;
285 default:
286 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
287 break;
288 }
289}
290
291
292
Brian Paulfbd8f211999-11-11 01:22:25 +0000293void
294_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +0000295{
Brian Paulfbd8f211999-11-11 01:22:25 +0000296 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000297 GLint l = (GLint) (light - GL_LIGHT0);
298
299 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
300
301 if (l<0 || l>=MAX_LIGHTS) {
302 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
303 return;
304 }
305
306 switch (pname) {
307 case GL_AMBIENT:
308 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
309 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
310 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
311 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
312 break;
313 case GL_DIFFUSE:
314 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
315 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
316 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
317 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
318 break;
319 case GL_SPECULAR:
320 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
321 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
322 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
323 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
324 break;
325 case GL_POSITION:
326 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
327 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
328 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
329 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
330 break;
331 case GL_SPOT_DIRECTION:
332 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
333 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
334 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
335 break;
336 case GL_SPOT_EXPONENT:
337 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
338 break;
339 case GL_SPOT_CUTOFF:
340 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
341 break;
342 case GL_CONSTANT_ATTENUATION:
343 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
344 break;
345 case GL_LINEAR_ATTENUATION:
346 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
347 break;
348 case GL_QUADRATIC_ATTENUATION:
349 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
350 break;
351 default:
352 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
353 break;
354 }
355}
356
357
358
359/**********************************************************************/
360/*** Light Model ***/
361/**********************************************************************/
362
363
Brian Paulfbd8f211999-11-11 01:22:25 +0000364void
365_mesa_LightModelfv( GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000366{
Brian Paulfbd8f211999-11-11 01:22:25 +0000367 GET_CURRENT_CONTEXT(ctx);
368 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModelfv");
jtgafb833d1999-08-19 00:55:39 +0000369
370 switch (pname) {
371 case GL_LIGHT_MODEL_AMBIENT:
372 COPY_4V( ctx->Light.Model.Ambient, params );
373 break;
374 case GL_LIGHT_MODEL_LOCAL_VIEWER:
375 if (params[0]==0.0)
376 ctx->Light.Model.LocalViewer = GL_FALSE;
377 else
378 ctx->Light.Model.LocalViewer = GL_TRUE;
379 break;
380 case GL_LIGHT_MODEL_TWO_SIDE:
381 if (params[0]==0.0)
382 ctx->Light.Model.TwoSide = GL_FALSE;
383 else
384 ctx->Light.Model.TwoSide = GL_TRUE;
385 break;
386 case GL_LIGHT_MODEL_COLOR_CONTROL:
Brian Paulf3f9b771999-10-19 20:32:40 +0000387 if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
jtgafb833d1999-08-19 00:55:39 +0000388 ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
Keith Whitwellfe5d67d2000-10-27 16:44:40 +0000389 if (!ctx->Fog.ColorSumEnabled)
390 CLEAR_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000391 }
jtgafb833d1999-08-19 00:55:39 +0000392 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
393 ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
Brian Paul8acb3a11999-11-22 18:58:53 +0000394 SET_BITS(ctx->TriangleCaps, DD_SEPERATE_SPECULAR);
Brian Paulf3f9b771999-10-19 20:32:40 +0000395 }
396 else {
jtgafb833d1999-08-19 00:55:39 +0000397 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
Brian Paulf3f9b771999-10-19 20:32:40 +0000398 }
399 ctx->NewState |= NEW_RASTER_OPS;
jtgafb833d1999-08-19 00:55:39 +0000400 break;
401 default:
402 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
403 break;
404 }
Keith Whitwell69cfdb21999-09-30 11:18:21 +0000405
406 if (ctx->Driver.LightModelfv)
407 ctx->Driver.LightModelfv( ctx, pname, params );
408
jtgafb833d1999-08-19 00:55:39 +0000409 ctx->NewState |= NEW_LIGHTING;
410}
411
412
Brian Paulfbd8f211999-11-11 01:22:25 +0000413void
414_mesa_LightModeliv( GLenum pname, const GLint *params )
415{
416 GLfloat fparam[4];
417 GET_CURRENT_CONTEXT(ctx);
418 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModeliv");
419
420 switch (pname) {
421 case GL_LIGHT_MODEL_AMBIENT:
422 fparam[0] = INT_TO_FLOAT( params[0] );
423 fparam[1] = INT_TO_FLOAT( params[1] );
424 fparam[2] = INT_TO_FLOAT( params[2] );
425 fparam[3] = INT_TO_FLOAT( params[3] );
426 break;
427 case GL_LIGHT_MODEL_LOCAL_VIEWER:
428 case GL_LIGHT_MODEL_TWO_SIDE:
429 case GL_LIGHT_MODEL_COLOR_CONTROL:
430 fparam[0] = (GLfloat) params[0];
431 break;
432 default:
433 /* Error will be caught later in gl_LightModelfv */
434 ;
435 }
436 _mesa_LightModelfv( pname, fparam );
437}
438
439
440void
441_mesa_LightModeli( GLenum pname, GLint param )
442{
443 _mesa_LightModeliv( pname, &param );
444}
445
446
447void
448_mesa_LightModelf( GLenum pname, GLfloat param )
449{
450 _mesa_LightModelfv( pname, &param );
451}
452
jtgafb833d1999-08-19 00:55:39 +0000453
454
455/********** MATERIAL **********/
456
457
458/*
459 * Given a face and pname value (ala glColorMaterial), compute a bitmask
460 * of the targeted material values.
461 */
462GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
463 GLuint legal,
464 const char *where )
465{
466 GLuint bitmask = 0;
467
468 /* Make a bitmask indicating what material attribute(s) we're updating */
469 switch (pname) {
470 case GL_EMISSION:
471 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
472 break;
473 case GL_AMBIENT:
474 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
475 break;
476 case GL_DIFFUSE:
477 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
478 break;
479 case GL_SPECULAR:
480 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
481 break;
482 case GL_SHININESS:
483 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
484 break;
485 case GL_AMBIENT_AND_DIFFUSE:
486 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
487 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
488 break;
489 case GL_COLOR_INDEXES:
490 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
491 break;
492 default:
493 gl_error( ctx, GL_INVALID_ENUM, where );
494 return 0;
495 }
496
497 if (face==GL_FRONT) {
498 bitmask &= FRONT_MATERIAL_BITS;
499 }
500 else if (face==GL_BACK) {
501 bitmask &= BACK_MATERIAL_BITS;
502 }
503 else if (face != GL_FRONT_AND_BACK) {
504 gl_error( ctx, GL_INVALID_ENUM, where );
505 return 0;
506 }
507
508 if (bitmask & ~legal) {
509 gl_error( ctx, GL_INVALID_ENUM, where );
510 return 0;
511 }
512
513 return bitmask;
514}
515
516
517
jtgafb833d1999-08-19 00:55:39 +0000518/*
519 * Check if the global material has to be updated with info that was
520 * associated with a vertex via glMaterial.
521 * This function is used when any material values get changed between
522 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
523 * when GL_COLOR_MATERIAL is enabled.
524 *
Brian Paulde82d062000-06-26 23:37:46 +0000525 * src[0] is front material, src[1] is back material
526 *
jtgafb833d1999-08-19 00:55:39 +0000527 * KW: Added code here to keep the precomputed variables uptodate.
528 * This means we can use the faster shade functions when using
529 * GL_COLOR_MATERIAL, and we can also now use the precomputed
530 * values in the slower shading functions, which further offsets
531 * the cost of doing this here.
532 */
533void gl_update_material( GLcontext *ctx,
Brian Paulde82d062000-06-26 23:37:46 +0000534 const struct gl_material src[2],
jtgafb833d1999-08-19 00:55:39 +0000535 GLuint bitmask )
536{
537 struct gl_light *light, *list = &ctx->Light.EnabledList;
jtgafb833d1999-08-19 00:55:39 +0000538
539 if (ctx->Light.ColorMaterialEnabled)
540 bitmask &= ~ctx->Light.ColorMaterialBitmask;
541
Keith Whitwell06ac5921999-11-10 06:29:44 +0000542 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000543 fprintf(stderr, "gl_update_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000544
jtgafb833d1999-08-19 00:55:39 +0000545 if (!bitmask)
546 return;
547
Brian Paulde82d062000-06-26 23:37:46 +0000548 /* update material emission */
549 if (bitmask & FRONT_EMISSION_BIT) {
550 struct gl_material *mat = &ctx->Light.Material[0];
551 COPY_4FV( mat->Emission, src[0].Emission );
552 }
553 if (bitmask & BACK_EMISSION_BIT) {
554 struct gl_material *mat = &ctx->Light.Material[1];
555 COPY_4FV( mat->Emission, src[1].Emission );
556 }
557
558 /* update material ambience */
jtgafb833d1999-08-19 00:55:39 +0000559 if (bitmask & FRONT_AMBIENT_BIT) {
560 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000561 COPY_4FV( mat->Ambient, src[0].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000562 foreach (light, list) {
563 SCALE_3V( light->MatAmbient[0], light->Ambient, src[0].Ambient);
564 }
jtgafb833d1999-08-19 00:55:39 +0000565 }
566 if (bitmask & BACK_AMBIENT_BIT) {
567 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000568 COPY_4FV( mat->Ambient, src[1].Ambient );
Brian Paulde82d062000-06-26 23:37:46 +0000569 foreach (light, list) {
570 SCALE_3V( light->MatAmbient[1], light->Ambient, src[1].Ambient);
571 }
jtgafb833d1999-08-19 00:55:39 +0000572 }
Brian Paulde82d062000-06-26 23:37:46 +0000573
574 /* update BaseColor = emission + scene's ambience * material's ambience */
575 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
576 struct gl_material *mat = &ctx->Light.Material[0];
577 COPY_3V( ctx->Light.BaseColor[0], mat->Emission );
578 ACC_SCALE_3V( ctx->Light.BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
579 }
580 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
581 struct gl_material *mat = &ctx->Light.Material[1];
582 COPY_3V( ctx->Light.BaseColor[1], mat->Emission );
583 ACC_SCALE_3V( ctx->Light.BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
584 }
585
586 /* update material diffuse values */
jtgafb833d1999-08-19 00:55:39 +0000587 if (bitmask & FRONT_DIFFUSE_BIT) {
588 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000589 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000590 SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
591 foreach (light, list) {
592 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
593 }
594 COPY_4FV( mat->Diffuse, src[0].Diffuse );
Brian Paulc893a012000-10-28 20:41:13 +0000595 FLOAT_COLOR_TO_CHAN(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000596 }
597 if (bitmask & BACK_DIFFUSE_BIT) {
598 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000599 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000600 SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
601 foreach (light, list) {
602 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
603 }
604 COPY_4FV( mat->Diffuse, src[1].Diffuse );
Brian Paulc893a012000-10-28 20:41:13 +0000605 FLOAT_COLOR_TO_CHAN(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000606 }
Brian Paulde82d062000-06-26 23:37:46 +0000607
608 /* update material specular values */
jtgafb833d1999-08-19 00:55:39 +0000609 if (bitmask & FRONT_SPECULAR_BIT) {
610 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000611 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000612 SUB_3V( tmp, src[0].Specular, mat->Specular );
613 foreach (light, list) {
614 if (light->Flags & LIGHT_SPECULAR) {
615 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
616 light->IsMatSpecular[0] =
617 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
618 }
619 }
620 COPY_4FV( mat->Specular, src[0].Specular );
621 }
622 if (bitmask & BACK_SPECULAR_BIT) {
623 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000624 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000625 SUB_3V( tmp, src[1].Specular, mat->Specular );
626 foreach (light, list) {
627 if (light->Flags & LIGHT_SPECULAR) {
628 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
629 light->IsMatSpecular[1] =
630 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
631 }
632 }
633 COPY_4FV( mat->Specular, src[1].Specular );
634 }
Brian Paulde82d062000-06-26 23:37:46 +0000635
jtgafb833d1999-08-19 00:55:39 +0000636 if (bitmask & FRONT_SHININESS_BIT) {
637 GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
638 gl_compute_shine_table( ctx, 0, shininess );
639 gl_compute_shine_table( ctx, 2, shininess * .5 );
640 }
641 if (bitmask & BACK_SHININESS_BIT) {
642 GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
643 gl_compute_shine_table( ctx, 1, shininess );
644 gl_compute_shine_table( ctx, 3, shininess * .5 );
645 }
Brian Paulde82d062000-06-26 23:37:46 +0000646
jtgafb833d1999-08-19 00:55:39 +0000647 if (bitmask & FRONT_INDEXES_BIT) {
648 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
649 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
650 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
651 }
652 if (bitmask & BACK_INDEXES_BIT) {
653 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
654 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
655 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
656 }
657
Keith Whitwell06ac5921999-11-10 06:29:44 +0000658 if (0)
659 {
660 struct gl_material *mat = &ctx->Light.Material[0];
661 fprintf(stderr, "update_mat emission : %f %f %f\n",
662 mat->Emission[0],
663 mat->Emission[1],
664 mat->Emission[2]);
665 fprintf(stderr, "update_mat specular : %f %f %f\n",
666 mat->Specular[0],
667 mat->Specular[1],
668 mat->Specular[2]);
669 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
670 mat->Diffuse[0],
671 mat->Diffuse[1],
672 mat->Diffuse[2]);
673 fprintf(stderr, "update_mat ambient : %f %f %f\n",
674 mat->Ambient[0],
675 mat->Ambient[1],
676 mat->Ambient[2]);
677 }
jtgafb833d1999-08-19 00:55:39 +0000678}
679
680
681
682
Brian Paulde82d062000-06-26 23:37:46 +0000683/*
684 * Update the current materials from the given rgba color
685 * according to the bitmask in ColorMaterialBitmask, which is
686 * set by glColorMaterial().
687 */
jtgafb833d1999-08-19 00:55:39 +0000688void gl_update_color_material( GLcontext *ctx,
Brian Paulba643a22000-10-28 18:34:48 +0000689 const GLchan rgba[4] )
jtgafb833d1999-08-19 00:55:39 +0000690{
691 struct gl_light *light, *list = &ctx->Light.EnabledList;
692 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
Brian Paulde82d062000-06-26 23:37:46 +0000693 GLfloat color[4];
jtgafb833d1999-08-19 00:55:39 +0000694
Brian Paulc893a012000-10-28 20:41:13 +0000695 color[0] = CHAN_TO_FLOAT(rgba[0]);
696 color[1] = CHAN_TO_FLOAT(rgba[1]);
697 color[2] = CHAN_TO_FLOAT(rgba[2]);
698 color[3] = CHAN_TO_FLOAT(rgba[3]);
699
Keith Whitwell06ac5921999-11-10 06:29:44 +0000700 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
Brian Paulde82d062000-06-26 23:37:46 +0000701 fprintf(stderr, "gl_update_color_material, mask 0x%x\n", bitmask);
Keith Whitwell06ac5921999-11-10 06:29:44 +0000702
Brian Paulde82d062000-06-26 23:37:46 +0000703 /* update emissive colors */
704 if (bitmask & FRONT_EMISSION_BIT) {
705 struct gl_material *mat = &ctx->Light.Material[0];
706 COPY_4FV( mat->Emission, color );
707 }
Brian Paulfbd8f211999-11-11 01:22:25 +0000708
Brian Paulde82d062000-06-26 23:37:46 +0000709 if (bitmask & BACK_EMISSION_BIT) {
710 struct gl_material *mat = &ctx->Light.Material[1];
711 COPY_4FV( mat->Emission, color );
712 }
713
714 /* update light->MatAmbient = light's ambient * material's ambient */
jtgafb833d1999-08-19 00:55:39 +0000715 if (bitmask & FRONT_AMBIENT_BIT) {
716 struct gl_material *mat = &ctx->Light.Material[0];
jtgafb833d1999-08-19 00:55:39 +0000717 foreach (light, list) {
Brian Paulde82d062000-06-26 23:37:46 +0000718 SCALE_3V( light->MatAmbient[0], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000719 }
720 COPY_4FV( mat->Ambient, color );
721 }
722
723 if (bitmask & BACK_AMBIENT_BIT) {
724 struct gl_material *mat = &ctx->Light.Material[1];
jtgafb833d1999-08-19 00:55:39 +0000725 foreach (light, list) {
Brian Paulde82d062000-06-26 23:37:46 +0000726 SCALE_3V( light->MatAmbient[1], light->Ambient, color);
jtgafb833d1999-08-19 00:55:39 +0000727 }
728 COPY_4FV( mat->Ambient, color );
729 }
730
Brian Paulde82d062000-06-26 23:37:46 +0000731 /* update BaseColor = emission + scene's ambience * material's ambience */
732 if (bitmask & (FRONT_EMISSION_BIT | FRONT_AMBIENT_BIT)) {
733 struct gl_material *mat = &ctx->Light.Material[0];
734 COPY_3V( ctx->Light.BaseColor[0], mat->Emission );
735 ACC_SCALE_3V( ctx->Light.BaseColor[0], mat->Ambient, ctx->Light.Model.Ambient );
736 }
737
738 if (bitmask & (BACK_EMISSION_BIT | BACK_AMBIENT_BIT)) {
739 struct gl_material *mat = &ctx->Light.Material[1];
740 COPY_3V( ctx->Light.BaseColor[1], mat->Emission );
741 ACC_SCALE_3V( ctx->Light.BaseColor[1], mat->Ambient, ctx->Light.Model.Ambient );
742 }
743
744 /* update light->MatDiffuse = light's diffuse * material's diffuse */
jtgafb833d1999-08-19 00:55:39 +0000745 if (bitmask & FRONT_DIFFUSE_BIT) {
746 struct gl_material *mat = &ctx->Light.Material[0];
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) {
750 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
751 }
752 COPY_4FV( mat->Diffuse, color );
Brian Paulc893a012000-10-28 20:41:13 +0000753 FLOAT_COLOR_TO_CHAN(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000754 }
755
756 if (bitmask & BACK_DIFFUSE_BIT) {
757 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000758 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000759 SUB_3V( tmp, color, mat->Diffuse );
760 foreach (light, list) {
761 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
762 }
763 COPY_4FV( mat->Diffuse, color );
Brian Paulc893a012000-10-28 20:41:13 +0000764 FLOAT_COLOR_TO_CHAN(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
jtgafb833d1999-08-19 00:55:39 +0000765 }
766
Brian Paulde82d062000-06-26 23:37:46 +0000767 /* update light->MatSpecular = light's specular * material's specular */
jtgafb833d1999-08-19 00:55:39 +0000768 if (bitmask & FRONT_SPECULAR_BIT) {
769 struct gl_material *mat = &ctx->Light.Material[0];
Brian Paulde82d062000-06-26 23:37:46 +0000770 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000771 SUB_3V( tmp, color, mat->Specular );
772 foreach (light, list) {
773 if (light->Flags & LIGHT_SPECULAR) {
774 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
775 light->IsMatSpecular[0] =
776 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
777 }
778 }
779 COPY_4FV( mat->Specular, color );
780 }
Brian Paulde82d062000-06-26 23:37:46 +0000781
jtgafb833d1999-08-19 00:55:39 +0000782 if (bitmask & BACK_SPECULAR_BIT) {
783 struct gl_material *mat = &ctx->Light.Material[1];
Brian Paulde82d062000-06-26 23:37:46 +0000784 GLfloat tmp[4];
jtgafb833d1999-08-19 00:55:39 +0000785 SUB_3V( tmp, color, mat->Specular );
786 foreach (light, list) {
787 if (light->Flags & LIGHT_SPECULAR) {
788 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
789 light->IsMatSpecular[1] =
790 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
791 }
792 }
793 COPY_4FV( mat->Specular, color );
794 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000795
796 if (0)
797 {
798 struct gl_material *mat = &ctx->Light.Material[0];
799 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
800 mat->Emission[0],
801 mat->Emission[1],
802 mat->Emission[2]);
803 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
804 mat->Specular[0],
805 mat->Specular[1],
806 mat->Specular[2]);
807 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
808 mat->Diffuse[0],
809 mat->Diffuse[1],
810 mat->Diffuse[2]);
811 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
812 mat->Ambient[0],
813 mat->Ambient[1],
814 mat->Ambient[2]);
815 }
jtgafb833d1999-08-19 00:55:39 +0000816}
817
818
819
820
Brian Paulfbd8f211999-11-11 01:22:25 +0000821void
822_mesa_ColorMaterial( GLenum face, GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000823{
Brian Paulfbd8f211999-11-11 01:22:25 +0000824 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000825 GLuint bitmask;
826 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
827 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
828 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
829 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
830
831 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
832
Keith Whitwell06ac5921999-11-10 06:29:44 +0000833 if (MESA_VERBOSE&VERBOSE_API)
834 fprintf(stderr, "glColorMaterial %s %s\n",
835 gl_lookup_enum_by_nr(face),
836 gl_lookup_enum_by_nr(mode));
837
jtgafb833d1999-08-19 00:55:39 +0000838 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
839
840 if (bitmask != 0) {
841 ctx->Light.ColorMaterialBitmask = bitmask;
842 ctx->Light.ColorMaterialFace = face;
843 ctx->Light.ColorMaterialMode = mode;
844 }
Keith Whitwell06ac5921999-11-10 06:29:44 +0000845
846 if (ctx->Light.ColorMaterialEnabled)
847 gl_update_color_material( ctx, ctx->Current.ByteColor );
jtgafb833d1999-08-19 00:55:39 +0000848}
849
850
851
Brian Paulfbd8f211999-11-11 01:22:25 +0000852
853void
854_mesa_Materialf( GLenum face, GLenum pname, GLfloat param )
855{
856 _mesa_Materialfv( face, pname, &param );
857}
858
859
jtgafb833d1999-08-19 00:55:39 +0000860/* KW: This is now called directly (ie by name) from the glMaterial*
861 * API functions.
862 */
Brian Paulfbd8f211999-11-11 01:22:25 +0000863void
864_mesa_Materialfv( GLenum face, GLenum pname, const GLfloat *params )
jtgafb833d1999-08-19 00:55:39 +0000865{
Brian Paulfbd8f211999-11-11 01:22:25 +0000866 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000867 struct immediate *IM;
868 struct gl_material *mat;
869 GLuint bitmask;
870 GLuint count;
871
872 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
873 if (bitmask == 0)
874 return;
875
876 IM = ctx->input;
877 count = IM->Count;
878
Keith Whitwelld4714731999-10-19 18:37:02 +0000879 if (!IM->Material) {
880 IM->Material =
881 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
882 VB_SIZE * 2 );
883 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
884 }
885
886
jtgafb833d1999-08-19 00:55:39 +0000887 if (!(IM->Flag[count] & VERT_MATERIAL)) {
888 IM->Flag[count] |= VERT_MATERIAL;
Keith Whitwelld4714731999-10-19 18:37:02 +0000889 IM->MaterialMask[count] = 0;
jtgafb833d1999-08-19 00:55:39 +0000890 }
891
Brian Paulfbd8f211999-11-11 01:22:25 +0000892
jtgafb833d1999-08-19 00:55:39 +0000893 IM->MaterialMask[count] |= bitmask;
894 mat = IM->Material[count];
jtgafb833d1999-08-19 00:55:39 +0000895
896 if (bitmask & FRONT_AMBIENT_BIT) {
897 COPY_4FV( mat[0].Ambient, params );
898 }
899 if (bitmask & BACK_AMBIENT_BIT) {
900 COPY_4FV( mat[1].Ambient, params );
901 }
902 if (bitmask & FRONT_DIFFUSE_BIT) {
903 COPY_4FV( mat[0].Diffuse, params );
904 }
905 if (bitmask & BACK_DIFFUSE_BIT) {
906 COPY_4FV( mat[1].Diffuse, params );
907 }
908 if (bitmask & FRONT_SPECULAR_BIT) {
909 COPY_4FV( mat[0].Specular, params );
910 }
911 if (bitmask & BACK_SPECULAR_BIT) {
912 COPY_4FV( mat[1].Specular, params );
913 }
914 if (bitmask & FRONT_EMISSION_BIT) {
915 COPY_4FV( mat[0].Emission, params );
916 }
917 if (bitmask & BACK_EMISSION_BIT) {
918 COPY_4FV( mat[1].Emission, params );
919 }
920 if (bitmask & FRONT_SHININESS_BIT) {
921 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
922 mat[0].Shininess = shininess;
923 }
924 if (bitmask & BACK_SHININESS_BIT) {
925 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
926 mat[1].Shininess = shininess;
927 }
928 if (bitmask & FRONT_INDEXES_BIT) {
929 mat[0].AmbientIndex = params[0];
930 mat[0].DiffuseIndex = params[1];
931 mat[0].SpecularIndex = params[2];
932 }
933 if (bitmask & BACK_INDEXES_BIT) {
934 mat[1].AmbientIndex = params[0];
935 mat[1].DiffuseIndex = params[1];
936 mat[1].SpecularIndex = params[2];
937 }
938}
939
940
Brian Paulfbd8f211999-11-11 01:22:25 +0000941void
942_mesa_Materiali(GLenum face, GLenum pname, GLint param )
jtgafb833d1999-08-19 00:55:39 +0000943{
Brian Paulfbd8f211999-11-11 01:22:25 +0000944 _mesa_Materialiv(face, pname, &param);
945}
946
947
948void
949_mesa_Materialiv(GLenum face, GLenum pname, const GLint *params )
950{
951 GLfloat fparam[4];
952 switch (pname) {
953 case GL_AMBIENT:
954 case GL_DIFFUSE:
955 case GL_SPECULAR:
956 case GL_EMISSION:
957 case GL_AMBIENT_AND_DIFFUSE:
958 fparam[0] = INT_TO_FLOAT( params[0] );
959 fparam[1] = INT_TO_FLOAT( params[1] );
960 fparam[2] = INT_TO_FLOAT( params[2] );
961 fparam[3] = INT_TO_FLOAT( params[3] );
962 break;
963 case GL_SHININESS:
964 fparam[0] = (GLfloat) params[0];
965 break;
966 case GL_COLOR_INDEXES:
967 fparam[0] = (GLfloat) params[0];
968 fparam[1] = (GLfloat) params[1];
969 fparam[2] = (GLfloat) params[2];
970 break;
971 default:
972 /* Error will be caught later in gl_Materialfv */
973 ;
974 }
975 _mesa_Materialfv(face, pname, fparam);
976}
977
978
979void
980_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
981{
982 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +0000983 GLuint f;
984
985 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
986
987 if (face==GL_FRONT) {
988 f = 0;
989 }
990 else if (face==GL_BACK) {
991 f = 1;
992 }
993 else {
994 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
995 return;
996 }
997 switch (pname) {
998 case GL_AMBIENT:
999 COPY_4FV( params, ctx->Light.Material[f].Ambient );
1000 break;
1001 case GL_DIFFUSE:
1002 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
1003 break;
1004 case GL_SPECULAR:
1005 COPY_4FV( params, ctx->Light.Material[f].Specular );
1006 break;
1007 case GL_EMISSION:
1008 COPY_4FV( params, ctx->Light.Material[f].Emission );
1009 break;
1010 case GL_SHININESS:
1011 *params = ctx->Light.Material[f].Shininess;
1012 break;
1013 case GL_COLOR_INDEXES:
1014 params[0] = ctx->Light.Material[f].AmbientIndex;
1015 params[1] = ctx->Light.Material[f].DiffuseIndex;
1016 params[2] = ctx->Light.Material[f].SpecularIndex;
1017 break;
1018 default:
1019 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1020 }
1021}
1022
1023
1024
Brian Paulfbd8f211999-11-11 01:22:25 +00001025void
1026_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
jtgafb833d1999-08-19 00:55:39 +00001027{
Brian Paulfbd8f211999-11-11 01:22:25 +00001028 GET_CURRENT_CONTEXT(ctx);
jtgafb833d1999-08-19 00:55:39 +00001029 GLuint f;
1030
1031 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
1032
1033 if (face==GL_FRONT) {
1034 f = 0;
1035 }
1036 else if (face==GL_BACK) {
1037 f = 1;
1038 }
1039 else {
1040 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
1041 return;
1042 }
1043 switch (pname) {
1044 case GL_AMBIENT:
1045 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
1046 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
1047 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
1048 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
1049 break;
1050 case GL_DIFFUSE:
1051 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
1052 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
1053 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
1054 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
1055 break;
1056 case GL_SPECULAR:
1057 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
1058 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
1059 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
1060 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
1061 break;
1062 case GL_EMISSION:
1063 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
1064 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
1065 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
1066 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
1067 break;
1068 case GL_SHININESS:
1069 *params = ROUNDF( ctx->Light.Material[f].Shininess );
1070 break;
1071 case GL_COLOR_INDEXES:
1072 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
1073 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
1074 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
1075 break;
1076 default:
1077 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
1078 }
1079}
1080
1081
1082
1083
1084/**********************************************************************/
1085/***** Lighting computation *****/
1086/**********************************************************************/
1087
1088
1089/*
1090 * Notes:
1091 * When two-sided lighting is enabled we compute the color (or index)
1092 * for both the front and back side of the primitive. Then, when the
1093 * orientation of the facet is later learned, we can determine which
1094 * color (or index) to use for rendering.
1095 *
1096 * KW: We now know orientation in advance and only shade for
1097 * the side or sides which are actually required.
1098 *
1099 * Variables:
1100 * n = normal vector
1101 * V = vertex position
1102 * P = light source position
1103 * Pe = (0,0,0,1)
1104 *
1105 * Precomputed:
1106 * IF P[3]==0 THEN
1107 * // light at infinity
1108 * IF local_viewer THEN
1109 * VP_inf_norm = unit vector from V to P // Precompute
1110 * ELSE
1111 * // eye at infinity
1112 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
1113 * ENDIF
1114 * ENDIF
1115 *
1116 * Functions:
1117 * Normalize( v ) = normalized vector v
1118 * Magnitude( v ) = length of vector v
1119 */
1120
1121
1122
1123/*
1124 * Whenever the spotlight exponent for a light changes we must call
1125 * this function to recompute the exponent lookup table.
1126 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001127void
1128gl_compute_spot_exp_table( struct gl_light *l )
jtgafb833d1999-08-19 00:55:39 +00001129{
Brian Paula0faa7f2000-07-18 16:55:56 +00001130 GLint i;
1131 GLdouble exponent = l->SpotExponent;
1132 GLdouble tmp = 0;
1133 GLint clamp = 0;
jtgafb833d1999-08-19 00:55:39 +00001134
1135 l->SpotExpTable[0][0] = 0.0;
1136
Brian Paula0faa7f2000-07-18 16:55:56 +00001137 for (i = EXP_TABLE_SIZE - 1; i > 0 ;i--) {
jtgafb833d1999-08-19 00:55:39 +00001138 if (clamp == 0) {
Brian Paula0faa7f2000-07-18 16:55:56 +00001139 tmp = pow(i / (GLdouble) (EXP_TABLE_SIZE - 1), exponent);
1140 if (tmp < FLT_MIN * 100.0) {
jtgafb833d1999-08-19 00:55:39 +00001141 tmp = 0.0;
1142 clamp = 1;
1143 }
1144 }
1145 l->SpotExpTable[i][0] = tmp;
1146 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001147 for (i = 0; i < EXP_TABLE_SIZE - 1; i++) {
jtgafb833d1999-08-19 00:55:39 +00001148 l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
1149 }
1150 l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
1151}
1152
1153
1154
1155
1156/* Calculate a new shine table. Doing this here saves a branch in
1157 * lighting, and the cost of doing it early may be partially offset
1158 * by keeping a MRU cache of shine tables for various shine values.
1159 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001160static void
1161compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001162{
Brian Paula0faa7f2000-07-18 16:55:56 +00001163 GLint i;
jtgafb833d1999-08-19 00:55:39 +00001164 GLfloat *m = tab->tab;
1165
Brian Paula0faa7f2000-07-18 16:55:56 +00001166 m[0] = 0.0;
1167 if (shininess == 0.0) {
jtgafb833d1999-08-19 00:55:39 +00001168 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
Brian Paula0faa7f2000-07-18 16:55:56 +00001169 m[i] = 1.0;
1170 }
1171 else {
1172 for (i = 1 ; i < SHINE_TABLE_SIZE ; i++) {
1173 GLdouble t = pow(i / (GLfloat) (SHINE_TABLE_SIZE - 1), shininess);
1174 if (t > 1e-20)
1175 m[i] = t;
1176 else
1177 m[i] = 0.0;
jtgafb833d1999-08-19 00:55:39 +00001178 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001179 m[SHINE_TABLE_SIZE] = 1.0;
jtgafb833d1999-08-19 00:55:39 +00001180 }
1181
1182 tab->shininess = shininess;
1183}
1184
jtgafb833d1999-08-19 00:55:39 +00001185
Brian Paula0faa7f2000-07-18 16:55:56 +00001186void
1187gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
jtgafb833d1999-08-19 00:55:39 +00001188{
Brian Paula0faa7f2000-07-18 16:55:56 +00001189#define DISTSQR(a,b) ((a-b)*(a-b))
jtgafb833d1999-08-19 00:55:39 +00001190 struct gl_shine_tab *list = ctx->ShineTabList;
1191 struct gl_shine_tab *s;
1192
1193 foreach(s, list)
1194 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
1195 break;
1196
Brian Paula0faa7f2000-07-18 16:55:56 +00001197 if (s == list) {
jtgafb833d1999-08-19 00:55:39 +00001198 foreach(s, list)
Brian Paula0faa7f2000-07-18 16:55:56 +00001199 if (s->refcount == 0)
1200 break;
jtgafb833d1999-08-19 00:55:39 +00001201
1202 compute_shine_table( s, shininess );
1203 }
1204
1205 ctx->ShineTable[i]->refcount--;
1206 ctx->ShineTable[i] = s;
1207 move_to_tail( list, s );
1208 s->refcount++;
Brian Paula0faa7f2000-07-18 16:55:56 +00001209#undef DISTSQR
jtgafb833d1999-08-19 00:55:39 +00001210}
1211
1212
1213
Brian Paul16a9efe2000-01-13 00:29:02 +00001214#if 0
Brian Paula0faa7f2000-07-18 16:55:56 +00001215static void
1216gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
jtgafb833d1999-08-19 00:55:39 +00001217{
1218 GLuint i;
1219
1220 if (ctx->ShineTable[0]->shininess != l->Material[0].Shininess) {
1221 gl_compute_shine_table( ctx, 0, l->Material[0].Shininess );
1222 gl_compute_shine_table( ctx, 2, l->Material[0].Shininess * .5 );
1223 }
1224
1225 if (ctx->ShineTable[1]->shininess != l->Material[1].Shininess) {
1226 gl_compute_shine_table( ctx, 1, l->Material[1].Shininess );
1227 gl_compute_shine_table( ctx, 3, l->Material[1].Shininess * .5 );
1228 }
1229
1230 make_empty_list( &l->EnabledList );
1231 for (i = 0 ; i < MAX_LIGHTS ; i++) {
1232 if (l->Light[i].Enabled)
1233 insert_at_tail( &l->EnabledList, &l->Light[i] );
1234 }
1235}
Brian Paul16a9efe2000-01-13 00:29:02 +00001236#endif
jtgafb833d1999-08-19 00:55:39 +00001237
1238
1239/*
1240 * Examine current lighting parameters to determine if the optimized lighting
1241 * function can be used.
1242 * Also, precompute some lighting values such as the products of light
1243 * source and material ambient, diffuse and specular coefficients.
1244 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001245void
1246gl_update_lighting( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001247{
1248 struct gl_light *light;
1249
1250 ctx->Light.Flags = 0;
1251
1252 foreach(light, &ctx->Light.EnabledList) {
1253
1254 light->Flags = 0;
1255
1256 if (light->EyePosition[3] != 0.0F)
1257 light->Flags |= LIGHT_POSITIONAL;
1258
1259 if (LEN_SQUARED_3FV(light->Specular) > 1e-16)
1260 light->Flags |= LIGHT_SPECULAR;
1261
1262 if (light->SpotCutoff != 180.0F)
1263 light->Flags |= LIGHT_SPOT;
1264
1265 ctx->Light.Flags |= light->Flags;
1266 }
1267
1268 ctx->Light.NeedVertices =
1269 ((ctx->Light.Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
1270 (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
1271 (ctx->Light.Model.LocalViewer && (ctx->Light.Flags & LIGHT_SPECULAR)));
1272
1273
1274 /* Precompute some shading values.
1275 */
Brian Paulb1394fa2000-09-26 20:53:53 +00001276 if (ctx->Visual.RGBAflag) {
jtgafb833d1999-08-19 00:55:39 +00001277 GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
1278 GLuint side;
1279 for (side=0; side < sides; side++) {
1280 struct gl_material *mat = &ctx->Light.Material[side];
Brian Paulc535ba52000-06-29 04:56:30 +00001281
jtgafb833d1999-08-19 00:55:39 +00001282 COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
1283 ACC_SCALE_3V(ctx->Light.BaseColor[side],
1284 ctx->Light.Model.Ambient,
1285 mat->Ambient);
1286
Brian Paulc893a012000-10-28 20:41:13 +00001287 FLOAT_COLOR_TO_CHAN(ctx->Light.BaseAlpha[side],
1288 ctx->Light.Material[side].Diffuse[3] );
jtgafb833d1999-08-19 00:55:39 +00001289 }
1290
1291 foreach (light, &ctx->Light.EnabledList) {
1292 for (side=0; side< sides; side++) {
Brian Paulc535ba52000-06-29 04:56:30 +00001293 const struct gl_material *mat = &ctx->Light.Material[side];
1294 SCALE_3V( light->MatDiffuse[side], light->Diffuse, mat->Diffuse );
1295 SCALE_3V( light->MatAmbient[side], light->Ambient, mat->Ambient );
1296 if (light->Flags & LIGHT_SPECULAR) {
jtgafb833d1999-08-19 00:55:39 +00001297 SCALE_3V( light->MatSpecular[side], light->Specular,
1298 mat->Specular);
1299 light->IsMatSpecular[side] =
1300 (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
1301 }
1302 else
1303 light->IsMatSpecular[side] = 0;
1304 }
1305 }
1306 }
Brian Paulc535ba52000-06-29 04:56:30 +00001307 else {
1308 static const GLfloat ci[3] = { .30, .59, .11 };
jtgafb833d1999-08-19 00:55:39 +00001309 foreach(light, &ctx->Light.EnabledList) {
1310 light->dli = DOT3(ci, light->Diffuse);
1311 light->sli = DOT3(ci, light->Specular);
1312 }
1313 }
1314}
1315
Brian Paulc535ba52000-06-29 04:56:30 +00001316
1317
jtgafb833d1999-08-19 00:55:39 +00001318/* Need to seriously restrict the circumstances under which these
1319 * calc's are performed.
1320 */
Brian Paula0faa7f2000-07-18 16:55:56 +00001321void
1322gl_compute_light_positions( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001323{
1324 struct gl_light *light;
1325
Brian Paulde82d062000-06-26 23:37:46 +00001326 if (1 /*ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer*/) {
1327 static const GLfloat eye_z[3] = { 0, 0, 1 };
1328 if (ctx->NeedEyeCoords) {
jtgafb833d1999-08-19 00:55:39 +00001329 COPY_3V( ctx->EyeZDir, eye_z );
1330 }
Brian Paulde82d062000-06-26 23:37:46 +00001331 else {
1332 TRANSFORM_NORMAL( ctx->EyeZDir, eye_z, ctx->ModelView.m );
1333 }
jtgafb833d1999-08-19 00:55:39 +00001334 }
1335
1336 foreach (light, &ctx->Light.EnabledList) {
1337
Brian Paulde82d062000-06-26 23:37:46 +00001338 if (ctx->NeedEyeCoords) {
jtgafb833d1999-08-19 00:55:39 +00001339 COPY_4FV( light->Position, light->EyePosition );
1340 }
Brian Paulde82d062000-06-26 23:37:46 +00001341 else {
1342 TRANSFORM_POINT( light->Position, ctx->ModelView.inv,
1343 light->EyePosition );
1344 }
jtgafb833d1999-08-19 00:55:39 +00001345
Brian Paulde82d062000-06-26 23:37:46 +00001346 if (!(light->Flags & LIGHT_POSITIONAL)) {
jtgafb833d1999-08-19 00:55:39 +00001347 /* VP (VP) = Normalize( Position ) */
1348 COPY_3V( light->VP_inf_norm, light->Position );
1349 NORMALIZE_3FV( light->VP_inf_norm );
1350
Brian Paulde82d062000-06-26 23:37:46 +00001351 if (!ctx->Light.Model.LocalViewer) {
jtgafb833d1999-08-19 00:55:39 +00001352 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1353 ADD_3V( light->h_inf_norm, light->VP_inf_norm, ctx->EyeZDir);
1354 NORMALIZE_3FV( light->h_inf_norm );
1355 }
jtgafb833d1999-08-19 00:55:39 +00001356 light->VP_inf_spot_attenuation = 1.0;
1357 }
1358
Brian Paulde82d062000-06-26 23:37:46 +00001359 if (light->Flags & LIGHT_SPOT) {
jtgafb833d1999-08-19 00:55:39 +00001360 if (ctx->NeedEyeNormals) {
1361 COPY_3V( light->NormDirection, light->EyeDirection );
Brian Paulde82d062000-06-26 23:37:46 +00001362 }
1363 else {
jtgafb833d1999-08-19 00:55:39 +00001364 TRANSFORM_NORMAL( light->NormDirection,
1365 light->EyeDirection,
1366 ctx->ModelView.m);
1367 }
1368
1369 NORMALIZE_3FV( light->NormDirection );
1370
1371
1372 /* Unlikely occurrance?
1373 */
1374 if (!(light->Flags & LIGHT_POSITIONAL)) {
1375 GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm,
1376 light->NormDirection);
1377
1378 if (PV_dot_dir > light->CosCutoff) {
1379 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1380 int k = (int) x;
1381 light->VP_inf_spot_attenuation =
1382 (light->SpotExpTable[k][0] +
1383 (x-k)*light->SpotExpTable[k][1]);
1384 }
Brian Paulde82d062000-06-26 23:37:46 +00001385 else {
jtgafb833d1999-08-19 00:55:39 +00001386 light->VP_inf_spot_attenuation = 0;
Brian Paulde82d062000-06-26 23:37:46 +00001387 }
jtgafb833d1999-08-19 00:55:39 +00001388 }
1389 }
1390 }
1391}
1392
1393
Brian Paula0faa7f2000-07-18 16:55:56 +00001394void
1395gl_update_normal_transform( GLcontext *ctx )
jtgafb833d1999-08-19 00:55:39 +00001396{
1397 GLuint new_flag = 0;
1398 normal_func *last = ctx->NormalTransform;
1399
1400 ctx->vb_rescale_factor = 1.0;
1401
1402 if (ctx->NeedEyeCoords) {
1403 if (ctx->NeedNormals) {
1404 GLuint transform = NORM_TRANSFORM_NO_ROT;
1405
1406 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1407 MAT_FLAG_ROTATION |
1408 MAT_FLAG_GENERAL_3D |
1409 MAT_FLAG_PERSPECTIVE))
1410 transform = NORM_TRANSFORM;
1411
1412
1413 new_flag = ctx->NewState & NEW_MODELVIEW;
1414 ctx->vb_rescale_factor = ctx->rescale_factor;
1415
Brian Paula0faa7f2000-07-18 16:55:56 +00001416 if (ctx->Transform.Normalize) {
jtgafb833d1999-08-19 00:55:39 +00001417 ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
1418 }
1419 else if (ctx->Transform.RescaleNormals &&
Brian Paula0faa7f2000-07-18 16:55:56 +00001420 ctx->rescale_factor != 1.0) {
jtgafb833d1999-08-19 00:55:39 +00001421 ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
1422 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001423 else {
jtgafb833d1999-08-19 00:55:39 +00001424 ctx->NormalTransform = gl_normal_tab[transform];
1425 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001426 }
1427 else {
jtgafb833d1999-08-19 00:55:39 +00001428 ctx->NormalTransform = 0;
1429 }
1430 }
1431 else {
1432 if (ctx->NeedNormals) {
1433 ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
1434
Brian Paula0faa7f2000-07-18 16:55:56 +00001435 if (ctx->Transform.Normalize) {
jtgafb833d1999-08-19 00:55:39 +00001436 ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
1437 }
1438 else if (!ctx->Transform.RescaleNormals &&
Brian Paula0faa7f2000-07-18 16:55:56 +00001439 ctx->rescale_factor != 1.0) {
jtgafb833d1999-08-19 00:55:39 +00001440 ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
1441 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001442 else {
jtgafb833d1999-08-19 00:55:39 +00001443 ctx->NormalTransform = 0;
1444 }
Brian Paula0faa7f2000-07-18 16:55:56 +00001445 }
1446 else {
jtgafb833d1999-08-19 00:55:39 +00001447 ctx->NormalTransform = 0;
1448 }
1449 }
1450
1451 if (last != ctx->NormalTransform || new_flag)
1452 ctx->NewState |= NEW_NORMAL_TRANSFORM;
1453}