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

📄 our_draw16.c

📁 MTK上3D特效的一些开源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************
Copyright (C) jianbo miao Corporation.  All Rights Released.
this is a 3d engin named our_3d_engin.
our_3d_engin feature:
1:there is no float.
2:it do the 3d things all by softwear.
3:base on 1 and 2 , it can execution on arm which have no 3d hardwear accelerate.

if you have any  suggestion or question,pls contact with me
mail:miaojb@126.com
msn:miaojianbo@hotmail.com
qq:30209027

2008/01/01
***************************************************************************/

//

#include "our_3d.h"
#include "our_draw16.h"
#include "our_draw32.h"


//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
//==================================================================================
int OUR_Draw_Line16(int x0, int y0, 	// starting position 
				                int x1, int y1, 	// ending position
				                int color,     	// color index
				                UCHAR *vb_start, int lpitch_2) // video buffer and memory pitch
{
// this function draws a line from xo,yo to x1,y1 using differential error
// terms (based on Bresenahams work)

int dx,             // difference in x's
    dy,             // difference in y's
    dx2,            // dx,dy * 2
    dy2, 
    x_inc,          // amount in pixel space to move during drawing
    y_inc,          // amount in pixel space to move during drawing
    error,          // the discriminant i.e. error i.e. decision variable
    index;          // used for looping
USHORT *vb_start2;

lpitch_2 = lpitch_2>>1 ; // USHORT strided lpitch

// pre-compute first pixel address in video buffer based on 16bit data
 vb_start2= (USHORT*)vb_start + x0 + y0*lpitch_2;
// pre-compute first pixel address in video buffer based on 16bit data
//UINT*vb_start2 = (UINT*)vb_start + x0 + y0*lpitch_2;

// compute horizontal and vertical deltas
dx = x1-x0;
dy = y1-y0;

// test which direction the line is going in i.e. slope angle
if (dx>=0)
   {
   x_inc = 1;
   } // end if line is moving right
else
   {
   x_inc = -1;
   dx    = -dx;  // need absolute value
   } // end else moving left
// test y component of slope
if (dy>=0)
   {
   y_inc = lpitch_2;
   } // end if line is moving down
else
   {
   y_inc = -lpitch_2;
   dy    = -dy;  // need absolute value
   } // end else moving up

dx2 = dx << 1;// compute (dx,dy) * 2
dy2 = dy << 1;

if (dx > dy)// now based on which delta is greater we can draw the line
   {
   
   error = dy2 - dx; // initialize error term
   
   for (index=0; index <= dx; index++)// draw the line
       {
       
       *vb_start2 = (UINT)color;// set the pixel
       
       if (error >= 0) // test if error has overflowed
	   {
          error-=dx2;
          
          vb_start2+=y_inc;// move to next line
	   } // end if error overflowed
       
       error+=dy2;// adjust the error term
       
       vb_start2+=x_inc;// move to the next pixel
       } // end for
   } // end if |slope| <= 1
else
   {
   // initialize error term
   error = dx2 - dy; 
   // draw the line
   for (index=0; index <= dy; index++)
       {
       // set the pixel
       *vb_start2 = (UINT)color;

       // test if error overflowed
       if (error >= 0)
          {
          error-=dy2;
          // move to next line
          vb_start2+=x_inc;
          } // end if error overflowed
       // adjust the error term
       error+=dx2;
       // move to the next pixel
       vb_start2+=y_inc;
       } // end for
   } // end else |slope| > 1
// return success
return(1);
} // end Draw_Line16
//=================================================================================
int OUR_Draw_Clip_Line16(int x0,int y0, int x1, int y1, int color, 
                    UCHAR *dest_buffer, int lpitch)
{
// this function draws a clipped line

int cxs, cys,
	cxe, cye;

// clip and draw each line
cxs = x0;
cys = y0;
cxe = x1;
cye = y1;

// clip the line
//if (OUR_Clip_Line(&cxs,&cys,&cxe,&cye))
	OUR_Draw_Line16(cxs, cys, cxe,cye,color,dest_buffer,lpitch);

// return success
return(1);

} // end Draw_Clip_Line16

//--------------------------------------------------------------------

