t_vb_lighttmp.h revision b305028464f02947c0cce0476af0e35f4ed1fafa
1d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu/*
28958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Mesa 3-D graphics library
38958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Version:  5.1
48958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu *
58958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Copyright (C) 1999-2003  Brian Paul   All Rights Reserved.
68958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu *
78958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Permission is hereby granted, free of charge, to any person obtaining a
88958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * copy of this software and associated documentation files (the "Software"),
98958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * to deal in the Software without restriction, including without limitation
10d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11d02174c1f22974a1f0e2334e393f8345c6d11302Zhongxing Xu * and/or sell copies of the Software, and to permit persons to whom the
128958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Software is furnished to do so, subject to the following conditions:
138958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu *
148958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * The above copyright notice and this permission notice shall be included
15d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * in all copies or substantial portions of the Software.
1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth *
1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19ec8605f1d7ec846dbf51047bfd5c56d32d1ff91cArgyrios Kyrtzidis * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21f540c54701e3eeb34cb619a3a4eb18f1ac70ef2dJordan Rose * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer *
24a93d0f280693b8418bc88cf7a8c93325f7fcf4c6Benjamin Kramer *
258958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu * Authors:
268958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu *    Brian Paul
279ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenek *    Keith Whitwell <keith@tungstengraphics.com>
288958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu */
29f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if (IDX & LIGHT_TWOSIDE)
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#  define NR_SIDES 2
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#  define NR_SIDES 1
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/* define TRACE to trace lighting code */
39ba5fb5a955c896815c439289fc51c03cf0635129Kovarththanan Rajaratnam/* #define TRACE 1 */
40fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
41fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose/*
42fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose * ctx is the current context
43fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose * VB is the vertex buffer
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * stage is the lighting stage-private data
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines * input is the vector of eye or object-space vertex coordinates
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines */
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstatic void TAG(light_rgba_spec)( GLcontext *ctx,
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				  struct vertex_buffer *VB,
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				  struct tnl_pipeline_stage *stage,
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				  GLvector4f *input )
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines{
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   GLfloat (*base)[3] = ctx->Light._BaseColor;
54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   GLfloat sumA[2];
55651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   GLuint j;
56651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
57f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek   const GLuint vstride = input->stride;
58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   const GLfloat *vertex = (GLfloat *)input->data;
59fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   const GLuint nstride = VB->NormalPtr->stride;
60d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis   const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
61fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
62de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
63fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose   GLfloat (*Fspec)[4] = (GLfloat (*)[4]) store->LitSecondary[0].data;
64fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE
65c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
66651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   GLfloat (*Bspec)[4] = (GLfloat (*)[4]) store->LitSecondary[1].data;
67651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   const GLuint nr = VB->Count;
70651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
718133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   (void) nstride;
729da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose   (void) vstride;
73de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose
74d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis#ifdef TRACE
75091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek   fprintf(stderr, "%s\n", __FUNCTION__ );
7618c66fdc3c4008d335885695fe36fb5353c5f672Ted Kremenek#endif
778bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek
78de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   VB->ColorPtr[0] = &store->LitColor[0];
79091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek   VB->SecondaryColorPtr[0] = &store->LitSecondary[0];
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
818133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE
83091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek   VB->ColorPtr[1] = &store->LitColor[1];
84651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   VB->SecondaryColorPtr[1] = &store->LitSecondary[1];
85651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
86651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
87651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
88f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek   /* Side-effects done, can we finish now?
89f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek    */
90f493f49fae3ab242ae055ae00b24fa5512655e15Ted Kremenek   if (stage->changed_inputs == 0)
919da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose      return;
929da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose
93d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek   for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
94c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek      GLfloat sum[2][3], spec[2][3];
95c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek      struct gl_light *light;
96091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek
97e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks#if IDX & LIGHT_MATERIAL
989da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose      update_materials( ctx, store );
999da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose      sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
10044ec3f00e64199667edf9f12c0f31f66916c95feJordan Rose#if IDX & LIGHT_TWOSIDE
10144ec3f00e64199667edf9f12c0f31f66916c95feJordan Rose      sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
102a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose#endif
1039da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose#endif
104785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose
105c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek      COPY_3V(sum[0], base[0]);
106c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek      ZERO_3V(spec[0]);
107da88536ed2c2755873a0db72656e443b95068d45Benjamin Kramer
108da88536ed2c2755873a0db72656e443b95068d45Benjamin Kramer#if IDX & LIGHT_TWOSIDE
1098919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose      COPY_3V(sum[1], base[1]);
1108919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose      ZERO_3V(spec[1]);
1118919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#endif
1128919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
1138919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose      /* Add contribution from each enabled light source */
1148919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose      foreach (light, &ctx->Light.EnabledList) {
1158919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat n_dot_h;
1168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat correction;
1178919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLint side;
1188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat contrib[3];
1198919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat attenuation;
1208919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat VP[3];  /* unit vector from vertex to light */
1218919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat n_dot_VP;       /* n dot VP */
1228919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 GLfloat *h;
1238919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
1248919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 /* compute VP and attenuation */
1258919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1268919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	    /* directional light */
1278919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	    COPY_3V(VP, light->_VP_inf_norm);
1288919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	    attenuation = light->_VP_inf_spot_attenuation;
1298919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 }
1308919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 else {
1318919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	    GLfloat d;     /* distance from vertex to light */
132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
133651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    SUB_3V(VP, light->_Position, vertex);
134651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    d = (GLfloat) LEN_3FV( VP );
136651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
137651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    if (d > 1e-6) {
138651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       GLfloat invd = 1.0F / d;
139651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       SELF_SCALE_SCALAR_3V(VP, invd);
140651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    }
141651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
142651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    attenuation = 1.0F / (light->ConstantAttenuation + d *
143651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				  (light->LinearAttenuation + d *
144651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				   light->QuadraticAttenuation));
145651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    /* spotlight attenuation */
147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    if (light->_Flags & LIGHT_SPOT) {
148651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
149651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
150651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       if (PV_dot_dir<light->_CosCutoff) {
151651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  continue; /* this light makes no contribution */
152651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       }
153651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       else {
154651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
155651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  GLint k = (GLint) x;
156651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines				    + (x-k)*light->_SpotExpTable[k][1]);
158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  attenuation *= spot;
159651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       }
160651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    }
161651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 }
162651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
163651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 if (attenuation < 1e-3)
164651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    continue;		/* this light makes no contribution */
165651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 /* Compute dot product or normal and vector from V to light pos */
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 n_dot_VP = DOT3( normal, VP );
168651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
169651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 /* Which side gets the diffuse & specular terms? */
170651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 if (n_dot_VP < 0.0F) {
171651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
172651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE
173651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    side = 1;
174651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    correction = -1;
175651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    n_dot_VP = -n_dot_VP;
176651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else
177651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            continue;
178651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
179651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 }
1808133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek         else {
181651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE
182651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
183651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
1848919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	    side = 0;
185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    correction = 1;
1868919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 }
187651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 /* diffuse term */
189651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 COPY_3V(contrib, light->_MatAmbient[side]);
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 ACC_SCALE_SCALAR_3V(sum[side], attenuation, contrib );
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 /* specular term - cannibalize VP... */
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 if (ctx->Light.Model.LocalViewer) {
1958133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    GLfloat v[3];
196d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek	    COPY_3V(v, vertex);
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    NORMALIZE_3FV(v);
1988133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    SUB_3V(VP, VP, v);                /* h = VP + VPe */
1998133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    h = VP;
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    NORMALIZE_3FV(h);
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 }
2028919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 else if (light->_Flags & LIGHT_POSITIONAL) {
203651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    h = VP;
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    ACC_3V(h, ctx->_EyeZDir);
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    NORMALIZE_3FV(h);
206785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose	 }
2078133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek         else {
2088133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    h = light->_h_inf_norm;
2098133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	 }
2108133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 n_dot_h = correction * DOT3(normal, h);
212e4d653b5a4cba281502177f6ef03d43e3ebb2b6aTed Kremenek
2135251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie	 if (n_dot_h > 0.0F) {
214dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie	    GLfloat spec_coef;
2155251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie	    struct gl_shine_tab *tab = ctx->_ShineTable[side];
2168133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
2178133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2188133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    if (spec_coef > 1.0e-10) {
2195f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner	       spec_coef *= attenuation;
2208133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	       ACC_SCALE_SCALAR_3V( spec[side], spec_coef,
2218133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek				    light->_MatSpecular[side]);
2228133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	    }
2238133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	 }
2248133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      } /*loop over lights*/
225facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer
2268133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      COPY_3V( Fcolor[j], sum[0] );
227facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer      COPY_3V( Fspec[j], spec[0] );
2288133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      Fcolor[j][3] = sumA[0];
2299697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek
230018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu#if IDX & LIGHT_TWOSIDE
2318133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      COPY_3V( Bcolor[j], sum[1] );
2328133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      COPY_3V( Bspec[j], spec[1] );
2338133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      Bcolor[j][3] = sumA[1];
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   }
236651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
237262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie
2388133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2398133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenekstatic void TAG(light_rgba)( GLcontext *ctx,
2408133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek			     struct vertex_buffer *VB,
2418133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek			     struct tnl_pipeline_stage *stage,
2428133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek			     GLvector4f *input )
2431437425a62dbf7bdb0a855d3ed3b05ed2019ec1eAnna Zaks{
2448133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
2458133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   GLuint j;
2468133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2478133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   GLfloat (*base)[3] = ctx->Light._BaseColor;
2488133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   GLfloat sumA[2];
2498133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2508133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   const GLuint vstride = input->stride;
2518133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   const GLfloat *vertex = (GLfloat *) input->data;
2528133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   const GLuint nstride = VB->NormalPtr->stride;
2538133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
2548133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2558133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
256facde171ae4b8926622a1bffa833732a06f1875bBenjamin Kramer   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
257c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek   GLfloat (*color[2])[4];
2588133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2598133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   const GLuint nr = VB->Count;
2608133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
261d048c6ef5b6cfaa0cecb8cc1d4bdace32ed21d07Ted Kremenek#ifdef TRACE
262651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   fprintf(stderr, "%s\n", __FUNCTION__ );
263f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith#endif
2648133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2658133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   (void) nstride;
2668133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   (void) vstride;
2678133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
268b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer   color[0] = Fcolor;
2698133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   color[1] = Bcolor;
2708133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2718133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   VB->ColorPtr[0] = &store->LitColor[0];
2725f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
2738133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2748133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#if IDX & LIGHT_TWOSIDE
2758133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   VB->ColorPtr[1] = &store->LitColor[1];
2768133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
2778133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#endif
278b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer
2798133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   if (stage->changed_inputs == 0)
2808133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      return;
2818133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2828133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek   for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
2838133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      GLfloat sum[2][3];
284e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks      struct gl_light *light;
285651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
2868133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      if ( IDX & LIGHT_MATERIAL ) {
2878133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	 update_materials( ctx, store );
2888133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
289785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose#if IDX & LIGHT_TWOSIDE
2908133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek         sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
2918133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek#endif
2928133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      }
2938133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2948133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      COPY_3V(sum[0], base[0]);
2958133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek
2968133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek      if ( IDX & LIGHT_TWOSIDE )
2978133716fc5cf705308c36aa6b0e7e4be2ac2ccdcTed Kremenek	 COPY_3V(sum[1], base[1]);
298d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis
299d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis      /* Add contribution from each enabled light source */
300091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek      foreach (light, &ctx->Light.EnabledList) {
301c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek
30255037cdc2e29b70df2fd1ca0ba9d4c36da1049e8Jordan Rose	 GLfloat n_dot_h;
3035eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek	 GLfloat correction;
30455037cdc2e29b70df2fd1ca0ba9d4c36da1049e8Jordan Rose	 GLint side;
305091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek	 GLfloat contrib[3];
306c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek	 GLfloat attenuation = 1.0;
307c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek	 GLfloat VP[3];          /* unit vector from vertex to light */
308651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 GLfloat n_dot_VP;       /* n dot VP */
309651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 GLfloat *h;
3109da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose
311c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek	 /* compute VP and attenuation */
312c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
313091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek	    /* directional light */
314a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose	    COPY_3V(VP, light->_VP_inf_norm);
315651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    attenuation = light->_VP_inf_spot_attenuation;
316a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose	 }
317a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose	 else {
318c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek	    GLfloat d;     /* distance from vertex to light */
319651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
320651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3219da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose	    SUB_3V(VP, light->_Position, vertex);
3227453624b98817f06d28ed2abe39c98805cfec623Jordan Rose
323091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek	    d = (GLfloat) LEN_3FV( VP );
3247f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose
3257f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose	    if ( d > 1e-6) {
326fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	       GLfloat invd = 1.0F / d;
327091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek	       SELF_SCALE_SCALAR_3V(VP, invd);
328fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	    }
329fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
330fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose            attenuation = 1.0F / (light->ConstantAttenuation + d *
331fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose                                  (light->LinearAttenuation + d *
332fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose                                   light->QuadraticAttenuation));
333fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
334fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	    /* spotlight attenuation */
335fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	    if (light->_Flags & LIGHT_SPOT) {
336fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	       GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
337fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
338651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       if (PV_dot_dir<light->_CosCutoff) {
339651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines		  continue; /* this light makes no contribution */
340fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	       }
341fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	       else {
342fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose		  GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
343fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose		  GLint k = (GLint) x;
344fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose		  GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
345fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose				  + (x-k)*light->_SpotExpTable[k][1]);
346fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose		  attenuation *= spot;
347fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	       }
348fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	    }
349fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	 }
350fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose
351fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	 if (attenuation < 1e-3)
352fa220f58f02014e4a3389f429b82948a09dc4986Jordan Rose	    continue;		/* this light makes no contribution */
353fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose
354fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	 /* Compute dot product or normal and vector from V to light pos */
3557f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose	 n_dot_VP = DOT3( normal, VP );
3567f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose
357fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 /* which side are we lighting? */
358fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 if (n_dot_VP < 0.0F) {
3599da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose	    ACC_SCALE_SCALAR_3V(sum[0], attenuation, light->_MatAmbient[0]);
360fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek#if IDX & LIGHT_TWOSIDE
361fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	    side = 1;
362fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	    correction = -1;
363651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    n_dot_VP = -n_dot_VP;
364651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#else
3659da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose            continue;
366fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek#endif
367fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 }
368a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose         else {
369a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose#if IDX & LIGHT_TWOSIDE
370651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            ACC_SCALE_SCALAR_3V( sum[1], attenuation, light->_MatAmbient[1]);
3715251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie#endif
372a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose	    side = 0;
373a8695180217806bb421cfc6700bec76fc0b1ae56Jordan Rose	    correction = 1;
374fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 }
375651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
376651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 COPY_3V(contrib, light->_MatAmbient[side]);
3779da59a67a27a4d3fc9d59552f07808a32f85e9d3Jordan Rose
378fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 /* diffuse term */
379fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 ACC_SCALE_SCALAR_3V(contrib, n_dot_VP, light->_MatDiffuse[side]);
3807f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose
3817f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose	 /* specular term - cannibalize VP... */
382fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	 {
383fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek	    if (ctx->Light.Model.LocalViewer) {
38437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       GLfloat v[3];
385651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       COPY_3V(v, vertex);
386651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       NORMALIZE_3FV(v);
38737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       SUB_3V(VP, VP, v);                /* h = VP + VPe */
38837926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       h = VP;
38937926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       NORMALIZE_3FV(h);
39037926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    }
39137926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    else if (light->_Flags & LIGHT_POSITIONAL) {
39237926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       h = VP;
39337926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       ACC_3V(h, ctx->_EyeZDir);
39437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       NORMALIZE_3FV(h);
39537926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    }
39637926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath            else {
39737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       h = light->_h_inf_norm;
39837926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    }
39937926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath
40037926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    n_dot_h = correction * DOT3(normal, h);
40137926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath
40237926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    if (n_dot_h > 0.0F)
40337926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	    {
40437926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       GLfloat spec_coef;
40537926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       struct gl_shine_tab *tab = ctx->_ShineTable[side];
40637926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath
40737926da411d5a0047240b3ffd4dad0c4838aac57Pavel Labath	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef );
408fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose
409fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	       ACC_SCALE_SCALAR_3V( contrib, spec_coef,
410fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose				    light->_MatSpecular[side]);
411fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	    }
412fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	 }
413fc999ac663eca933359047c88dc4a1ef6e579e8aTed Kremenek
414fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose	 ACC_SCALE_SCALAR_3V( sum[side], attenuation, contrib );
415651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
4168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
417fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose      COPY_3V( Fcolor[j], sum[0] );
4188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose      Fcolor[j][3] = sumA[0];
419fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose
420fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose#if IDX & LIGHT_TWOSIDE
421651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      COPY_3V( Bcolor[j], sum[1] );
4226bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Bcolor[j][3] = sumA[1];
423651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
424651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   }
4258919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose}
4268919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
427651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
428fe6a011a113b3ddcb32f42af152d7476054e7f79Jordan Rose
429651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
4307f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose/* As below, but with just a single light.
4317f660857309a14c036a80ef90b40bf8f68fda9daJordan Rose */
4327f660857309a14c036a80ef90b40bf8f68fda9daJordan Rosestatic void TAG(light_fast_rgba_single)( GLcontext *ctx,
43364fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek					 struct vertex_buffer *VB,
43464fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek					 struct tnl_pipeline_stage *stage,
435de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose					 GLvector4f *input )
436d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis
437de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose{
438de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
439de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   const GLuint nstride = VB->NormalPtr->stride;
4406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines   const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
4418919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
4428919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE
443de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
444651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
445651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   const struct gl_light *light = ctx->Light.EnabledList.next;
446de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   GLuint j = 0;
447de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   GLfloat base[2][3];
4488919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   const GLuint nr = VB->Count;
4498919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
4508919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#ifdef TRACE
451651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   fprintf(stderr, "%s\n", __FUNCTION__ );
452651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
4538919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
4548919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   (void) input;		/* doesn't refer to Eye or Obj */
4558919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   (void) nr;
4568919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   (void) nstride;
457651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
458651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   VB->ColorPtr[0] = &store->LitColor[0];
4598919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE
4608919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   VB->ColorPtr[1] = &store->LitColor[1];
461de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif
4628919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
4638919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   if (stage->changed_inputs == 0)
464de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose      return;
4658919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
4668919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose   for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
46764fa85855638d69e56ed1b2fad7ed65deb3ecdfdTed Kremenek
468de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose      GLfloat n_dot_VP;
4698919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose
470a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose      if ( IDX & LIGHT_MATERIAL )
471785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose	 update_materials( ctx, store );
472de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose
473de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose      /* No attenuation, so incoporate _MatAmbient into base color.
474de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose       */
475de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose      if ( j == 0 || (IDX & LIGHT_MATERIAL) ) {
4765251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie	 COPY_3V(base[0], light->_MatAmbient[0]);
477de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose	 ACC_3V(base[0], ctx->Light._BaseColor[0] );
478de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose	 base[0][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
479de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose
480651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#if IDX & LIGHT_TWOSIDE
481de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose         COPY_3V(base[1], light->_MatAmbient[1]);
482de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose         ACC_3V(base[1], ctx->Light._BaseColor[1]);
483de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose         base[1][3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
484de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif
485c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek      }
486c79d7d49c5ec42e8bb6ac34350ebb5bc24ca663dTed Kremenek
487d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis      n_dot_VP = DOT3(normal, light->_VP_inf_norm);
488a46e4d91d8f3eb341f2387768db66dcfe8dd0afaZhongxing Xu
4892055effed54d614b51e3501a174c9b1fe92e4de4Zhongxing Xu      if (n_dot_VP < 0.0F) {
490c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek#if IDX & LIGHT_TWOSIDE
491de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose         GLfloat n_dot_h = -DOT3(normal, light->_h_inf_norm);
492d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis         GLfloat sum[3];
493091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek         COPY_3V(sum, base[1]);
494fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek         ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]);
495d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis         if (n_dot_h > 0.0F) {
496651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines            GLfloat spec;
497091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek            GET_SHINE_TAB_ENTRY( ctx->_ShineTable[1], n_dot_h, spec );
4988919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose            ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]);
4998919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose         }
500841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks         COPY_3V(Bcolor[j], sum );
501841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks         Bcolor[j][3] = base[1][3];
502f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith#endif
503fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek	 COPY_4FV(Fcolor[j], base[0]);
504651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      }
505651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      else {
506651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 GLfloat n_dot_h = DOT3(normal, light->_h_inf_norm);
507841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	 GLfloat sum[3];
508841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	 COPY_3V(sum, base[0]);
509841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	 ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]);
510841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	 if (n_dot_h > 0.0F) {
511841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	    GLfloat spec;
512841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	    GET_SHINE_TAB_ENTRY( ctx->_ShineTable[0], n_dot_h, spec );
513841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks	    ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]);
514091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek
515e172e8b9e7fc67d7d03589af7e92fe777afcf33aAnna Zaks	 }
5168919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose	 COPY_3V(Fcolor[j], sum );
517de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose	 Fcolor[j][3] = base[0][3];
5188919e688dc610d1f632a4d43f7f1489f67255476Jordan Rose#if IDX & LIGHT_TWOSIDE
519a1f81bb0e55749a1414b1b5124bb83b9052ff2acJordan Rose         COPY_4FV(Bcolor[j], base[1]);
52004badcf84c8d504d8491c7c7e29b58f52cb16640Douglas Gregor#endif
521785950e59424dca7ce0081bebf13c0acd2c4fff6Jordan Rose      }
522fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   }
523fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek}
524c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek
5258f1e65617844d315dd19b6cf9bfc437fd4902ed8Bob Wilson
52657b1da1588a3f5785ad8bd5d9f2d795d685e1058Cameron Esfahani/* Light infinite lights
527f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek */
528f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenekstatic void TAG(light_fast_rgba)( GLcontext *ctx,
529fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek				  struct vertex_buffer *VB,
5308bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek				  struct tnl_pipeline_stage *stage,
531de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose				  GLvector4f *input )
532432424d67641d609e4990d791baa782fc161027eArgyrios Kyrtzidis{
533651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
534091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek   GLfloat sumA[2];
535fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   const GLuint nstride = VB->NormalPtr->stride;
536fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
537de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   GLfloat (*Fcolor)[4] = (GLfloat (*)[4]) store->LitColor[0].data;
538f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek#if IDX & LIGHT_TWOSIDE
5395eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek   GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
540fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif
541fb87b89fc9eb103e19fb8e4b925c23f0bd091b99Douglas Gregor   GLuint j = 0;
5424a037c70fdaefafb9c635fedb7035ad462a2742cTed Kremenek   const GLuint nr = VB->Count;
543de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   const struct gl_light *light;
5444a49df3be929d442535d6721ab8a2bbc8a7cd528Anna Zaks
545fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#ifdef TRACE
546fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   fprintf(stderr, "%s %d\n", __FUNCTION__, nr );
547fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif
5484a037c70fdaefafb9c635fedb7035ad462a2742cTed Kremenek
549a2a860306e3697fcf7a12c5ba59551ca60578968Anna Zaks   (void) input;
550de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   (void) nr;
551fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   (void) nstride;
552091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek
553f81330c741e0f70b227f113d2e5a84948d1a5752Ted Kremenek   sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
554fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek   sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
555841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks
556841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks   VB->ColorPtr[0] = &store->LitColor[0];
557841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks#if IDX & LIGHT_TWOSIDE
558841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks   VB->ColorPtr[1] = &store->LitColor[1];
559841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks#endif
560841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks
561841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks   if (stage->changed_inputs == 0)
562841f16846e17f625874ecfe9c6dba822d29a2b95Anna Zaks      return;
5636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
564de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose   for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
565fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
566fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      GLfloat sum[2][3];
567fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
568fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      if ( IDX & LIGHT_MATERIAL ) {
569fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek	 update_materials( ctx, store );
570fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
571fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek	 sumA[0] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3];
572fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE
573fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek         sumA[1] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3];
574fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#endif
575fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      }
576fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
577fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek
578fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      COPY_3V(sum[0], ctx->Light._BaseColor[0]);
579fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek#if IDX & LIGHT_TWOSIDE
580fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      COPY_3V(sum[1], ctx->Light._BaseColor[1]);
581de507eaf3cb54d3cb234dc14499c10ab3373d15fJordan Rose#endif
5824a49df3be929d442535d6721ab8a2bbc8a7cd528Anna Zaks
583fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek      foreach (light, &ctx->Light.EnabledList) {
584fee96e043108b6e24e7d4c5464bf89ac970a7f81Ted Kremenek	 GLfloat n_dot_h, n_dot_VP, spec;
585091b588f09401f2ec20cabffe57d9e09962970abTed Kremenek
5860bd6b110e908892d4b5c8671a9f435a1d72ad16aAnna Zaks	 ACC_3V(sum[0], light->_MatAmbient[0]);
5878958fff8aad09f317a51b2d4cda3d7b126a530a4Zhongxing Xu#if IDX & LIGHT_TWOSIDE
588d84f422ebfde2145bce79a8fa823e3393b392994Argyrios Kyrtzidis         ACC_3V(sum[1], light->_MatAmbient[1]);
589651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#endif
590651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
591651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 n_dot_VP = DOT3(normal, light->_VP_inf_norm);
592651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
593651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	 if (n_dot_VP > 0.0F) {
594651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]);
595651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    n_dot_h = DOT3(normal, light->_h_inf_norm);
596651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	    if (n_dot_h > 0.0F) {
597651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       struct gl_shine_tab *tab = ctx->_ShineTable[0];
598651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
599	       ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]);
600	    }
601	 }
602#if IDX & LIGHT_TWOSIDE
603         else {
604	    ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]);
605	    n_dot_h = -DOT3(normal, light->_h_inf_norm);
606	    if (n_dot_h > 0.0F) {
607	       struct gl_shine_tab *tab = ctx->_ShineTable[1];
608	       GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec );
609	       ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]);
610	    }
611	 }
612#endif
613      }
614
615      COPY_3V( Fcolor[j], sum[0] );
616      Fcolor[j][3] = sumA[0];
617
618#if IDX & LIGHT_TWOSIDE
619      COPY_3V( Bcolor[j], sum[1] );
620      Bcolor[j][3] = sumA[1];
621#endif
622   }
623}
624
625
626
627
628
629/*
630 * Use current lighting/material settings to compute the color indexes
631 * for an array of vertices.
632 * Input:  n - number of vertices to light
633 *         side - 0=use front material, 1=use back material
634 *         vertex - array of [n] vertex position in eye coordinates
635 *         normal - array of [n] surface normal vector
636 * Output:  indexResult - resulting array of [n] color indexes
637 */
638static void TAG(light_ci)( GLcontext *ctx,
639			   struct vertex_buffer *VB,
640			   struct tnl_pipeline_stage *stage,
641			   GLvector4f *input )
642{
643   struct light_stage_data *store = LIGHT_STAGE_DATA(stage);
644   GLuint j;
645   const GLuint vstride = input->stride;
646   const GLfloat *vertex = (GLfloat *) input->data;
647   const GLuint nstride = VB->NormalPtr->stride;
648   const GLfloat *normal = (GLfloat *)VB->NormalPtr->data;
649   GLfloat *indexResult[2];
650   const GLuint nr = VB->Count;
651
652#ifdef TRACE
653   fprintf(stderr, "%s\n", __FUNCTION__ );
654#endif
655
656   (void) nstride;
657   (void) vstride;
658
659   VB->IndexPtr[0] = &store->LitIndex[0];
660#if IDX & LIGHT_TWOSIDE
661   VB->IndexPtr[1] = &store->LitIndex[1];
662#endif
663
664   if (stage->changed_inputs == 0)
665      return;
666
667   indexResult[0] = (GLfloat *)VB->IndexPtr[0]->data;
668#if IDX & LIGHT_TWOSIDE
669   indexResult[1] = (GLfloat *)VB->IndexPtr[1]->data;
670#endif
671
672   /* loop over vertices */
673   for (j=0; j<nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal, nstride)) {
674      GLfloat diffuse[2], specular[2];
675      GLuint side = 0;
676      struct gl_light *light;
677
678      if ( IDX & LIGHT_MATERIAL )
679	 update_materials( ctx, store );
680
681      diffuse[0] = specular[0] = 0.0F;
682
683      if ( IDX & LIGHT_TWOSIDE ) {
684	 diffuse[1] = specular[1] = 0.0F;
685      }
686
687      /* Accumulate diffuse and specular from each light source */
688      foreach (light, &ctx->Light.EnabledList) {
689
690	 GLfloat attenuation = 1.0F;
691	 GLfloat VP[3];  /* unit vector from vertex to light */
692	 GLfloat n_dot_VP;  /* dot product of l and n */
693	 GLfloat *h, n_dot_h, correction = 1.0;
694
695	 /* compute l and attenuation */
696	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
697	    /* directional light */
698	    COPY_3V(VP, light->_VP_inf_norm);
699	 }
700	 else {
701	    GLfloat d;     /* distance from vertex to light */
702
703	    SUB_3V(VP, light->_Position, vertex);
704
705	    d = (GLfloat) LEN_3FV( VP );
706	    if ( d > 1e-6) {
707	       GLfloat invd = 1.0F / d;
708	       SELF_SCALE_SCALAR_3V(VP, invd);
709	    }
710
711	    attenuation = 1.0F / (light->ConstantAttenuation + d *
712				  (light->LinearAttenuation + d *
713				   light->QuadraticAttenuation));
714
715	    /* spotlight attenuation */
716	    if (light->_Flags & LIGHT_SPOT) {
717	       GLfloat PV_dot_dir = - DOT3(VP, light->_NormDirection);
718	       if (PV_dot_dir < light->_CosCutoff) {
719		  continue; /* this light makes no contribution */
720	       }
721	       else {
722		  GLdouble x = PV_dot_dir * (EXP_TABLE_SIZE-1);
723		  GLint k = (GLint) x;
724		  GLfloat spot = (GLfloat) (light->_SpotExpTable[k][0]
725				  + (x-k)*light->_SpotExpTable[k][1]);
726		  attenuation *= spot;
727	       }
728	    }
729	 }
730
731	 if (attenuation < 1e-3)
732	    continue;		/* this light makes no contribution */
733
734	 n_dot_VP = DOT3( normal, VP );
735
736	 /* which side are we lighting? */
737	 if (n_dot_VP < 0.0F) {
738#if IDX & LIGHT_TWOSIDE
739	    side = 1;
740	    correction = -1;
741	    n_dot_VP = -n_dot_VP;
742#else
743            continue;
744#endif
745	 }
746
747	 /* accumulate diffuse term */
748	 diffuse[side] += n_dot_VP * light->_dli * attenuation;
749
750	 /* specular term */
751	 if (ctx->Light.Model.LocalViewer) {
752	    GLfloat v[3];
753	    COPY_3V(v, vertex);
754	    NORMALIZE_3FV(v);
755	    SUB_3V(VP, VP, v);                /* h = VP + VPe */
756	    h = VP;
757	    NORMALIZE_3FV(h);
758	 }
759	 else if (light->_Flags & LIGHT_POSITIONAL) {
760	    h = VP;
761            /* Strangely, disabling this addition fixes a conformance
762             * problem.  If this code is enabled, l_sed.c fails.
763             */
764	    /*ACC_3V(h, ctx->_EyeZDir);*/
765	    NORMALIZE_3FV(h);
766	 }
767         else {
768	    h = light->_h_inf_norm;
769	 }
770
771	 n_dot_h = correction * DOT3(normal, h);
772	 if (n_dot_h > 0.0F) {
773	    GLfloat spec_coef;
774	    struct gl_shine_tab *tab = ctx->_ShineTable[side];
775	    GET_SHINE_TAB_ENTRY( tab, n_dot_h, spec_coef);
776	    specular[side] += spec_coef * light->_sli * attenuation;
777	 }
778      } /*loop over lights*/
779
780      /* Now compute final color index */
781      for (side = 0 ; side < NR_SIDES ; side++) {
782	 const GLfloat *ind = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_INDEXES + side];
783	 GLfloat index;
784
785	 if (specular[side] > 1.0F) {
786	    index = ind[MAT_INDEX_SPECULAR];
787	 }
788	 else {
789	    GLfloat d_a = ind[MAT_INDEX_DIFFUSE] - ind[MAT_INDEX_AMBIENT];
790	    GLfloat s_a = ind[MAT_INDEX_SPECULAR] - ind[MAT_INDEX_AMBIENT];
791	    index = (ind[MAT_INDEX_AMBIENT]
792		     + diffuse[side] * (1.0F-specular[side]) * d_a
793		     + specular[side] * s_a);
794	    if (index > ind[MAT_INDEX_SPECULAR]) {
795	       index = ind[MAT_INDEX_SPECULAR];
796	    }
797	 }
798	 indexResult[side][j] = index;
799      }
800   } /*for vertex*/
801}
802
803
804
805static void TAG(init_light_tab)( void )
806{
807   _tnl_light_tab[IDX] = TAG(light_rgba);
808   _tnl_light_fast_tab[IDX] = TAG(light_fast_rgba);
809   _tnl_light_fast_single_tab[IDX] = TAG(light_fast_rgba_single);
810   _tnl_light_spec_tab[IDX] = TAG(light_rgba_spec);
811   _tnl_light_ci_tab[IDX] = TAG(light_ci);
812}
813
814
815#undef TAG
816#undef IDX
817#undef NR_SIDES
818