示例#1
0
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]);
}
void blending(context_t* c, pixel_t* fragment, pixel_t* fb)
{
    rescale(fragment->c[0], fragment->s[0], fb->c[0], fb->s[0]);
    rescale(fragment->c[1], fragment->s[1], fb->c[1], fb->s[1]);
    rescale(fragment->c[2], fragment->s[2], fb->c[2], fb->s[2]);
    rescale(fragment->c[3], fragment->s[3], fb->c[3], fb->s[3]);

    pixel_t sf, df;
    blend_factor(c, &sf, c->state.blend.src, fragment, fb);
    blend_factor(c, &df, c->state.blend.dst, fragment, fb);

    fragment->c[1] =
            gglMulAddx(fragment->c[1], sf.c[1], gglMulx(fb->c[1], df.c[1]));
    fragment->c[2] =
            gglMulAddx(fragment->c[2], sf.c[2], gglMulx(fb->c[2], df.c[2]));
    fragment->c[3] =
            gglMulAddx(fragment->c[3], sf.c[3], gglMulx(fb->c[3], df.c[3]));

    if (c->state.blend.alpha_separate) {
        blend_factor(c, &sf, c->state.blend.src_alpha, fragment, fb);
        blend_factor(c, &df, c->state.blend.dst_alpha, fragment, fb);
    }

    fragment->c[0] =
            gglMulAddx(fragment->c[0], sf.c[0], gglMulx(fb->c[0], df.c[0]));

    // clamp to 1.0
    if (fragment->c[0] >= (1LU<<fragment->s[0]))
        fragment->c[0] = (1<<fragment->s[0])-1;
    if (fragment->c[1] >= (1LU<<fragment->s[1]))
        fragment->c[1] = (1<<fragment->s[1])-1;
    if (fragment->c[2] >= (1LU<<fragment->s[2]))
        fragment->c[2] = (1<<fragment->s[2])-1;
    if (fragment->c[3] >= (1LU<<fragment->s[3]))
        fragment->c[3] = (1<<fragment->s[3])-1;
}
示例#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;
}
示例#4
0
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]);
}