void OUR_Draw_Wire16( OUR_3D_OBJ_PTR	obj,UCHAR *video_buffer, int lpitch,int num)
{
// this function "executes" the render list or in other words
// draws all the faces in the list in wire frame 16bit mode
// note there is no need to sort wire frame polygons, but 
// later we will need to, so hidden surfaces stay hidden
// also, we leave it to the function to determine the bitdepth
// and call the correct rasterizer

// at this point, all we have is a list of polygons and it's time
// to draw them
sint32 i1,i2,i3;
sint32 poly;
FIX_POINT3D_PTR point_work=obj->pPoints_work;
OUR_3D_TRAG_PTR  	triangle_work=obj->pTriangle;

for (poly=0; poly <num; poly++)
    {
    if(OUR_D_FrameTH==obj->pTriangle_changed[poly])
    	{
	    i1=triangle_work[poly].p1;
	    i2=triangle_work[poly].p2;
	    i3=triangle_work[poly].p3;
#if 1
	    OUR_Draw_Clip_Line16(point_work[i1].MM.x, 
				               point_work[i1].MM.y,
				               point_work[i2].MM.x, 
				               point_work[i2].MM.y,
				               triangle_work[poly].CC.clor,
				                video_buffer, lpitch);
	    OUR_Draw_Clip_Line16(	point_work[i3].MM.x, 
				                point_work[i3].MM.y,
				                point_work[i2].MM.x, 
				                point_work[i2].MM.y,
				                triangle_work[poly].CC.clor,
				                video_buffer, lpitch);
	    OUR_Draw_Clip_Line16(	point_work[i1].MM.x, 
				                point_work[i1].MM.y,
				                point_work[i3].MM.x, 
				                point_work[i3].MM.y,
				                triangle_work[poly].CC.clor,
				                video_buffer, lpitch);
#else		
	
		Draw_Triangle_2D16(point_work[i1].MM.x, 
				               point_work[i1].MM.y,
				               point_work[i2].MM.x, 
				               point_work[i2].MM.y,
				                point_work[i3].MM.x, 
				                point_work[i3].MM.y,
				                triangle_work[poly].color,
				                video_buffer, lpitch);
#endif
		OUR_D_triangle_drawed_num++;

    	}
    }
} // end Draw_RENDERLIST4DV1_Wire

//===========================================================



//--------------------------------------------------------------------------
#define DRAW_T_SHIFT 20
void OUR_Draw_Triangle_2D16(	int x1,int y1,
				                        int x2,int y2,
				                        int x3,int y3,
				                        CLR color,
						    	UCHAR *dest_buffer, int mempitch)
{
	int xs,xe,ks,ke,xinc;
	int yinc;
	CLR16 *dest;
        OUR_RGB32_2_16(color);
	//make sure y1<y2<y3
	if(y1>y2)
	{
		OUR_SWAP(y1,y2,xs);
		OUR_SWAP(x1,x2,xs);
	}
	if(y1>y3)
	{
		OUR_SWAP(y1,y3,xs);
		OUR_SWAP(x1,x3,xs);
	}
	if(y2>y3)
	{
		OUR_SWAP(y2,y3,xs);
		OUR_SWAP(x2,x3,xs);
	}					//18t

	//mempitch>>=1;//(sizeof(dest)/2);
	dest = (CLR16*)dest_buffer +y1*mempitch;		//point to the line of y1
	if(y1<y2 )//the top part
	{		
		ks=((x1-x2)<<DRAW_T_SHIFT)/(y1-y2);		//slope 1 --> 2
		ke=((x1-x3)<<DRAW_T_SHIFT)/(y1-y3);		//slope 1 --> 3
		if(ks>ke)						//start slope must be smaller than the end one
		{
			OUR_SWAP(ks,ke,xs);
		}		
		xs=x1<<DRAW_T_SHIFT;
		xe=xs;
		for(yinc=y1;yinc<y2;yinc++)		//scan lines
		{			
			//y1=xe>>8;
			for(xinc=xs>>DRAW_T_SHIFT;xinc<=(xe>>DRAW_T_SHIFT);xinc++) 		//scan point 
			{
				dest[xinc] =color;		//display
			}
			dest+=mempitch;			//point to next line
			xs+=ks;					//next line xs
			xe+=ke;					//next line xe
		}		
		if(y2<y3)//the butt part
		{	
			x1=((x2-x3)<<DRAW_T_SHIFT)/(y2-y3);
			if(x1>ke)
			{
				ks=x1;
			}
			else
			{
				ke=x1;
			}
			for(;yinc<=y3;yinc++)
			{			
				//y1=xe>>8;
				for(xinc=xs>>DRAW_T_SHIFT;xinc<=(xe>>DRAW_T_SHIFT);xinc++)
				{
					dest[xinc] =color;
				}
				dest+=mempitch;
				xs+=ks;
				xe+=ke;
			}		
			
		}
		return;
	}
	else
	{		
		if(y2<y3)//the butt part
		{	
			ks=((x2-x3)<<DRAW_T_SHIFT)/(y1-y3);
			ke=((x1-x3)<<DRAW_T_SHIFT)/(y1-y3);
			if(ks<ke)
			{
				OUR_SWAP(ks,ke,xs);
			}	
			if(x1<x2)
			{
				xs=x1<<DRAW_T_SHIFT;
				xe=(x2<<DRAW_T_SHIFT);//+(xei>>1);
			}
			else 
			{
				xs=x2<<DRAW_T_SHIFT;
				xe=(x1<<DRAW_T_SHIFT);//+(xei>>1);
			
			}
			for(yinc=y1;yinc<y3;yinc++)
			{			
				//y1=xe>>8;
				for(xinc=xs>>DRAW_T_SHIFT;xinc<=(xe>>DRAW_T_SHIFT);xinc++)
				{
					dest[xinc] =color;
				}
				dest+=mempitch;
				xs+=ks;
				xe+=ke;
			}		
		}
		return;
	}
		
}

