2013年9月11日星期三(demo8-7,三角形)

 

开始定义了

#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 );

         }

 

 

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值