Exemple #1
0
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);
}
Exemple #2
0
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);
}
Exemple #3
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);
}
Exemple #4
0
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);
}
Exemple #5
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;
}
static void pick_scanline(context_t* c)
{
#if (!defined(DEBUG__CODEGEN_ONLY) || (DEBUG__CODEGEN_ONLY == 0))

#if ANDROID_CODEGEN == ANDROID_CODEGEN_GENERIC
    c->init_y = init_y;
    c->step_y = step_y__generic;
    c->scanline = scanline;
    return;
#endif

    //printf("*** needs [%08lx:%08lx:%08lx:%08lx]\n",
    //    c->state.needs.n, c->state.needs.p,
    //    c->state.needs.t[0], c->state.needs.t[1]);

    // first handle the special case that we cannot test with a filter
    const uint32_t cb_format = GGL_READ_NEEDS(CB_FORMAT, c->state.needs.n);
    if (GGL_READ_NEEDS(T_FORMAT, c->state.needs.t[0]) == cb_format) {
        if (c->state.needs.match(noblend1to1)) {
            // this will match regardless of dithering state, since both
            // src and dest have the same format anyway, there is no dithering
            // to be done.
            const GGLFormat* f =
                &(c->formats[GGL_READ_NEEDS(T_FORMAT, c->state.needs.t[0])]);
            if ((f->components == GGL_RGB) ||
                (f->components == GGL_RGBA) ||
                (f->components == GGL_LUMINANCE) ||
                (f->components == GGL_LUMINANCE_ALPHA))
            {
                // format must have all of RGB components
                // (so the current color doesn't show through)
                c->scanline = scanline_memcpy;
                c->init_y = init_y_noop;
                return;
            }
        }
    }

    if (c->state.needs.match(fill16noblend)) {
        c->init_y = init_y_packed;
        switch (c->formats[cb_format].size) {
        case 1: c->scanline = scanline_memset8;  return;
        case 2: c->scanline = scanline_memset16; return;
        case 4: c->scanline = scanline_memset32; return;
        }
    }

    const int numFilters = sizeof(shortcuts)/sizeof(shortcut_t);
    for (int i=0 ; i<numFilters ; i++) {
        if (c->state.needs.match(shortcuts[i].filter)) {
            c->scanline = shortcuts[i].scanline;
            c->init_y = shortcuts[i].init_y;
            return;
        }
    }

#endif // DEBUG__CODEGEN_ONLY

    c->init_y = init_y;
    c->step_y = step_y__generic;

#if ANDROID_ARM_CODEGEN
    // we're going to have to generate some code...
    // here, generate code for our pixel pipeline
    const AssemblyKey<needs_t> key(c->state.needs);
    sp<Assembly> assembly = gCodeCache.lookup(key);
    if (assembly == 0) {
        // create a new assembly region
        sp<ScanlineAssembly> a = new ScanlineAssembly(c->state.needs, 
                ASSEMBLY_SCRATCH_SIZE);
        // initialize our assembler
        GGLAssembler assembler( new ARMAssembler(a) );
        //GGLAssembler assembler(
        //        new ARMAssemblerOptimizer(new ARMAssembler(a)) );
        // generate the scanline code for the given needs
        int err = assembler.scanline(c->state.needs, c);
        if (ggl_likely(!err)) {
            // finally, cache this assembly
            err = gCodeCache.cache(a->key(), a);
        }
        if (ggl_unlikely(err)) {
            LOGE("error generating or caching assembly. Reverting to NOP.");
            c->scanline = scanline_noop;
            c->init_y = init_y_noop;
            c->step_y = step_y__nop;
            return;
        }
        assembly = a;
    }

    // release the previous assembly
    if (c->scanline_as) {
        c->scanline_as->decStrong(c);
    }

    //LOGI("using generated pixel-pipeline");
    c->scanline_as = assembly.get();
    c->scanline_as->incStrong(c); //  hold on to assembly
    c->scanline = (void(*)(context_t* c))assembly->base();
#else
//    LOGW("using generic (slow) pixel-pipeline");
    c->scanline = scanline;
#endif
}