//--------------------------------------------------------------------------
//------------------------------------				
#define FILL_POINT	{				\
					dest[xinc] =color;	\
					xinc++;			\
					}
//----------------------------------------------------------------------------

#define DRAW_P_SHFT_X 18
#define SHIFR_L 18
#define SHIFT 30
//------------------------------------------------------
#define FILE_GOURAUD	{\
				dest[xinc++] =((k_r_inc>>(SHIFR_L-16))&OUR_RGB_MASK0800)+\
				((k_g_inc>>(SHIFR_L-8))&OUR_RGB_MASK0080)+((k_b_inc>>SHIFR_L)&OUR_RGB_MASK0008);\
				\
				k_r_inc+=kre;\
				k_g_inc+=kge;\
				k_b_inc+=kbe;\
						}
//------------------------------------------------------


void OUR_Draw_Gouraud_2D16(	int x1,int y1,
				                        int x2,int y2,
				                        int x3,int y3,
				                        CLR color1,
				                        CLR color2,
				                        CLR color3,
						    	UCHAR *dest_buffer, int mempitch)
{
	int xs,xe,ks,ke,xinc;
	int yinc;
	CLR rs,re,gs,ge,bs,be;
	int krs,kre,kgs,kge,kbs,kbe;
	int  k_r_inc;
	int  k_g_inc;
	int  k_b_inc;
	CLR16 *dest;
/*
	x1=200;
	y1=0;
	x2=1;
	y2=200;
	x3=350;
	y3=350;


	color1 = 0x000000;
	color2 = 0xff0000;
	color3 = 0x000000;
*/
	//make sure y1<y2<y3
	if(y1>y2)
	{
		OUR_SWAP(y1,y2,xs);
		OUR_SWAP(x1,x2,xs);
		OUR_SWAP(color1,color2,rs);
	}
	if(y1>y3)
	{
		OUR_SWAP(y1,y3,xs);
		OUR_SWAP(x1,x3,xs);
		OUR_SWAP(color1,color3,rs);
	}
	if(y2>y3)
	{
		OUR_SWAP(y2,y3,xs);
		OUR_SWAP(x2,x3,xs);
		OUR_SWAP(color2,color3,rs);
	}								//18t

	//mempitch>>=2;					//(sizeof(dest)/2);
	dest = (CLR16*)dest_buffer +y1*mempitch;		//point to the line of y1
#if 1
	if(y1<y2 )						//the top part
	{
		xs=(1<<(DRAW_P_SHFT_X))/(y1-y2);
		xe=(1<<(DRAW_P_SHFT_X))/(y1-y3);	
		ks=((x1-x2))*xs;				//slope 1 --> 2
		ke=((x1-x3))*xe;				//slope 1 --> 3
		xs>>=(DRAW_P_SHFT_X-SHIFR_L);
		xe>>=(DRAW_P_SHFT_X-SHIFR_L);
		if(ks>ke)						//start slope must be smaller than the end one
		{
			kre=(((color1&OUR_RGB_MASK0800)-(color2&OUR_RGB_MASK0800))>>16)*xs;
			krs=(((color1&OUR_RGB_MASK0800)-(color3&OUR_RGB_MASK0800))>>16)*xe;
			
			kge=(((color1&OUR_RGB_MASK0080)-(color2&OUR_RGB_MASK0080))>>8)*xs;
			kgs=(((color1&OUR_RGB_MASK0080)-(color3&OUR_RGB_MASK0080))>>8)*xe;
			
			kbe=(((color1&OUR_RGB_MASK0008)-(color2&OUR_RGB_MASK0008)))*xs;
			kbs=(((color1&OUR_RGB_MASK0008)-(color3&OUR_RGB_MASK0008)))*xe;
			OUR_SWAP(ks,ke,xs);
		}	
		else if(ks<ke)	
		{
			krs=(((color1&OUR_RGB_MASK0800)-(color2&OUR_RGB_MASK0800))>>16)*xs;
			kre=(((color1&OUR_RGB_MASK0800)-(color3&OUR_RGB_MASK0800))>>16)*xe;
			
			kgs=(((color1&OUR_RGB_MASK0080)-(color2&OUR_RGB_MASK0080))>>8)*xs;
			kge=(((color1&OUR_RGB_MASK0080)-(color3&OUR_RGB_MASK0080))>>8)*xe;
			
			kbs=(((color1&OUR_RGB_MASK0008)-(color2&OUR_RGB_MASK0008)))*xs;
			kbe=(((color1&OUR_RGB_MASK0008)-(color3&OUR_RGB_MASK0008)))*xe;
		}
		else
		{
			return;
		}
#define GND_KKKK 2
		if((ke-ks)<(1<<DRAW_P_SHFT_X))
                {      
			xs=((1<<(SHIFT-4)))/((ke-ks));
			kre=(((kre-krs)>>5)*xs)>>(SHIFT-SHIFR_L-5-4);		
			kge=(((kge-kgs)>>5)*xs)>>(SHIFT-SHIFR_L-5-4);		
			kbe=(((kbe-kbs)>>5)*xs)>>(SHIFT-SHIFR_L-5-4);
		}
		else
		{
			xs=((1<<(SHIFT)))/((ke-ks)>>GND_KKKK);
			kre=(((kre-krs)>>5)*xs)>>(SHIFT-SHIFR_L-5+GND_KKKK);		
			kge=(((kge-kgs)>>5)*xs)>>(SHIFT-SHIFR_L-5+GND_KKKK);		
			kbe=(((kbe-kbs)>>5)*xs)>>(SHIFT-SHIFR_L-5+GND_KKKK);
		}/**/
		xs=(x1<<(DRAW_P_SHFT_X));
		xe=(x1<<(DRAW_P_SHFT_X));

		rs=(color1&OUR_RGB_MASK0800)<<(SHIFR_L-16);		
		gs=(color1&OUR_RGB_MASK0080)<<(SHIFR_L-8);		
		bs=(color1&OUR_RGB_MASK0008)<<SHIFR_L;
		for(yinc=y1;yinc<y2;yinc++)		//scan lines
		{	
			k_r_inc=rs;
			k_g_inc=gs;
			k_b_inc=bs;
//------------------------------------------------------	
			xinc=xs>>(DRAW_P_SHFT_X);
			y1=(xe>>(DRAW_P_SHFT_X));
			dest[xinc++] =((k_r_inc>>(SHIFR_L-16))&OUR_RGB_MASK0800)+\
				((k_g_inc>>(SHIFR_L-8))&OUR_RGB_MASK0080)+((k_b_inc>>SHIFR_L)&OUR_RGB_MASK0008);
			for(;xinc<=y1;)	
			{
				FILE_GOURAUD;
			}	
			rs+=krs;			
			gs+=kgs;			
			bs+=kbs;
			
			dest+=mempitch;			//point to next line
			xs+=ks;					//next line xs
			xe+=ke;					//next line xe
		}
		if(y2<y3)						//the butt part
		{	
			y1=(1<<(DRAW_P_SHFT_X))/(y2-y3);
			x1=((x2-x3))*y1;
			y1>>=(DRAW_P_SHFT_X-SHIFR_L);
			if(x1>ke)
			{
				ks=x1;

				krs=(((color2&OUR_RGB_MASK0800)-(color3&OUR_RGB_MASK0800))>>16)*y1;			
				kgs=(((color2&OUR_RGB_MASK0080)-(color3&OUR_RGB_MASK0080))>>8)*y1;				
				kbs=(((color2&OUR_RGB_MASK0008)-(color3&OUR_RGB_MASK0008)))*y1;
			}
			else
			{
				ke=x1;
			}
			for(;yinc<=y3;yinc++)
			{			
				k_r_inc=rs;
				k_g_inc=gs;
				k_b_inc=bs;
	//------------------------------------------------------
				xinc=xs>>(DRAW_P_SHFT_X);
				y1=(xe>>(DRAW_P_SHFT_X));

⌨️ 快捷键说明

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