xref: /aosp_15_r20/external/mesa3d/src/mesa/main/light.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
15*61046927SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
16*61046927SAndroid Build Coastguard Worker  *
17*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21*61046927SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23*61046927SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
24*61046927SAndroid Build Coastguard Worker  */
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
28*61046927SAndroid Build Coastguard Worker #include "context.h"
29*61046927SAndroid Build Coastguard Worker #include "enums.h"
30*61046927SAndroid Build Coastguard Worker #include "light.h"
31*61046927SAndroid Build Coastguard Worker #include "macros.h"
32*61046927SAndroid Build Coastguard Worker #include "mtypes.h"
33*61046927SAndroid Build Coastguard Worker #include "math/m_matrix.h"
34*61046927SAndroid Build Coastguard Worker #include "util/bitscan.h"
35*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #include <math.h>
38*61046927SAndroid Build Coastguard Worker 
39*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ShadeModel(GLenum mode)40*61046927SAndroid Build Coastguard Worker _mesa_ShadeModel( GLenum mode )
41*61046927SAndroid Build Coastguard Worker {
42*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
43*61046927SAndroid Build Coastguard Worker 
44*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API)
45*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glShadeModel %s\n", _mesa_enum_to_string(mode));
46*61046927SAndroid Build Coastguard Worker 
47*61046927SAndroid Build Coastguard Worker    if (ctx->Light.ShadeModel == mode)
48*61046927SAndroid Build Coastguard Worker       return;
49*61046927SAndroid Build Coastguard Worker 
50*61046927SAndroid Build Coastguard Worker    if (mode != GL_FLAT && mode != GL_SMOOTH) {
51*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glShadeModel");
52*61046927SAndroid Build Coastguard Worker       return;
53*61046927SAndroid Build Coastguard Worker    }
54*61046927SAndroid Build Coastguard Worker 
55*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, _NEW_LIGHT_STATE, GL_LIGHTING_BIT);
56*61046927SAndroid Build Coastguard Worker    ctx->Light.ShadeModel = mode;
57*61046927SAndroid Build Coastguard Worker }
58*61046927SAndroid Build Coastguard Worker 
59*61046927SAndroid Build Coastguard Worker 
60*61046927SAndroid Build Coastguard Worker /**
61*61046927SAndroid Build Coastguard Worker  * Set the provoking vertex (the vertex which specifies the prim's
62*61046927SAndroid Build Coastguard Worker  * color when flat shading) to either the first or last vertex of the
63*61046927SAndroid Build Coastguard Worker  * triangle or line.
64*61046927SAndroid Build Coastguard Worker  */
65*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ProvokingVertex(GLenum mode)66*61046927SAndroid Build Coastguard Worker _mesa_ProvokingVertex(GLenum mode)
67*61046927SAndroid Build Coastguard Worker {
68*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE&VERBOSE_API)
71*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glProvokingVertexEXT 0x%x\n", mode);
72*61046927SAndroid Build Coastguard Worker 
73*61046927SAndroid Build Coastguard Worker    if (ctx->Light.ProvokingVertex == mode)
74*61046927SAndroid Build Coastguard Worker       return;
75*61046927SAndroid Build Coastguard Worker 
76*61046927SAndroid Build Coastguard Worker    switch (mode) {
77*61046927SAndroid Build Coastguard Worker    case GL_FIRST_VERTEX_CONVENTION_EXT:
78*61046927SAndroid Build Coastguard Worker    case GL_LAST_VERTEX_CONVENTION_EXT:
79*61046927SAndroid Build Coastguard Worker       break;
80*61046927SAndroid Build Coastguard Worker    default:
81*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glProvokingVertexEXT(0x%x)", mode);
82*61046927SAndroid Build Coastguard Worker       return;
83*61046927SAndroid Build Coastguard Worker    }
84*61046927SAndroid Build Coastguard Worker 
85*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, _NEW_LIGHT_STATE, GL_LIGHTING_BIT);
86*61046927SAndroid Build Coastguard Worker    ctx->Light.ProvokingVertex = mode;
87*61046927SAndroid Build Coastguard Worker }
88*61046927SAndroid Build Coastguard Worker 
89*61046927SAndroid Build Coastguard Worker 
90*61046927SAndroid Build Coastguard Worker /**
91*61046927SAndroid Build Coastguard Worker  * Helper function called by _mesa_Lightfv and _mesa_PopAttrib to set
92*61046927SAndroid Build Coastguard Worker  * per-light state.
93*61046927SAndroid Build Coastguard Worker  * For GL_POSITION and GL_SPOT_DIRECTION the params position/direction
94*61046927SAndroid Build Coastguard Worker  * will have already been transformed by the modelview matrix!
95*61046927SAndroid Build Coastguard Worker  * Also, all error checking should have already been done.
96*61046927SAndroid Build Coastguard Worker  */
97*61046927SAndroid Build Coastguard Worker static void
do_light(struct gl_context * ctx,GLuint lnum,GLenum pname,const GLfloat * params)98*61046927SAndroid Build Coastguard Worker do_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params)
99*61046927SAndroid Build Coastguard Worker {
100*61046927SAndroid Build Coastguard Worker    struct gl_light *light;
101*61046927SAndroid Build Coastguard Worker 
102*61046927SAndroid Build Coastguard Worker    assert(lnum < MAX_LIGHTS);
103*61046927SAndroid Build Coastguard Worker    light = &ctx->Light.Light[lnum];
104*61046927SAndroid Build Coastguard Worker 
105*61046927SAndroid Build Coastguard Worker    struct gl_light_uniforms *lu = &ctx->Light.LightSource[lnum];
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    switch (pname) {
108*61046927SAndroid Build Coastguard Worker    case GL_AMBIENT:
109*61046927SAndroid Build Coastguard Worker       if (TEST_EQ_4V(lu->Ambient, params))
110*61046927SAndroid Build Coastguard Worker 	 return;
111*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
112*61046927SAndroid Build Coastguard Worker       COPY_4V( lu->Ambient, params );
113*61046927SAndroid Build Coastguard Worker       break;
114*61046927SAndroid Build Coastguard Worker    case GL_DIFFUSE:
115*61046927SAndroid Build Coastguard Worker       if (TEST_EQ_4V(lu->Diffuse, params))
116*61046927SAndroid Build Coastguard Worker 	 return;
117*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
118*61046927SAndroid Build Coastguard Worker       COPY_4V( lu->Diffuse, params );
119*61046927SAndroid Build Coastguard Worker       break;
120*61046927SAndroid Build Coastguard Worker    case GL_SPECULAR:
121*61046927SAndroid Build Coastguard Worker       if (TEST_EQ_4V(lu->Specular, params))
122*61046927SAndroid Build Coastguard Worker 	 return;
123*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
124*61046927SAndroid Build Coastguard Worker       COPY_4V( lu->Specular, params );
125*61046927SAndroid Build Coastguard Worker       break;
126*61046927SAndroid Build Coastguard Worker    case GL_POSITION: {
127*61046927SAndroid Build Coastguard Worker       /* NOTE: position has already been transformed by ModelView! */
128*61046927SAndroid Build Coastguard Worker       if (TEST_EQ_4V(lu->EyePosition, params))
129*61046927SAndroid Build Coastguard Worker 	 return;
130*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
131*61046927SAndroid Build Coastguard Worker 
132*61046927SAndroid Build Coastguard Worker       bool old_positional = lu->EyePosition[3] != 0.0f;
133*61046927SAndroid Build Coastguard Worker       bool positional = params[3] != 0.0f;
134*61046927SAndroid Build Coastguard Worker       COPY_4V(lu->EyePosition, params);
135*61046927SAndroid Build Coastguard Worker 
136*61046927SAndroid Build Coastguard Worker       if (positional != old_positional) {
137*61046927SAndroid Build Coastguard Worker          if (positional)
138*61046927SAndroid Build Coastguard Worker             light->_Flags |= LIGHT_POSITIONAL;
139*61046927SAndroid Build Coastguard Worker          else
140*61046927SAndroid Build Coastguard Worker             light->_Flags &= ~LIGHT_POSITIONAL;
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker          /* Used by fixed-func vertex program. */
143*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_FF_VERT_PROGRAM;
144*61046927SAndroid Build Coastguard Worker       }
145*61046927SAndroid Build Coastguard Worker 
146*61046927SAndroid Build Coastguard Worker       static const GLfloat eye_z[] = {0, 0, 1};
147*61046927SAndroid Build Coastguard Worker       GLfloat p[3];
148*61046927SAndroid Build Coastguard Worker       /* Compute infinite half angle vector:
149*61046927SAndroid Build Coastguard Worker        *   halfVector = normalize(normalize(lightPos) + (0, 0, 1))
150*61046927SAndroid Build Coastguard Worker        * light.EyePosition.w should be 0 for infinite lights.
151*61046927SAndroid Build Coastguard Worker        */
152*61046927SAndroid Build Coastguard Worker       COPY_3V(p, params);
153*61046927SAndroid Build Coastguard Worker       NORMALIZE_3FV(p);
154*61046927SAndroid Build Coastguard Worker       ADD_3V(p, p, eye_z);
155*61046927SAndroid Build Coastguard Worker       NORMALIZE_3FV(p);
156*61046927SAndroid Build Coastguard Worker       COPY_3V(lu->_HalfVector, p);
157*61046927SAndroid Build Coastguard Worker       lu->_HalfVector[3] = 1.0;
158*61046927SAndroid Build Coastguard Worker       break;
159*61046927SAndroid Build Coastguard Worker    }
160*61046927SAndroid Build Coastguard Worker    case GL_SPOT_DIRECTION:
161*61046927SAndroid Build Coastguard Worker       /* NOTE: Direction already transformed by inverse ModelView! */
162*61046927SAndroid Build Coastguard Worker       if (TEST_EQ_3V(lu->SpotDirection, params))
163*61046927SAndroid Build Coastguard Worker 	 return;
164*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
165*61046927SAndroid Build Coastguard Worker       COPY_3V(lu->SpotDirection, params);
166*61046927SAndroid Build Coastguard Worker       break;
167*61046927SAndroid Build Coastguard Worker    case GL_SPOT_EXPONENT:
168*61046927SAndroid Build Coastguard Worker       assert(params[0] >= 0.0F);
169*61046927SAndroid Build Coastguard Worker       assert(params[0] <= ctx->Const.MaxSpotExponent);
170*61046927SAndroid Build Coastguard Worker       if (lu->SpotExponent == params[0])
171*61046927SAndroid Build Coastguard Worker 	 return;
172*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
173*61046927SAndroid Build Coastguard Worker       lu->SpotExponent = params[0];
174*61046927SAndroid Build Coastguard Worker       break;
175*61046927SAndroid Build Coastguard Worker    case GL_SPOT_CUTOFF: {
176*61046927SAndroid Build Coastguard Worker       assert(params[0] == 180.0F || (params[0] >= 0.0F && params[0] <= 90.0F));
177*61046927SAndroid Build Coastguard Worker       if (lu->SpotCutoff == params[0])
178*61046927SAndroid Build Coastguard Worker          return;
179*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker       bool old_is_180 = lu->SpotCutoff == 180.0f;
182*61046927SAndroid Build Coastguard Worker       bool is_180 = params[0] == 180.0f;
183*61046927SAndroid Build Coastguard Worker       lu->SpotCutoff = params[0];
184*61046927SAndroid Build Coastguard Worker       lu->_CosCutoff = (cosf(lu->SpotCutoff * M_PI / 180.0));
185*61046927SAndroid Build Coastguard Worker       if (lu->_CosCutoff < 0)
186*61046927SAndroid Build Coastguard Worker          lu->_CosCutoff = 0;
187*61046927SAndroid Build Coastguard Worker 
188*61046927SAndroid Build Coastguard Worker       if (is_180 != old_is_180) {
189*61046927SAndroid Build Coastguard Worker          if (!is_180)
190*61046927SAndroid Build Coastguard Worker             light->_Flags |= LIGHT_SPOT;
191*61046927SAndroid Build Coastguard Worker          else
192*61046927SAndroid Build Coastguard Worker             light->_Flags &= ~LIGHT_SPOT;
193*61046927SAndroid Build Coastguard Worker 
194*61046927SAndroid Build Coastguard Worker          /* Used by fixed-func vertex program. */
195*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_FF_VERT_PROGRAM;
196*61046927SAndroid Build Coastguard Worker       }
197*61046927SAndroid Build Coastguard Worker       break;
198*61046927SAndroid Build Coastguard Worker    }
199*61046927SAndroid Build Coastguard Worker    case GL_CONSTANT_ATTENUATION: {
200*61046927SAndroid Build Coastguard Worker       assert(params[0] >= 0.0F);
201*61046927SAndroid Build Coastguard Worker       if (lu->ConstantAttenuation == params[0])
202*61046927SAndroid Build Coastguard Worker 	 return;
203*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker       bool old_is_one = lu->ConstantAttenuation == 1.0f;
206*61046927SAndroid Build Coastguard Worker       bool is_one = params[0] == 1.0f;
207*61046927SAndroid Build Coastguard Worker       lu->ConstantAttenuation = params[0];
208*61046927SAndroid Build Coastguard Worker 
209*61046927SAndroid Build Coastguard Worker       if (old_is_one != is_one) {
210*61046927SAndroid Build Coastguard Worker          /* Used by fixed-func vertex program. */
211*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_FF_VERT_PROGRAM;
212*61046927SAndroid Build Coastguard Worker       }
213*61046927SAndroid Build Coastguard Worker       break;
214*61046927SAndroid Build Coastguard Worker    }
215*61046927SAndroid Build Coastguard Worker    case GL_LINEAR_ATTENUATION: {
216*61046927SAndroid Build Coastguard Worker       assert(params[0] >= 0.0F);
217*61046927SAndroid Build Coastguard Worker       if (lu->LinearAttenuation == params[0])
218*61046927SAndroid Build Coastguard Worker 	 return;
219*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker       bool old_is_zero = lu->LinearAttenuation == 0.0f;
222*61046927SAndroid Build Coastguard Worker       bool is_zero = params[0] == 0.0f;
223*61046927SAndroid Build Coastguard Worker       lu->LinearAttenuation = params[0];
224*61046927SAndroid Build Coastguard Worker 
225*61046927SAndroid Build Coastguard Worker       if (old_is_zero != is_zero) {
226*61046927SAndroid Build Coastguard Worker          /* Used by fixed-func vertex program. */
227*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_FF_VERT_PROGRAM;
228*61046927SAndroid Build Coastguard Worker       }
229*61046927SAndroid Build Coastguard Worker       break;
230*61046927SAndroid Build Coastguard Worker    }
231*61046927SAndroid Build Coastguard Worker    case GL_QUADRATIC_ATTENUATION: {
232*61046927SAndroid Build Coastguard Worker       assert(params[0] >= 0.0F);
233*61046927SAndroid Build Coastguard Worker       if (lu->QuadraticAttenuation == params[0])
234*61046927SAndroid Build Coastguard Worker 	 return;
235*61046927SAndroid Build Coastguard Worker       FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker       bool old_is_zero = lu->QuadraticAttenuation == 0.0f;
238*61046927SAndroid Build Coastguard Worker       bool is_zero = params[0] == 0.0f;
239*61046927SAndroid Build Coastguard Worker       lu->QuadraticAttenuation = params[0];
240*61046927SAndroid Build Coastguard Worker 
241*61046927SAndroid Build Coastguard Worker       if (old_is_zero != is_zero) {
242*61046927SAndroid Build Coastguard Worker          /* Used by fixed-func vertex program. */
243*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_FF_VERT_PROGRAM;
244*61046927SAndroid Build Coastguard Worker       }
245*61046927SAndroid Build Coastguard Worker       break;
246*61046927SAndroid Build Coastguard Worker    }
247*61046927SAndroid Build Coastguard Worker    default:
248*61046927SAndroid Build Coastguard Worker       unreachable("Unexpected pname in do_light()");
249*61046927SAndroid Build Coastguard Worker    }
250*61046927SAndroid Build Coastguard Worker }
251*61046927SAndroid Build Coastguard Worker 
252*61046927SAndroid Build Coastguard Worker 
253*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Lightf(GLenum light,GLenum pname,GLfloat param)254*61046927SAndroid Build Coastguard Worker _mesa_Lightf( GLenum light, GLenum pname, GLfloat param )
255*61046927SAndroid Build Coastguard Worker {
256*61046927SAndroid Build Coastguard Worker    GLfloat fparam[4];
257*61046927SAndroid Build Coastguard Worker    fparam[0] = param;
258*61046927SAndroid Build Coastguard Worker    fparam[1] = fparam[2] = fparam[3] = 0.0F;
259*61046927SAndroid Build Coastguard Worker    _mesa_Lightfv( light, pname, fparam );
260*61046927SAndroid Build Coastguard Worker }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Lightfv(GLenum light,GLenum pname,const GLfloat * params)264*61046927SAndroid Build Coastguard Worker _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params )
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
267*61046927SAndroid Build Coastguard Worker    GLint i = (GLint) (light - GL_LIGHT0);
268*61046927SAndroid Build Coastguard Worker    GLfloat temp[4];
269*61046927SAndroid Build Coastguard Worker 
270*61046927SAndroid Build Coastguard Worker    if (i < 0 || i >= (GLint) ctx->Const.MaxLights) {
271*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "glLight(light=0x%x)", light );
272*61046927SAndroid Build Coastguard Worker       return;
273*61046927SAndroid Build Coastguard Worker    }
274*61046927SAndroid Build Coastguard Worker 
275*61046927SAndroid Build Coastguard Worker    /* do particular error checks, transformations */
276*61046927SAndroid Build Coastguard Worker    switch (pname) {
277*61046927SAndroid Build Coastguard Worker    case GL_AMBIENT:
278*61046927SAndroid Build Coastguard Worker    case GL_DIFFUSE:
279*61046927SAndroid Build Coastguard Worker    case GL_SPECULAR:
280*61046927SAndroid Build Coastguard Worker       /* nothing */
281*61046927SAndroid Build Coastguard Worker       break;
282*61046927SAndroid Build Coastguard Worker    case GL_POSITION:
283*61046927SAndroid Build Coastguard Worker       /* transform position by ModelView matrix */
284*61046927SAndroid Build Coastguard Worker       TRANSFORM_POINT(temp, ctx->ModelviewMatrixStack.Top->m, params);
285*61046927SAndroid Build Coastguard Worker       params = temp;
286*61046927SAndroid Build Coastguard Worker       break;
287*61046927SAndroid Build Coastguard Worker    case GL_SPOT_DIRECTION:
288*61046927SAndroid Build Coastguard Worker       /* transform direction by inverse modelview */
289*61046927SAndroid Build Coastguard Worker       if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) {
290*61046927SAndroid Build Coastguard Worker 	 _math_matrix_analyse(ctx->ModelviewMatrixStack.Top);
291*61046927SAndroid Build Coastguard Worker       }
292*61046927SAndroid Build Coastguard Worker       TRANSFORM_DIRECTION(temp, params, ctx->ModelviewMatrixStack.Top->m);
293*61046927SAndroid Build Coastguard Worker       params = temp;
294*61046927SAndroid Build Coastguard Worker       break;
295*61046927SAndroid Build Coastguard Worker    case GL_SPOT_EXPONENT:
296*61046927SAndroid Build Coastguard Worker       if (params[0] < 0.0F || params[0] > ctx->Const.MaxSpotExponent) {
297*61046927SAndroid Build Coastguard Worker 	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
298*61046927SAndroid Build Coastguard Worker 	 return;
299*61046927SAndroid Build Coastguard Worker       }
300*61046927SAndroid Build Coastguard Worker       break;
301*61046927SAndroid Build Coastguard Worker    case GL_SPOT_CUTOFF:
302*61046927SAndroid Build Coastguard Worker       if ((params[0] < 0.0F || params[0] > 90.0F) && params[0] != 180.0F) {
303*61046927SAndroid Build Coastguard Worker 	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
304*61046927SAndroid Build Coastguard Worker 	 return;
305*61046927SAndroid Build Coastguard Worker       }
306*61046927SAndroid Build Coastguard Worker       break;
307*61046927SAndroid Build Coastguard Worker    case GL_CONSTANT_ATTENUATION:
308*61046927SAndroid Build Coastguard Worker    case GL_LINEAR_ATTENUATION:
309*61046927SAndroid Build Coastguard Worker    case GL_QUADRATIC_ATTENUATION:
310*61046927SAndroid Build Coastguard Worker       if (params[0] < 0.0F) {
311*61046927SAndroid Build Coastguard Worker 	 _mesa_error(ctx, GL_INVALID_VALUE, "glLight");
312*61046927SAndroid Build Coastguard Worker 	 return;
313*61046927SAndroid Build Coastguard Worker       }
314*61046927SAndroid Build Coastguard Worker       break;
315*61046927SAndroid Build Coastguard Worker    default:
316*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glLight(pname=0x%x)", pname);
317*61046927SAndroid Build Coastguard Worker       return;
318*61046927SAndroid Build Coastguard Worker    }
319*61046927SAndroid Build Coastguard Worker 
320*61046927SAndroid Build Coastguard Worker    do_light(ctx, i, pname, params);
321*61046927SAndroid Build Coastguard Worker }
322*61046927SAndroid Build Coastguard Worker 
323*61046927SAndroid Build Coastguard Worker 
324*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Lighti(GLenum light,GLenum pname,GLint param)325*61046927SAndroid Build Coastguard Worker _mesa_Lighti( GLenum light, GLenum pname, GLint param )
326*61046927SAndroid Build Coastguard Worker {
327*61046927SAndroid Build Coastguard Worker    GLint iparam[4];
328*61046927SAndroid Build Coastguard Worker    iparam[0] = param;
329*61046927SAndroid Build Coastguard Worker    iparam[1] = iparam[2] = iparam[3] = 0;
330*61046927SAndroid Build Coastguard Worker    _mesa_Lightiv( light, pname, iparam );
331*61046927SAndroid Build Coastguard Worker }
332*61046927SAndroid Build Coastguard Worker 
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_Lightiv(GLenum light,GLenum pname,const GLint * params)335*61046927SAndroid Build Coastguard Worker _mesa_Lightiv( GLenum light, GLenum pname, const GLint *params )
336*61046927SAndroid Build Coastguard Worker {
337*61046927SAndroid Build Coastguard Worker    GLfloat fparam[4];
338*61046927SAndroid Build Coastguard Worker 
339*61046927SAndroid Build Coastguard Worker    switch (pname) {
340*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
341*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
342*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
343*61046927SAndroid Build Coastguard Worker          fparam[0] = INT_TO_FLOAT( params[0] );
344*61046927SAndroid Build Coastguard Worker          fparam[1] = INT_TO_FLOAT( params[1] );
345*61046927SAndroid Build Coastguard Worker          fparam[2] = INT_TO_FLOAT( params[2] );
346*61046927SAndroid Build Coastguard Worker          fparam[3] = INT_TO_FLOAT( params[3] );
347*61046927SAndroid Build Coastguard Worker          break;
348*61046927SAndroid Build Coastguard Worker       case GL_POSITION:
349*61046927SAndroid Build Coastguard Worker          fparam[0] = (GLfloat) params[0];
350*61046927SAndroid Build Coastguard Worker          fparam[1] = (GLfloat) params[1];
351*61046927SAndroid Build Coastguard Worker          fparam[2] = (GLfloat) params[2];
352*61046927SAndroid Build Coastguard Worker          fparam[3] = (GLfloat) params[3];
353*61046927SAndroid Build Coastguard Worker          break;
354*61046927SAndroid Build Coastguard Worker       case GL_SPOT_DIRECTION:
355*61046927SAndroid Build Coastguard Worker          fparam[0] = (GLfloat) params[0];
356*61046927SAndroid Build Coastguard Worker          fparam[1] = (GLfloat) params[1];
357*61046927SAndroid Build Coastguard Worker          fparam[2] = (GLfloat) params[2];
358*61046927SAndroid Build Coastguard Worker          break;
359*61046927SAndroid Build Coastguard Worker       case GL_SPOT_EXPONENT:
360*61046927SAndroid Build Coastguard Worker       case GL_SPOT_CUTOFF:
361*61046927SAndroid Build Coastguard Worker       case GL_CONSTANT_ATTENUATION:
362*61046927SAndroid Build Coastguard Worker       case GL_LINEAR_ATTENUATION:
363*61046927SAndroid Build Coastguard Worker       case GL_QUADRATIC_ATTENUATION:
364*61046927SAndroid Build Coastguard Worker          fparam[0] = (GLfloat) params[0];
365*61046927SAndroid Build Coastguard Worker          break;
366*61046927SAndroid Build Coastguard Worker       default:
367*61046927SAndroid Build Coastguard Worker          /* error will be caught later in gl_Lightfv */
368*61046927SAndroid Build Coastguard Worker          ;
369*61046927SAndroid Build Coastguard Worker    }
370*61046927SAndroid Build Coastguard Worker 
371*61046927SAndroid Build Coastguard Worker    _mesa_Lightfv( light, pname, fparam );
372*61046927SAndroid Build Coastguard Worker }
373*61046927SAndroid Build Coastguard Worker 
374*61046927SAndroid Build Coastguard Worker 
375*61046927SAndroid Build Coastguard Worker 
376*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetLightfv(GLenum light,GLenum pname,GLfloat * params)377*61046927SAndroid Build Coastguard Worker _mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params )
378*61046927SAndroid Build Coastguard Worker {
379*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
380*61046927SAndroid Build Coastguard Worker    GLint l = (GLint) (light - GL_LIGHT0);
381*61046927SAndroid Build Coastguard Worker 
382*61046927SAndroid Build Coastguard Worker    if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
383*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
384*61046927SAndroid Build Coastguard Worker       return;
385*61046927SAndroid Build Coastguard Worker    }
386*61046927SAndroid Build Coastguard Worker 
387*61046927SAndroid Build Coastguard Worker    switch (pname) {
388*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
389*61046927SAndroid Build Coastguard Worker          COPY_4V( params, ctx->Light.LightSource[l].Ambient );
390*61046927SAndroid Build Coastguard Worker          break;
391*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
392*61046927SAndroid Build Coastguard Worker          COPY_4V( params, ctx->Light.LightSource[l].Diffuse );
393*61046927SAndroid Build Coastguard Worker          break;
394*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
395*61046927SAndroid Build Coastguard Worker          COPY_4V( params, ctx->Light.LightSource[l].Specular );
396*61046927SAndroid Build Coastguard Worker          break;
397*61046927SAndroid Build Coastguard Worker       case GL_POSITION:
398*61046927SAndroid Build Coastguard Worker          COPY_4V( params, ctx->Light.LightSource[l].EyePosition );
399*61046927SAndroid Build Coastguard Worker          break;
400*61046927SAndroid Build Coastguard Worker       case GL_SPOT_DIRECTION:
401*61046927SAndroid Build Coastguard Worker          COPY_3V( params, ctx->Light.LightSource[l].SpotDirection );
402*61046927SAndroid Build Coastguard Worker          break;
403*61046927SAndroid Build Coastguard Worker       case GL_SPOT_EXPONENT:
404*61046927SAndroid Build Coastguard Worker          params[0] = ctx->Light.LightSource[l].SpotExponent;
405*61046927SAndroid Build Coastguard Worker          break;
406*61046927SAndroid Build Coastguard Worker       case GL_SPOT_CUTOFF:
407*61046927SAndroid Build Coastguard Worker          params[0] = ctx->Light.LightSource[l].SpotCutoff;
408*61046927SAndroid Build Coastguard Worker          break;
409*61046927SAndroid Build Coastguard Worker       case GL_CONSTANT_ATTENUATION:
410*61046927SAndroid Build Coastguard Worker          params[0] = ctx->Light.LightSource[l].ConstantAttenuation;
411*61046927SAndroid Build Coastguard Worker          break;
412*61046927SAndroid Build Coastguard Worker       case GL_LINEAR_ATTENUATION:
413*61046927SAndroid Build Coastguard Worker          params[0] = ctx->Light.LightSource[l].LinearAttenuation;
414*61046927SAndroid Build Coastguard Worker          break;
415*61046927SAndroid Build Coastguard Worker       case GL_QUADRATIC_ATTENUATION:
416*61046927SAndroid Build Coastguard Worker          params[0] = ctx->Light.LightSource[l].QuadraticAttenuation;
417*61046927SAndroid Build Coastguard Worker          break;
418*61046927SAndroid Build Coastguard Worker       default:
419*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightfv" );
420*61046927SAndroid Build Coastguard Worker          break;
421*61046927SAndroid Build Coastguard Worker    }
422*61046927SAndroid Build Coastguard Worker }
423*61046927SAndroid Build Coastguard Worker 
424*61046927SAndroid Build Coastguard Worker 
425*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetLightiv(GLenum light,GLenum pname,GLint * params)426*61046927SAndroid Build Coastguard Worker _mesa_GetLightiv( GLenum light, GLenum pname, GLint *params )
427*61046927SAndroid Build Coastguard Worker {
428*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
429*61046927SAndroid Build Coastguard Worker    GLint l = (GLint) (light - GL_LIGHT0);
430*61046927SAndroid Build Coastguard Worker 
431*61046927SAndroid Build Coastguard Worker    if (l < 0 || l >= (GLint) ctx->Const.MaxLights) {
432*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
433*61046927SAndroid Build Coastguard Worker       return;
434*61046927SAndroid Build Coastguard Worker    }
435*61046927SAndroid Build Coastguard Worker 
436*61046927SAndroid Build Coastguard Worker    switch (pname) {
437*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
438*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT(ctx->Light.LightSource[l].Ambient[0]);
439*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT(ctx->Light.LightSource[l].Ambient[1]);
440*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT(ctx->Light.LightSource[l].Ambient[2]);
441*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT(ctx->Light.LightSource[l].Ambient[3]);
442*61046927SAndroid Build Coastguard Worker          break;
443*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
444*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT(ctx->Light.LightSource[l].Diffuse[0]);
445*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT(ctx->Light.LightSource[l].Diffuse[1]);
446*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT(ctx->Light.LightSource[l].Diffuse[2]);
447*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT(ctx->Light.LightSource[l].Diffuse[3]);
448*61046927SAndroid Build Coastguard Worker          break;
449*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
450*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT(ctx->Light.LightSource[l].Specular[0]);
451*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT(ctx->Light.LightSource[l].Specular[1]);
452*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT(ctx->Light.LightSource[l].Specular[2]);
453*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT(ctx->Light.LightSource[l].Specular[3]);
454*61046927SAndroid Build Coastguard Worker          break;
455*61046927SAndroid Build Coastguard Worker       case GL_POSITION:
456*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].EyePosition[0];
457*61046927SAndroid Build Coastguard Worker          params[1] = (GLint) ctx->Light.LightSource[l].EyePosition[1];
458*61046927SAndroid Build Coastguard Worker          params[2] = (GLint) ctx->Light.LightSource[l].EyePosition[2];
459*61046927SAndroid Build Coastguard Worker          params[3] = (GLint) ctx->Light.LightSource[l].EyePosition[3];
460*61046927SAndroid Build Coastguard Worker          break;
461*61046927SAndroid Build Coastguard Worker       case GL_SPOT_DIRECTION:
462*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].SpotDirection[0];
463*61046927SAndroid Build Coastguard Worker          params[1] = (GLint) ctx->Light.LightSource[l].SpotDirection[1];
464*61046927SAndroid Build Coastguard Worker          params[2] = (GLint) ctx->Light.LightSource[l].SpotDirection[2];
465*61046927SAndroid Build Coastguard Worker          break;
466*61046927SAndroid Build Coastguard Worker       case GL_SPOT_EXPONENT:
467*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].SpotExponent;
468*61046927SAndroid Build Coastguard Worker          break;
469*61046927SAndroid Build Coastguard Worker       case GL_SPOT_CUTOFF:
470*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].SpotCutoff;
471*61046927SAndroid Build Coastguard Worker          break;
472*61046927SAndroid Build Coastguard Worker       case GL_CONSTANT_ATTENUATION:
473*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].ConstantAttenuation;
474*61046927SAndroid Build Coastguard Worker          break;
475*61046927SAndroid Build Coastguard Worker       case GL_LINEAR_ATTENUATION:
476*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].LinearAttenuation;
477*61046927SAndroid Build Coastguard Worker          break;
478*61046927SAndroid Build Coastguard Worker       case GL_QUADRATIC_ATTENUATION:
479*61046927SAndroid Build Coastguard Worker          params[0] = (GLint) ctx->Light.LightSource[l].QuadraticAttenuation;
480*61046927SAndroid Build Coastguard Worker          break;
481*61046927SAndroid Build Coastguard Worker       default:
482*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_ENUM, "glGetLightiv" );
483*61046927SAndroid Build Coastguard Worker          break;
484*61046927SAndroid Build Coastguard Worker    }
485*61046927SAndroid Build Coastguard Worker }
486*61046927SAndroid Build Coastguard Worker 
487*61046927SAndroid Build Coastguard Worker 
488*61046927SAndroid Build Coastguard Worker 
489*61046927SAndroid Build Coastguard Worker /**********************************************************************/
490*61046927SAndroid Build Coastguard Worker /***                        Light Model                             ***/
491*61046927SAndroid Build Coastguard Worker /**********************************************************************/
492*61046927SAndroid Build Coastguard Worker 
493*61046927SAndroid Build Coastguard Worker 
494*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_LightModelfv(GLenum pname,const GLfloat * params)495*61046927SAndroid Build Coastguard Worker _mesa_LightModelfv( GLenum pname, const GLfloat *params )
496*61046927SAndroid Build Coastguard Worker {
497*61046927SAndroid Build Coastguard Worker    GLenum newenum;
498*61046927SAndroid Build Coastguard Worker    GLboolean newbool;
499*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
500*61046927SAndroid Build Coastguard Worker 
501*61046927SAndroid Build Coastguard Worker    switch (pname) {
502*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_AMBIENT:
503*61046927SAndroid Build Coastguard Worker          if (TEST_EQ_4V( ctx->Light.Model.Ambient, params ))
504*61046927SAndroid Build Coastguard Worker 	    return;
505*61046927SAndroid Build Coastguard Worker 	 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS, GL_LIGHTING_BIT);
506*61046927SAndroid Build Coastguard Worker          COPY_4V( ctx->Light.Model.Ambient, params );
507*61046927SAndroid Build Coastguard Worker          break;
508*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_LOCAL_VIEWER:
509*61046927SAndroid Build Coastguard Worker          if (ctx->API != API_OPENGL_COMPAT)
510*61046927SAndroid Build Coastguard Worker             goto invalid_pname;
511*61046927SAndroid Build Coastguard Worker          newbool = (params[0] != 0.0F);
512*61046927SAndroid Build Coastguard Worker 	 if (ctx->Light.Model.LocalViewer == newbool)
513*61046927SAndroid Build Coastguard Worker 	    return;
514*61046927SAndroid Build Coastguard Worker 	 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM,
515*61046927SAndroid Build Coastguard Worker                         GL_LIGHTING_BIT);
516*61046927SAndroid Build Coastguard Worker 	 ctx->Light.Model.LocalViewer = newbool;
517*61046927SAndroid Build Coastguard Worker          break;
518*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_TWO_SIDE:
519*61046927SAndroid Build Coastguard Worker          newbool = (params[0] != 0.0F);
520*61046927SAndroid Build Coastguard Worker 	 if (ctx->Light.Model.TwoSide == newbool)
521*61046927SAndroid Build Coastguard Worker 	    return;
522*61046927SAndroid Build Coastguard Worker 	 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM |
523*61046927SAndroid Build Coastguard Worker                         _NEW_LIGHT_STATE, GL_LIGHTING_BIT);
524*61046927SAndroid Build Coastguard Worker 	 ctx->Light.Model.TwoSide = newbool;
525*61046927SAndroid Build Coastguard Worker          break;
526*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_COLOR_CONTROL:
527*61046927SAndroid Build Coastguard Worker          if (ctx->API != API_OPENGL_COMPAT)
528*61046927SAndroid Build Coastguard Worker             goto invalid_pname;
529*61046927SAndroid Build Coastguard Worker          if (params[0] == (GLfloat) GL_SINGLE_COLOR)
530*61046927SAndroid Build Coastguard Worker 	    newenum = GL_SINGLE_COLOR;
531*61046927SAndroid Build Coastguard Worker          else if (params[0] == (GLfloat) GL_SEPARATE_SPECULAR_COLOR)
532*61046927SAndroid Build Coastguard Worker 	    newenum = GL_SEPARATE_SPECULAR_COLOR;
533*61046927SAndroid Build Coastguard Worker 	 else {
534*61046927SAndroid Build Coastguard Worker             _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(param=0x0%x)",
535*61046927SAndroid Build Coastguard Worker                          (GLint) params[0] );
536*61046927SAndroid Build Coastguard Worker 	    return;
537*61046927SAndroid Build Coastguard Worker          }
538*61046927SAndroid Build Coastguard Worker 	 if (ctx->Light.Model.ColorControl == newenum)
539*61046927SAndroid Build Coastguard Worker 	    return;
540*61046927SAndroid Build Coastguard Worker 	 FLUSH_VERTICES(ctx, _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM |
541*61046927SAndroid Build Coastguard Worker                         _NEW_FF_FRAG_PROGRAM, GL_LIGHTING_BIT);
542*61046927SAndroid Build Coastguard Worker 	 ctx->Light.Model.ColorControl = newenum;
543*61046927SAndroid Build Coastguard Worker          break;
544*61046927SAndroid Build Coastguard Worker       default:
545*61046927SAndroid Build Coastguard Worker          goto invalid_pname;
546*61046927SAndroid Build Coastguard Worker    }
547*61046927SAndroid Build Coastguard Worker 
548*61046927SAndroid Build Coastguard Worker    return;
549*61046927SAndroid Build Coastguard Worker 
550*61046927SAndroid Build Coastguard Worker invalid_pname:
551*61046927SAndroid Build Coastguard Worker    _mesa_error( ctx, GL_INVALID_ENUM, "glLightModel(pname=0x%x)", pname );
552*61046927SAndroid Build Coastguard Worker    return;
553*61046927SAndroid Build Coastguard Worker }
554*61046927SAndroid Build Coastguard Worker 
555*61046927SAndroid Build Coastguard Worker 
556*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_LightModeliv(GLenum pname,const GLint * params)557*61046927SAndroid Build Coastguard Worker _mesa_LightModeliv( GLenum pname, const GLint *params )
558*61046927SAndroid Build Coastguard Worker {
559*61046927SAndroid Build Coastguard Worker    GLfloat fparam[4];
560*61046927SAndroid Build Coastguard Worker 
561*61046927SAndroid Build Coastguard Worker    switch (pname) {
562*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_AMBIENT:
563*61046927SAndroid Build Coastguard Worker          fparam[0] = INT_TO_FLOAT( params[0] );
564*61046927SAndroid Build Coastguard Worker          fparam[1] = INT_TO_FLOAT( params[1] );
565*61046927SAndroid Build Coastguard Worker          fparam[2] = INT_TO_FLOAT( params[2] );
566*61046927SAndroid Build Coastguard Worker          fparam[3] = INT_TO_FLOAT( params[3] );
567*61046927SAndroid Build Coastguard Worker          break;
568*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_LOCAL_VIEWER:
569*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_TWO_SIDE:
570*61046927SAndroid Build Coastguard Worker       case GL_LIGHT_MODEL_COLOR_CONTROL:
571*61046927SAndroid Build Coastguard Worker          fparam[0] = (GLfloat) params[0];
572*61046927SAndroid Build Coastguard Worker          break;
573*61046927SAndroid Build Coastguard Worker       default:
574*61046927SAndroid Build Coastguard Worker          /* Error will be caught later in gl_LightModelfv */
575*61046927SAndroid Build Coastguard Worker          ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
576*61046927SAndroid Build Coastguard Worker    }
577*61046927SAndroid Build Coastguard Worker    _mesa_LightModelfv( pname, fparam );
578*61046927SAndroid Build Coastguard Worker }
579*61046927SAndroid Build Coastguard Worker 
580*61046927SAndroid Build Coastguard Worker 
581*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_LightModeli(GLenum pname,GLint param)582*61046927SAndroid Build Coastguard Worker _mesa_LightModeli( GLenum pname, GLint param )
583*61046927SAndroid Build Coastguard Worker {
584*61046927SAndroid Build Coastguard Worker    GLint iparam[4];
585*61046927SAndroid Build Coastguard Worker    iparam[0] = param;
586*61046927SAndroid Build Coastguard Worker    iparam[1] = iparam[2] = iparam[3] = 0;
587*61046927SAndroid Build Coastguard Worker    _mesa_LightModeliv( pname, iparam );
588*61046927SAndroid Build Coastguard Worker }
589*61046927SAndroid Build Coastguard Worker 
590*61046927SAndroid Build Coastguard Worker 
591*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_LightModelf(GLenum pname,GLfloat param)592*61046927SAndroid Build Coastguard Worker _mesa_LightModelf( GLenum pname, GLfloat param )
593*61046927SAndroid Build Coastguard Worker {
594*61046927SAndroid Build Coastguard Worker    GLfloat fparam[4];
595*61046927SAndroid Build Coastguard Worker    fparam[0] = param;
596*61046927SAndroid Build Coastguard Worker    fparam[1] = fparam[2] = fparam[3] = 0.0F;
597*61046927SAndroid Build Coastguard Worker    _mesa_LightModelfv( pname, fparam );
598*61046927SAndroid Build Coastguard Worker }
599*61046927SAndroid Build Coastguard Worker 
600*61046927SAndroid Build Coastguard Worker 
601*61046927SAndroid Build Coastguard Worker 
602*61046927SAndroid Build Coastguard Worker /********** MATERIAL **********/
603*61046927SAndroid Build Coastguard Worker 
604*61046927SAndroid Build Coastguard Worker 
605*61046927SAndroid Build Coastguard Worker /*
606*61046927SAndroid Build Coastguard Worker  * Given a face and pname value (ala glColorMaterial), compute a bitmask
607*61046927SAndroid Build Coastguard Worker  * of the targeted material values.
608*61046927SAndroid Build Coastguard Worker  */
609*61046927SAndroid Build Coastguard Worker GLuint
_mesa_material_bitmask(struct gl_context * ctx,GLenum face,GLenum pname,GLuint legal,const char * where)610*61046927SAndroid Build Coastguard Worker _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname,
611*61046927SAndroid Build Coastguard Worker                         GLuint legal, const char *where )
612*61046927SAndroid Build Coastguard Worker {
613*61046927SAndroid Build Coastguard Worker    GLuint bitmask = 0;
614*61046927SAndroid Build Coastguard Worker 
615*61046927SAndroid Build Coastguard Worker    /* Make a bitmask indicating what material attribute(s) we're updating */
616*61046927SAndroid Build Coastguard Worker    switch (pname) {
617*61046927SAndroid Build Coastguard Worker       case GL_EMISSION:
618*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION;
619*61046927SAndroid Build Coastguard Worker          break;
620*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
621*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
622*61046927SAndroid Build Coastguard Worker          break;
623*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
624*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
625*61046927SAndroid Build Coastguard Worker          break;
626*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
627*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR;
628*61046927SAndroid Build Coastguard Worker          break;
629*61046927SAndroid Build Coastguard Worker       case GL_SHININESS:
630*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_SHININESS | MAT_BIT_BACK_SHININESS;
631*61046927SAndroid Build Coastguard Worker          break;
632*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT_AND_DIFFUSE:
633*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_AMBIENT | MAT_BIT_BACK_AMBIENT;
634*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_DIFFUSE | MAT_BIT_BACK_DIFFUSE;
635*61046927SAndroid Build Coastguard Worker          break;
636*61046927SAndroid Build Coastguard Worker       case GL_COLOR_INDEXES:
637*61046927SAndroid Build Coastguard Worker          bitmask |= MAT_BIT_FRONT_INDEXES  | MAT_BIT_BACK_INDEXES;
638*61046927SAndroid Build Coastguard Worker          break;
639*61046927SAndroid Build Coastguard Worker       default:
640*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
641*61046927SAndroid Build Coastguard Worker          return 0;
642*61046927SAndroid Build Coastguard Worker    }
643*61046927SAndroid Build Coastguard Worker 
644*61046927SAndroid Build Coastguard Worker    if (face==GL_FRONT) {
645*61046927SAndroid Build Coastguard Worker       bitmask &= FRONT_MATERIAL_BITS;
646*61046927SAndroid Build Coastguard Worker    }
647*61046927SAndroid Build Coastguard Worker    else if (face==GL_BACK) {
648*61046927SAndroid Build Coastguard Worker       bitmask &= BACK_MATERIAL_BITS;
649*61046927SAndroid Build Coastguard Worker    }
650*61046927SAndroid Build Coastguard Worker    else if (face != GL_FRONT_AND_BACK) {
651*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
652*61046927SAndroid Build Coastguard Worker       return 0;
653*61046927SAndroid Build Coastguard Worker    }
654*61046927SAndroid Build Coastguard Worker 
655*61046927SAndroid Build Coastguard Worker    if (bitmask & ~legal) {
656*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "%s", where );
657*61046927SAndroid Build Coastguard Worker       return 0;
658*61046927SAndroid Build Coastguard Worker    }
659*61046927SAndroid Build Coastguard Worker 
660*61046927SAndroid Build Coastguard Worker    return bitmask;
661*61046927SAndroid Build Coastguard Worker }
662*61046927SAndroid Build Coastguard Worker 
663*61046927SAndroid Build Coastguard Worker 
664*61046927SAndroid Build Coastguard Worker 
665*61046927SAndroid Build Coastguard Worker /* Update derived values following a change in ctx->Light.Material
666*61046927SAndroid Build Coastguard Worker  */
667*61046927SAndroid Build Coastguard Worker void
_mesa_update_material(struct gl_context * ctx,GLuint bitmask)668*61046927SAndroid Build Coastguard Worker _mesa_update_material( struct gl_context *ctx, GLuint bitmask )
669*61046927SAndroid Build Coastguard Worker {
670*61046927SAndroid Build Coastguard Worker    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
671*61046927SAndroid Build Coastguard Worker 
672*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_MATERIAL)
673*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "_mesa_update_material, mask 0x%x\n", bitmask);
674*61046927SAndroid Build Coastguard Worker 
675*61046927SAndroid Build Coastguard Worker    if (!bitmask)
676*61046927SAndroid Build Coastguard Worker       return;
677*61046927SAndroid Build Coastguard Worker 
678*61046927SAndroid Build Coastguard Worker    /* update material ambience */
679*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_FRONT_AMBIENT) {
680*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
681*61046927SAndroid Build Coastguard Worker       while (mask) {
682*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
683*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
684*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
685*61046927SAndroid Build Coastguard Worker          SCALE_3V( light->_MatAmbient[0], lu->Ambient,
686*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_FRONT_AMBIENT]);
687*61046927SAndroid Build Coastguard Worker       }
688*61046927SAndroid Build Coastguard Worker    }
689*61046927SAndroid Build Coastguard Worker 
690*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_BACK_AMBIENT) {
691*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
692*61046927SAndroid Build Coastguard Worker       while (mask) {
693*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
694*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
695*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
696*61046927SAndroid Build Coastguard Worker          SCALE_3V( light->_MatAmbient[1], lu->Ambient,
697*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_BACK_AMBIENT]);
698*61046927SAndroid Build Coastguard Worker       }
699*61046927SAndroid Build Coastguard Worker    }
700*61046927SAndroid Build Coastguard Worker 
701*61046927SAndroid Build Coastguard Worker    /* update BaseColor = emission + scene's ambience * material's ambience */
702*61046927SAndroid Build Coastguard Worker    if (bitmask & (MAT_BIT_FRONT_EMISSION | MAT_BIT_FRONT_AMBIENT)) {
703*61046927SAndroid Build Coastguard Worker       COPY_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_EMISSION] );
704*61046927SAndroid Build Coastguard Worker       ACC_SCALE_3V( ctx->Light._BaseColor[0], mat[MAT_ATTRIB_FRONT_AMBIENT],
705*61046927SAndroid Build Coastguard Worker 		    ctx->Light.Model.Ambient );
706*61046927SAndroid Build Coastguard Worker    }
707*61046927SAndroid Build Coastguard Worker 
708*61046927SAndroid Build Coastguard Worker    if (bitmask & (MAT_BIT_BACK_EMISSION | MAT_BIT_BACK_AMBIENT)) {
709*61046927SAndroid Build Coastguard Worker       COPY_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_EMISSION] );
710*61046927SAndroid Build Coastguard Worker       ACC_SCALE_3V( ctx->Light._BaseColor[1], mat[MAT_ATTRIB_BACK_AMBIENT],
711*61046927SAndroid Build Coastguard Worker 		    ctx->Light.Model.Ambient );
712*61046927SAndroid Build Coastguard Worker    }
713*61046927SAndroid Build Coastguard Worker 
714*61046927SAndroid Build Coastguard Worker    /* update material diffuse values */
715*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_FRONT_DIFFUSE) {
716*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
717*61046927SAndroid Build Coastguard Worker       while (mask) {
718*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
719*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
720*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
721*61046927SAndroid Build Coastguard Worker 	 SCALE_3V( light->_MatDiffuse[0], lu->Diffuse,
722*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_FRONT_DIFFUSE] );
723*61046927SAndroid Build Coastguard Worker       }
724*61046927SAndroid Build Coastguard Worker    }
725*61046927SAndroid Build Coastguard Worker 
726*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_BACK_DIFFUSE) {
727*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
728*61046927SAndroid Build Coastguard Worker       while (mask) {
729*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
730*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
731*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
732*61046927SAndroid Build Coastguard Worker 	 SCALE_3V( light->_MatDiffuse[1], lu->Diffuse,
733*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_BACK_DIFFUSE] );
734*61046927SAndroid Build Coastguard Worker       }
735*61046927SAndroid Build Coastguard Worker    }
736*61046927SAndroid Build Coastguard Worker 
737*61046927SAndroid Build Coastguard Worker    /* update material specular values */
738*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_FRONT_SPECULAR) {
739*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
740*61046927SAndroid Build Coastguard Worker       while (mask) {
741*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
742*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
743*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
744*61046927SAndroid Build Coastguard Worker 	 SCALE_3V( light->_MatSpecular[0], lu->Specular,
745*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_FRONT_SPECULAR]);
746*61046927SAndroid Build Coastguard Worker       }
747*61046927SAndroid Build Coastguard Worker    }
748*61046927SAndroid Build Coastguard Worker 
749*61046927SAndroid Build Coastguard Worker    if (bitmask & MAT_BIT_BACK_SPECULAR) {
750*61046927SAndroid Build Coastguard Worker       GLbitfield mask = ctx->Light._EnabledLights;
751*61046927SAndroid Build Coastguard Worker       while (mask) {
752*61046927SAndroid Build Coastguard Worker          const int i = u_bit_scan(&mask);
753*61046927SAndroid Build Coastguard Worker          struct gl_light *light = &ctx->Light.Light[i];
754*61046927SAndroid Build Coastguard Worker          struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
755*61046927SAndroid Build Coastguard Worker 	 SCALE_3V( light->_MatSpecular[1], lu->Specular,
756*61046927SAndroid Build Coastguard Worker 		   mat[MAT_ATTRIB_BACK_SPECULAR]);
757*61046927SAndroid Build Coastguard Worker       }
758*61046927SAndroid Build Coastguard Worker    }
759*61046927SAndroid Build Coastguard Worker }
760*61046927SAndroid Build Coastguard Worker 
761*61046927SAndroid Build Coastguard Worker 
762*61046927SAndroid Build Coastguard Worker /*
763*61046927SAndroid Build Coastguard Worker  * Update the current materials from the given rgba color
764*61046927SAndroid Build Coastguard Worker  * according to the bitmask in _ColorMaterialBitmask, which is
765*61046927SAndroid Build Coastguard Worker  * set by glColorMaterial().
766*61046927SAndroid Build Coastguard Worker  */
767*61046927SAndroid Build Coastguard Worker void
_mesa_update_color_material(struct gl_context * ctx,const GLfloat color[4])768*61046927SAndroid Build Coastguard Worker _mesa_update_color_material( struct gl_context *ctx, const GLfloat color[4] )
769*61046927SAndroid Build Coastguard Worker {
770*61046927SAndroid Build Coastguard Worker    GLbitfield bitmask = ctx->Light._ColorMaterialBitmask;
771*61046927SAndroid Build Coastguard Worker    struct gl_material *mat = &ctx->Light.Material;
772*61046927SAndroid Build Coastguard Worker 
773*61046927SAndroid Build Coastguard Worker    while (bitmask) {
774*61046927SAndroid Build Coastguard Worker       const int i = u_bit_scan(&bitmask);
775*61046927SAndroid Build Coastguard Worker 
776*61046927SAndroid Build Coastguard Worker       if (memcmp(mat->Attrib[i], color, sizeof(mat->Attrib[i]))) {
777*61046927SAndroid Build Coastguard Worker          COPY_4FV(mat->Attrib[i], color);
778*61046927SAndroid Build Coastguard Worker          ctx->NewState |= _NEW_MATERIAL;
779*61046927SAndroid Build Coastguard Worker       }
780*61046927SAndroid Build Coastguard Worker    }
781*61046927SAndroid Build Coastguard Worker }
782*61046927SAndroid Build Coastguard Worker 
783*61046927SAndroid Build Coastguard Worker 
784*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_ColorMaterial(GLenum face,GLenum mode)785*61046927SAndroid Build Coastguard Worker _mesa_ColorMaterial( GLenum face, GLenum mode )
786*61046927SAndroid Build Coastguard Worker {
787*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
788*61046927SAndroid Build Coastguard Worker    GLuint bitmask;
789*61046927SAndroid Build Coastguard Worker    GLuint legal = (MAT_BIT_FRONT_EMISSION | MAT_BIT_BACK_EMISSION |
790*61046927SAndroid Build Coastguard Worker 		   MAT_BIT_FRONT_SPECULAR | MAT_BIT_BACK_SPECULAR |
791*61046927SAndroid Build Coastguard Worker 		   MAT_BIT_FRONT_DIFFUSE  | MAT_BIT_BACK_DIFFUSE  |
792*61046927SAndroid Build Coastguard Worker 		   MAT_BIT_FRONT_AMBIENT  | MAT_BIT_BACK_AMBIENT);
793*61046927SAndroid Build Coastguard Worker 
794*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE&VERBOSE_API)
795*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glColorMaterial %s %s\n",
796*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(face),
797*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(mode));
798*61046927SAndroid Build Coastguard Worker 
799*61046927SAndroid Build Coastguard Worker    bitmask = _mesa_material_bitmask(ctx, face, mode, legal, "glColorMaterial");
800*61046927SAndroid Build Coastguard Worker    if (bitmask == 0)
801*61046927SAndroid Build Coastguard Worker       return; /* error was recorded */
802*61046927SAndroid Build Coastguard Worker 
803*61046927SAndroid Build Coastguard Worker    if (ctx->Light._ColorMaterialBitmask == bitmask &&
804*61046927SAndroid Build Coastguard Worker        ctx->Light.ColorMaterialFace == face &&
805*61046927SAndroid Build Coastguard Worker        ctx->Light.ColorMaterialMode == mode)
806*61046927SAndroid Build Coastguard Worker       return;
807*61046927SAndroid Build Coastguard Worker 
808*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, GL_LIGHTING_BIT);
809*61046927SAndroid Build Coastguard Worker    ctx->Light._ColorMaterialBitmask = bitmask;
810*61046927SAndroid Build Coastguard Worker    ctx->Light.ColorMaterialFace = face;
811*61046927SAndroid Build Coastguard Worker    ctx->Light.ColorMaterialMode = mode;
812*61046927SAndroid Build Coastguard Worker 
813*61046927SAndroid Build Coastguard Worker    if (ctx->Light.ColorMaterialEnabled) {
814*61046927SAndroid Build Coastguard Worker       /* Used by fixed-func vertex program. */
815*61046927SAndroid Build Coastguard Worker       FLUSH_CURRENT(ctx, _NEW_FF_VERT_PROGRAM);
816*61046927SAndroid Build Coastguard Worker       _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]);
817*61046927SAndroid Build Coastguard Worker    }
818*61046927SAndroid Build Coastguard Worker }
819*61046927SAndroid Build Coastguard Worker 
820*61046927SAndroid Build Coastguard Worker 
821*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)822*61046927SAndroid Build Coastguard Worker _mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params )
823*61046927SAndroid Build Coastguard Worker {
824*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
825*61046927SAndroid Build Coastguard Worker    GLuint f;
826*61046927SAndroid Build Coastguard Worker    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
827*61046927SAndroid Build Coastguard Worker 
828*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0); /* update materials */
829*61046927SAndroid Build Coastguard Worker    FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
830*61046927SAndroid Build Coastguard Worker 
831*61046927SAndroid Build Coastguard Worker    if (face==GL_FRONT) {
832*61046927SAndroid Build Coastguard Worker       f = 0;
833*61046927SAndroid Build Coastguard Worker    }
834*61046927SAndroid Build Coastguard Worker    else if (face==GL_BACK) {
835*61046927SAndroid Build Coastguard Worker       f = 1;
836*61046927SAndroid Build Coastguard Worker    }
837*61046927SAndroid Build Coastguard Worker    else {
838*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(face)" );
839*61046927SAndroid Build Coastguard Worker       return;
840*61046927SAndroid Build Coastguard Worker    }
841*61046927SAndroid Build Coastguard Worker 
842*61046927SAndroid Build Coastguard Worker    switch (pname) {
843*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
844*61046927SAndroid Build Coastguard Worker          COPY_4FV( params, mat[MAT_ATTRIB_AMBIENT(f)] );
845*61046927SAndroid Build Coastguard Worker          break;
846*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
847*61046927SAndroid Build Coastguard Worker          COPY_4FV( params, mat[MAT_ATTRIB_DIFFUSE(f)] );
848*61046927SAndroid Build Coastguard Worker 	 break;
849*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
850*61046927SAndroid Build Coastguard Worker          COPY_4FV( params, mat[MAT_ATTRIB_SPECULAR(f)] );
851*61046927SAndroid Build Coastguard Worker 	 break;
852*61046927SAndroid Build Coastguard Worker       case GL_EMISSION:
853*61046927SAndroid Build Coastguard Worker 	 COPY_4FV( params, mat[MAT_ATTRIB_EMISSION(f)] );
854*61046927SAndroid Build Coastguard Worker 	 break;
855*61046927SAndroid Build Coastguard Worker       case GL_SHININESS:
856*61046927SAndroid Build Coastguard Worker 	 *params = mat[MAT_ATTRIB_SHININESS(f)][0];
857*61046927SAndroid Build Coastguard Worker 	 break;
858*61046927SAndroid Build Coastguard Worker       case GL_COLOR_INDEXES:
859*61046927SAndroid Build Coastguard Worker          if (ctx->API != API_OPENGL_COMPAT) {
860*61046927SAndroid Build Coastguard Worker             _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
861*61046927SAndroid Build Coastguard Worker             return;
862*61046927SAndroid Build Coastguard Worker          }
863*61046927SAndroid Build Coastguard Worker 	 params[0] = mat[MAT_ATTRIB_INDEXES(f)][0];
864*61046927SAndroid Build Coastguard Worker 	 params[1] = mat[MAT_ATTRIB_INDEXES(f)][1];
865*61046927SAndroid Build Coastguard Worker 	 params[2] = mat[MAT_ATTRIB_INDEXES(f)][2];
866*61046927SAndroid Build Coastguard Worker 	 break;
867*61046927SAndroid Build Coastguard Worker       default:
868*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
869*61046927SAndroid Build Coastguard Worker    }
870*61046927SAndroid Build Coastguard Worker }
871*61046927SAndroid Build Coastguard Worker 
872*61046927SAndroid Build Coastguard Worker 
873*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetMaterialiv(GLenum face,GLenum pname,GLint * params)874*61046927SAndroid Build Coastguard Worker _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params )
875*61046927SAndroid Build Coastguard Worker {
876*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
877*61046927SAndroid Build Coastguard Worker    GLuint f;
878*61046927SAndroid Build Coastguard Worker    GLfloat (*mat)[4] = ctx->Light.Material.Attrib;
879*61046927SAndroid Build Coastguard Worker 
880*61046927SAndroid Build Coastguard Worker    assert(_mesa_is_desktop_gl_compat(ctx));
881*61046927SAndroid Build Coastguard Worker 
882*61046927SAndroid Build Coastguard Worker    FLUSH_VERTICES(ctx, 0, 0); /* update materials */
883*61046927SAndroid Build Coastguard Worker    FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */
884*61046927SAndroid Build Coastguard Worker 
885*61046927SAndroid Build Coastguard Worker    if (face==GL_FRONT) {
886*61046927SAndroid Build Coastguard Worker       f = 0;
887*61046927SAndroid Build Coastguard Worker    }
888*61046927SAndroid Build Coastguard Worker    else if (face==GL_BACK) {
889*61046927SAndroid Build Coastguard Worker       f = 1;
890*61046927SAndroid Build Coastguard Worker    }
891*61046927SAndroid Build Coastguard Worker    else {
892*61046927SAndroid Build Coastguard Worker       _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialiv(face)" );
893*61046927SAndroid Build Coastguard Worker       return;
894*61046927SAndroid Build Coastguard Worker    }
895*61046927SAndroid Build Coastguard Worker    switch (pname) {
896*61046927SAndroid Build Coastguard Worker       case GL_AMBIENT:
897*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][0] );
898*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][1] );
899*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][2] );
900*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_AMBIENT(f)][3] );
901*61046927SAndroid Build Coastguard Worker          break;
902*61046927SAndroid Build Coastguard Worker       case GL_DIFFUSE:
903*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][0] );
904*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][1] );
905*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][2] );
906*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_DIFFUSE(f)][3] );
907*61046927SAndroid Build Coastguard Worker 	 break;
908*61046927SAndroid Build Coastguard Worker       case GL_SPECULAR:
909*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][0] );
910*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][1] );
911*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][2] );
912*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_SPECULAR(f)][3] );
913*61046927SAndroid Build Coastguard Worker 	 break;
914*61046927SAndroid Build Coastguard Worker       case GL_EMISSION:
915*61046927SAndroid Build Coastguard Worker          params[0] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][0] );
916*61046927SAndroid Build Coastguard Worker          params[1] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][1] );
917*61046927SAndroid Build Coastguard Worker          params[2] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][2] );
918*61046927SAndroid Build Coastguard Worker          params[3] = FLOAT_TO_INT( mat[MAT_ATTRIB_EMISSION(f)][3] );
919*61046927SAndroid Build Coastguard Worker 	 break;
920*61046927SAndroid Build Coastguard Worker       case GL_SHININESS:
921*61046927SAndroid Build Coastguard Worker          *params = lroundf( mat[MAT_ATTRIB_SHININESS(f)][0] );
922*61046927SAndroid Build Coastguard Worker 	 break;
923*61046927SAndroid Build Coastguard Worker       case GL_COLOR_INDEXES:
924*61046927SAndroid Build Coastguard Worker 	 params[0] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][0] );
925*61046927SAndroid Build Coastguard Worker 	 params[1] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][1] );
926*61046927SAndroid Build Coastguard Worker 	 params[2] = lroundf( mat[MAT_ATTRIB_INDEXES(f)][2] );
927*61046927SAndroid Build Coastguard Worker 	 break;
928*61046927SAndroid Build Coastguard Worker       default:
929*61046927SAndroid Build Coastguard Worker          _mesa_error( ctx, GL_INVALID_ENUM, "glGetMaterialfv(pname)" );
930*61046927SAndroid Build Coastguard Worker    }
931*61046927SAndroid Build Coastguard Worker }
932*61046927SAndroid Build Coastguard Worker 
933*61046927SAndroid Build Coastguard Worker 
934*61046927SAndroid Build Coastguard Worker 
935*61046927SAndroid Build Coastguard Worker /**
936*61046927SAndroid Build Coastguard Worker  * Examine current lighting parameters to determine if the optimized lighting
937*61046927SAndroid Build Coastguard Worker  * function can be used.
938*61046927SAndroid Build Coastguard Worker  * Also, precompute some lighting values such as the products of light
939*61046927SAndroid Build Coastguard Worker  * source and material ambient, diffuse and specular coefficients.
940*61046927SAndroid Build Coastguard Worker  */
941*61046927SAndroid Build Coastguard Worker GLbitfield
_mesa_update_lighting(struct gl_context * ctx)942*61046927SAndroid Build Coastguard Worker _mesa_update_lighting( struct gl_context *ctx )
943*61046927SAndroid Build Coastguard Worker {
944*61046927SAndroid Build Coastguard Worker    GLbitfield flags = 0;
945*61046927SAndroid Build Coastguard Worker    bool old_need_eye_coords = ctx->Light._NeedEyeCoords;
946*61046927SAndroid Build Coastguard Worker    ctx->Light._NeedEyeCoords = GL_FALSE;
947*61046927SAndroid Build Coastguard Worker 
948*61046927SAndroid Build Coastguard Worker    if (!ctx->Light.Enabled) {
949*61046927SAndroid Build Coastguard Worker       return old_need_eye_coords != ctx->Light._NeedEyeCoords ?
950*61046927SAndroid Build Coastguard Worker                                        _NEW_TNL_SPACES : 0;
951*61046927SAndroid Build Coastguard Worker    }
952*61046927SAndroid Build Coastguard Worker 
953*61046927SAndroid Build Coastguard Worker    GLbitfield mask = ctx->Light._EnabledLights;
954*61046927SAndroid Build Coastguard Worker    while (mask) {
955*61046927SAndroid Build Coastguard Worker       const int i = u_bit_scan(&mask);
956*61046927SAndroid Build Coastguard Worker       struct gl_light *light = &ctx->Light.Light[i];
957*61046927SAndroid Build Coastguard Worker       flags |= light->_Flags;
958*61046927SAndroid Build Coastguard Worker    }
959*61046927SAndroid Build Coastguard Worker 
960*61046927SAndroid Build Coastguard Worker    ctx->Light._NeedVertices =
961*61046927SAndroid Build Coastguard Worker       ((flags & (LIGHT_POSITIONAL|LIGHT_SPOT)) ||
962*61046927SAndroid Build Coastguard Worker        ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ||
963*61046927SAndroid Build Coastguard Worker        ctx->Light.Model.LocalViewer);
964*61046927SAndroid Build Coastguard Worker 
965*61046927SAndroid Build Coastguard Worker    ctx->Light._NeedEyeCoords = ((flags & LIGHT_POSITIONAL) ||
966*61046927SAndroid Build Coastguard Worker 				ctx->Light.Model.LocalViewer);
967*61046927SAndroid Build Coastguard Worker 
968*61046927SAndroid Build Coastguard Worker    /* XXX: This test is overkill & needs to be fixed both for software and
969*61046927SAndroid Build Coastguard Worker     * hardware t&l drivers.  The above should be sufficient & should
970*61046927SAndroid Build Coastguard Worker     * be tested to verify this.
971*61046927SAndroid Build Coastguard Worker     */
972*61046927SAndroid Build Coastguard Worker    if (ctx->Light._NeedVertices)
973*61046927SAndroid Build Coastguard Worker       ctx->Light._NeedEyeCoords = GL_TRUE;
974*61046927SAndroid Build Coastguard Worker 
975*61046927SAndroid Build Coastguard Worker    return old_need_eye_coords != ctx->Light._NeedEyeCoords ?
976*61046927SAndroid Build Coastguard Worker                                     _NEW_TNL_SPACES : 0;
977*61046927SAndroid Build Coastguard Worker }
978*61046927SAndroid Build Coastguard Worker 
979*61046927SAndroid Build Coastguard Worker void
_mesa_update_light_materials(struct gl_context * ctx)980*61046927SAndroid Build Coastguard Worker _mesa_update_light_materials(struct gl_context *ctx)
981*61046927SAndroid Build Coastguard Worker {
982*61046927SAndroid Build Coastguard Worker    /* Precompute some shading values.  Although we reference
983*61046927SAndroid Build Coastguard Worker     * Light.Material here, we can get away without flushing
984*61046927SAndroid Build Coastguard Worker     * FLUSH_UPDATE_CURRENT, as when any outstanding material changes
985*61046927SAndroid Build Coastguard Worker     * are flushed, they will update the derived state at that time.
986*61046927SAndroid Build Coastguard Worker     */
987*61046927SAndroid Build Coastguard Worker    if (ctx->Light.Model.TwoSide)
988*61046927SAndroid Build Coastguard Worker       _mesa_update_material(ctx,
989*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_EMISSION |
990*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_AMBIENT |
991*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_DIFFUSE |
992*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_SPECULAR |
993*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_BACK_EMISSION |
994*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_BACK_AMBIENT |
995*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_BACK_DIFFUSE |
996*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_BACK_SPECULAR);
997*61046927SAndroid Build Coastguard Worker    else
998*61046927SAndroid Build Coastguard Worker       _mesa_update_material(ctx,
999*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_EMISSION |
1000*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_AMBIENT |
1001*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_DIFFUSE |
1002*61046927SAndroid Build Coastguard Worker 			    MAT_BIT_FRONT_SPECULAR);
1003*61046927SAndroid Build Coastguard Worker }
1004*61046927SAndroid Build Coastguard Worker 
1005*61046927SAndroid Build Coastguard Worker 
1006*61046927SAndroid Build Coastguard Worker /**
1007*61046927SAndroid Build Coastguard Worker  * Update state derived from light position, spot direction.
1008*61046927SAndroid Build Coastguard Worker  * Called upon:
1009*61046927SAndroid Build Coastguard Worker  *   _NEW_MODELVIEW
1010*61046927SAndroid Build Coastguard Worker  *   _NEW_LIGHT_CONSTANTS
1011*61046927SAndroid Build Coastguard Worker  *   _TNL_NEW_NEED_EYE_COORDS
1012*61046927SAndroid Build Coastguard Worker  *
1013*61046927SAndroid Build Coastguard Worker  * Update on (_NEW_MODELVIEW | _NEW_LIGHT_CONSTANTS) when lighting is enabled.
1014*61046927SAndroid Build Coastguard Worker  * Also update on lighting space changes.
1015*61046927SAndroid Build Coastguard Worker  */
1016*61046927SAndroid Build Coastguard Worker static void
compute_light_positions(struct gl_context * ctx)1017*61046927SAndroid Build Coastguard Worker compute_light_positions( struct gl_context *ctx )
1018*61046927SAndroid Build Coastguard Worker {
1019*61046927SAndroid Build Coastguard Worker    static const GLfloat eye_z[3] = { 0, 0, 1 };
1020*61046927SAndroid Build Coastguard Worker 
1021*61046927SAndroid Build Coastguard Worker    if (!ctx->Light.Enabled)
1022*61046927SAndroid Build Coastguard Worker       return;
1023*61046927SAndroid Build Coastguard Worker 
1024*61046927SAndroid Build Coastguard Worker    if (ctx->_NeedEyeCoords) {
1025*61046927SAndroid Build Coastguard Worker       COPY_3V( ctx->_EyeZDir, eye_z );
1026*61046927SAndroid Build Coastguard Worker    }
1027*61046927SAndroid Build Coastguard Worker    else {
1028*61046927SAndroid Build Coastguard Worker       TRANSFORM_NORMAL( ctx->_EyeZDir, eye_z, ctx->ModelviewMatrixStack.Top->m );
1029*61046927SAndroid Build Coastguard Worker    }
1030*61046927SAndroid Build Coastguard Worker 
1031*61046927SAndroid Build Coastguard Worker    GLbitfield mask = ctx->Light._EnabledLights;
1032*61046927SAndroid Build Coastguard Worker    while (mask) {
1033*61046927SAndroid Build Coastguard Worker       const int i = u_bit_scan(&mask);
1034*61046927SAndroid Build Coastguard Worker       struct gl_light *light = &ctx->Light.Light[i];
1035*61046927SAndroid Build Coastguard Worker       struct gl_light_uniforms *lu = &ctx->Light.LightSource[i];
1036*61046927SAndroid Build Coastguard Worker 
1037*61046927SAndroid Build Coastguard Worker       if (ctx->_NeedEyeCoords) {
1038*61046927SAndroid Build Coastguard Worker          /* _Position is in eye coordinate space */
1039*61046927SAndroid Build Coastguard Worker 	 COPY_4FV( light->_Position, lu->EyePosition );
1040*61046927SAndroid Build Coastguard Worker       }
1041*61046927SAndroid Build Coastguard Worker       else {
1042*61046927SAndroid Build Coastguard Worker          /* _Position is in object coordinate space */
1043*61046927SAndroid Build Coastguard Worker 	 TRANSFORM_POINT( light->_Position, ctx->ModelviewMatrixStack.Top->inv,
1044*61046927SAndroid Build Coastguard Worker 			  lu->EyePosition );
1045*61046927SAndroid Build Coastguard Worker       }
1046*61046927SAndroid Build Coastguard Worker 
1047*61046927SAndroid Build Coastguard Worker       if (!(light->_Flags & LIGHT_POSITIONAL)) {
1048*61046927SAndroid Build Coastguard Worker 	 /* VP (VP) = Normalize( Position ) */
1049*61046927SAndroid Build Coastguard Worker 	 COPY_3V( light->_VP_inf_norm, light->_Position );
1050*61046927SAndroid Build Coastguard Worker 	 NORMALIZE_3FV( light->_VP_inf_norm );
1051*61046927SAndroid Build Coastguard Worker 
1052*61046927SAndroid Build Coastguard Worker 	 if (!ctx->Light.Model.LocalViewer) {
1053*61046927SAndroid Build Coastguard Worker 	    /* _h_inf_norm = Normalize( V_to_P + <0,0,1> ) */
1054*61046927SAndroid Build Coastguard Worker 	    ADD_3V( light->_h_inf_norm, light->_VP_inf_norm, ctx->_EyeZDir);
1055*61046927SAndroid Build Coastguard Worker 	    NORMALIZE_3FV( light->_h_inf_norm );
1056*61046927SAndroid Build Coastguard Worker 	 }
1057*61046927SAndroid Build Coastguard Worker 	 light->_VP_inf_spot_attenuation = 1.0;
1058*61046927SAndroid Build Coastguard Worker       }
1059*61046927SAndroid Build Coastguard Worker       else {
1060*61046927SAndroid Build Coastguard Worker          /* positional light w/ homogeneous coordinate, divide by W */
1061*61046927SAndroid Build Coastguard Worker          GLfloat wInv = 1.0F / light->_Position[3];
1062*61046927SAndroid Build Coastguard Worker          light->_Position[0] *= wInv;
1063*61046927SAndroid Build Coastguard Worker          light->_Position[1] *= wInv;
1064*61046927SAndroid Build Coastguard Worker          light->_Position[2] *= wInv;
1065*61046927SAndroid Build Coastguard Worker       }
1066*61046927SAndroid Build Coastguard Worker 
1067*61046927SAndroid Build Coastguard Worker       if (light->_Flags & LIGHT_SPOT) {
1068*61046927SAndroid Build Coastguard Worker          /* Note: we normalize the spot direction now */
1069*61046927SAndroid Build Coastguard Worker 
1070*61046927SAndroid Build Coastguard Worker 	 if (ctx->_NeedEyeCoords) {
1071*61046927SAndroid Build Coastguard Worker 	    COPY_3V( light->_NormSpotDirection, lu->SpotDirection );
1072*61046927SAndroid Build Coastguard Worker             NORMALIZE_3FV( light->_NormSpotDirection );
1073*61046927SAndroid Build Coastguard Worker 	 }
1074*61046927SAndroid Build Coastguard Worker          else {
1075*61046927SAndroid Build Coastguard Worker             GLfloat spotDir[3];
1076*61046927SAndroid Build Coastguard Worker             COPY_3V(spotDir, lu->SpotDirection);
1077*61046927SAndroid Build Coastguard Worker             NORMALIZE_3FV(spotDir);
1078*61046927SAndroid Build Coastguard Worker 	    TRANSFORM_NORMAL( light->_NormSpotDirection,
1079*61046927SAndroid Build Coastguard Worker 			      spotDir,
1080*61046927SAndroid Build Coastguard Worker 			      ctx->ModelviewMatrixStack.Top->m);
1081*61046927SAndroid Build Coastguard Worker 	 }
1082*61046927SAndroid Build Coastguard Worker 
1083*61046927SAndroid Build Coastguard Worker 	 NORMALIZE_3FV( light->_NormSpotDirection );
1084*61046927SAndroid Build Coastguard Worker 
1085*61046927SAndroid Build Coastguard Worker 	 if (!(light->_Flags & LIGHT_POSITIONAL)) {
1086*61046927SAndroid Build Coastguard Worker 	    GLfloat PV_dot_dir = - DOT3(light->_VP_inf_norm,
1087*61046927SAndroid Build Coastguard Worker 					light->_NormSpotDirection);
1088*61046927SAndroid Build Coastguard Worker 
1089*61046927SAndroid Build Coastguard Worker 	    if (PV_dot_dir > lu->_CosCutoff) {
1090*61046927SAndroid Build Coastguard Worker 	       light->_VP_inf_spot_attenuation =
1091*61046927SAndroid Build Coastguard Worker                   powf(PV_dot_dir, lu->SpotExponent);
1092*61046927SAndroid Build Coastguard Worker 	    }
1093*61046927SAndroid Build Coastguard Worker 	    else {
1094*61046927SAndroid Build Coastguard Worker 	       light->_VP_inf_spot_attenuation = 0;
1095*61046927SAndroid Build Coastguard Worker             }
1096*61046927SAndroid Build Coastguard Worker 	 }
1097*61046927SAndroid Build Coastguard Worker       }
1098*61046927SAndroid Build Coastguard Worker    }
1099*61046927SAndroid Build Coastguard Worker }
1100*61046927SAndroid Build Coastguard Worker 
1101*61046927SAndroid Build Coastguard Worker 
1102*61046927SAndroid Build Coastguard Worker 
1103*61046927SAndroid Build Coastguard Worker static void
update_modelview_scale(struct gl_context * ctx)1104*61046927SAndroid Build Coastguard Worker update_modelview_scale( struct gl_context *ctx )
1105*61046927SAndroid Build Coastguard Worker {
1106*61046927SAndroid Build Coastguard Worker    ctx->_ModelViewInvScale = 1.0F;
1107*61046927SAndroid Build Coastguard Worker    ctx->_ModelViewInvScaleEyespace = 1.0F;
1108*61046927SAndroid Build Coastguard Worker    if (!_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top)) {
1109*61046927SAndroid Build Coastguard Worker       const GLfloat *m = ctx->ModelviewMatrixStack.Top->inv;
1110*61046927SAndroid Build Coastguard Worker       GLfloat f = m[2] * m[2] + m[6] * m[6] + m[10] * m[10];
1111*61046927SAndroid Build Coastguard Worker       if (f < 1e-12f) f = 1.0f;
1112*61046927SAndroid Build Coastguard Worker       if (ctx->_NeedEyeCoords)
1113*61046927SAndroid Build Coastguard Worker 	 ctx->_ModelViewInvScale = 1.0f / sqrtf(f);
1114*61046927SAndroid Build Coastguard Worker       else
1115*61046927SAndroid Build Coastguard Worker 	 ctx->_ModelViewInvScale = sqrtf(f);
1116*61046927SAndroid Build Coastguard Worker       ctx->_ModelViewInvScaleEyespace = 1.0f / sqrtf(f);
1117*61046927SAndroid Build Coastguard Worker    }
1118*61046927SAndroid Build Coastguard Worker }
1119*61046927SAndroid Build Coastguard Worker 
1120*61046927SAndroid Build Coastguard Worker 
1121*61046927SAndroid Build Coastguard Worker /**
1122*61046927SAndroid Build Coastguard Worker  * Bring up to date any state that relies on _NeedEyeCoords.
1123*61046927SAndroid Build Coastguard Worker  *
1124*61046927SAndroid Build Coastguard Worker  * Return true if ctx->_NeedEyeCoords has been changed.
1125*61046927SAndroid Build Coastguard Worker  */
1126*61046927SAndroid Build Coastguard Worker bool
_mesa_update_tnl_spaces(struct gl_context * ctx,GLuint new_state)1127*61046927SAndroid Build Coastguard Worker _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state )
1128*61046927SAndroid Build Coastguard Worker {
1129*61046927SAndroid Build Coastguard Worker    const GLuint oldneedeyecoords = ctx->_NeedEyeCoords;
1130*61046927SAndroid Build Coastguard Worker 
1131*61046927SAndroid Build Coastguard Worker    (void) new_state;
1132*61046927SAndroid Build Coastguard Worker    ctx->_NeedEyeCoords = GL_FALSE;
1133*61046927SAndroid Build Coastguard Worker 
1134*61046927SAndroid Build Coastguard Worker    if ((ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) ||
1135*61046927SAndroid Build Coastguard Worker        ctx->Point._Attenuated ||
1136*61046927SAndroid Build Coastguard Worker        ctx->Light._NeedEyeCoords)
1137*61046927SAndroid Build Coastguard Worker       ctx->_NeedEyeCoords = GL_TRUE;
1138*61046927SAndroid Build Coastguard Worker 
1139*61046927SAndroid Build Coastguard Worker    if (ctx->Light.Enabled &&
1140*61046927SAndroid Build Coastguard Worker        !_math_matrix_is_length_preserving(ctx->ModelviewMatrixStack.Top))
1141*61046927SAndroid Build Coastguard Worker       ctx->_NeedEyeCoords = GL_TRUE;
1142*61046927SAndroid Build Coastguard Worker 
1143*61046927SAndroid Build Coastguard Worker    /* Check if the truth-value interpretations of the bitfields have
1144*61046927SAndroid Build Coastguard Worker     * changed:
1145*61046927SAndroid Build Coastguard Worker     */
1146*61046927SAndroid Build Coastguard Worker    if (oldneedeyecoords != ctx->_NeedEyeCoords) {
1147*61046927SAndroid Build Coastguard Worker       /* Recalculate all state that depends on _NeedEyeCoords.
1148*61046927SAndroid Build Coastguard Worker        */
1149*61046927SAndroid Build Coastguard Worker       update_modelview_scale(ctx);
1150*61046927SAndroid Build Coastguard Worker       compute_light_positions( ctx );
1151*61046927SAndroid Build Coastguard Worker 
1152*61046927SAndroid Build Coastguard Worker       return true;
1153*61046927SAndroid Build Coastguard Worker    }
1154*61046927SAndroid Build Coastguard Worker    else {
1155*61046927SAndroid Build Coastguard Worker       GLuint new_state2 = ctx->NewState;
1156*61046927SAndroid Build Coastguard Worker 
1157*61046927SAndroid Build Coastguard Worker       /* Recalculate that same state only if it has been invalidated
1158*61046927SAndroid Build Coastguard Worker        * by other statechanges.
1159*61046927SAndroid Build Coastguard Worker        */
1160*61046927SAndroid Build Coastguard Worker       if (new_state2 & _NEW_MODELVIEW)
1161*61046927SAndroid Build Coastguard Worker 	 update_modelview_scale(ctx);
1162*61046927SAndroid Build Coastguard Worker 
1163*61046927SAndroid Build Coastguard Worker       if (new_state2 & (_NEW_LIGHT_CONSTANTS | _NEW_MODELVIEW))
1164*61046927SAndroid Build Coastguard Worker 	 compute_light_positions( ctx );
1165*61046927SAndroid Build Coastguard Worker 
1166*61046927SAndroid Build Coastguard Worker       return false;
1167*61046927SAndroid Build Coastguard Worker    }
1168*61046927SAndroid Build Coastguard Worker }
1169*61046927SAndroid Build Coastguard Worker 
1170*61046927SAndroid Build Coastguard Worker 
1171*61046927SAndroid Build Coastguard Worker /**********************************************************************/
1172*61046927SAndroid Build Coastguard Worker /*****                      Initialization                        *****/
1173*61046927SAndroid Build Coastguard Worker /**********************************************************************/
1174*61046927SAndroid Build Coastguard Worker 
1175*61046927SAndroid Build Coastguard Worker /**
1176*61046927SAndroid Build Coastguard Worker  * Initialize the n-th light data structure.
1177*61046927SAndroid Build Coastguard Worker  *
1178*61046927SAndroid Build Coastguard Worker  * \param l pointer to the gl_light structure to be initialized.
1179*61046927SAndroid Build Coastguard Worker  * \param n number of the light.
1180*61046927SAndroid Build Coastguard Worker  * \note The defaults for light 0 are different than the other lights.
1181*61046927SAndroid Build Coastguard Worker  */
1182*61046927SAndroid Build Coastguard Worker static void
init_light(struct gl_light * l,struct gl_light_uniforms * lu,GLuint n)1183*61046927SAndroid Build Coastguard Worker init_light( struct gl_light *l, struct gl_light_uniforms *lu, GLuint n )
1184*61046927SAndroid Build Coastguard Worker {
1185*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( lu->Ambient, 0.0, 0.0, 0.0, 1.0 );
1186*61046927SAndroid Build Coastguard Worker    if (n==0) {
1187*61046927SAndroid Build Coastguard Worker       ASSIGN_4V( lu->Diffuse, 1.0, 1.0, 1.0, 1.0 );
1188*61046927SAndroid Build Coastguard Worker       ASSIGN_4V( lu->Specular, 1.0, 1.0, 1.0, 1.0 );
1189*61046927SAndroid Build Coastguard Worker    }
1190*61046927SAndroid Build Coastguard Worker    else {
1191*61046927SAndroid Build Coastguard Worker       ASSIGN_4V( lu->Diffuse, 0.0, 0.0, 0.0, 1.0 );
1192*61046927SAndroid Build Coastguard Worker       ASSIGN_4V( lu->Specular, 0.0, 0.0, 0.0, 1.0 );
1193*61046927SAndroid Build Coastguard Worker    }
1194*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( lu->EyePosition, 0.0, 0.0, 1.0, 0.0 );
1195*61046927SAndroid Build Coastguard Worker    ASSIGN_3V( lu->SpotDirection, 0.0, 0.0, -1.0 );
1196*61046927SAndroid Build Coastguard Worker    lu->SpotExponent = 0.0;
1197*61046927SAndroid Build Coastguard Worker    lu->SpotCutoff = 180.0;
1198*61046927SAndroid Build Coastguard Worker    lu->_CosCutoff = 0.0;		/* KW: -ve values not admitted */
1199*61046927SAndroid Build Coastguard Worker    lu->ConstantAttenuation = 1.0;
1200*61046927SAndroid Build Coastguard Worker    lu->LinearAttenuation = 0.0;
1201*61046927SAndroid Build Coastguard Worker    lu->QuadraticAttenuation = 0.0;
1202*61046927SAndroid Build Coastguard Worker    l->Enabled = GL_FALSE;
1203*61046927SAndroid Build Coastguard Worker }
1204*61046927SAndroid Build Coastguard Worker 
1205*61046927SAndroid Build Coastguard Worker 
1206*61046927SAndroid Build Coastguard Worker /**
1207*61046927SAndroid Build Coastguard Worker  * Initialize the light model data structure.
1208*61046927SAndroid Build Coastguard Worker  *
1209*61046927SAndroid Build Coastguard Worker  * \param lm pointer to the gl_lightmodel structure to be initialized.
1210*61046927SAndroid Build Coastguard Worker  */
1211*61046927SAndroid Build Coastguard Worker static void
init_lightmodel(struct gl_lightmodel * lm)1212*61046927SAndroid Build Coastguard Worker init_lightmodel( struct gl_lightmodel *lm )
1213*61046927SAndroid Build Coastguard Worker {
1214*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( lm->Ambient, 0.2F, 0.2F, 0.2F, 1.0F );
1215*61046927SAndroid Build Coastguard Worker    lm->LocalViewer = GL_FALSE;
1216*61046927SAndroid Build Coastguard Worker    lm->TwoSide = GL_FALSE;
1217*61046927SAndroid Build Coastguard Worker    lm->ColorControl = GL_SINGLE_COLOR;
1218*61046927SAndroid Build Coastguard Worker }
1219*61046927SAndroid Build Coastguard Worker 
1220*61046927SAndroid Build Coastguard Worker 
1221*61046927SAndroid Build Coastguard Worker /**
1222*61046927SAndroid Build Coastguard Worker  * Initialize the material data structure.
1223*61046927SAndroid Build Coastguard Worker  *
1224*61046927SAndroid Build Coastguard Worker  * \param m pointer to the gl_material structure to be initialized.
1225*61046927SAndroid Build Coastguard Worker  */
1226*61046927SAndroid Build Coastguard Worker static void
init_material(struct gl_material * m)1227*61046927SAndroid Build Coastguard Worker init_material( struct gl_material *m )
1228*61046927SAndroid Build Coastguard Worker {
1229*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1230*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1231*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1232*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1233*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1234*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_FRONT_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1235*61046927SAndroid Build Coastguard Worker 
1236*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_AMBIENT],  0.2F, 0.2F, 0.2F, 1.0F );
1237*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_DIFFUSE],  0.8F, 0.8F, 0.8F, 1.0F );
1238*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SPECULAR], 0.0F, 0.0F, 0.0F, 1.0F );
1239*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_EMISSION], 0.0F, 0.0F, 0.0F, 1.0F );
1240*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_SHININESS], 0.0F, 0.0F, 0.0F, 0.0F );
1241*61046927SAndroid Build Coastguard Worker    ASSIGN_4V( m->Attrib[MAT_ATTRIB_BACK_INDEXES], 0.0F, 1.0F, 1.0F, 0.0F );
1242*61046927SAndroid Build Coastguard Worker }
1243*61046927SAndroid Build Coastguard Worker 
1244*61046927SAndroid Build Coastguard Worker 
1245*61046927SAndroid Build Coastguard Worker /**
1246*61046927SAndroid Build Coastguard Worker  * Initialize all lighting state for the given context.
1247*61046927SAndroid Build Coastguard Worker  */
1248*61046927SAndroid Build Coastguard Worker void
_mesa_init_lighting(struct gl_context * ctx)1249*61046927SAndroid Build Coastguard Worker _mesa_init_lighting( struct gl_context *ctx )
1250*61046927SAndroid Build Coastguard Worker {
1251*61046927SAndroid Build Coastguard Worker    GLuint i;
1252*61046927SAndroid Build Coastguard Worker 
1253*61046927SAndroid Build Coastguard Worker    /* Lighting group */
1254*61046927SAndroid Build Coastguard Worker    ctx->Light._EnabledLights = 0;
1255*61046927SAndroid Build Coastguard Worker    for (i = 0; i < MAX_LIGHTS; i++) {
1256*61046927SAndroid Build Coastguard Worker       init_light( &ctx->Light.Light[i], &ctx->Light.LightSource[i], i );
1257*61046927SAndroid Build Coastguard Worker    }
1258*61046927SAndroid Build Coastguard Worker 
1259*61046927SAndroid Build Coastguard Worker    init_lightmodel( &ctx->Light.Model );
1260*61046927SAndroid Build Coastguard Worker    init_material( &ctx->Light.Material );
1261*61046927SAndroid Build Coastguard Worker    ctx->Light.ShadeModel = GL_SMOOTH;
1262*61046927SAndroid Build Coastguard Worker    ctx->Light.ProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1263*61046927SAndroid Build Coastguard Worker    ctx->Light.Enabled = GL_FALSE;
1264*61046927SAndroid Build Coastguard Worker    ctx->Light.ColorMaterialFace = GL_FRONT_AND_BACK;
1265*61046927SAndroid Build Coastguard Worker    ctx->Light.ColorMaterialMode = GL_AMBIENT_AND_DIFFUSE;
1266*61046927SAndroid Build Coastguard Worker    ctx->Light._ColorMaterialBitmask = _mesa_material_bitmask( ctx,
1267*61046927SAndroid Build Coastguard Worker                                                GL_FRONT_AND_BACK,
1268*61046927SAndroid Build Coastguard Worker                                                GL_AMBIENT_AND_DIFFUSE, ~0,
1269*61046927SAndroid Build Coastguard Worker                                                NULL );
1270*61046927SAndroid Build Coastguard Worker 
1271*61046927SAndroid Build Coastguard Worker    ctx->Light.ColorMaterialEnabled = GL_FALSE;
1272*61046927SAndroid Build Coastguard Worker    ctx->Light.ClampVertexColor = _mesa_is_desktop_gl_compat(ctx);
1273*61046927SAndroid Build Coastguard Worker    ctx->Light._ClampVertexColor = _mesa_is_desktop_gl_compat(ctx);
1274*61046927SAndroid Build Coastguard Worker 
1275*61046927SAndroid Build Coastguard Worker    /* Miscellaneous */
1276*61046927SAndroid Build Coastguard Worker    ctx->Light._NeedEyeCoords = GL_FALSE;
1277*61046927SAndroid Build Coastguard Worker    ctx->_NeedEyeCoords = GL_FALSE;
1278*61046927SAndroid Build Coastguard Worker    ctx->_ModelViewInvScale = 1.0;
1279*61046927SAndroid Build Coastguard Worker    ctx->_ModelViewInvScaleEyespace = 1.0;
1280*61046927SAndroid Build Coastguard Worker }
1281