diff --git a/opengl/libagl/light.cpp b/opengl/libagl/light.cpp
new file mode 100644
index 0000000..25c41d0
--- /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);
+}
