⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tmapper.cpp

📁 3D游戏开发领域专家撰写的经典游戏开发启迪性文章之一 到此为止所有的文章都已上传完毕,希望大家喜欢,以后会继续收集相关质料供大家分享
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
		dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;    

		// RHS
		dyr = (y2 - y0);	

		dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
		dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
		dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   
		
		// compute overclip
		dyr = (poly_clip_min_y - y0);
		dyl = (poly_clip_min_y - y1);

		// computer new LHS starting values
		xl = dxdyl*dyl + (x1  << FIXP16_SHIFT);
		ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
		vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);

		// compute new RHS starting values
		xr = dxdyr*dyr + (x0  << FIXP16_SHIFT);
		ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
		vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);

		// compute new starting y
		ystart = poly_clip_min_y;

		// test if we need swap to keep rendering left to right
		if (dxdyr > dxdyl)
			{
			SWAP(dxdyl,dxdyr,temp);
			SWAP(dudyl,dudyr,temp);
			SWAP(dvdyl,dvdyr,temp);
			SWAP(xl,xr,temp);
			SWAP(ul,ur,temp);
			SWAP(vl,vr,temp);
			SWAP(x1,x2,temp);
			SWAP(y1,y2,temp);
			SWAP(tu1,tu2,temp);
			SWAP(tv1,tv2,temp);
		
			// set interpolation restart
			irestart = INTERP_RHS;

			} // end if

		} // end if
	else
	if (y0 < poly_clip_min_y)
		{
		// compute all deltas
		// LHS
		dyl = (y1 - y0);

		dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
		dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;  
		dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;    

		// RHS
		dyr = (y2 - y0);	

		dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
		dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
		dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   
		
		// compute overclip
		dy = (poly_clip_min_y - y0);

		// computer new LHS starting values
		xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
		ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
		vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);

		// compute new RHS starting values
		xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
		ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
		vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);

		// compute new starting y
		ystart = poly_clip_min_y;

		// test if we need swap to keep rendering left to right
		if (dxdyr < dxdyl)
			{
			SWAP(dxdyl,dxdyr,temp);
			SWAP(dudyl,dudyr,temp);
			SWAP(dvdyl,dvdyr,temp);
			SWAP(xl,xr,temp);
			SWAP(ul,ur,temp);
			SWAP(vl,vr,temp);
			SWAP(x1,x2,temp);
			SWAP(y1,y2,temp);
			SWAP(tu1,tu2,temp);
			SWAP(tv1,tv2,temp);
		
			// set interpolation restart
			irestart = INTERP_RHS;

			} // end if

		} // end if
	else
		{
		// no initial y clipping
	
		// compute all deltas
		// LHS
		dyl = (y1 - y0);

		dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
		dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;  
		dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;    

		// RHS
		dyr = (y2 - y0);	

		dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
		dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
		dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   		

		// no clipping y

		// set starting values
		xl = (x0 << FIXP16_SHIFT);
		xr = (x0 << FIXP16_SHIFT);

		ul = (tu0 << FIXP16_SHIFT);
		vl = (tv0 << FIXP16_SHIFT);

		ur = (tu0 << FIXP16_SHIFT);
		vr = (tv0 << FIXP16_SHIFT);

		// set starting y
		ystart = y0;

		// test if we need swap to keep rendering left to right
		if (dxdyr < dxdyl)
			{
			SWAP(dxdyl,dxdyr,temp);
			SWAP(dudyl,dudyr,temp);
			SWAP(dvdyl,dvdyr,temp);
			SWAP(xl,xr,temp);
			SWAP(ul,ur,temp);
			SWAP(vl,vr,temp);
			SWAP(x1,x2,temp);
			SWAP(y1,y2,temp);
			SWAP(tu1,tu2,temp);
			SWAP(tv1,tv2,temp);
		
			// set interpolation restart
			irestart = INTERP_RHS;

			} // end if

		} // end else


    // test for horizontal clipping
	if ((x0 < poly_clip_min_x) || (x0 > poly_clip_max_x) ||
		(x1 < poly_clip_min_x) || (x1 > poly_clip_max_x) ||
		(x2 < poly_clip_min_x) || (x2 > poly_clip_max_x))
	{
    // clip version
	// x clipping	

	// point screen ptr to starting line
	screen_ptr = dest_buffer + (ystart * mem_pitch);

	for (yi = ystart; yi<=yend; yi++)
		{
		// compute span endpoints
		xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
		xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
		
		// compute starting points for u,v interpolants
		ui = ul + FIXP16_ROUND_UP;
		vi = vl + FIXP16_ROUND_UP;
	
		// compute u,v interpolants
		if ((dx = (xend - xstart))>0)
			{
			du = (ur - ul)/dx;
			dv = (vr - vl)/dx;
			} // end if
		else
			{
			du = (ur - ul);
			dv = (vr - vl);
			} // end else

		///////////////////////////////////////////////////////////////////////

		// test for x clipping, LHS
		if (xstart < poly_clip_min_x)
			{
			// compute x overlap
			dx = poly_clip_min_x - xstart;

			// slide interpolants over
			ui+=dx*du;
			vi+=dx*dv;
			
			// set x to left clip edge
			xstart = poly_clip_min_x;

			} // end if
		
		// test for x clipping RHS
		if (xend > poly_clip_max_x)
			xend = poly_clip_max_x;

		///////////////////////////////////////////////////////////////////////

		// draw span
		for (xi=xstart; xi<=xend; xi++)
			{
			// write textel
            screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << 6)];
			
			// interpolate u,v
			ui+=du;
			vi+=dv;
			} // end for xi

		// interpolate u,v,x along right and left edge
		xl+=dxdyl;
		ul+=dudyl;
		vl+=dvdyl;
	
		xr+=dxdyr;
		ur+=dudyr;
		vr+=dvdyr;

		// advance screen ptr
		screen_ptr+=mem_pitch;

		// test for yi hitting second region, if so change interpolant
		if (yi==yrestart)
			{

		// test interpolation side change flag

			if (irestart == INTERP_LHS)
			{
			// LHS
			dyl = (y2 - y1);	

			dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
			dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
			dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;   		

			// set starting values
			xl = (x1  << FIXP16_SHIFT);
			ul = (tu1 << FIXP16_SHIFT);
			vl = (tv1 << FIXP16_SHIFT);

			// interpolate down on LHS to even up
			xl+=dxdyl;
			ul+=dudyl;
			vl+=dvdyl;
			} // end if
			else
			{
			// RHS
			dyr = (y1 - y2);	

			dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
			dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;  
			dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;   		

			// set starting values
			xr = (x2  << FIXP16_SHIFT);
			ur = (tu2 << FIXP16_SHIFT);
			vr = (tv2 << FIXP16_SHIFT);

			// interpolate down on RHS to even up
			xr+=dxdyr;
			ur+=dudyr;
			vr+=dvdyr;
		
			} // end else


			} // end if

		} // end for y

	} // end if
	else
	{
	// no x clipping
	// point screen ptr to starting line
	screen_ptr = dest_buffer + (ystart * mem_pitch);

	for (yi = ystart; yi<=yend; yi++)
		{
		// compute span endpoints
		xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
		xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
		
		// compute starting points for u,v interpolants
		ui = ul + FIXP16_ROUND_UP;
		vi = vl + FIXP16_ROUND_UP;
	
		// compute u,v interpolants
		if ((dx = (xend - xstart))>0)
			{
			du = (ur - ul)/dx;
			dv = (vr - vl)/dx;
			} // end if
		else
			{
			du = (ur - ul);
			dv = (vr - vl);
			} // end else

		// draw span
		for (xi=xstart; xi<=xend; xi++)
			{
			// write textel
            screen_ptr[xi] = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << 6)];
			
			// interpolate u,v
			ui+=du;
			vi+=dv;
			} // end for xi

		// interpolate u,v,x along right and left edge
		xl+=dxdyl;
		ul+=dudyl;
		vl+=dvdyl;
	
		xr+=dxdyr;
		ur+=dudyr;
		vr+=dvdyr;

		// advance screen ptr
		screen_ptr+=mem_pitch;

		// test for yi hitting second region, if so change interpolant
		if (yi==yrestart)
			{
			// test interpolation side change flag

			if (irestart == INTERP_LHS)
			{
			// LHS
			dyl = (y2 - y1);	

			dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
			dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
			dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;   		

			// set starting values
			xl = (x1  << FIXP16_SHIFT);
			ul = (tu1 << FIXP16_SHIFT);
			vl = (tv1 << FIXP16_SHIFT);

			// interpolate down on LHS to even up
			xl+=dxdyl;
			ul+=dudyl;
			vl+=dvdyl;
			} // end if
			else
			{
			// RHS
			dyr = (y1 - y2);	

			dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
			dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;  
			dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;   		

			// set starting values
			xr = (x2  << FIXP16_SHIFT);
			ur = (tu2 << FIXP16_SHIFT);
			vr = (tv2 << FIXP16_SHIFT);

			// interpolate down on RHS to even up
			xr+=dxdyr;
			ur+=dudyr;
			vr+=dvdyr;
		
			} // end else

			} // end if

		} // end for y

	} // end else	

	} // end if

} // end Draw_Textured_Triangle

/******************************* EXAMPLE ***********************************

This is the setup:

To create a single triangle to be rendered consisting of the 3
points (in CC order I think):

(x0,y0,u0,v0)
(x1,y1,u1,v1)
(x2,y2,u2,v2)

64x64 texture at address texture_buffer in row major form

FACE3D face; // the triangle object

// set up the vertices
face.tlist[0].x = x0;
face.tlist[0].y = y0;
face.tlist[0].u = u0;
face.tlist[0].v = v0;

face.tlist[1].x = x1;
face.tlist[1].y = y1;
face.tlist[1].u = u1;
face.tlist[1].v = v1;

face.tlist[2].x = x2;
face.tlist[2].y = y2;
face.tlist[2].u = u2;
face.tlist[2].v = v2;

// assign the texture to your 64x64 texture map buffer
face.texture = texture_buffer;

// set the clipping coords of the desired 2D viewport
poly_clip_min_x = 0; 
poly_clip_max_x = 0;
poly_clip_min_y = SCREEN_WIDTH-1;
poly_clip_max_y = SCREEN_HEIGHT-1

// then draw the triangle to the rendering buffer
Draw_Textured_Triangle((void *)&face, double_buffer, memory_pitch);

***************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -