📄 our_draw16.c
字号:
/**************************************************************************
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 + -