Пример #1
0
void FrameBuffer::Draw3DPoint(V3 pt, PPC *ppc, int psize, V3 color) {

    V3 ppt;
    if (!ppc->Project(pt, ppt))
        return;
    DrawPoint((int)ppt[0], (int)ppt[1], psize, color.getColor());
}
Пример #2
0
void TMesh::RenderFilled(PPC *ppc, FrameBuffer *fb, unsigned int color, V3 L, 
                         float ka, float se, int tm, int tl) 
{

    //Project all vertices
    V3 *pverts = new V3[vertsN];
    for (int vi = 0; vi < vertsN; vi++) {
        ppc->Project(verts[vi], pverts[vi]);
    }

    for (int tri = 0; tri < trisN; tri++) {

        int vinds[3];
        vinds[0] = tris[tri*3+0];
        vinds[1] = tris[tri*3+1];
        vinds[2] = tris[tri*3+2];

        // Do not render triangle if any of its vertices had an invalid projection
        if (pverts[vinds[0]][0] == FLT_MAX ||
            pverts[vinds[1]][0] == FLT_MAX ||
            pverts[vinds[2]][0] == FLT_MAX)
            continue;

        // Compute bounding box aabb of projected vertices
        AABB aabb(pverts[vinds[0]]);
        aabb.AddPoint(pverts[vinds[1]]);
        aabb.AddPoint(pverts[vinds[2]]);

        // Clip aabb with frame
        if (!aabb.Clip(0.0f, (float) fb->w, 0.0f, (float) fb->h)) {
            continue;
        }

        // Setup edge equations ee0, ee1, ee2
        V3 eeqs[3];
        SetEEQS(pverts[vinds[0]], pverts[vinds[1]], pverts[vinds[2]], eeqs);

        //Setup coefficient matrix
        M33 ptm;
        ptm[0] = pverts[vinds[0]];
        ptm[1] = pverts[vinds[1]];
        ptm[2] = pverts[vinds[2]];
        ptm.setColumn(2, V3(1.0f, 1.0f, 1.0f));
        ptm = ptm.inverse();

        //Get colors at verts
        V3 reds(cols[vinds[0]][0], cols[vinds[1]][0], cols[vinds[2]][0]);
        V3 greens(cols[vinds[0]][1], cols[vinds[1]][1], cols[vinds[2]][1]);
        V3 blues(cols[vinds[0]][2], cols[vinds[1]][2], cols[vinds[2]][2]);

        // Setup screen space interpolation of depth: zABC 
        V3 zABC = ptm*V3(pverts[vinds[0]][2],
                pverts[vinds[1]][2], pverts[vinds[2]][2]);

        //Setup screen space interpolation of normals
        V3 nxABC = ptm*V3(normals[vinds[0]][0],
                normals[vinds[1]][0], normals[vinds[2]][0]);
        V3 nyABC = ptm*V3(normals[vinds[0]][1],
                normals[vinds[1]][1], normals[vinds[2]][1]);
        V3 nzABC = ptm*V3(normals[vinds[0]][2],
                normals[vinds[1]][2], normals[vinds[2]][2]);

        //Model space interpolation parameters
        M33 msiQ = GetMSIQ(verts[vinds[0]], verts[vinds[1]], verts[vinds[2]], ppc); 
        V3 denABC = msiQ[0] + msiQ[1] + msiQ[2];
        V3 redNABC(msiQ.getColumn(0) * reds, msiQ.getColumn(1) * reds, 
                msiQ.getColumn(2) * reds);
        V3 greenNABC(msiQ.getColumn(0) * greens, msiQ.getColumn(1) * greens, 
                msiQ.getColumn(2) * greens);
        V3 blueNABC(msiQ.getColumn(0) * blues, msiQ.getColumn(1) * blues, 
                msiQ.getColumn(2) * blues);
        
        //Texture coordinates interpolation
        V3 sNumABC, tNumABC, sABC, tABC;
        if (tcs) {
            V3 ss(tcs[2*vinds[0]+0], tcs[2*vinds[1]+0], tcs[2*vinds[2]+0]);
            V3 ts(tcs[2*vinds[0]+1], tcs[2*vinds[1]+1], tcs[2*vinds[2]+1]);
            sNumABC = V3(msiQ.getColumn(0) * ss, msiQ.getColumn(1) * ss, 
                    msiQ.getColumn(2) * ss);
            tNumABC = V3(msiQ.getColumn(0) * ts, msiQ.getColumn(1) * ts, 
                    msiQ.getColumn(2) * ts);
            sABC = ptm * ss;
            tABC = ptm * ts;
        }

        // For every pixel in the bounding box
        int top = (int) (aabb.corners[0][1] + 0.5f);
        int bottom = (int) (aabb.corners[1][1] - 0.5f);
        int left = (int) (aabb.corners[0][0] + 0.5f);
        int right = (int) (aabb.corners[1][0] - 0.5f);
        for (int v = top; v <= bottom; v++) {
            for (int u = left; u <= right; u++) {

                V3 pixv(.5f + (float)u, .5f + (float)v, 1.0f);

                //Check edge equations
                if (eeqs[0]*pixv < 0.0f || 
                    eeqs[1]*pixv < 0.0f || 
                    eeqs[2]*pixv < 0.0f)
                    continue;

                // Check z-buffer
                float currz = zABC * pixv;
                if (fb->IsFarther(u, v, currz))
                    continue;
                fb->SetZ(u, v, currz);

                V3 currColor;
                float msdn = denABC * pixv;

                V3 fullColor;
                if (tcs) {
                    float currs = sABC * pixv;
                    float currt = tABC * pixv;
                    int ut, vt;
                    ut=vt=0;
                    if (tm == 0) { //nearest neighbor
                        ut = (int) (currs * (float) texture->w);
                        vt = (int) (currt * (float) texture->h);
                    }
                    else if(tm == 1) { //bilinear
                    }
                    fullColor.setFromColor(texture->Get(ut, vt));
                }
                else {
                    fullColor = V3(redNABC * pixv, greenNABC * pixv, blueNABC * pixv) / msdn;
                }
                V3 currNormal, lv;
                V3 pp(pixv);
                pp[2] = currz;
                lv = (L - ppc->UnProject(pp)).normalize();
                currNormal = V3(nxABC*pixv, nyABC*pixv, nzABC*pixv).normalize();
                float kd = lv * currNormal;
                kd = (kd < 0.0f) ? 0.0f : kd;
                float ks = 0; //pow(reflectedLightVector * eyeVector, se)
                currColor = fullColor * (ka + (1.0f-ka)*kd + ks);

                fb->Set(u, v, currColor.getColor());
            }
        }
    }

    delete []pverts;
}