__
/ */
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);
};