• Advertisement
Sign in to follow this  

a problem with triangle raster

This topic is 4616 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

C++
#define FIXP16_SHIFT     16
#define FIXP16_MAG       65536
#define FIXP16_DP_MASK   0x0000ffff
#define FIXP16_WP_MASK   0xffff0000
#define FIXP16_ROUND_UP  0x00008000



void Draw_Top_TriFP(int x1,int y1,
                    int x2,int y2, 
                    int x3,int y3,
                    int color, 
                    UCHAR *dest_buffer, int mempitch)
{
// this function draws a triangle that has a flat top using fixed point math

int dx_right,    // the dx/dy ratio of the right edge of line
    dx_left,     // the dx/dy ratio of the left edge of line
    xs,xe,       // the starting and ending points of the edges
    height;      // the height of the triangle

int temp_x,        // used during sorting as temps
    temp_y,
    right,         // used by clipping
    left;

UCHAR  *dest_addr;

// test for degenerate
if (y1==y3 || y2==y3)
return;

// test order of x1 and x2
if (x2 < x1)
   {
   temp_x = x2;
   x2     = x1;
   x1     = temp_x;
   } // end if swap

// compute delta's
height = ((y3-y1)<<FIXP16_SHIFT);

dx_left  = ((x3-x1)<<FIXP16_SHIFT)/height;
dx_right = ((x3-x2)<<FIXP16_SHIFT)/height;

// set starting points
xs = (x1<<FIXP16_SHIFT);
xe = (x2<<FIXP16_SHIFT);

// perform y clipping
if (y1<min_clip_y)
   {
   // compute new xs and ys
   xs = xs+dx_left*(-y1+min_clip_y);
   xe = xe+dx_right*(-y1+min_clip_y);

   // reset y1
   y1=min_clip_y;

   } // end if top is off screen

if (y3>max_clip_y)
   y3=max_clip_y;

// compute starting address in video memory
dest_addr = dest_buffer+y1*mempitch;

// test if x clipping is needed
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)
    {
    // draw the triangle
    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));

        // adjust starting point and ending point
        xs+=dx_left;
        xe+=dx_right;

        } // end for

    } // end if no x clipping needed
else
   {
   // clip x axis with slower version

   // draw the triangle
   for (temp_y=y1; temp_y<=y3; temp_y++,dest_addr+=mempitch)
       {
       // do x clip
       left  = ((xs+FIXP16_ROUND_UP)>>16);
       right = ((xe+FIXP16_ROUND_UP)>>16);

       // adjust starting point and ending point
       xs+=dx_left;
       xe+=dx_right;

       // clip line
       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));

       } // end for

   } // end else x clipping needed

} // end Draw_Top_TriF

problem: The triangle which be drawed has a excursion in _X(axis) . I dont know why. maybe this is a logistic error about arithmetic. Big Fuking Thanks For you help!!!!

Share this post


Link to post
Share on other sites
Advertisement
Maybe this helps: swShader - Advanced Rasterization. It's not the fastest technique on the planet (for a software implementation), but it's very elegant and robust. It clips automatically but not outside 2048x2048 dimensions. A geometrical clipper is highly advised anyway.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement