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()); }
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; }