0

My triangle rasterization program works as-is, but I would like to make it easier to use by specifying explicit coordinates instead of differentials. Unfortunately, I don't know how to calculate the necessary change-of-basis matrix. This can be seen by the empty "rasterizeCnvTri" function.

The following section is my code, using the PixelToaster library for a framebuffer:

// TrueColor Example
// How to open a display in truecolor mode and work with 32 bit integer pixels.
// Copyright © Glenn Fiedler, 2004-2005. http://www.pixeltoaster.com

#include "pt/source/PixelToaster.h"

using namespace PixelToaster;

int fbuf[256][256][3];
int zbuf[256][256];

void rasterizeTriangle(int u,int dudx,int dudy,int v,int dvdx,int dvdy,int w,int dwdx,int dwdy,int r,int g,int b)
{
    int u_rw = u;
    int v_rw = v;
    int w_rw = w;
    for(int j=0; j<256; j++)
    {
        int u_pt = u_rw;
        int v_pt = v_rw;
        int w_pt = w_rw;
        for(int i=0; i<256; i++)
        {
            if(w_pt>=zbuf[i][j] && u_pt>=0 && v_pt>=0 && (u_pt+v_pt)<4096)
                {fbuf[i][j][0]=r; fbuf[i][j][1]=g; fbuf[i][j][2]=b; zbuf[i][j]=w_pt;}
            u_pt += dudx;
            v_pt += dvdx;
            w_pt += dwdx;
        }
        u_rw += dudy;
        v_rw += dvdy;
        w_rw += dwdy;
    }
}

void rasterizeCnvTri(int x1,int x2,int x3,int y1,int y2,int y3,int w1,int w2,int w3,int r,int g,int b)
{
    //how to do this?
}

int main()
{
    const int width = 256;
    const int height = 256;

    Display display( "Triangle Rasterizer", width, height, Output::Default, Mode::TrueColor );

    vector<TrueColorPixel> pixels( width * height );

    rasterizeTriangle(-2048,32,0,-2048,0,32,2048,0,0,255,0,0);
    rasterizeTriangle(0,32,-32,-2048,0,32,4096,-16,0,255,255,255);

    while ( display.open() )
    {
        unsigned int index = 0;

        for ( int y = 0; y < height; ++y )
        {
            for ( int x = 0; x < width; ++x )
            {
                pixels[index].r = fbuf[x][y][0];
                pixels[index].g = fbuf[x][y][1];
                pixels[index].b = fbuf[x][y][2];

                ++index;
            }
        }

        display.update( pixels );
    }
}

U and V are the axes along two of the sides, and W is the inverse depth. All three coordinates are scaled by 4096, so integers are sufficient.

[EDIT]

The following code works for me (also does basic perspective divide):

void rasterizeCnvTri(int x1,int x2,int x3,int y1,int y2,int y3,int w1,int w2,int w3,int r,int g,int b)
{
    int xp1 = (((x1-128)*w1)>>8)+128;
    int yp1 = (((y1-128)*w1)>>8)+128;
    int xp2 = (((x2-128)*w2)>>8)+128;
    int yp2 = (((y2-128)*w2)>>8)+128;
    int xp3 = (((x3-128)*w3)>>8)+128;
    int yp3 = (((y3-128)*w3)>>8)+128;

    int xd2 = xp2-xp1;
    int xd3 = xp3-xp1;
    int yd2 = yp2-yp1;
    int yd3 = yp3-yp1;
    int wd2 = w2-w1;
    int wd3 = w3-w1;

    int plna = (yd2*wd3)-(yd3*wd2);
    int plnb = (wd2*xd3)-(wd3*xd2);
    int plnc = (xd2*yd3)-(xd3*yd2);
    int plnd = -(plna*xp1)-(plnb*yp1)-(plnc*w1);

    int invdet = (xd2*yd3)-(yd2*xd3);

    int dudx = (-yd3<<12)/invdet;
    int dudy = (yd2<<12)/invdet;
    int u = (-xp1*dudx)-(yp1*dudy);
    int dvdx = (xd3<<12)/invdet;
    int dvdy = (-xd2<<12)/invdet;
    int v = (-xp1*dvdx)-(yp1*dvdy);

    rasterizeTriangle(-u,-dudx,-dudy,-v,-dvdx,-dvdy,-plnd/plnc,-plna/plnc,-plnb/plnc,r,g,b);
}

0 Answers0