1 /* libs/opengles/light.cpp
3 ** Copyright 2006, The Android Open Source Project
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
26 #if defined(__arm__) && defined(__thumb__)
27 #warning "light.cpp should not be compiled in thumb on ARM."
32 // ----------------------------------------------------------------------------
34 static void invalidate_lighting(ogles_context_t* c);
35 static void lightVertexValidate(ogles_context_t* c, vertex_t* v);
36 static void lightVertexNop(ogles_context_t* c, vertex_t* v);
37 static void lightVertex(ogles_context_t* c, vertex_t* v);
38 static void lightVertexMaterial(ogles_context_t* c, vertex_t* v);
40 static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s);
42 static __attribute__((noinline))
43 void vnorm3(GLfixed* d, const GLfixed* a);
45 static inline void vsa3(GLfixed* d,
46 const GLfixed* m, GLfixed s, const GLfixed* a);
47 static inline void vss3(GLfixed* d,
48 const GLfixed* m, GLfixed s, const GLfixed* a);
49 static inline void vmla3(GLfixed* d,
50 const GLfixed* m0, const GLfixed* m1, const GLfixed* a);
51 static inline void vmul3(GLfixed* d,
52 const GLfixed* m0, const GLfixed* m1);
54 static GLfixed fog_linear(ogles_context_t* c, GLfixed z);
55 static GLfixed fog_exp(ogles_context_t* c, GLfixed z);
56 static GLfixed fog_exp2(ogles_context_t* c, GLfixed z);
59 // ----------------------------------------------------------------------------
61 static void init_white(vec4_t& c) {
62 c.r = c.g = c.b = c.a = 0x10000;
65 void ogles_init_light(ogles_context_t* c)
67 for (unsigned int i=0 ; i<OGLES_MAX_LIGHTS ; i++) {
68 c->lighting.lights[i].ambient.a = 0x10000;
69 c->lighting.lights[i].position.z = 0x10000;
70 c->lighting.lights[i].spotDir.z = -0x10000;
71 c->lighting.lights[i].spotCutoff = gglIntToFixed(180);
72 c->lighting.lights[i].attenuation[0] = 0x10000;
74 init_white(c->lighting.lights[0].diffuse);
75 init_white(c->lighting.lights[0].specular);
77 c->lighting.front.ambient.r =
78 c->lighting.front.ambient.g =
79 c->lighting.front.ambient.b = gglFloatToFixed(0.2f);
80 c->lighting.front.ambient.a = 0x10000;
81 c->lighting.front.diffuse.r =
82 c->lighting.front.diffuse.g =
83 c->lighting.front.diffuse.b = gglFloatToFixed(0.8f);
84 c->lighting.front.diffuse.a = 0x10000;
85 c->lighting.front.specular.a = 0x10000;
86 c->lighting.front.emission.a = 0x10000;
88 c->lighting.lightModel.ambient.r =
89 c->lighting.lightModel.ambient.g =
90 c->lighting.lightModel.ambient.b = gglFloatToFixed(0.2f);
91 c->lighting.lightModel.ambient.a = 0x10000;
93 c->lighting.colorMaterial.face = GL_FRONT_AND_BACK;
94 c->lighting.colorMaterial.mode = GL_AMBIENT_AND_DIFFUSE;
98 c->fog.density = 0x10000;
100 c->fog.invEndMinusStart = 0x10000;
102 invalidate_lighting(c);
104 c->rasterizer.procs.shadeModel(c, GL_SMOOTH);
105 c->lighting.shadeModel = GL_SMOOTH;
108 void ogles_uninit_light(ogles_context_t* c)
112 static inline int32_t clampF(GLfixed f) CONST;
113 int32_t clampF(GLfixed f) {
120 static GLfixed fog_linear(ogles_context_t* c, GLfixed z) {
121 return clampF(gglMulx((c->fog.end - ((z<0)?-z:z)), c->fog.invEndMinusStart));
124 static GLfixed fog_exp(ogles_context_t* c, GLfixed z) {
125 const float e = fixedToFloat(gglMulx(c->fog.density, ((z<0)?-z:z)));
126 return clampF(gglFloatToFixed(fastexpf(-e)));
129 static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) {
130 const float e = fixedToFloat(gglMulx(c->fog.density, z));
131 return clampF(gglFloatToFixed(fastexpf(-e*e)));
134 // ----------------------------------------------------------------------------
137 #pragma mark math helpers
141 void vscale3(GLfixed* d, const GLfixed* m, GLfixed s) {
142 d[0] = gglMulx(m[0], s);
143 d[1] = gglMulx(m[1], s);
144 d[2] = gglMulx(m[2], s);
148 void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
149 d[0] = gglMulAddx(m[0], s, a[0]);
150 d[1] = gglMulAddx(m[1], s, a[1]);
151 d[2] = gglMulAddx(m[2], s, a[2]);
155 void vss3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
156 d[0] = gglMulSubx(m[0], s, a[0]);
157 d[1] = gglMulSubx(m[1], s, a[1]);
158 d[2] = gglMulSubx(m[2], s, a[2]);
162 void vmla3(GLfixed* d,
163 const GLfixed* m0, const GLfixed* m1, const GLfixed* a)
165 d[0] = gglMulAddx(m0[0], m1[0], a[0]);
166 d[1] = gglMulAddx(m0[1], m1[1], a[1]);
167 d[2] = gglMulAddx(m0[2], m1[2], a[2]);
171 void vmul3(GLfixed* d, const GLfixed* m0, const GLfixed* m1) {
172 d[0] = gglMulx(m0[0], m1[0]);
173 d[1] = gglMulx(m0[1], m1[1]);
174 d[2] = gglMulx(m0[2], m1[2]);
177 void vnorm3(GLfixed* d, const GLfixed* a)
179 // we must take care of overflows when normalizing a vector
181 int32_t x = a[0]; x = x>=0 ? x : -x;
182 int32_t y = a[1]; y = y>=0 ? y : -y;
183 int32_t z = a[2]; z = z>=0 ? z : -z;
184 if (ggl_likely(x<=0x6800 && y<=0x6800 && z<= 0x6800)) {
185 // in this case this will all fit on 32 bits
187 n = gglSqrtRecipx(n);
190 // here norm^2 is at least 0x7EC00000 (>>32 == 0.495117)
191 n = vsquare3(x, y, z);
192 n = gglSqrtRecipx(n);
197 // ----------------------------------------------------------------------------
200 #pragma mark lighting equations
203 static inline void light_picker(ogles_context_t* c)
205 if (ggl_likely(!c->lighting.enable)) {
206 c->lighting.lightVertex = lightVertexNop;
209 if (c->lighting.colorMaterial.enable) {
210 c->lighting.lightVertex = lightVertexMaterial;
212 c->lighting.lightVertex = lightVertex;
216 static inline void validate_light_mvi(ogles_context_t* c)
218 uint32_t en = c->lighting.enabledLights;
219 // Vector from object to viewer, in eye coordinates
221 const int i = 31 - gglClz(en);
223 light_t& l = c->lighting.lights[i];
224 #if OBJECT_SPACE_LIGHTING
225 c->transforms.mvui.point4(&c->transforms.mvui,
226 &l.objPosition, &l.position);
228 l.objPosition = l.position;
230 vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
232 const vec4_t eyeViewer = { 0, 0, 0x10000, 0 };
233 #if OBJECT_SPACE_LIGHTING
234 c->transforms.mvui.point3(&c->transforms.mvui,
235 &c->lighting.objViewer, &eyeViewer);
236 vnorm3(c->lighting.objViewer.v, c->lighting.objViewer.v);
238 c->lighting.objViewer = eyeViewer;
242 static inline void validate_light(ogles_context_t* c)
244 // if colorMaterial is enabled, we get the color from the vertex
245 if (!c->lighting.colorMaterial.enable) {
246 material_t& material = c->lighting.front;
247 uint32_t en = c->lighting.enabledLights;
249 const int i = 31 - gglClz(en);
251 light_t& l = c->lighting.lights[i];
252 vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v);
253 vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v);
254 vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
256 // this is just a flag to tell if we have a specular component
257 l.implicitSpecular.v[3] =
258 l.implicitSpecular.r |
259 l.implicitSpecular.g |
260 l.implicitSpecular.b;
262 l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0;
263 if (l.rConstAttenuation)
264 l.rConstAttenuation = gglRecipFast(l.attenuation[0]);
266 // emission and ambient for the whole scene
267 vmla3( c->lighting.implicitSceneEmissionAndAmbient.v,
268 c->lighting.lightModel.ambient.v,
270 material.emission.v);
271 c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
273 validate_light_mvi(c);
276 void invalidate_lighting(ogles_context_t* c)
278 // TODO: pick lightVertexValidate or lightVertexValidateMVI
279 // instead of systematically the heavier lightVertexValidate()
280 c->lighting.lightVertex = lightVertexValidate;
283 void ogles_invalidate_lighting_mvui(ogles_context_t* c)
285 invalidate_lighting(c);
288 void lightVertexNop(ogles_context_t*, vertex_t* v)
290 // we should never end-up here
293 void lightVertexValidateMVI(ogles_context_t* c, vertex_t* v)
295 validate_light_mvi(c);
297 c->lighting.lightVertex(c, v);
300 void lightVertexValidate(ogles_context_t* c, vertex_t* v)
304 c->lighting.lightVertex(c, v);
307 void lightVertexMaterial(ogles_context_t* c, vertex_t* v)
309 // fetch the material color
310 const GLvoid* cp = c->arrays.color.element(
311 v->index & vertex_cache_t::INDEX_MASK);
312 c->arrays.color.fetch(c, v->color.v, cp);
314 // acquire the color-material from the vertex
315 material_t& material = c->lighting.front;
317 material.diffuse = v->color;
318 // implicit arguments need to be computed per/vertex
319 uint32_t en = c->lighting.enabledLights;
321 const int i = 31 - gglClz(en);
323 light_t& l = c->lighting.lights[i];
324 vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v);
325 vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v);
326 vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v);
327 // this is just a flag to tell if we have a specular component
328 l.implicitSpecular.v[3] =
329 l.implicitSpecular.r |
330 l.implicitSpecular.g |
331 l.implicitSpecular.b;
333 // emission and ambient for the whole scene
334 vmla3( c->lighting.implicitSceneEmissionAndAmbient.v,
335 c->lighting.lightModel.ambient.v,
337 material.emission.v);
338 c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a;
340 // now we can light our vertex as usual
344 void lightVertex(ogles_context_t* c, vertex_t* v)
346 // emission and ambient for the whole scene
347 vec4_t r = c->lighting.implicitSceneEmissionAndAmbient;
348 const vec4_t objViewer = c->lighting.objViewer;
350 uint32_t en = c->lighting.enabledLights;
351 if (ggl_likely(en)) {
352 // since we do the lighting in object-space, we don't need to
353 // transform each normal. However, we might still have to normalize
354 // it if GL_NORMALIZE is enabled.
356 c->arrays.normal.fetch(c, n.v,
357 c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK));
359 #if !OBJECT_SPACE_LIGHTING
360 c->transforms.mvui.point3(&c->transforms.mvui, &n, &n);
363 // TODO: right now we handle GL_RESCALE_NORMALS as if it were
364 // GL_NORMALIZE. We could optimize this by scaling mvui
365 // appropriately instead.
366 if (c->transforms.rescaleNormals)
369 const material_t& material = c->lighting.front;
370 const int twoSide = c->lighting.lightModel.twoSide;
373 const int i = 31 - gglClz(en);
375 const light_t& l = c->lighting.lights[i];
379 GLfixed sqDist = 0x10000;
381 // compute vertex-to-light vector
382 if (ggl_unlikely(l.position.w)) {
383 // lightPos/1.0 - vertex/vertex.w == lightPos*vertex.w - vertex
384 #if !OBJECT_SPACE_LIGHTING
386 const transform_t& mv = c->transforms.modelview.transform;
387 mv.point4(&mv, &o, &v->obj);
388 vss3(d.v, l.objPosition.v, o.w, o.v);
390 vss3(d.v, l.objPosition.v, v->obj.w, v->obj.v);
392 sqDist = dot3(d.v, d.v);
393 vscale3(d.v, d.v, gglSqrtRecipx(sqDist));
395 // TODO: avoid copy here
396 d = l.normalizedObjPosition;
401 s = (s<0) ? (twoSide?(-s):0) : s;
402 vsa3(t.v, l.implicitDiffuse.v, s, l.implicitAmbient.v);
405 if (ggl_unlikely(s && l.implicitSpecular.v[3])) {
407 h.x = d.x + objViewer.x;
408 h.y = d.y + objViewer.y;
409 h.z = d.z + objViewer.z;
412 s = (s<0) ? (twoSide?(-s):0) : s;
414 s = gglPowx(s, material.shininess);
415 vsa3(t.v, l.implicitSpecular.v, s, t.v);
420 if (ggl_unlikely(l.spotCutoff != gglIntToFixed(180))) {
421 GLfixed spotAtt = -dot3(l.normalizedSpotDir.v, d.v);
422 if (spotAtt >= l.spotCutoffCosine) {
423 vscale3(t.v, t.v, gglPowx(spotAtt, l.spotExp));
428 if (ggl_unlikely(l.position.w)) {
429 if (l.rConstAttenuation) {
430 s = l.rConstAttenuation;
432 s = gglMulAddx(sqDist, l.attenuation[2], l.attenuation[0]);
433 if (l.attenuation[1])
434 s = gglMulAddx(gglSqrtx(sqDist), l.attenuation[1], s);
437 vscale3(t.v, t.v, s);
445 v->color.r = gglClampx(r.r);
446 v->color.g = gglClampx(r.g);
447 v->color.b = gglClampx(r.b);
448 v->color.a = gglClampx(r.a);
449 v->flags |= vertex_t::LIT;
452 static void lightModelx(GLenum pname, GLfixed param, ogles_context_t* c)
454 if (ggl_unlikely(pname != GL_LIGHT_MODEL_TWO_SIDE)) {
455 ogles_error(c, GL_INVALID_ENUM);
458 c->lighting.lightModel.twoSide = param ? GL_TRUE : GL_FALSE;
459 invalidate_lighting(c);
462 static void lightx(GLenum i, GLenum pname, GLfixed param, ogles_context_t* c)
464 if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
465 ogles_error(c, GL_INVALID_ENUM);
469 light_t& light = c->lighting.lights[i-GL_LIGHT0];
470 const GLfixed kDegToRad = GLfixed((M_PI * gglIntToFixed(1)) / 180.0f);
472 case GL_SPOT_EXPONENT:
473 if (GGLfixed(param) >= gglIntToFixed(128)) {
474 ogles_error(c, GL_INVALID_VALUE);
477 light.spotExp = param;
480 if (param!=gglIntToFixed(180) && GGLfixed(param)>=gglIntToFixed(90)) {
481 ogles_error(c, GL_INVALID_VALUE);
484 light.spotCutoff = param;
485 light.spotCutoffCosine =
486 gglFloatToFixed(cosinef((M_PI/(180.0f*65536.0f))*param));
488 case GL_CONSTANT_ATTENUATION:
490 ogles_error(c, GL_INVALID_VALUE);
493 light.attenuation[0] = param;
495 case GL_LINEAR_ATTENUATION:
497 ogles_error(c, GL_INVALID_VALUE);
500 light.attenuation[1] = param;
502 case GL_QUADRATIC_ATTENUATION:
504 ogles_error(c, GL_INVALID_VALUE);
507 light.attenuation[2] = param;
510 ogles_error(c, GL_INVALID_ENUM);
513 invalidate_lighting(c);
516 static void lightxv(GLenum i, GLenum pname, const GLfixed *params, ogles_context_t* c)
518 if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) {
519 ogles_error(c, GL_INVALID_ENUM);
524 light_t& light = c->lighting.lights[i-GL_LIGHT0];
527 what = light.ambient.v;
530 what = light.diffuse.v;
533 what = light.specular.v;
536 ogles_validate_transform(c, transform_state_t::MODELVIEW);
537 transform_t& mv = c->transforms.modelview.transform;
538 mv.point4(&mv, &light.position, reinterpret_cast<vec4_t const*>(params));
539 invalidate_lighting(c);
542 case GL_SPOT_DIRECTION: {
543 #if OBJECT_SPACE_LIGHTING
544 ogles_validate_transform(c, transform_state_t::MVUI);
545 transform_t& mvui = c->transforms.mvui;
546 mvui.point3(&mvui, &light.spotDir, reinterpret_cast<vec4_t const*>(params));
548 light.spotDir = *reinterpret_cast<vec4_t const*>(params);
550 vnorm3(light.normalizedSpotDir.v, light.spotDir.v);
551 invalidate_lighting(c);
555 lightx(i, pname, params[0], c);
562 invalidate_lighting(c);
565 static void materialx(GLenum face, GLenum pname, GLfixed param, ogles_context_t* c)
567 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
568 ogles_error(c, GL_INVALID_ENUM);
571 if (ggl_unlikely(pname != GL_SHININESS)) {
572 ogles_error(c, GL_INVALID_ENUM);
575 c->lighting.front.shininess = param;
576 invalidate_lighting(c);
579 static void fogx(GLenum pname, GLfixed param, ogles_context_t* c)
584 c->fog.density = param;
587 ogles_error(c, GL_INVALID_VALUE);
590 c->fog.start = param;
591 c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
595 c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start);
601 c->fog.fog = fog_linear;
605 c->fog.fog = fog_exp;
609 c->fog.fog = fog_exp2;
612 ogles_error(c, GL_INVALID_ENUM);
617 ogles_error(c, GL_INVALID_ENUM);
622 // ----------------------------------------------------------------------------
623 }; // namespace android
624 // ----------------------------------------------------------------------------
626 using namespace android;
630 #pragma mark lighting APIs
633 void glShadeModel(GLenum mode)
635 ogles_context_t* c = ogles_context_t::get();
636 if (ggl_unlikely(mode != GL_SMOOTH && mode != GL_FLAT)) {
637 ogles_error(c, GL_INVALID_ENUM);
640 c->lighting.shadeModel = mode;
643 void glLightModelf(GLenum pname, GLfloat param)
645 ogles_context_t* c = ogles_context_t::get();
646 lightModelx(pname, gglFloatToFixed(param), c);
649 void glLightModelx(GLenum pname, GLfixed param)
651 ogles_context_t* c = ogles_context_t::get();
652 lightModelx(pname, param, c);
655 void glLightModelfv(GLenum pname, const GLfloat *params)
657 ogles_context_t* c = ogles_context_t::get();
658 if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
659 lightModelx(pname, gglFloatToFixed(params[0]), c);
663 if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
664 ogles_error(c, GL_INVALID_ENUM);
668 c->lighting.lightModel.ambient.r = gglFloatToFixed(params[0]);
669 c->lighting.lightModel.ambient.g = gglFloatToFixed(params[1]);
670 c->lighting.lightModel.ambient.b = gglFloatToFixed(params[2]);
671 c->lighting.lightModel.ambient.a = gglFloatToFixed(params[3]);
672 invalidate_lighting(c);
675 void glLightModelxv(GLenum pname, const GLfixed *params)
677 ogles_context_t* c = ogles_context_t::get();
678 if (pname == GL_LIGHT_MODEL_TWO_SIDE) {
679 lightModelx(pname, params[0], c);
683 if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) {
684 ogles_error(c, GL_INVALID_ENUM);
688 c->lighting.lightModel.ambient.r = params[0];
689 c->lighting.lightModel.ambient.g = params[1];
690 c->lighting.lightModel.ambient.b = params[2];
691 c->lighting.lightModel.ambient.a = params[3];
692 invalidate_lighting(c);
695 // ----------------------------------------------------------------------------
700 void glLightf(GLenum i, GLenum pname, GLfloat param)
702 ogles_context_t* c = ogles_context_t::get();
703 lightx(i, pname, gglFloatToFixed(param), c);
706 void glLightx(GLenum i, GLenum pname, GLfixed param)
708 ogles_context_t* c = ogles_context_t::get();
709 lightx(i, pname, param, c);
712 void glLightfv(GLenum i, GLenum pname, const GLfloat *params)
714 ogles_context_t* c = ogles_context_t::get();
716 case GL_SPOT_EXPONENT:
718 case GL_CONSTANT_ATTENUATION:
719 case GL_LINEAR_ATTENUATION:
720 case GL_QUADRATIC_ATTENUATION:
721 lightx(i, pname, gglFloatToFixed(params[0]), c);
726 paramsx[0] = gglFloatToFixed(params[0]);
727 paramsx[1] = gglFloatToFixed(params[1]);
728 paramsx[2] = gglFloatToFixed(params[2]);
729 if (pname != GL_SPOT_DIRECTION)
730 paramsx[3] = gglFloatToFixed(params[3]);
732 lightxv(i, pname, paramsx, c);
735 void glLightxv(GLenum i, GLenum pname, const GLfixed *params)
737 ogles_context_t* c = ogles_context_t::get();
738 lightxv(i, pname, params, c);
741 // ----------------------------------------------------------------------------
746 void glMaterialf(GLenum face, GLenum pname, GLfloat param)
748 ogles_context_t* c = ogles_context_t::get();
749 materialx(face, pname, gglFloatToFixed(param), c);
752 void glMaterialx(GLenum face, GLenum pname, GLfixed param)
754 ogles_context_t* c = ogles_context_t::get();
755 materialx(face, pname, param, c);
759 GLenum face, GLenum pname, const GLfloat *params)
761 ogles_context_t* c = ogles_context_t::get();
762 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
763 ogles_error(c, GL_INVALID_ENUM);
769 case GL_AMBIENT: what = c->lighting.front.ambient.v; break;
770 case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break;
771 case GL_SPECULAR: what = c->lighting.front.specular.v; break;
772 case GL_EMISSION: what = c->lighting.front.emission.v; break;
773 case GL_AMBIENT_AND_DIFFUSE:
774 what = c->lighting.front.ambient.v;
775 other = c->lighting.front.diffuse.v;
778 c->lighting.front.shininess = gglFloatToFixed(params[0]);
779 invalidate_lighting(c);
782 ogles_error(c, GL_INVALID_ENUM);
785 what[0] = gglFloatToFixed(params[0]);
786 what[1] = gglFloatToFixed(params[1]);
787 what[2] = gglFloatToFixed(params[2]);
788 what[3] = gglFloatToFixed(params[3]);
795 invalidate_lighting(c);
799 GLenum face, GLenum pname, const GLfixed *params)
801 ogles_context_t* c = ogles_context_t::get();
802 if (ggl_unlikely(face != GL_FRONT_AND_BACK)) {
803 ogles_error(c, GL_INVALID_ENUM);
809 case GL_AMBIENT: what = c->lighting.front.ambient.v; break;
810 case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break;
811 case GL_SPECULAR: what = c->lighting.front.specular.v; break;
812 case GL_EMISSION: what = c->lighting.front.emission.v; break;
813 case GL_AMBIENT_AND_DIFFUSE:
814 what = c->lighting.front.ambient.v;
815 other = c->lighting.front.diffuse.v;
818 c->lighting.front.shininess = gglFloatToFixed(params[0]);
819 invalidate_lighting(c);
822 ogles_error(c, GL_INVALID_ENUM);
835 invalidate_lighting(c);
838 // ----------------------------------------------------------------------------
844 void glFogf(GLenum pname, GLfloat param) {
845 ogles_context_t* c = ogles_context_t::get();
846 GLfixed paramx = (GLfixed)param;
847 if (pname != GL_FOG_MODE)
848 paramx = gglFloatToFixed(param);
849 fogx(pname, paramx, c);
852 void glFogx(GLenum pname, GLfixed param) {
853 ogles_context_t* c = ogles_context_t::get();
854 fogx(pname, param, c);
857 void glFogfv(GLenum pname, const GLfloat *params)
859 ogles_context_t* c = ogles_context_t::get();
860 if (pname != GL_FOG_COLOR) {
861 GLfixed paramx = (GLfixed)params[0];
862 if (pname != GL_FOG_MODE)
863 paramx = gglFloatToFixed(params[0]);
864 fogx(pname, paramx, c);
868 paramsx[0] = gglFloatToFixed(params[0]);
869 paramsx[1] = gglFloatToFixed(params[1]);
870 paramsx[2] = gglFloatToFixed(params[2]);
871 paramsx[3] = gglFloatToFixed(params[3]);
872 c->rasterizer.procs.fogColor3xv(c, paramsx);
875 void glFogxv(GLenum pname, const GLfixed *params)
877 ogles_context_t* c = ogles_context_t::get();
878 if (pname != GL_FOG_COLOR) {
879 fogx(pname, params[0], c);
882 c->rasterizer.procs.fogColor3xv(c, params);