开始定义了
#define FIXP16_SHIFT 16
#define FIXP16_MAG 65536
#define FIX16_DP_MASK 0x0000ffff
#define FIX16_WP_MASK 0xffff0000
#define FIXP16_ROUND_UP 0x00008000
底部三角形
void Draw_Bottom_Tri( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( x3 < x2 )
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3- y1;
dx_left = ( x2 - x1 ) / height;
dx_right = ( x3 - x1 ) / height;
xs = ( float ) x1;
xe = ( float )x1;
if ( y1 < min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + min_clip_y );
y1 = min_clip_y;
}
if ( y3 > max_clip_y )
{
y3 = max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= min_clip_x && x1 <= max_clip_x && x2 >= min_clip_x && x2 <= max_clip_x && x3 >= min_clip_x && x3 <= max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( unsigned int ) xs, color, ( unsigned int ) ( xe - xs + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < min_clip_x )
{
left = min_clip_x;
if ( right < min_clip_x )
{
return;
}
}
if ( right > max_clip_x )
{
right = max_clip_x;
if ( left > max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
void Draw_Bottom_TriFP( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
Int dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( y1 == y2 || y1 == y3)
{
return;
}
if ( x3 < x2 )
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3 - y1;
dx_left = ( ( x2 - x1 ) << FIXP16_SHIFT ) / height;
dx_right = ( ( x3 - x1 ) << FIXP16_SHIFT ) / height;
xs = ( x1 << FIXP16_SHIFT );
xe = ( x1 << FIXP16_SHIFT );
if ( y1 < min_clip_y )
{
xs = xs + dx_left * ( -y1 + min_clip_y );
xe = xe + dx_right * ( -y1 + min_clip_y );
y1 = min_clip_y;
}
if ( y3 > max_clip_y )
{
y3 = max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= min_clip_x && x1 <= max_clip_x && x2 >= min_clip_x && x2 <= max_clip_x && x3 >= min_clip_x && x3 <= max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( ( xs + FIXP16_ROUND_UP) >> ), color, ( ( ( xe - xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ) + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( ( xs + FIX16_ROUND_UP ) >> FIXP16_SHIFT );
right = ( ( xe + FIX16_ROUND_UP ) >> FIXP16_SHIFT );
xs += dx_left;
xe += dx_right;
if ( left < min_clip_x )
{
left = min_clip_x;
if ( right < min_clip_x )
{
return;
}
}
if ( right > max_clip_x )
{
right = max_clip_x;
if ( left > max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + left, color, ( right - left + 1 ));
}
}
}
上三角形
void Draw_Top_Tri( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr = NULL;
if ( x2 < x1 )
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3- y1;
dx_left = ( x3 - x1 ) / height;
dx_right = ( x3 - x2 ) / height;
xs = ( float ) x1;
xe = ( float )x2 + ( float ) 0.5;
if ( y1 < min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + min_clip_y );
y1 = min_clip_y;
}
if ( y3 > max_clip_y )
{
y3 = max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= min_clip_x && x1 <= max_clip_x && x2 >= min_clip_x && x2 <= max_clip_x && x3 >= min_clip_x && x3 <= max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( unsigned int ) xs, color, ( unsigned int ) ( xe - xs + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < min_clip_x )
{
left = min_clip_x;
if ( right < min_clip_x )
{
continue;
}
}
if ( right > max_clip_x )
{
right = max_clip_x;
if ( left > max_clip_x )
{
continue;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
void Draw_Top_TriFP( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
Int dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( y3 == y2 || y1 == y3)
{
return;
}
if ( x2 < x1 )
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3 - y1;
dx_left = ( ( x3 - x1 ) << FIXP16_SHIFT ) / height;
dx_right = ( ( x3 - x2 ) << FIXP16_SHIFT ) / height;
xs = ( x1 << FIXP16_SHIFT );
xe = ( x2 << FIXP16_SHIFT );
if ( y1 < min_clip_y )
{
xs = xs + dx_left * ( -y1 + min_clip_y );
xe = xe + dx_right * ( -y1 + min_clip_y );
y1 = min_clip_y;
}
if ( y3 > max_clip_y )
{
y3 = max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= min_clip_x && x1 <= max_clip_x && x2 >= min_clip_x && x2 <= max_clip_x && x3 >= min_clip_x && x3 <= max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( ( xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ), color, ( ( ( xe - xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ) + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( ( xs + FIX16_ROUND_UP ) >> 16 );
right = ( ( xe + FIX16_ROUND_UP ) >> 16 );
xs += dx_left;
xe += dx_right;
if ( left < min_clip_x )
{
left = min_clip_x;
if ( right < min_clip_x )
{
return;
}
}
if ( right > max_clip_x )
{
right = max_clip_x;
if ( left > max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
对于普通的三角形
void Draw_Triangle_2D( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int temp_x, temp_y, new_x;
if( ( x1 == x2 && x2 == x3) || ( y1 == y2 && y2 == y3 ) )
return;
if ( y2 < y1 )
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y1 )
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y2 )
{
temp_x = x2;
temp_y = y2;
x2 = x3;
y2 = y3;
x3 = temp_x;
y3 = temp_y;
}
if ( y3 < min_clip_y || y1 > max_clip_y ||
( x1 < min_clip_x && x2 < min_clip_x && x3 < min_clip_x) ||
( x1 > max_clip_x && x2 > max_clip_x && x3 > max_clip_x )
)
{
return;
}
if ( y1 == y2 )
{
Draw_Top_Tri( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else if( y2 == y3)
{
Draw_Bottom_Tri( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else
{
new_x = x1 + ( int ) ( 0.5 + ( float ) ( y2 - y1) * (float) ( x3 - x1 ) / ( float ) ( y3 - y1));
Draw_Bottom_Tri( x1, y1, new_x, y2, x2, y2, color, dest_buffer, mempitch );
Draw_Top_Tri( x2, y2, new_x, y2, x3, y3, color, dest_buffer, mempitch );
}
}
void Draw_TriangleFP_2D( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int temp_x, temp_y, new_x;
if( ( x1 == x2 && x2 == x3) || ( y1 == y2 && y2 == y3 ) )
return;
if ( y2 < y1 )
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y1 )
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y2 )
{
temp_x = x2;
temp_y = y2;
x2 = x3;
y2 = y3;
x3 = temp_x;
y3 = temp_y;
}
if ( y3 < min_clip_y || y1 > max_clip_y ||
( x1 < min_clip_x && x2 < min_clip_x && x3 < min_clip_x) ||
( x1 > max_clip_x && x2 > max_clip_x && x3 > max_clip_x )
)
{
return;
}
if ( y1 == y2 )
{
Draw_Top_TriFP( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else if( y2 == y3)
{
Draw_Bottom_TriFP( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else
{
new_x = x1 + ( int ) ( 0.5 + ( float ) ( y2 - y1) * (float) ( x3 - x1 ) / ( float ) ( y3 - y1));
Draw_Bottom_TriFP( x1, y1, new_x, y2, x3, y3, color, dest_buffer, mempitch );
Draw_Top_TriFP( x1, y1, new_x, y2, x3, y3, color, dest_buffer, mempitch );
}
}
int Set_Palette_Entry( int color_index, LPPALETTEENTRY color )
{
lpddpal->SetEntries( 0, color_index, 1, color );
memcpy( & palette[color_index], color, sizeof( PALETTEENTRY ) );
return ( 1 );
}
在game_main()中,画了一个任意三角形
Draw_Triangle_2D( rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT,rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT,rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT, rand()%256, ( UCHAR * ) ddsd.lpSurface, ddsd.lPitch );
在Game_Init()中,初始化物体为四边形。
// define points of asteroid
VERTEX2DF object_vertices[4] = { -100, -100, 100, -100, 100, 100, -100, 100 };
// initialize asteroid
object.state = 1; // turn it on
object.num_verts = 24;
object.x0 = SCREEN_WIDTH/2; // position it
object.y0 = SCREEN_HEIGHT/2;
object.xv = 0;
object.yv = 0;
object.color = 2; // white
object.vlist = new VERTEX2DF [object.num_verts];
for (int index = 0; index < object.num_verts; index++)
object.vlist[index] = object_vertices[index];
截图如下:
现在进行封装。
几个成员变量
void DDRAW_Interface::Draw_Bottom_Tri( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( x3 < x2 )
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3- y1;
dx_left = ( x2 - x1 ) / height;
dx_right = ( x3 - x1 ) / height;
xs = ( float ) x1;
xe = ( float )x1;
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( unsigned int ) xs, color, ( unsigned int ) ( xe - xs + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
return;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
void DDRAW_Interface::Draw_Bottom_TriFP( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( y1 == y2 || y1 == y3)
{
return;
}
if ( x3 < x2 )
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3 - y1;
dx_left = ( ( x2 - x1 ) << FIXP16_SHIFT ) / height;
dx_right = ( ( x3 - x1 ) << FIXP16_SHIFT ) / height;
xs = ( x1 << FIXP16_SHIFT );
xe = ( x1 << FIXP16_SHIFT );
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( ( xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ), color, ( ( ( xe - xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ) + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( ( xs + FIXP16_ROUND_UP ) >> FIXP16_SHIFT );
right = ( ( xe + FIXP16_ROUND_UP ) >> FIXP16_SHIFT );
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
return;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + left, color, ( right - left + 1 ));
}
}
}
void DDRAW_Interface::Draw_Top_Tri( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr = NULL;
if ( x2 < x1 )
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3- y1;
dx_left = ( x3 - x1 ) / height;
dx_right = ( x3 - x2 ) / height;
xs = ( float ) x1;
xe = ( float )x2 + ( float ) 0.5;
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( unsigned int ) xs, color, ( unsigned int ) ( xe - xs + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
continue;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
continue;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
void DDRAW_Interface::Draw_Top_TriFP( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
UCHAR * dest_addr;
if ( y3 == y2 || y1 == y3)
{
return;
}
if ( x2 < x1 )
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3 - y1;
dx_left = ( ( x3 - x1 ) << FIXP16_SHIFT ) / height;
dx_right = ( ( x3 - x2 ) << FIXP16_SHIFT ) / height;
xs = ( x1 << FIXP16_SHIFT );
xe = ( x2 << FIXP16_SHIFT );
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
memset( ( UCHAR *) dest_addr + ( ( xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ), color, ( ( ( xe - xs + FIXP16_ROUND_UP) >> FIXP16_SHIFT ) + 1 ) );
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( ( xs + FIXP16_ROUND_UP ) >> 16 );
right = ( ( xe + FIXP16_ROUND_UP ) >> 16 );
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
return;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
return;
}
}
memset( ( UCHAR * ) dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1 ));
}
}
}
void DDRAW_Interface::Draw_Triangle_2D( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int temp_x, temp_y, new_x;
if( ( x1 == x2 && x2 == x3) || ( y1 == y2 && y2 == y3 ) )
return;
if ( y2 < y1 )
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y1 )
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y2 )
{
temp_x = x2;
temp_y = y2;
x2 = x3;
y2 = y3;
x3 = temp_x;
y3 = temp_y;
}
if ( y3 < m_min_clip_y || y1 > m_max_clip_y ||
( x1 < m_min_clip_x && x2 < m_min_clip_x && x3 < m_min_clip_x) ||
( x1 > m_max_clip_x && x2 > m_max_clip_x && x3 > m_max_clip_x )
)
{
return;
}
if ( y1 == y2 )
{
Draw_Top_Tri( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else if( y2 == y3)
{
Draw_Bottom_Tri( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else
{
new_x = x1 + ( int ) ( 0.5 + ( float ) ( y2 - y1) * (float) ( x3 - x1 ) / ( float ) ( y3 - y1));
Draw_Bottom_Tri( x1, y1, new_x, y2, x2, y2, color, dest_buffer, mempitch );
Draw_Top_Tri( x2, y2, new_x, y2, x3, y3, color, dest_buffer, mempitch );
}
}
void DDRAW_Interface::Draw_TriangleFP_2D( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int temp_x, temp_y, new_x;
if( ( x1 == x2 && x2 == x3) || ( y1 == y2 && y2 == y3 ) )
return;
if ( y2 < y1 )
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y1 )
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y2 )
{
temp_x = x2;
temp_y = y2;
x2 = x3;
y2 = y3;
x3 = temp_x;
y3 = temp_y;
}
if ( y3 < m_min_clip_y || y1 > m_max_clip_y ||
( x1 < m_min_clip_x && x2 < m_min_clip_x && x3 < m_min_clip_x) ||
( x1 > m_max_clip_x && x2 > m_max_clip_x && x3 > m_max_clip_x )
)
{
return;
}
if ( y1 == y2 )
{
Draw_Top_TriFP( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else if( y2 == y3)
{
Draw_Bottom_TriFP( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else
{
new_x = x1 + ( int ) ( 0.5 + ( float ) ( y2 - y1) * (float) ( x3 - x1 ) / ( float ) ( y3 - y1));
Draw_Bottom_TriFP( x1, y1, new_x, y2, x3, y3, color, dest_buffer, mempitch );
Draw_Top_TriFP( x1, y1, new_x, y2, x3, y3, color, dest_buffer, mempitch );
}
}
在Game_Init()中,
// define points of asteroid
VERTEX2DF object_vertices[4] = { -100, -100, 100, -100, 100, 100, -100, 100 };
// initialize asteroid
object.state = 1; // turn it on
object.num_verts = 24;
object.x0 = SCREEN_WIDTH/2; // position it
object.y0 = SCREEN_HEIGHT/2;
object.xv = 0;
object.yv = 0;
object.color = 2; // white
object.vlist = new VERTEX2DF [object.num_verts];
for (int index = 0; index < object.num_verts; index++)
object.vlist[index] = object_vertices[index];
在 game_main()中,
ddraw->Draw_Triangle_2D( rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT,
rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT,
rand() % SCREEN_WIDTH, rand()% SCREEN_HEIGHT,
rand()%256, ddraw->getbackbuffer(), ddraw->getbacklpitch() );
结果就OK了。
现在我们看下T3DLIB中,如何封装的。
typedef struct MATRIX1X3_TYP
{
union
{
float M[3];
struct
{
float M00, M01, M02;
};
};
}MATRIX1X3, * MATRIX1X3_PTR;
typedef struct MATRIX3X3_TYP
{
union
{
float M[3][3];
struct
{
float M00, M01, M02;
float M10, M11, M12;
float M20, M21, M22;
};
};
}MATRIX3X3, * MATRIX3X3_PTR;
int DDRAW_Interface::Mat_Mul3X3( MATRIX1X2_PTR ma, MATRIX3X2_PTR mb, MATRIX1X2_PTR mprod )
{
int index;
for ( int row = 0; row < 3; row++)
{
for( int col = 0; col < 3; col ++ )
{
float sum = 0;
for ( index = 0; index < 3; index++ )
{
sum += ( ma->M[index] * mb->M[index][col]);
}
mprod->M[col] = sum;
}
}
return ( 1 );
}
整合 角度
void DDRAW_Interface::Build_Sin_Cos_Tables( void )
{
for (int ang = 0; ang < 360; ang++)
{
// convert ang to radians
float theta = (float)ang*PI/(float)180;
cos_look[ang] = cos(theta);
sin_look[ang] = sin( theta );
} // end for ang
}
void DDRAW_Interface::Draw_Top_Tri16( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * _dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
USHORT * dest_buffer = ( USHORT * ) _dest_buffer;
USHORT * dest_addr = NULL;
mempitch = ( mempitch >> 1 );
if ( x2 < x1 )
{
temp_x = x2;
x2 = x1;
x1 = temp_x;
}
height = y3- y1;
dx_left = ( x3 - x1 ) / height;
dx_right = ( x3 - x2 ) / height;
xs = ( float ) x1;
xe = ( float )x2 + ( float ) 0.5;
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
Mem_Set_WORD( dest_addr + ( unsigned int ) xs, color, ( unsigned int ) ( xe - xs + 1));
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
continue;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
continue;
}
}
Mem_Set_WORD( dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left + 1));
}
}
}
void DDRAW_Interface::Mem_Set_WORD( void * dest, USHORT data, int count )
{
_asm
{
mov edi, dest ;
mov ecx, count ;
mov ax, data ;
rep stosw ;
}
}
void DDRAW_Interface::Draw_Bottom_Tri16( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * _dest_buffer, int mempitch )
{
float dx_right, dx_left, xs, xe,height;
int temp_x, temp_y, right, left;
USHORT * dest_buffer = ( USHORT * ) _dest_buffer;
USHORT * dest_addr = NULL;
mempitch = ( mempitch >> 1 );
if ( x3 < x2 )
{
temp_x = x2;
x2 = x3;
x3 = temp_x;
}
height = y3- y1;
dx_left = ( x2 - x1 ) / height;
dx_right = ( x3 - x1 ) / height;
xs = ( float ) x1;
xe = ( float )x1;
if ( y1 < m_min_clip_y )
{
xs = xs + dx_left * ( float ) ( -y1 + m_min_clip_y );
xe = xe + dx_right * ( float ) ( -y1 + m_min_clip_y );
y1 = m_min_clip_y;
}
if ( y3 > m_max_clip_y )
{
y3 = m_max_clip_y;
}
dest_addr = dest_buffer + y1 * mempitch;
if ( x1 >= m_min_clip_x && x1 <= m_max_clip_x && x2 >= m_min_clip_x && x2 <= m_max_clip_x && x3 >= m_min_clip_x && x3 <= m_max_clip_x )
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
Mem_Set_WORD( dest_addr + ( unsigned int ) xs, color, ( unsigned int ) (xe - xs + 1));
xs += dx_left;
xe += dx_right;
}
}
else
{
for( temp_y = y1; temp_y<= y3; temp_y++, dest_addr += mempitch )
{
left = ( int ) xs;
right = ( int ) xe;
xs += dx_left;
xe += dx_right;
if ( left < m_min_clip_x )
{
left = m_min_clip_x;
if ( right < m_min_clip_x )
{
return;
}
}
if ( right > m_max_clip_x )
{
right = m_max_clip_x;
if ( left > m_max_clip_x )
{
return;
}
}
Mem_Set_WORD( dest_addr + ( unsigned int ) left, color, ( unsigned int ) ( right - left +1));
}
}
}
void DDRAW_Interface::Draw_Triangle_2D16( int x1, int y1, int x2, int y2, int x3, int y3, int color, UCHAR * dest_buffer, int mempitch )
{
int temp_x, temp_y, new_x;
if( ( x1 == x2 && x2 == x3) || ( y1 == y2 && y2 == y3 ) )
return;
if ( y2 < y1 )
{
temp_x = x2;
temp_y = y2;
x2 = x1;
y2 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y1 )
{
temp_x = x3;
temp_y = y3;
x3 = x1;
y3 = y1;
x1 = temp_x;
y1 = temp_y;
}
if ( y3 < y2 )
{
temp_x = x2;
temp_y = y2;
x2 = x3;
y2 = y3;
x3 = temp_x;
y3 = temp_y;
}
if ( y3 < m_min_clip_y || y1 > m_max_clip_y ||
( x1 < m_min_clip_x && x2 < m_min_clip_x && x3 < m_min_clip_x) ||
( x1 > m_max_clip_x && x2 > m_max_clip_x && x3 > m_max_clip_x )
)
{
return;
}
if ( y1 == y2 )
{
Draw_Top_Tri16( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else if( y2 == y3)
{
Draw_Bottom_Tri16( x1, y1, x2, y2, x3, y3, color, dest_buffer, mempitch );
}
else
{
new_x = x1 + ( int ) ( 0.5 + ( float ) ( y2 - y1) * (float) ( x3 - x1 ) / ( float ) ( y3 - y1));
Draw_Bottom_Tri16( x1, y1, new_x, y2, x2, y2, color, dest_buffer, mempitch );
Draw_Top_Tri16( x2, y2, new_x, y2, x3, y3, color, dest_buffer, mempitch );
}
}