diff options
Diffstat (limited to 'opengl/libagl/light.cpp')
-rw-r--r-- | opengl/libagl/light.cpp | 852 |
1 files changed, 852 insertions, 0 deletions
diff --git a/opengl/libagl/light.cpp b/opengl/libagl/light.cpp new file mode 100644 index 00000000000..25c41d0c5b9 --- /dev/null +++ b/opengl/libagl/light.cpp @@ -0,0 +1,852 @@ +/* libs/opengles/light.cpp +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include <stdio.h> +#include "context.h" +#include "fp.h" +#include "light.h" +#include "state.h" +#include "matrix.h" + + +#if defined(__arm__) && defined(__thumb__) +#warning "light.cpp should not be compiled in thumb on ARM." +#endif + +namespace android { + +// ---------------------------------------------------------------------------- + +static void invalidate_lighting(ogles_context_t* c); +static void lightVertexValidate(ogles_context_t* c, vertex_t* v); +static void lightVertexNop(ogles_context_t* c, vertex_t* v); +static void lightVertex(ogles_context_t* c, vertex_t* v); +static void lightVertexMaterial(ogles_context_t* c, vertex_t* v); + +static inline void vscale3(GLfixed* d, const GLfixed* m, GLfixed s); +static inline void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b); + +static __attribute__((noinline)) +void vnorm3(GLfixed* d, const GLfixed* a); + +static inline void vsa3(GLfixed* d, + const GLfixed* m, GLfixed s, const GLfixed* a); +static inline void vmla3(GLfixed* d, + const GLfixed* m0, const GLfixed* m1, const GLfixed* a); +static inline void vmul3(GLfixed* d, + const GLfixed* m0, const GLfixed* m1); + +static GLfixed fog_linear(ogles_context_t* c, GLfixed z); +static GLfixed fog_exp(ogles_context_t* c, GLfixed z); +static GLfixed fog_exp2(ogles_context_t* c, GLfixed z); + + +// ---------------------------------------------------------------------------- + +static void init_white(vec4_t& c) { + c.r = c.g = c.b = c.a = 0x10000; +} + +void ogles_init_light(ogles_context_t* c) +{ + for (unsigned int i=0 ; i<OGLES_MAX_LIGHTS ; i++) { + c->lighting.lights[i].ambient.a = 0x10000; + c->lighting.lights[i].position.z = 0x10000; + c->lighting.lights[i].spotDir.z = -0x10000; + c->lighting.lights[i].spotCutoff = gglIntToFixed(180); + c->lighting.lights[i].attenuation[0] = 0x10000; + } + init_white(c->lighting.lights[0].diffuse); + init_white(c->lighting.lights[0].specular); + + c->lighting.front.ambient.r = + c->lighting.front.ambient.g = + c->lighting.front.ambient.b = gglFloatToFixed(0.2f); + c->lighting.front.ambient.a = 0x10000; + c->lighting.front.diffuse.r = + c->lighting.front.diffuse.g = + c->lighting.front.diffuse.b = gglFloatToFixed(0.8f); + c->lighting.front.diffuse.a = 0x10000; + c->lighting.front.specular.a = 0x10000; + c->lighting.front.emission.a = 0x10000; + + c->lighting.lightModel.ambient.r = + c->lighting.lightModel.ambient.g = + c->lighting.lightModel.ambient.b = gglFloatToFixed(0.2f); + c->lighting.lightModel.ambient.a = 0x10000; + + c->lighting.colorMaterial.face = GL_FRONT_AND_BACK; + c->lighting.colorMaterial.mode = GL_AMBIENT_AND_DIFFUSE; + + c->fog.mode = GL_EXP; + c->fog.fog = fog_exp; + c->fog.density = 0x10000; + c->fog.end = 0x10000; + c->fog.invEndMinusStart = 0x10000; + + invalidate_lighting(c); + + c->rasterizer.procs.shadeModel(c, GL_SMOOTH); + c->lighting.shadeModel = GL_SMOOTH; +} + +void ogles_uninit_light(ogles_context_t* c) +{ +} + +static inline int32_t clampF(GLfixed f) CONST; +int32_t clampF(GLfixed f) { + f = (f & ~(f>>31)); + if (f >= 0x10000) + f = 0x10000; + return f; +} + +static GLfixed fog_linear(ogles_context_t* c, GLfixed z) { + return clampF(gglMulx((c->fog.end - ((z<0)?-z:z)), c->fog.invEndMinusStart)); +} + +static GLfixed fog_exp(ogles_context_t* c, GLfixed z) { + const float e = fixedToFloat(gglMulx(c->fog.density, ((z<0)?-z:z))); + return clampF(gglFloatToFixed(fastexpf(-e))); +} + +static GLfixed fog_exp2(ogles_context_t* c, GLfixed z) { + const float e = fixedToFloat(gglMulx(c->fog.density, z)); + return clampF(gglFloatToFixed(fastexpf(-e*e))); +} + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#pragma mark math helpers +#endif + +static inline +void vscale3(GLfixed* d, const GLfixed* m, GLfixed s) { + d[0] = gglMulx(m[0], s); + d[1] = gglMulx(m[1], s); + d[2] = gglMulx(m[2], s); +} + +static inline +void vsa3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) { + d[0] = gglMulAddx(m[0], s, a[0]); + d[1] = gglMulAddx(m[1], s, a[1]); + d[2] = gglMulAddx(m[2], s, a[2]); +} + +static inline +void vsub3w(GLfixed* d, const GLfixed* a, const GLfixed* b) { + const GLfixed wa = a[3]; + const GLfixed wb = b[3]; + if (ggl_likely(wa == wb)) { + d[0] = a[0] - b[0]; + d[1] = a[1] - b[1]; + d[2] = a[2] - b[2]; + } else { + d[0] = gglMulSubx(a[0], wb, gglMulx(b[0], wa)); + d[1] = gglMulSubx(a[1], wb, gglMulx(b[1], wa)); + d[2] = gglMulSubx(a[2], wb, gglMulx(b[2], wa)); + } +} + +static inline +void vmla3(GLfixed* d, + const GLfixed* m0, const GLfixed* m1, const GLfixed* a) +{ + d[0] = gglMulAddx(m0[0], m1[0], a[0]); + d[1] = gglMulAddx(m0[1], m1[1], a[1]); + d[2] = gglMulAddx(m0[2], m1[2], a[2]); +} + +static inline +void vmul3(GLfixed* d, const GLfixed* m0, const GLfixed* m1) { + d[0] = gglMulx(m0[0], m1[0]); + d[1] = gglMulx(m0[1], m1[1]); + d[2] = gglMulx(m0[2], m1[2]); +} + +void vnorm3(GLfixed* d, const GLfixed* a) +{ + // we must take care of overflows when normalizing a vector + GLfixed n; + int32_t x = a[0]; x = x>=0 ? x : -x; + int32_t y = a[1]; y = y>=0 ? y : -y; + int32_t z = a[2]; z = z>=0 ? z : -z; + if (ggl_likely(x<=0x6800 && y<=0x6800 && z<= 0x6800)) { + // in this case this will all fit on 32 bits + n = x*x + y*y + z*z; + n = gglSqrtRecipx(n); + n <<= 8; + } else { + // here norm^2 is at least 0x7EC00000 (>>32 == 0.495117) + n = vsquare3(x, y, z); + n = gglSqrtRecipx(n); + } + vscale3(d, a, n); +} + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#pragma mark lighting equations +#endif + +static inline void light_picker(ogles_context_t* c) +{ + if (ggl_likely(!c->lighting.enable)) { + c->lighting.lightVertex = lightVertexNop; + return; + } + if (c->lighting.colorMaterial.enable) { + c->lighting.lightVertex = lightVertexMaterial; + } else { + c->lighting.lightVertex = lightVertex; + } +} + +static inline void validate_light_mvi(ogles_context_t* c) +{ + uint32_t en = c->lighting.enabledLights; + while (en) { + const int i = 31 - gglClz(en); + en &= ~(1<<i); + light_t& l = c->lighting.lights[i]; + c->transforms.mvui.point3(&c->transforms.mvui, + &l.objPosition, &l.position); + vnorm3(l.normalizedObjPosition.v, l.objPosition.v); + } +} + +static inline void validate_light(ogles_context_t* c) +{ + // if colorMaterial is enabled, we get the color from the vertex + if (!c->lighting.colorMaterial.enable) { + material_t& material = c->lighting.front; + uint32_t en = c->lighting.enabledLights; + while (en) { + const int i = 31 - gglClz(en); + en &= ~(1<<i); + light_t& l = c->lighting.lights[i]; + vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); + vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); + vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); + + // this is just a flag to tell if we have a specular component + l.implicitSpecular.v[3] = + l.implicitSpecular.r | + l.implicitSpecular.g | + l.implicitSpecular.b; + + l.rConstAttenuation = (l.attenuation[1] | l.attenuation[2])==0; + if (l.rConstAttenuation) + l.rConstAttenuation = gglRecipFast(l.attenuation[0]); + } + // emission and ambient for the whole scene + vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, + c->lighting.lightModel.ambient.v, + material.ambient.v, + material.emission.v); + c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; + } + validate_light_mvi(c); +} + +void invalidate_lighting(ogles_context_t* c) +{ + // TODO: pick lightVertexValidate or lightVertexValidateMVI + // instead of systematically the heavier lightVertexValidate() + c->lighting.lightVertex = lightVertexValidate; +} + +void ogles_invalidate_lighting_mvui(ogles_context_t* c) +{ + invalidate_lighting(c); +} + +void lightVertexNop(ogles_context_t*, vertex_t* v) +{ + // we should never end-up here +} + +void lightVertexValidateMVI(ogles_context_t* c, vertex_t* v) +{ + validate_light_mvi(c); + light_picker(c); + c->lighting.lightVertex(c, v); +} + +void lightVertexValidate(ogles_context_t* c, vertex_t* v) +{ + validate_light(c); + light_picker(c); + c->lighting.lightVertex(c, v); +} + +void lightVertexMaterial(ogles_context_t* c, vertex_t* v) +{ + // fetch the material color + const GLvoid* cp = c->arrays.color.element( + v->index & vertex_cache_t::INDEX_MASK); + c->arrays.color.fetch(c, v->color.v, cp); + + // acquire the color-material from the vertex + material_t& material = c->lighting.front; + material.ambient = + material.diffuse = v->color; + // implicit arguments need to be computed per/vertex + uint32_t en = c->lighting.enabledLights; + while (en) { + const int i = 31 - gglClz(en); + en &= ~(1<<i); + light_t& l = c->lighting.lights[i]; + vmul3(l.implicitAmbient.v, material.ambient.v, l.ambient.v); + vmul3(l.implicitDiffuse.v, material.diffuse.v, l.diffuse.v); + vmul3(l.implicitSpecular.v, material.specular.v, l.specular.v); + } + // emission and ambient for the whole scene + vmla3( c->lighting.implicitSceneEmissionAndAmbient.v, + c->lighting.lightModel.ambient.v, + material.ambient.v, + material.emission.v); + c->lighting.implicitSceneEmissionAndAmbient.a = material.diffuse.a; + + // now we can light our vertex as usual + lightVertex(c, v); +} + +void lightVertex(ogles_context_t* c, vertex_t* v) +{ + // emission and ambient for the whole scene + vec4_t r = c->lighting.implicitSceneEmissionAndAmbient; + + uint32_t en = c->lighting.enabledLights; + if (ggl_likely(en)) { + // since we do the lighting in object-space, we don't need to + // transform each normal. However, we might still have to normalize + // it if GL_NORMALIZE is enabled. + vec4_t n; + c->arrays.normal.fetch(c, n.v, + c->arrays.normal.element(v->index & vertex_cache_t::INDEX_MASK)); + if (c->transforms.rescaleNormals == GL_NORMALIZE) + vnorm3(n.v, n.v); + + const material_t& material = c->lighting.front; + const int twoSide = c->lighting.lightModel.twoSide; + + while (en) { + const int i = 31 - gglClz(en); + en &= ~(1<<i); + const light_t& l = c->lighting.lights[i]; + + vec4_t d, t; + GLfixed s; + GLfixed sqDist = 0x10000; + + // compute vertex-to-light vector + if (ggl_unlikely(l.position.w)) { + vsub3w(d.v, l.objPosition.v, v->obj.v); + sqDist = dot3(d.v, d.v); + vscale3(d.v, d.v, gglSqrtRecipx(sqDist)); + } else { + // TODO: avoid copy here + d = l.normalizedObjPosition; + } + + // ambient & diffuse + s = dot3(n.v, d.v); + s = (s<0) ? (twoSide?(-s):0) : s; + vsa3(t.v, l.implicitDiffuse.v, s, l.implicitAmbient.v); + + // specular + if (ggl_unlikely(s && l.implicitSpecular.v[3])) { + vec4_t h; + h.x = d.x; + h.y = d.y; + h.z = d.z + 0x10000; + vnorm3(h.v, h.v); + s = dot3(n.v, h.v); + s = (s<0) ? (twoSide?(-s):0) : s; + if (s > 0) { + s = gglPowx(s, material.shininess); + vsa3(t.v, l.implicitSpecular.v, s, t.v); + } + } + + // spot + if (ggl_unlikely(l.spotCutoff != gglIntToFixed(180))) { + GLfixed spotAtt = -dot3(l.normalizedSpotDir.v, d.v); + if (spotAtt >= l.spotCutoffCosine) { + vscale3(t.v, t.v, gglPowx(spotAtt, l.spotExp)); + } + } + + // attenuation + if (ggl_unlikely(l.position.w)) { + if (l.rConstAttenuation) { + s = l.rConstAttenuation; + } else { + s = gglMulAddx(sqDist, l.attenuation[2], l.attenuation[0]); + if (l.attenuation[1]) + s = gglMulAddx(gglSqrtx(sqDist), l.attenuation[1], s); + s = gglRecipFast(s); + } + vscale3(t.v, t.v, s); + } + + r.r += t.r; + r.g += t.g; + r.b += t.b; + } + } + v->color.r = gglClampx(r.r); + v->color.g = gglClampx(r.g); + v->color.b = gglClampx(r.b); + v->color.a = gglClampx(r.a); + v->flags |= vertex_t::LIT; +} + +static void lightModelx(GLenum pname, GLfixed param, ogles_context_t* c) +{ + if (ggl_unlikely(pname != GL_LIGHT_MODEL_TWO_SIDE)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + c->lighting.lightModel.twoSide = param ? GL_TRUE : GL_FALSE; + invalidate_lighting(c); +} + +static void lightx(GLenum i, GLenum pname, GLfixed param, ogles_context_t* c) +{ + if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + light_t& light = c->lighting.lights[i-GL_LIGHT0]; + const GLfixed kDegToRad = GLfixed((M_PI * gglIntToFixed(1)) / 180.0f); + switch (pname) { + case GL_SPOT_EXPONENT: + if (GGLfixed(param) >= gglIntToFixed(128)) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + light.spotExp = param; + break; + case GL_SPOT_CUTOFF: + if (param!=gglIntToFixed(180) && GGLfixed(param)>=gglIntToFixed(90)) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + light.spotCutoff = param; + light.spotCutoffCosine = + gglFloatToFixed(cosinef((M_PI/(180.0f*65536.0f))*param)); + break; + case GL_CONSTANT_ATTENUATION: + if (param < 0) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + light.attenuation[0] = param; + break; + case GL_LINEAR_ATTENUATION: + if (param < 0) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + light.attenuation[1] = param; + break; + case GL_QUADRATIC_ATTENUATION: + if (param < 0) { + ogles_error(c, GL_INVALID_VALUE); + return; + } + light.attenuation[2] = param; + break; + default: + ogles_error(c, GL_INVALID_ENUM); + return; + } + invalidate_lighting(c); +} + +static void lightxv(GLenum i, GLenum pname, const GLfixed *params, ogles_context_t* c) +{ + if (ggl_unlikely(uint32_t(i-GL_LIGHT0) >= OGLES_MAX_LIGHTS)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + GLfixed* what; + light_t& light = c->lighting.lights[i-GL_LIGHT0]; + switch (pname) { + case GL_AMBIENT: + what = light.ambient.v; + break; + case GL_DIFFUSE: + what = light.diffuse.v; + break; + case GL_SPECULAR: + what = light.specular.v; + break; + case GL_POSITION: { + ogles_validate_transform(c, transform_state_t::MODELVIEW); + transform_t& mv = c->transforms.modelview.transform; + memcpy(light.position.v, params, sizeof(light.position.v)); + mv.point4(&mv, &light.position, &light.position); + invalidate_lighting(c); + return; + } + case GL_SPOT_DIRECTION: { + ogles_validate_transform(c, transform_state_t::MVUI); + transform_t& mvui = c->transforms.mvui; + mvui.point3(&mvui, &light.spotDir, (vec4_t*)params); + vnorm3(light.normalizedSpotDir.v, light.spotDir.v); + invalidate_lighting(c); + return; + } + default: + lightx(i, pname, params[0], c); + return; + } + what[0] = params[0]; + what[1] = params[1]; + what[2] = params[2]; + what[3] = params[3]; + invalidate_lighting(c); +} + +static void materialx(GLenum face, GLenum pname, GLfixed param, ogles_context_t* c) +{ + if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + if (ggl_unlikely(pname != GL_SHININESS)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + c->lighting.front.shininess = param; + invalidate_lighting(c); +} + +static void fogx(GLenum pname, GLfixed param, ogles_context_t* c) +{ + switch (pname) { + case GL_FOG_DENSITY: + if (param >= 0) { + c->fog.density = param; + break; + } + ogles_error(c, GL_INVALID_VALUE); + break; + case GL_FOG_START: + c->fog.start = param; + c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start); + break; + case GL_FOG_END: + c->fog.end = param; + c->fog.invEndMinusStart = gglRecip(c->fog.end - c->fog.start); + break; + case GL_FOG_MODE: + switch (param) { + case GL_LINEAR: + c->fog.mode = param; + c->fog.fog = fog_linear; + break; + case GL_EXP: + c->fog.mode = param; + c->fog.fog = fog_exp; + break; + case GL_EXP2: + c->fog.mode = param; + c->fog.fog = fog_exp2; + break; + default: + ogles_error(c, GL_INVALID_ENUM); + break; + } + break; + default: + ogles_error(c, GL_INVALID_ENUM); + break; + } +} + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + +using namespace android; + +#if 0 +#pragma mark - +#pragma mark lighting APIs +#endif + +void glShadeModel(GLenum mode) +{ + ogles_context_t* c = ogles_context_t::get(); + if (ggl_unlikely(mode != GL_SMOOTH && mode != GL_FLAT)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + c->lighting.shadeModel = mode; +} + +void glLightModelf(GLenum pname, GLfloat param) +{ + ogles_context_t* c = ogles_context_t::get(); + lightModelx(pname, gglFloatToFixed(param), c); +} + +void glLightModelx(GLenum pname, GLfixed param) +{ + ogles_context_t* c = ogles_context_t::get(); + lightModelx(pname, param, c); +} + +void glLightModelfv(GLenum pname, const GLfloat *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (pname == GL_LIGHT_MODEL_TWO_SIDE) { + lightModelx(pname, gglFloatToFixed(params[0]), c); + return; + } + + if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + c->lighting.lightModel.ambient.r = gglFloatToFixed(params[0]); + c->lighting.lightModel.ambient.g = gglFloatToFixed(params[1]); + c->lighting.lightModel.ambient.b = gglFloatToFixed(params[2]); + c->lighting.lightModel.ambient.a = gglFloatToFixed(params[3]); + invalidate_lighting(c); +} + +void glLightModelxv(GLenum pname, const GLfixed *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (pname == GL_LIGHT_MODEL_TWO_SIDE) { + lightModelx(pname, params[0], c); + return; + } + + if (ggl_unlikely(pname != GL_LIGHT_MODEL_AMBIENT)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + + c->lighting.lightModel.ambient.r = params[0]; + c->lighting.lightModel.ambient.g = params[1]; + c->lighting.lightModel.ambient.b = params[2]; + c->lighting.lightModel.ambient.a = params[3]; + invalidate_lighting(c); +} + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#endif + +void glLightf(GLenum i, GLenum pname, GLfloat param) +{ + ogles_context_t* c = ogles_context_t::get(); + lightx(i, pname, gglFloatToFixed(param), c); +} + +void glLightx(GLenum i, GLenum pname, GLfixed param) +{ + ogles_context_t* c = ogles_context_t::get(); + lightx(i, pname, param, c); +} + +void glLightfv(GLenum i, GLenum pname, const GLfloat *params) +{ + ogles_context_t* c = ogles_context_t::get(); + switch (pname) { + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + lightx(i, pname, gglFloatToFixed(params[0]), c); + return; + } + + GLfixed paramsx[4]; + paramsx[0] = gglFloatToFixed(params[0]); + paramsx[1] = gglFloatToFixed(params[1]); + paramsx[2] = gglFloatToFixed(params[2]); + if (pname != GL_SPOT_DIRECTION) + paramsx[3] = gglFloatToFixed(params[3]); + + lightxv(i, pname, paramsx, c); +} + +void glLightxv(GLenum i, GLenum pname, const GLfixed *params) +{ + ogles_context_t* c = ogles_context_t::get(); + lightxv(i, pname, params, c); +} + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#endif + +void glMaterialf(GLenum face, GLenum pname, GLfloat param) +{ + ogles_context_t* c = ogles_context_t::get(); + materialx(face, pname, gglFloatToFixed(param), c); +} + +void glMaterialx(GLenum face, GLenum pname, GLfixed param) +{ + ogles_context_t* c = ogles_context_t::get(); + materialx(face, pname, param, c); +} + +void glMaterialfv( + GLenum face, GLenum pname, const GLfloat *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + GLfixed* what=0; + GLfixed* other=0; + switch (pname) { + case GL_AMBIENT: what = c->lighting.front.ambient.v; break; + case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break; + case GL_SPECULAR: what = c->lighting.front.specular.v; break; + case GL_EMISSION: what = c->lighting.front.emission.v; break; + case GL_AMBIENT_AND_DIFFUSE: + what = c->lighting.front.ambient.v; break; + other = c->lighting.front.diffuse.v; break; + break; + case GL_SHININESS: + c->lighting.front.shininess = gglFloatToFixed(params[0]); + invalidate_lighting(c); + return; + default: + ogles_error(c, GL_INVALID_ENUM); + return; + } + what[0] = gglFloatToFixed(params[0]); + what[1] = gglFloatToFixed(params[1]); + what[2] = gglFloatToFixed(params[2]); + what[3] = gglFloatToFixed(params[3]); + if (other) { + other[0] = what[0]; + other[1] = what[1]; + other[2] = what[2]; + other[3] = what[3]; + } + invalidate_lighting(c); +} + +void glMaterialxv( + GLenum face, GLenum pname, const GLfixed *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (ggl_unlikely(face != GL_FRONT_AND_BACK)) { + ogles_error(c, GL_INVALID_ENUM); + return; + } + GLfixed* what=0; + GLfixed* other=0; + switch (pname) { + case GL_AMBIENT: what = c->lighting.front.ambient.v; break; + case GL_DIFFUSE: what = c->lighting.front.diffuse.v; break; + case GL_SPECULAR: what = c->lighting.front.specular.v; break; + case GL_EMISSION: what = c->lighting.front.emission.v; break; + case GL_AMBIENT_AND_DIFFUSE: + what = c->lighting.front.ambient.v; break; + other= c->lighting.front.diffuse.v; break; + break; + case GL_SHININESS: + c->lighting.front.shininess = gglFloatToFixed(params[0]); + invalidate_lighting(c); + return; + default: + ogles_error(c, GL_INVALID_ENUM); + return; + } + what[0] = params[0]; + what[1] = params[1]; + what[2] = params[2]; + what[3] = params[3]; + if (other) { + other[0] = what[0]; + other[1] = what[1]; + other[2] = what[2]; + other[3] = what[3]; + } + invalidate_lighting(c); +} + +// ---------------------------------------------------------------------------- +#if 0 +#pragma mark - +#pragma mark fog +#endif + +void glFogf(GLenum pname, GLfloat param) { + ogles_context_t* c = ogles_context_t::get(); + GLfixed paramx = (GLfixed)param; + if (pname != GL_FOG_MODE) + paramx = gglFloatToFixed(param); + fogx(pname, paramx, c); +} + +void glFogx(GLenum pname, GLfixed param) { + ogles_context_t* c = ogles_context_t::get(); + fogx(pname, param, c); +} + +void glFogfv(GLenum pname, const GLfloat *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (pname != GL_FOG_COLOR) { + GLfixed paramx = (GLfixed)params[0]; + if (pname != GL_FOG_MODE) + paramx = gglFloatToFixed(params[0]); + fogx(pname, paramx, c); + return; + } + GLfixed paramsx[4]; + paramsx[0] = gglFloatToFixed(params[0]); + paramsx[1] = gglFloatToFixed(params[1]); + paramsx[2] = gglFloatToFixed(params[2]); + paramsx[3] = gglFloatToFixed(params[3]); + c->rasterizer.procs.fogColor3xv(c, paramsx); +} + +void glFogxv(GLenum pname, const GLfixed *params) +{ + ogles_context_t* c = ogles_context_t::get(); + if (pname != GL_FOG_COLOR) { + fogx(pname, params[0], c); + return; + } + c->rasterizer.procs.fogColor3xv(c, params); +} |