source: trunk/src/opengl/mesa/light.c@ 3079

Last change on this file since 3079 was 2962, checked in by jeroen, 25 years ago

* empty log message *

File size: 36.4 KB
Line 
1/* $Id: light.c,v 1.2 2000-03-01 18:49:31 jeroen Exp $ */
2
3/*
4 * Mesa 3-D graphics library
5 * Version: 3.1
6 *
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
8 *
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
28
29
30
31#ifdef PC_HEADER
32#include "all.h"
33#else
34#include <float.h>
35#ifndef XFree86Server
36#include <assert.h>
37#include <float.h>
38#include <math.h>
39#include <stdlib.h>
40#include <stdio.h>
41#else
42#include "GL/xf86glx.h"
43#endif
44#include "types.h"
45#include "context.h"
46#include "enums.h"
47#include "light.h"
48#include "macros.h"
49#include "matrix.h"
50#include "mmath.h"
51#include "simple_list.h"
52#include "vb.h"
53#include "xform.h"
54#endif
55
56
57
58void gl_ShadeModel( GLcontext *ctx, GLenum mode )
59{
60 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glShadeModel");
61
62 if (MESA_VERBOSE & VERBOSE_API)
63 fprintf(stderr, "glShadeModel %s\n", gl_lookup_enum_by_nr(mode));
64
65 if (mode == GL_FLAT || mode == GL_SMOOTH) {
66 if (ctx->Light.ShadeModel != mode) {
67 ctx->Light.ShadeModel = mode;
68 if (ctx->Light.ShadeModel == GL_FLAT)
69 ctx->TriangleCaps |= DD_FLATSHADE;
70 else
71 ctx->TriangleCaps &= ~DD_FLATSHADE;
72 ctx->NewState |= NEW_RASTER_OPS;
73 if (ctx->Driver.ShadeModel)
74 (*ctx->Driver.ShadeModel)( ctx, mode );
75 }
76 }
77 else {
78 gl_error( ctx, GL_INVALID_ENUM, "glShadeModel" );
79 }
80}
81
82
83
84void gl_Lightfv( GLcontext *ctx,
85 GLenum light, GLenum pname, const GLfloat *params,
86 GLint nparams )
87{
88 GLint l;
89
90 (void) nparams;
91
92 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLight");
93
94 l = (GLint) (light - GL_LIGHT0);
95
96 if (l<0 || l>=MAX_LIGHTS) {
97 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
98 return;
99 }
100
101 switch (pname) {
102 case GL_AMBIENT:
103 COPY_4V( ctx->Light.Light[l].Ambient, params );
104 break;
105 case GL_DIFFUSE:
106 COPY_4V( ctx->Light.Light[l].Diffuse, params );
107 break;
108 case GL_SPECULAR:
109 COPY_4V( ctx->Light.Light[l].Specular, params );
110 break;
111 case GL_POSITION:
112 /* transform position by ModelView matrix */
113 TRANSFORM_POINT( ctx->Light.Light[l].EyePosition,
114 ctx->ModelView.m,
115 params );
116 break;
117 case GL_SPOT_DIRECTION:
118 /* transform direction by inverse modelview */
119 if (ctx->ModelView.flags & MAT_DIRTY_INVERSE) {
120 gl_matrix_analyze( &ctx->ModelView );
121 }
122 TRANSFORM_NORMAL( ctx->Light.Light[l].EyeDirection,
123 params,
124 ctx->ModelView.inv );
125 break;
126 case GL_SPOT_EXPONENT:
127 if (params[0]<0.0 || params[0]>128.0) {
128 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
129 return;
130 }
131 if (ctx->Light.Light[l].SpotExponent != params[0]) {
132 ctx->Light.Light[l].SpotExponent = params[0];
133 gl_compute_spot_exp_table( &ctx->Light.Light[l] );
134 }
135 break;
136 case GL_SPOT_CUTOFF:
137 if ((params[0]<0.0 || params[0]>90.0) && params[0]!=180.0) {
138 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
139 return;
140 }
141 ctx->Light.Light[l].SpotCutoff = params[0];
142 ctx->Light.Light[l].CosCutoff = cos(params[0]*DEG2RAD);
143 if (ctx->Light.Light[l].CosCutoff < 0)
144 ctx->Light.Light[l].CosCutoff = 0;
145 break;
146 case GL_CONSTANT_ATTENUATION:
147 if (params[0]<0.0) {
148 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
149 return;
150 }
151 ctx->Light.Light[l].ConstantAttenuation = params[0];
152 break;
153 case GL_LINEAR_ATTENUATION:
154 if (params[0]<0.0) {
155 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
156 return;
157 }
158 ctx->Light.Light[l].LinearAttenuation = params[0];
159 break;
160 case GL_QUADRATIC_ATTENUATION:
161 if (params[0]<0.0) {
162 gl_error( ctx, GL_INVALID_VALUE, "glLight" );
163 return;
164 }
165 ctx->Light.Light[l].QuadraticAttenuation = params[0];
166 break;
167 default:
168 gl_error( ctx, GL_INVALID_ENUM, "glLight" );
169 break;
170 }
171
172 if (ctx->Driver.Lightfv)
173 ctx->Driver.Lightfv( ctx, light, pname, params, nparams );
174
175 ctx->NewState |= NEW_LIGHTING;
176}
177
178
179
180void gl_GetLightfv( GLcontext *ctx,
181 GLenum light, GLenum pname, GLfloat *params )
182{
183 GLint l = (GLint) (light - GL_LIGHT0);
184
185 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
186
187 if (l<0 || l>=MAX_LIGHTS) {
188 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
189 return;
190 }
191
192 switch (pname) {
193 case GL_AMBIENT:
194 COPY_4V( params, ctx->Light.Light[l].Ambient );
195 break;
196 case GL_DIFFUSE:
197 COPY_4V( params, ctx->Light.Light[l].Diffuse );
198 break;
199 case GL_SPECULAR:
200 COPY_4V( params, ctx->Light.Light[l].Specular );
201 break;
202 case GL_POSITION:
203 COPY_4V( params, ctx->Light.Light[l].EyePosition );
204 break;
205 case GL_SPOT_DIRECTION:
206 COPY_3V( params, ctx->Light.Light[l].EyeDirection );
207 break;
208 case GL_SPOT_EXPONENT:
209 params[0] = ctx->Light.Light[l].SpotExponent;
210 break;
211 case GL_SPOT_CUTOFF:
212 params[0] = ctx->Light.Light[l].SpotCutoff;
213 break;
214 case GL_CONSTANT_ATTENUATION:
215 params[0] = ctx->Light.Light[l].ConstantAttenuation;
216 break;
217 case GL_LINEAR_ATTENUATION:
218 params[0] = ctx->Light.Light[l].LinearAttenuation;
219 break;
220 case GL_QUADRATIC_ATTENUATION:
221 params[0] = ctx->Light.Light[l].QuadraticAttenuation;
222 break;
223 default:
224 gl_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
225 break;
226 }
227}
228
229
230
231void gl_GetLightiv( GLcontext *ctx, GLenum light, GLenum pname, GLint *params )
232{
233 GLint l = (GLint) (light - GL_LIGHT0);
234
235 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetLight");
236
237 if (l<0 || l>=MAX_LIGHTS) {
238 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
239 return;
240 }
241
242 switch (pname) {
243 case GL_AMBIENT:
244 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[0]);
245 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[1]);
246 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[2]);
247 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Ambient[3]);
248 break;
249 case GL_DIFFUSE:
250 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[0]);
251 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[1]);
252 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[2]);
253 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Diffuse[3]);
254 break;
255 case GL_SPECULAR:
256 params[0] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[0]);
257 params[1] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[1]);
258 params[2] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[2]);
259 params[3] = FLOAT_TO_INT(ctx->Light.Light[l].Specular[3]);
260 break;
261 case GL_POSITION:
262 params[0] = (GLint) ctx->Light.Light[l].EyePosition[0];
263 params[1] = (GLint) ctx->Light.Light[l].EyePosition[1];
264 params[2] = (GLint) ctx->Light.Light[l].EyePosition[2];
265 params[3] = (GLint) ctx->Light.Light[l].EyePosition[3];
266 break;
267 case GL_SPOT_DIRECTION:
268 params[0] = (GLint) ctx->Light.Light[l].EyeDirection[0];
269 params[1] = (GLint) ctx->Light.Light[l].EyeDirection[1];
270 params[2] = (GLint) ctx->Light.Light[l].EyeDirection[2];
271 break;
272 case GL_SPOT_EXPONENT:
273 params[0] = (GLint) ctx->Light.Light[l].SpotExponent;
274 break;
275 case GL_SPOT_CUTOFF:
276 params[0] = (GLint) ctx->Light.Light[l].SpotCutoff;
277 break;
278 case GL_CONSTANT_ATTENUATION:
279 params[0] = (GLint) ctx->Light.Light[l].ConstantAttenuation;
280 break;
281 case GL_LINEAR_ATTENUATION:
282 params[0] = (GLint) ctx->Light.Light[l].LinearAttenuation;
283 break;
284 case GL_QUADRATIC_ATTENUATION:
285 params[0] = (GLint) ctx->Light.Light[l].QuadraticAttenuation;
286 break;
287 default:
288 gl_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
289 break;
290 }
291}
292
293
294
295/**********************************************************************/
296/*** Light Model ***/
297/**********************************************************************/
298
299
300void gl_LightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *params )
301{
302 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glLightModel");
303
304 switch (pname) {
305 case GL_LIGHT_MODEL_AMBIENT:
306 COPY_4V( ctx->Light.Model.Ambient, params );
307 break;
308 case GL_LIGHT_MODEL_LOCAL_VIEWER:
309 if (params[0]==0.0)
310 ctx->Light.Model.LocalViewer = GL_FALSE;
311 else
312 ctx->Light.Model.LocalViewer = GL_TRUE;
313 break;
314 case GL_LIGHT_MODEL_TWO_SIDE:
315 if (params[0]==0.0)
316 ctx->Light.Model.TwoSide = GL_FALSE;
317 else
318 ctx->Light.Model.TwoSide = GL_TRUE;
319 break;
320 case GL_LIGHT_MODEL_COLOR_CONTROL:
321 if (params[0] == (GLfloat) GL_SINGLE_COLOR) {
322 ctx->Light.Model.ColorControl = GL_SINGLE_COLOR;
323 ctx->TriangleCaps &= ~DD_SEPERATE_SPECULAR;
324 }
325 else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR) {
326 ctx->Light.Model.ColorControl = GL_SEPARATE_SPECULAR_COLOR;
327 ctx->TriangleCaps |= DD_SEPERATE_SPECULAR;
328 }
329 else {
330 gl_error( ctx, GL_INVALID_ENUM, "glLightModel(param)" );
331 }
332 ctx->NewState |= NEW_RASTER_OPS;
333 break;
334 default:
335 gl_error( ctx, GL_INVALID_ENUM, "glLightModel" );
336 break;
337 }
338
339 if (ctx->Driver.LightModelfv)
340 ctx->Driver.LightModelfv( ctx, pname, params );
341
342 ctx->NewState |= NEW_LIGHTING;
343}
344
345
346
347
348/********** MATERIAL **********/
349
350
351/*
352 * Given a face and pname value (ala glColorMaterial), compute a bitmask
353 * of the targeted material values.
354 */
355GLuint gl_material_bitmask( GLcontext *ctx, GLenum face, GLenum pname,
356 GLuint legal,
357 const char *where )
358{
359 GLuint bitmask = 0;
360
361 /* Make a bitmask indicating what material attribute(s) we're updating */
362 switch (pname) {
363 case GL_EMISSION:
364 bitmask |= FRONT_EMISSION_BIT | BACK_EMISSION_BIT;
365 break;
366 case GL_AMBIENT:
367 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
368 break;
369 case GL_DIFFUSE:
370 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
371 break;
372 case GL_SPECULAR:
373 bitmask |= FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT;
374 break;
375 case GL_SHININESS:
376 bitmask |= FRONT_SHININESS_BIT | BACK_SHININESS_BIT;
377 break;
378 case GL_AMBIENT_AND_DIFFUSE:
379 bitmask |= FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT;
380 bitmask |= FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT;
381 break;
382 case GL_COLOR_INDEXES:
383 bitmask |= FRONT_INDEXES_BIT | BACK_INDEXES_BIT;
384 break;
385 default:
386 gl_error( ctx, GL_INVALID_ENUM, where );
387 return 0;
388 }
389
390 if (face==GL_FRONT) {
391 bitmask &= FRONT_MATERIAL_BITS;
392 }
393 else if (face==GL_BACK) {
394 bitmask &= BACK_MATERIAL_BITS;
395 }
396 else if (face != GL_FRONT_AND_BACK) {
397 gl_error( ctx, GL_INVALID_ENUM, where );
398 return 0;
399 }
400
401 if (bitmask & ~legal) {
402 gl_error( ctx, GL_INVALID_ENUM, where );
403 return 0;
404 }
405
406 return bitmask;
407}
408
409
410
411
412
413
414/*
415 * Check if the global material has to be updated with info that was
416 * associated with a vertex via glMaterial.
417 * This function is used when any material values get changed between
418 * glBegin/glEnd either by calling glMaterial() or by calling glColor()
419 * when GL_COLOR_MATERIAL is enabled.
420 *
421 * KW: Added code here to keep the precomputed variables uptodate.
422 * This means we can use the faster shade functions when using
423 * GL_COLOR_MATERIAL, and we can also now use the precomputed
424 * values in the slower shading functions, which further offsets
425 * the cost of doing this here.
426 */
427void gl_update_material( GLcontext *ctx,
428 struct gl_material *src,
429 GLuint bitmask )
430{
431 struct gl_light *light, *list = &ctx->Light.EnabledList;
432 GLfloat tmp[4];
433
434 if (ctx->Light.ColorMaterialEnabled)
435 bitmask &= ~ctx->Light.ColorMaterialBitmask;
436
437 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
438 fprintf(stderr, "gl_update_material, mask %x\n", bitmask);
439
440 if (!bitmask)
441 return;
442
443 if (bitmask & FRONT_AMBIENT_BIT) {
444 struct gl_material *mat = &ctx->Light.Material[0];
445 SUB_3V( tmp, src[0].Ambient, mat->Ambient );
446 ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
447 foreach (light, list) {
448 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
449 }
450 COPY_4FV( mat->Ambient, src[0].Ambient );
451 }
452 if (bitmask & BACK_AMBIENT_BIT) {
453 struct gl_material *mat = &ctx->Light.Material[1];
454 SUB_3V( tmp, src[1].Ambient, mat->Ambient );
455 ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
456 foreach (light, list) {
457 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
458 }
459 COPY_4FV( mat->Ambient, src[1].Ambient );
460 }
461 if (bitmask & FRONT_DIFFUSE_BIT) {
462 struct gl_material *mat = &ctx->Light.Material[0];
463 SUB_3V( tmp, src[0].Diffuse, mat->Diffuse );
464 foreach (light, list) {
465 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
466 }
467 COPY_4FV( mat->Diffuse, src[0].Diffuse );
468 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
469 }
470 if (bitmask & BACK_DIFFUSE_BIT) {
471 struct gl_material *mat = &ctx->Light.Material[1];
472 SUB_3V( tmp, src[1].Diffuse, mat->Diffuse );
473 foreach (light, list) {
474 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
475 }
476 COPY_4FV( mat->Diffuse, src[1].Diffuse );
477 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
478 }
479 if (bitmask & FRONT_SPECULAR_BIT) {
480 struct gl_material *mat = &ctx->Light.Material[0];
481 SUB_3V( tmp, src[0].Specular, mat->Specular );
482 foreach (light, list) {
483 if (light->Flags & LIGHT_SPECULAR) {
484 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
485 light->IsMatSpecular[0] =
486 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
487 }
488 }
489 COPY_4FV( mat->Specular, src[0].Specular );
490 }
491 if (bitmask & BACK_SPECULAR_BIT) {
492 struct gl_material *mat = &ctx->Light.Material[1];
493 SUB_3V( tmp, src[1].Specular, mat->Specular );
494 foreach (light, list) {
495 if (light->Flags & LIGHT_SPECULAR) {
496 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
497 light->IsMatSpecular[1] =
498 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
499 }
500 }
501 COPY_4FV( mat->Specular, src[1].Specular );
502 }
503 if (bitmask & FRONT_EMISSION_BIT) {
504 struct gl_material *mat = &ctx->Light.Material[0];
505 SUB_3V( tmp, src[0].Emission, mat->Emission );
506 ACC_3V( ctx->Light.BaseColor[0], tmp );
507 COPY_4FV( mat->Emission, src[0].Emission );
508 }
509 if (bitmask & BACK_EMISSION_BIT) {
510 struct gl_material *mat = &ctx->Light.Material[1];
511 SUB_3V( tmp, src[1].Emission, mat->Emission );
512 ACC_3V( ctx->Light.BaseColor[1], tmp );
513 COPY_4FV( mat->Emission, src[1].Emission );
514 }
515 if (bitmask & FRONT_SHININESS_BIT) {
516 GLfloat shininess = ctx->Light.Material[0].Shininess = src[0].Shininess;
517 gl_compute_shine_table( ctx, 0, shininess );
518 gl_compute_shine_table( ctx, 2, shininess * .5 );
519 }
520 if (bitmask & BACK_SHININESS_BIT) {
521 GLfloat shininess = ctx->Light.Material[1].Shininess = src[1].Shininess;
522 gl_compute_shine_table( ctx, 1, shininess );
523 gl_compute_shine_table( ctx, 3, shininess * .5 );
524 }
525 if (bitmask & FRONT_INDEXES_BIT) {
526 ctx->Light.Material[0].AmbientIndex = src[0].AmbientIndex;
527 ctx->Light.Material[0].DiffuseIndex = src[0].DiffuseIndex;
528 ctx->Light.Material[0].SpecularIndex = src[0].SpecularIndex;
529 }
530 if (bitmask & BACK_INDEXES_BIT) {
531 ctx->Light.Material[1].AmbientIndex = src[1].AmbientIndex;
532 ctx->Light.Material[1].DiffuseIndex = src[1].DiffuseIndex;
533 ctx->Light.Material[1].SpecularIndex = src[1].SpecularIndex;
534 }
535
536 if (0)
537 {
538 struct gl_material *mat = &ctx->Light.Material[0];
539 fprintf(stderr, "update_mat emission : %f %f %f\n",
540 mat->Emission[0],
541 mat->Emission[1],
542 mat->Emission[2]);
543 fprintf(stderr, "update_mat specular : %f %f %f\n",
544 mat->Specular[0],
545 mat->Specular[1],
546 mat->Specular[2]);
547 fprintf(stderr, "update_mat diffuse : %f %f %f\n",
548 mat->Diffuse[0],
549 mat->Diffuse[1],
550 mat->Diffuse[2]);
551 fprintf(stderr, "update_mat ambient : %f %f %f\n",
552 mat->Ambient[0],
553 mat->Ambient[1],
554 mat->Ambient[2]);
555 }
556}
557
558
559
560
561
562
563void gl_update_color_material( GLcontext *ctx,
564 const GLubyte rgba[4] )
565{
566 struct gl_light *light, *list = &ctx->Light.EnabledList;
567 GLuint bitmask = ctx->Light.ColorMaterialBitmask;
568 GLfloat tmp[4], color[4];
569
570 UBYTE_RGBA_TO_FLOAT_RGBA( color, rgba );
571
572 if (MESA_VERBOSE&VERBOSE_IMMEDIATE)
573 fprintf(stderr, "gl_update_color_material, mask %x\n", bitmask);
574
575
576 if (bitmask & FRONT_AMBIENT_BIT) {
577 struct gl_material *mat = &ctx->Light.Material[0];
578 SUB_3V( tmp, color, mat->Ambient );
579 ACC_SCALE_3V( ctx->Light.BaseColor[0], ctx->Light.Model.Ambient, tmp);
580 foreach (light, list) {
581 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
582 }
583 COPY_4FV( mat->Ambient, color );
584 }
585
586 if (bitmask & BACK_AMBIENT_BIT) {
587 struct gl_material *mat = &ctx->Light.Material[1];
588 SUB_3V( tmp, color, mat->Ambient );
589 ACC_SCALE_3V( ctx->Light.BaseColor[1], ctx->Light.Model.Ambient, tmp);
590 foreach (light, list) {
591 ACC_SCALE_3V( ctx->Light.BaseColor[0], light->Ambient, tmp );
592 }
593 COPY_4FV( mat->Ambient, color );
594 }
595
596 if (bitmask & FRONT_DIFFUSE_BIT) {
597 struct gl_material *mat = &ctx->Light.Material[0];
598 SUB_3V( tmp, color, mat->Diffuse );
599 foreach (light, list) {
600 ACC_SCALE_3V( light->MatDiffuse[0], light->Diffuse, tmp );
601 }
602 COPY_4FV( mat->Diffuse, color );
603 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[0], mat->Diffuse[3]);
604 }
605
606 if (bitmask & BACK_DIFFUSE_BIT) {
607 struct gl_material *mat = &ctx->Light.Material[1];
608 SUB_3V( tmp, color, mat->Diffuse );
609 foreach (light, list) {
610 ACC_SCALE_3V( light->MatDiffuse[1], light->Diffuse, tmp );
611 }
612 COPY_4FV( mat->Diffuse, color );
613 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[1], mat->Diffuse[3]);
614 }
615
616 if (bitmask & FRONT_SPECULAR_BIT) {
617 struct gl_material *mat = &ctx->Light.Material[0];
618 SUB_3V( tmp, color, mat->Specular );
619 foreach (light, list) {
620 if (light->Flags & LIGHT_SPECULAR) {
621 ACC_SCALE_3V( light->MatSpecular[0], light->Specular, tmp );
622 light->IsMatSpecular[0] =
623 (LEN_SQUARED_3FV(light->MatSpecular[0]) > 1e-16);
624 }
625 }
626 COPY_4FV( mat->Specular, color );
627 }
628 if (bitmask & BACK_SPECULAR_BIT) {
629 struct gl_material *mat = &ctx->Light.Material[1];
630 SUB_3V( tmp, color, mat->Specular );
631 foreach (light, list) {
632 if (light->Flags & LIGHT_SPECULAR) {
633 ACC_SCALE_3V( light->MatSpecular[1], light->Specular, tmp );
634 light->IsMatSpecular[1] =
635 (LEN_SQUARED_3FV(light->MatSpecular[1]) > 1e-16);
636 }
637 }
638 COPY_4FV( mat->Specular, color );
639 }
640 if (bitmask & FRONT_EMISSION_BIT) {
641 struct gl_material *mat = &ctx->Light.Material[0];
642 SUB_3V( tmp, color, mat->Emission );
643 ACC_3V( ctx->Light.BaseColor[0], tmp );
644 COPY_4FV( mat->Emission, color );
645 }
646 if (bitmask & BACK_EMISSION_BIT) {
647 struct gl_material *mat = &ctx->Light.Material[1];
648 SUB_3V( tmp, color, mat->Emission );
649 ACC_3V( ctx->Light.BaseColor[1], tmp );
650 COPY_4FV( mat->Emission, color );
651 }
652
653 if (0)
654 {
655 struct gl_material *mat = &ctx->Light.Material[0];
656 fprintf(stderr, "update_color_mat emission : %f %f %f\n",
657 mat->Emission[0],
658 mat->Emission[1],
659 mat->Emission[2]);
660 fprintf(stderr, "update_color_mat specular : %f %f %f\n",
661 mat->Specular[0],
662 mat->Specular[1],
663 mat->Specular[2]);
664 fprintf(stderr, "update_color_mat diffuse : %f %f %f\n",
665 mat->Diffuse[0],
666 mat->Diffuse[1],
667 mat->Diffuse[2]);
668 fprintf(stderr, "update_color_mat ambient : %f %f %f\n",
669 mat->Ambient[0],
670 mat->Ambient[1],
671 mat->Ambient[2]);
672 }
673}
674
675
676
677
678void gl_ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode )
679{
680 GLuint bitmask;
681 GLuint legal = (FRONT_EMISSION_BIT | BACK_EMISSION_BIT |
682 FRONT_SPECULAR_BIT | BACK_SPECULAR_BIT |
683 FRONT_DIFFUSE_BIT | BACK_DIFFUSE_BIT |
684 FRONT_AMBIENT_BIT | BACK_AMBIENT_BIT);
685
686 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glColorMaterial");
687
688 if (MESA_VERBOSE&VERBOSE_API)
689 fprintf(stderr, "glColorMaterial %s %s\n",
690 gl_lookup_enum_by_nr(face),
691 gl_lookup_enum_by_nr(mode));
692
693 bitmask = gl_material_bitmask( ctx, face, mode, legal, "glColorMaterial" );
694
695 if (bitmask != 0) {
696 ctx->Light.ColorMaterialBitmask = bitmask;
697 ctx->Light.ColorMaterialFace = face;
698 ctx->Light.ColorMaterialMode = mode;
699 }
700
701 if (ctx->Light.ColorMaterialEnabled)
702 gl_update_color_material( ctx, ctx->Current.ByteColor );
703}
704
705
706
707/* KW: This is now called directly (ie by name) from the glMaterial*
708 * API functions.
709 */
710void gl_Materialfv( GLcontext *ctx,
711 GLenum face, GLenum pname, const GLfloat *params )
712{
713 struct immediate *IM;
714 struct gl_material *mat;
715 GLuint bitmask;
716 GLuint count;
717
718 bitmask = gl_material_bitmask( ctx, face, pname, ~0, "gl_Materialfv" );
719 if (bitmask == 0)
720 return;
721
722 IM = ctx->input;
723 count = IM->Count;
724
725 if (!IM->Material) {
726 IM->Material =
727 (struct gl_material (*)[2]) MALLOC( sizeof(struct gl_material) *
728 VB_SIZE * 2 );
729 IM->MaterialMask = (GLuint *) MALLOC( sizeof(GLuint) * VB_SIZE );
730 }
731
732
733 if (!(IM->Flag[count] & VERT_MATERIAL)) {
734 IM->Flag[count] |= VERT_MATERIAL;
735 IM->MaterialMask[count] = 0;
736 }
737
738 IM->MaterialMask[count] |= bitmask;
739 mat = IM->Material[count];
740
741 if (bitmask & FRONT_AMBIENT_BIT) {
742 COPY_4FV( mat[0].Ambient, params );
743 }
744 if (bitmask & BACK_AMBIENT_BIT) {
745 COPY_4FV( mat[1].Ambient, params );
746 }
747 if (bitmask & FRONT_DIFFUSE_BIT) {
748 COPY_4FV( mat[0].Diffuse, params );
749 }
750 if (bitmask & BACK_DIFFUSE_BIT) {
751 COPY_4FV( mat[1].Diffuse, params );
752 }
753 if (bitmask & FRONT_SPECULAR_BIT) {
754 COPY_4FV( mat[0].Specular, params );
755 }
756 if (bitmask & BACK_SPECULAR_BIT) {
757 COPY_4FV( mat[1].Specular, params );
758 }
759 if (bitmask & FRONT_EMISSION_BIT) {
760 COPY_4FV( mat[0].Emission, params );
761 }
762 if (bitmask & BACK_EMISSION_BIT) {
763 COPY_4FV( mat[1].Emission, params );
764 }
765 if (bitmask & FRONT_SHININESS_BIT) {
766 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
767 mat[0].Shininess = shininess;
768 }
769 if (bitmask & BACK_SHININESS_BIT) {
770 GLfloat shininess = CLAMP( params[0], 0.0F, 128.0F );
771 mat[1].Shininess = shininess;
772 }
773 if (bitmask & FRONT_INDEXES_BIT) {
774 mat[0].AmbientIndex = params[0];
775 mat[0].DiffuseIndex = params[1];
776 mat[0].SpecularIndex = params[2];
777 }
778 if (bitmask & BACK_INDEXES_BIT) {
779 mat[1].AmbientIndex = params[0];
780 mat[1].DiffuseIndex = params[1];
781 mat[1].SpecularIndex = params[2];
782 }
783}
784
785
786
787
788void gl_GetMaterialfv( GLcontext *ctx,
789 GLenum face, GLenum pname, GLfloat *params )
790{
791 GLuint f;
792
793 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialfv");
794
795 if (face==GL_FRONT) {
796 f = 0;
797 }
798 else if (face==GL_BACK) {
799 f = 1;
800 }
801 else {
802 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
803 return;
804 }
805 switch (pname) {
806 case GL_AMBIENT:
807 COPY_4FV( params, ctx->Light.Material[f].Ambient );
808 break;
809 case GL_DIFFUSE:
810 COPY_4FV( params, ctx->Light.Material[f].Diffuse );
811 break;
812 case GL_SPECULAR:
813 COPY_4FV( params, ctx->Light.Material[f].Specular );
814 break;
815 case GL_EMISSION:
816 COPY_4FV( params, ctx->Light.Material[f].Emission );
817 break;
818 case GL_SHININESS:
819 *params = ctx->Light.Material[f].Shininess;
820 break;
821 case GL_COLOR_INDEXES:
822 params[0] = ctx->Light.Material[f].AmbientIndex;
823 params[1] = ctx->Light.Material[f].DiffuseIndex;
824 params[2] = ctx->Light.Material[f].SpecularIndex;
825 break;
826 default:
827 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
828 }
829}
830
831
832
833void gl_GetMaterialiv( GLcontext *ctx,
834 GLenum face, GLenum pname, GLint *params )
835{
836 GLuint f;
837
838 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glGetMaterialiv");
839
840 if (face==GL_FRONT) {
841 f = 0;
842 }
843 else if (face==GL_BACK) {
844 f = 1;
845 }
846 else {
847 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
848 return;
849 }
850 switch (pname) {
851 case GL_AMBIENT:
852 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[0] );
853 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[1] );
854 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[2] );
855 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Ambient[3] );
856 break;
857 case GL_DIFFUSE:
858 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[0] );
859 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[1] );
860 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[2] );
861 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Diffuse[3] );
862 break;
863 case GL_SPECULAR:
864 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[0] );
865 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[1] );
866 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[2] );
867 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Specular[3] );
868 break;
869 case GL_EMISSION:
870 params[0] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[0] );
871 params[1] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[1] );
872 params[2] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[2] );
873 params[3] = FLOAT_TO_INT( ctx->Light.Material[f].Emission[3] );
874 break;
875 case GL_SHININESS:
876 *params = ROUNDF( ctx->Light.Material[f].Shininess );
877 break;
878 case GL_COLOR_INDEXES:
879 params[0] = ROUNDF( ctx->Light.Material[f].AmbientIndex );
880 params[1] = ROUNDF( ctx->Light.Material[f].DiffuseIndex );
881 params[2] = ROUNDF( ctx->Light.Material[f].SpecularIndex );
882 break;
883 default:
884 gl_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
885 }
886}
887
888
889
890
891/**********************************************************************/
892/***** Lighting computation *****/
893/**********************************************************************/
894
895
896/*
897 * Notes:
898 * When two-sided lighting is enabled we compute the color (or index)
899 * for both the front and back side of the primitive. Then, when the
900 * orientation of the facet is later learned, we can determine which
901 * color (or index) to use for rendering.
902 *
903 * KW: We now know orientation in advance and only shade for
904 * the side or sides which are actually required.
905 *
906 * Variables:
907 * n = normal vector
908 * V = vertex position
909 * P = light source position
910 * Pe = (0,0,0,1)
911 *
912 * Precomputed:
913 * IF P[3]==0 THEN
914 * // light at infinity
915 * IF local_viewer THEN
916 * VP_inf_norm = unit vector from V to P // Precompute
917 * ELSE
918 * // eye at infinity
919 * h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute
920 * ENDIF
921 * ENDIF
922 *
923 * Functions:
924 * Normalize( v ) = normalized vector v
925 * Magnitude( v ) = length of vector v
926 */
927
928
929
930/*
931 * Whenever the spotlight exponent for a light changes we must call
932 * this function to recompute the exponent lookup table.
933 */
934void gl_compute_spot_exp_table( struct gl_light *l )
935{
936 int i;
937 double exponent = l->SpotExponent;
938 double tmp = 0;
939 int clamp = 0;
940
941 l->SpotExpTable[0][0] = 0.0;
942
943 for (i=EXP_TABLE_SIZE-1;i>0;i--) {
944 if (clamp == 0) {
945 tmp = pow(i/(double)(EXP_TABLE_SIZE-1), exponent);
946 if (tmp < FLT_MIN*100.0) {
947 tmp = 0.0;
948 clamp = 1;
949 }
950 }
951 l->SpotExpTable[i][0] = tmp;
952 }
953 for (i=0;i<EXP_TABLE_SIZE-1;i++) {
954 l->SpotExpTable[i][1] = l->SpotExpTable[i+1][0] - l->SpotExpTable[i][0];
955 }
956 l->SpotExpTable[EXP_TABLE_SIZE-1][1] = 0.0;
957}
958
959
960
961
962/* Calculate a new shine table. Doing this here saves a branch in
963 * lighting, and the cost of doing it early may be partially offset
964 * by keeping a MRU cache of shine tables for various shine values.
965 */
966static void compute_shine_table( struct gl_shine_tab *tab, GLfloat shininess )
967{
968 int i;
969 GLfloat *m = tab->tab;
970
971 m[0] = 0;
972 if (shininess == 0) {
973 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++)
974 m[i] = 1;
975 } else {
976 for (i = 1 ; i <= SHINE_TABLE_SIZE ; i++) {
977 double t = pow( i/(GLfloat)SHINE_TABLE_SIZE, shininess );
978 m[i] = 0;
979 if (t > 1e-20) m[i] = t;
980 }
981 }
982
983 tab->shininess = shininess;
984}
985
986#define DISTSQR(a,b) ((a-b)*(a-b))
987
988void gl_compute_shine_table( GLcontext *ctx, GLuint i, GLfloat shininess )
989{
990 struct gl_shine_tab *list = ctx->ShineTabList;
991 struct gl_shine_tab *s;
992
993 foreach(s, list)
994 if ( DISTSQR(s->shininess, shininess) < 1e-4 )
995 break;
996
997 if (s == list)
998 {
999 foreach(s, list)
1000 if (s->refcount == 0) break;
1001
1002 compute_shine_table( s, shininess );
1003 }
1004
1005 ctx->ShineTable[i]->refcount--;
1006 ctx->ShineTable[i] = s;
1007 move_to_tail( list, s );
1008 s->refcount++;
1009}
1010
1011
1012
1013
1014void gl_reinit_light_attrib( GLcontext *ctx, struct gl_light_attrib *l )
1015{
1016 GLuint i;
1017
1018 if (ctx->ShineTable[0]->shininess != l->Material[0].Shininess) {
1019 gl_compute_shine_table( ctx, 0, l->Material[0].Shininess );
1020 gl_compute_shine_table( ctx, 2, l->Material[0].Shininess * .5 );
1021 }
1022
1023 if (ctx->ShineTable[1]->shininess != l->Material[1].Shininess) {
1024 gl_compute_shine_table( ctx, 1, l->Material[1].Shininess );
1025 gl_compute_shine_table( ctx, 3, l->Material[1].Shininess * .5 );
1026 }
1027
1028 make_empty_list( &l->EnabledList );
1029 for (i = 0 ; i < MAX_LIGHTS ; i++) {
1030 if (l->Light[i].Enabled)
1031 insert_at_tail( &l->EnabledList, &l->Light[i] );
1032 }
1033}
1034
1035
1036
1037/*
1038 * Examine current lighting parameters to determine if the optimized lighting
1039 * function can be used.
1040 * Also, precompute some lighting values such as the products of light
1041 * source and material ambient, diffuse and specular coefficients.
1042 */
1043void gl_update_lighting( GLcontext *ctx )
1044{
1045 struct gl_light *light;
1046
1047 ctx->Light.Flags = 0;
1048
1049 foreach(light, &ctx->Light.EnabledList) {
1050
1051 light->Flags = 0;
1052
1053 if (light->EyePosition[3] != 0.0F)
1054 light->Flags |= LIGHT_POSITIONAL;
1055
1056 if (LEN_SQUARED_3FV(light->Specular) > 1e-16)
1057 light->Flags |= LIGHT_SPECULAR;
1058
1059 if (light->SpotCutoff != 180.0F)
1060 light->Flags |= LIGHT_SPOT;
1061
1062 ctx->Light.Flags |= light->Flags;
1063 }
1064
1065 ctx->Light.NeedVertices =
1066 ((ctx->Light.Flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
1067 (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) ||
1068 (ctx->Light.Model.LocalViewer && (ctx->Light.Flags & LIGHT_SPECULAR)));
1069
1070
1071 /* Precompute some shading values.
1072 */
1073 if (ctx->Visual->RGBAflag)
1074 {
1075 GLuint sides = ((ctx->TriangleCaps & DD_TRI_LIGHT_TWOSIDE) ? 2 : 1);
1076 GLuint side;
1077 for (side=0; side < sides; side++) {
1078 struct gl_material *mat = &ctx->Light.Material[side];
1079
1080 COPY_3V(ctx->Light.BaseColor[side], mat->Emission);
1081 ACC_SCALE_3V(ctx->Light.BaseColor[side],
1082 ctx->Light.Model.Ambient,
1083 mat->Ambient);
1084
1085 FLOAT_COLOR_TO_UBYTE_COLOR(ctx->Light.BaseAlpha[side],
1086 ctx->Light.Material[side].Diffuse[3] );
1087 }
1088
1089 foreach (light, &ctx->Light.EnabledList) {
1090 for (side=0; side< sides; side++) {
1091 struct gl_material *mat = &ctx->Light.Material[side];
1092 SCALE_3V( light->MatDiffuse[side], light->Diffuse, mat->Diffuse );
1093 SCALE_3V( light->MatAmbient[side], light->Ambient, mat->Ambient );
1094 ACC_3V( ctx->Light.BaseColor[side], light->MatAmbient[side] );
1095 if (light->Flags & LIGHT_SPECULAR)
1096 {
1097 SCALE_3V( light->MatSpecular[side], light->Specular,
1098 mat->Specular);
1099 light->IsMatSpecular[side] =
1100 (LEN_SQUARED_3FV(light->MatSpecular[side]) > 1e-16);
1101 }
1102 else
1103 light->IsMatSpecular[side] = 0;
1104 }
1105 }
1106 }
1107 else
1108 {
1109 static GLfloat ci[3] = { .30, .59, .11 };
1110
1111 foreach(light, &ctx->Light.EnabledList) {
1112 light->dli = DOT3(ci, light->Diffuse);
1113 light->sli = DOT3(ci, light->Specular);
1114 }
1115 }
1116}
1117
1118/* Need to seriously restrict the circumstances under which these
1119 * calc's are performed.
1120 */
1121void gl_compute_light_positions( GLcontext *ctx )
1122{
1123 struct gl_light *light;
1124
1125 if (ctx->Light.NeedVertices && !ctx->Light.Model.LocalViewer) {
1126 GLfloat eye_z[3] = { 0, 0, 1 };
1127 if (!ctx->NeedEyeCoords) {
1128 TRANSFORM_NORMAL( ctx->EyeZDir, eye_z, ctx->ModelView.m );
1129 } else {
1130 COPY_3V( ctx->EyeZDir, eye_z );
1131 }
1132 }
1133
1134 foreach (light, &ctx->Light.EnabledList) {
1135
1136 if (!ctx->NeedEyeCoords) {
1137 TRANSFORM_POINT( light->Position, ctx->ModelView.inv,
1138 light->EyePosition );
1139 } else {
1140 COPY_4FV( light->Position, light->EyePosition );
1141 }
1142
1143 if (!(light->Flags & LIGHT_POSITIONAL))
1144 {
1145 /* VP (VP) = Normalize( Position ) */
1146 COPY_3V( light->VP_inf_norm, light->Position );
1147 NORMALIZE_3FV( light->VP_inf_norm );
1148
1149 if (!ctx->Light.Model.LocalViewer)
1150 {
1151 /* h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1152 ADD_3V( light->h_inf_norm, light->VP_inf_norm, ctx->EyeZDir);
1153 NORMALIZE_3FV( light->h_inf_norm );
1154 }
1155
1156 light->VP_inf_spot_attenuation = 1.0;
1157 }
1158
1159 if (light->Flags & LIGHT_SPOT)
1160 {
1161 if (ctx->NeedEyeNormals) {
1162 COPY_3V( light->NormDirection, light->EyeDirection );
1163 } else {
1164 TRANSFORM_NORMAL( light->NormDirection,
1165 light->EyeDirection,
1166 ctx->ModelView.m);
1167 }
1168
1169 NORMALIZE_3FV( light->NormDirection );
1170
1171
1172 /* Unlikely occurrance?
1173 */
1174 if (!(light->Flags & LIGHT_POSITIONAL)) {
1175 GLfloat PV_dot_dir = - DOT3(light->VP_inf_norm,
1176 light->NormDirection);
1177
1178 if (PV_dot_dir > light->CosCutoff) {
1179 double x = PV_dot_dir * (EXP_TABLE_SIZE-1);
1180 int k = (int) x;
1181 light->VP_inf_spot_attenuation =
1182 (light->SpotExpTable[k][0] +
1183 (x-k)*light->SpotExpTable[k][1]);
1184 }
1185 else
1186 light->VP_inf_spot_attenuation = 0;
1187 }
1188 }
1189 }
1190}
1191
1192
1193
1194
1195
1196void gl_update_normal_transform( GLcontext *ctx )
1197{
1198 GLuint new_flag = 0;
1199 normal_func *last = ctx->NormalTransform;
1200
1201 ctx->vb_rescale_factor = 1.0;
1202
1203 if (ctx->NeedEyeCoords) {
1204 if (ctx->NeedNormals) {
1205 GLuint transform = NORM_TRANSFORM_NO_ROT;
1206
1207 if (ctx->ModelView.flags & (MAT_FLAG_GENERAL |
1208 MAT_FLAG_ROTATION |
1209 MAT_FLAG_GENERAL_3D |
1210 MAT_FLAG_PERSPECTIVE))
1211 transform = NORM_TRANSFORM;
1212
1213
1214 new_flag = ctx->NewState & NEW_MODELVIEW;
1215 ctx->vb_rescale_factor = ctx->rescale_factor;
1216
1217 if (ctx->Transform.Normalize)
1218 {
1219 ctx->NormalTransform = gl_normal_tab[transform | NORM_NORMALIZE];
1220 }
1221 else if (ctx->Transform.RescaleNormals &&
1222 ctx->rescale_factor != 1.0)
1223 {
1224 ctx->NormalTransform = gl_normal_tab[transform | NORM_RESCALE];
1225 }
1226 else
1227 {
1228 ctx->NormalTransform = gl_normal_tab[transform];
1229 }
1230 } else {
1231 ctx->NormalTransform = 0;
1232 }
1233 }
1234 else {
1235 if (ctx->NeedNormals) {
1236 ctx->vb_rescale_factor = 1.0/ctx->rescale_factor;
1237
1238 if (ctx->Transform.Normalize)
1239 {
1240 ctx->NormalTransform = gl_normal_tab[NORM_NORMALIZE];
1241 }
1242 else if (!ctx->Transform.RescaleNormals &&
1243 ctx->rescale_factor != 1.0)
1244 {
1245 ctx->NormalTransform = gl_normal_tab[NORM_RESCALE];
1246 }
1247 else
1248 {
1249 ctx->NormalTransform = 0;
1250 }
1251 } else {
1252 ctx->NormalTransform = 0;
1253 }
1254 }
1255
1256 if (last != ctx->NormalTransform || new_flag)
1257 ctx->NewState |= NEW_NORMAL_TRANSFORM;
1258}
1259
Note: See TracBrowser for help on using the repository browser.