Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
void ggl_rasterPos2i(void* con, GGLint x, GGLint y)
{
    ggl_rasterPos2x(con, gglIntToFixed(x), gglIntToFixed(y));
}
Ejemplo n.º 3
0
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));

        // TODO: right now we handle GL_RESCALE_NORMALS as if ti 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
                vss3(d.v, l.objPosition.v, v->obj.w, 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;
}