示例#1
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;
}
示例#2
0
文件: tmesh.cpp 项目: Sylast/Graphics
/*	Render Modes are
 *	-Vertex Color Interpolation
 *  -Texture Mapping
 *	Renders the triangle mess, shades using the sence lights.
 *  Shadow Mapping implimented 
 */
void TMesh::RenderFilled(PPC *ppc, FrameBuffer *fb, unsigned int color, int lightsN, 
						 Light **L, float ka, FrameBuffer *texture, 
						 enviromap *cube, int renderMode) {

	//Project vertices on to the camera
	vector *pverts = new vector[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];

		if( pverts[vinds[0]][2] == FLT_MAX || 
			pverts[vinds[1]][2] == FLT_MAX || 
			pverts[vinds[2]][2] == 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;

		int left = (int)(aabb.corners[0][0] + 0.5f);
		int right = (int)(aabb.corners[1][0] - 0.5f);
		int top = (int)(aabb.corners[0][1] + 0.5f);
		int bottom = (int)(aabb.corners[1][1] - 0.5f);

		vector red( cols[vinds[0]][0], cols[vinds[1]][0], cols[vinds[2]][0]); 
		vector green( cols[vinds[0]][1], cols[vinds[1]][1], cols[vinds[2]][1]); 
		vector blue( cols[vinds[0]][2], cols[vinds[1]][2], cols[vinds[2]][2]); 
		vector depth( pverts[vinds[0]][2], pverts[vinds[1]][2], pverts[vinds[2]][2] );

		vector rABC, gABC, bABC, zABC, nxABC, nyABC, nzABC, sABC, tABC;
		vector DEF;

		vector eeqs[3];
		SetEEQS( pverts[vinds[0]], pverts[vinds[1]], pverts[vinds[2]], eeqs);

		matrix ptm(pverts[vinds[0]], pverts[vinds[1]], pverts[vinds[2]]);
		ptm.setCol(2, vector(1.0f, 1.0f, 1.0f));
		ptm = invert(ptm);

		// Set up for normals
		vector nx( normals[vinds[0]][0], normals[vinds[1]][0], normals[vinds[2]][0] );
		vector ny( normals[vinds[0]][1], normals[vinds[1]][1], normals[vinds[2]][1] );
		vector nz( normals[vinds[0]][2], normals[vinds[1]][2], normals[vinds[2]][2] );
		// Set depth interpolation through screen space interpolation
		zABC = ptm * depth;

		//Matrix for Model Space interpolation
		matrix Q;
		Q = ComputeRastMatrix(ppc, verts[vinds[0]], verts[vinds[1]], verts[vinds[2]]);
		DEF = Q[0] + Q[1] + Q[2];
		//Compute Model Space interpolation constants
		SetModelRast(Q, nx, &nxABC); 
		SetModelRast(Q, ny, &nyABC); 
		SetModelRast(Q, nz, &nzABC); 
		//SetModelRast(Q, depth, &zABC);

		if( renderMode == VCI ) { 
			// Setup screen space linear variation of color 
			rABC = ptm * red;
			gABC = ptm * green;
			bABC = ptm * blue;

		}else if( renderMode == MCI ) {
			// Set Color Model Space Constants
			SetModelRast(Q, red, &rABC);
			SetModelRast(Q, green, &gABC);
			SetModelRast(Q, blue, &bABC);

		}else if( renderMode == TM) {
			//Get texture model space parameters
			vector s( tcs[2*vinds[0]+0], tcs[2*vinds[1]+0], tcs[2*vinds[2]+0]); 
			vector t( tcs[2*vinds[0]+1], tcs[2*vinds[1]+1], tcs[2*vinds[2]+1]); 
			SetModelRast(Q, s, &sABC);
			SetModelRast(Q, t, &tABC);

		}

		for( int v = top; v <= bottom; v++ ){
			for ( int u = left; u <= right; u++ ) {

				if(fb->IsOutsideFrame(u,v)) 
					continue;
				vector pv((float)u+0.5f, (float)v+0.5f, 1.0f);

				//Check whether pixel is inside triangle
				if (eeqs[0]*pv < 0.0f || eeqs[1]*pv < 0.0f || eeqs[2]*pv < 0.0f)
					continue;

				// Check whether triangle is closer than what was previously
				// seen at this pixel
				
				float currz = zABC * pv;
				//currz  /= (DEF * pv);
				if (fb->IsFarther(u, v, currz))
					continue;
				fb->SetZ(u, v, currz);
				
				// pixel is inside triangle and triangle is visible at pixel
				// compute color of pixel based on current triangle
				vector currColor;
				if ( renderMode == SM) 
					continue;
				if ( renderMode == VCI ){
					currColor = vector( rABC * pv, gABC * pv, bABC * pv );
				}else if ( renderMode == MCI ) {
					float r = ModelInterpolation(u, v, rABC, DEF);				
					float g = ModelInterpolation(u, v, gABC, DEF);				
					float b = ModelInterpolation(u, v, bABC, DEF);				
					currColor = vector(r,g,b);
				}
				if ( renderMode == TM) {
					int w = texture->w;
					int h = texture->h;
					float miS = ModelInterpolation(u, v, sABC, DEF);
					float miT = ModelInterpolation(u, v, tABC, DEF);
					miS = (miS * (float)w);
					miT = (miT * (float)h);

					int st = (h-1-(int)(miT)%h) * w+(int)(miS)%w;
					if(st < 0 || st > h*w) continue;
					currColor.SetFromColor(texture->pix[st]);
				}
				vector currNormal = vector(nxABC*pv/(DEF*pv), nyABC*pv/(DEF*pv), nzABC*pv/(DEF*pv)).norm();
				if ( renderMode == RFL ) {
					vector eye = ppc->C;
					vector P = ppc->UnProject(pv);
					vector ev = (eye - P);
					vector rv = currNormal*(currNormal*ev)*2.0f - ev; 
					rv = rv.norm();
					//currColor = (rv + vector(1.0f, 1.0f, 1.0f))/2.0f;
					currColor.SetFromColor(cube->getColor(rv));
				}
				//Calculated Color at pixel using phong equation
				for( int li = 0; li < lightsN; li++ ){
					if(!L[li]->on)
						continue;
					vector fullColor;
					fullColor.SetFromColor(color);
					vector lv;
					vector pp(pv);
					pp[2] = currz;
					lv = (L[li]->L->C - ppc->UnProject(pp)).norm();
					float kd = lv * currNormal;
					kd = (kd < 0.0f) ? 0.0f : kd;
					//currColor = currColor * ka ;
					//currColor = currColor * (ka + (1.0f-ka)*kd);
					
					vector point = ppc->UnProject(pp);
					vector SMp;
					L[li]->L->Project(point, SMp);
					float ul = SMp[0];
					float vl = SMp[1];
					if(L[li]->sm->IsOutsideFrame(ul, vl)) {
						currColor = currColor * ka ;
						//fb->Set(u,v, currColor.GetColor());
						continue;
					}
					//Check depth from light to calculate shadows
					float e = SMp[2]*.01;
					if(L[li]->sm->IsFarther((int)ul, (int)vl, SMp[2]+e)) {
						currColor = currColor * ka ;
						//fb->Set(u,v, currColor.GetColor());
					}else {
						currColor *= ka +(1.0f-ka)*kd;
						//fb->Set(u,v, currColor.GetColor());
					}
				}
				fb->Set(u,v, currColor.GetColor());
			}
		}
	}
	delete []pverts;

}