__

/ */

void ScanGouraudEdgeAndStoreInArray(int side, float TopX, float TopY, int

FirstShade, float BottomX, float BottomY, float LastShade, int *Array, int

*Shade)

{

int FirstScreenY = (int)ceil(TopY);

int LastScreenY = (int)ceil(BottomY)-1;

int y;

if (FirstScreenY > LastScreenY)

return;

float DeltaX = (BottomX-TopX) / (BottomY-TopY);

float GouraudStep = (float)((LastShade-FirstShade)/(BottomY-TopY));

float CurrentShade = FirstShade;

float x = TopX + (FirstScreenY-TopY) * DeltaX;

if (side)

for (y=FirstScreenY; y<=LastScreenY; y++,x+=DeltaX, CurrentShade

+=GouraudStep)

{

Array[y] = (int)ceil(x);

Shade[y] = (int)CurrentShade;

}

else

for (y=FirstScreenY; y<=LastScreenY; y++,x+=DeltaX, CurrentShade

+=GouraudStep)

{

Array[y] = (int)ceil(x)-1;

Shade[y] = (int)CurrentShade;

}

};

/* _______________________________________________________________

/ /

/ GouraudHline: Gouraud horizontal scan-line filler /

/____________________________________________________________ / */

void GouraudHLine(BITMAP *bitmap, int x1, int FirstShade, int x2, int

LastShade, int y, int Colour)

{

int Length;

int NumColours;

float CurrentShade;

float Step;

int x;

Length = x2 - x1+1;

if (Length < 0)

return;

NumColours = LastShade - FirstShade+1;

Step = (float)NumColours/(float)Length;

CurrentShade = FirstShade;

for (x=x1; x<=x2; x++, CurrentShade+=Step)

{

putpixel(bitmap, x, y, color_map->data[(int)CurrentShade][Colour]);

};

};

/* ________________________________________________________________

/ /

/ FlatShadedTriangle: 100% Flat shaded triangle renderer /

/_____________________________________________________________/ */

void FlatShadedTriangle(BITMAP *bitmap, int x1, int y1, int x2, int y2, int

x3, int y3, int col)

{

// edge table

// change this to suit video mode

int Left[200], Right[200];

// Sort verticies top->bottom

if (y1 > y2)

{

int tx=x1, ty=y1;

x1=x2, y2=y2;

x2=tx, y2=ty;

}

if (y1 > y3)

{

int tx=x1, ty=y1;

x1=x3, y2=y3;

x3=tx, y3=ty;

}

if (y2 > y3)

{

int tx=x2, ty=y2;

x2=x3, y2=y3;

x3=tx, y3=ty;

}

// make sure polygon isn't abnormally thin

if (x2 == x3)

return;

// scan-convert the edges

if (x2 < x3)

{

ScanEdgeAndStoreInArray(LEFT, x1, y1, x2, y2, Left);

ScanEdgeAndStoreInArray(RIGHT, x1, y1, x3, y3, Right);

if (y2!=y3) // skip if it's a horizontal edge

ScanEdgeAndStoreInArray(LEFT, x2, y2, x3, y3, Left);

}

else

{

ScanEdgeAndStoreInArray(LEFT, x1, y1, x3, y3, Left);

ScanEdgeAndStoreInArray(RIGHT, x1, y1, x2, y2, Right);

if (y2!=y3)

ScanEdgeAndStoreInArray(RIGHT, x2, y2, x3, y3, Right);

};

// spanfil the the polygon

for (int y=y1; y<y3; y++)

{

if (Left[y] <= Right[y])

hline(bitmap, Left[y], y, Right[y], col);

}

};

/* ___________________________________________________________________

/ /

/ GouraudShadedTriangle: 100% Gouraud shaded triangle renderer /

/_________________________________________________________________/ */

void GouraudShadedTriangle(BITMAP *bitmap, int x1, int y1, int c1, int x2,

int y2, int c2, int x3, int y3, int c3, int col)

{

// change to suit video mode

int Left[200], Right[200], LeftShade[200], RightShade[200];

if (y1 > y2)

{

int tx=x1, ty=y1;

x1=x2, y2=y2;

x2=tx, y2=ty;

tx=c1, c1=c2, c2=tx;

}

if (y1 > y3)

{

int tx=x1, ty=y1;

x1=x3, y2=y3;

x3=tx, y3=ty;

tx=c1, c1=c3, c3=tx;

}

if (y2 > y3)

{

int tx=x2, ty=y2;

x2=x3, y2=y3;

x3=tx, y3=ty;

tx=c2, c2=c3, c3=tx;

}

if (x2 == x3)

return;

if (x2 < x3)

{

ScanGouraudEdgeAndStoreInArray(LEFT, x1, y1, c1, x2, y2, c2, Left,

LeftShade);

ScanGouraudEdgeAndStoreInArray(RIGHT, x1, y1, c1, x3, y3, c3, Right,

RightShade);

if (y2!=y3)

ScanGouraudEdgeAndStoreInArray(LEFT, x2, y2, c2, x3, y3, c3, Left,

LeftShade);

}

else

{

ScanGouraudEdgeAndStoreInArray(LEFT, x1, y1, c1, x3, y3, c3, Left,

LeftShade);

ScanGouraudEdgeAndStoreInArray(RIGHT, x1, y1, c1, x2, y2, c2, Right,

RightShade);

if (y2!=y3)

ScanGouraudEdgeAndStoreInArray(RIGHT, x2, y2, c2, x3, y3, c3, Right,

RightShade);

};

for (int y=y1; y<y3; y++)

{

if (Left[y] <= Right[y])

GouraudHLine(bitmap, Left[y], LeftShade[y], Right[y], RightShade[y], y,

col);

}

};

int main()

{

set_gfx_mode(GFX_VGA, 320, 200, 0, 0);

LoadLightmaps();

PALETTE pal;

BITMAP *fuckyou = load_pcx("pal.pcx", pal);

set_pallete(pal);

/*

FlatShadedTriangle(screen, 160, 20, 200, 40, 120, 60, 25);

getch();*/

//*

GouraudShadedTriangle(screen, 160, 20, 255,

200, 40, 0,

120, 60, 0,

25);

getch();

//*/

/* while (!kbhit())

GouraudShadedTriangle(screen,

rand()%320, rand()%200, rand()%255,

rand()%320, rand()%200, rand()%255,

rand()%320, rand()%200, rand()%255,

0);

getch();

*/

textmode(C80);

};