/* 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 __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 vss3(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 vss3(GLfixed* d, const GLfixed* m, GLfixed s, const GLfixed* a) {
    d[0] = gglMulSubx(m[0], s, a[0]);
    d[1] = gglMulSubx(m[1], s, a[1]);
    d[2] = gglMulSubx(m[2], s, a[2]);
}

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;
    // Vector from object to viewer, in eye coordinates
    while (en) {
        const int i = 31 - gglClz(en);
        en &= ~(1<<i);
        light_t& l = c->lighting.lights[i];
#if OBJECT_SPACE_LIGHTING
        c->transforms.mvui.point4(&c->transforms.mvui,
                &l.objPosition, &l.position);
#else
        l.objPosition = l.position;
#endif
        vnorm3(l.normalizedObjPosition.v, l.objPosition.v);
    }
    const vec4_t eyeViewer = {{{ 0, 0, 0x10000, 0 }}};
#if OBJECT_SPACE_LIGHTING
    c->transforms.mvui.point3(&c->transforms.mvui,
            &c->lighting.objViewer, &eyeViewer);
    vnorm3(c->lighting.objViewer.v, c->lighting.objViewer.v);
#else
    c->lighting.objViewer = eyeViewer;
#endif
}

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);
        // 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;
    }
    // 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;
    const vec4_t objViewer = c->lighting.objViewer;

    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 !OBJECT_SPACE_LIGHTING
        c->transforms.mvui.point3(&c->transforms.mvui, &n, &n);
#endif

        // TODO: right now we handle GL_RESCALE_NORMALS as if it were
        // GL_NORMALIZE. We could optimize this by  scaling mvui 
        // appropriately instead.
        if (c->transforms.rescaleNormals)
            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)) {
                // lightPos/1.0 - vertex/vertex.w == lightPos*vertex.w - vertex
#if !OBJECT_SPACE_LIGHTING
                vec4_t o;
                const transform_t& mv = c->transforms.modelview.transform;
                mv.point4(&mv, &o, &v->obj);
                vss3(d.v, l.objPosition.v, o.w, o.v);
#else
                vss3(d.v, l.objPosition.v, v->obj.w, v->obj.v);
#endif
                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 + objViewer.x;
                h.y = d.y + objViewer.y;
                h.z = d.z + objViewer.z;
                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];
    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;
        mv.point4(&mv, &light.position, reinterpret_cast<vec4_t const*>(params));
        invalidate_lighting(c);
        return;
    }
    case GL_SPOT_DIRECTION: {
#if OBJECT_SPACE_LIGHTING
        ogles_validate_transform(c, transform_state_t::MVUI);
        transform_t& mvui = c->transforms.mvui;
        mvui.point3(&mvui, &light.spotDir, reinterpret_cast<vec4_t const*>(params));
#else
        light.spotDir = *reinterpret_cast<vec4_t const*>(params);
#endif
        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;
        other = c->lighting.front.diffuse.v;
        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;
        other = c->lighting.front.diffuse.v;
        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);
}
