void
Draw_Gouraud_Triangle(unsigned
int* pBits, int
w, int h, int
pitch,
int x0,
int y0, float
r0, float g0, float
b0,
int x1,
int y1, float
r1, float g1, float
b1,
int x2,
int y2, float
r2, float g2, float
b2)
{
// Sort our points into order of y
// 0 top
// 2 middle
// 1 bottom
if( y1 < y0 )
{
SWAP(y1, y0);
SWAP(x1, x0);
SWAP(r1, r0); SWAP(g1, g0); SWAP(b1, b0);
}
if( y2 < y0 )
{
SWAP(y2, y0);
SWAP(x2, x0);
SWAP(r2, r0); SWAP(g2, g0); SWAP(b2, b0);
}
if( y1 < y2 )
{
SWAP(y2, y1);
SWAP(x2, x1);
SWAP(r2, r1); SWAP(g2, g1); SWAP(b2, b1);
}
float xl_edge = (float)x0;
// left edge
float xr_edge = (float)x0;
// right edge
float dxldy;
float dxrdy;
float dxdy1 = (float)(x2-x0)/(y2-y0);
float dxdy2 = (float)(x1-x0)/(y1-y0);
float dr1 = (float)(r2-r0)/(y2-y0);
float dg1 = (float)(g2-g0)/(y2-y0);
float db1 = (float)(b2-b0)/(y2-y0);
float dr2 = (float)(r1-r0)/(y1-y0);
float dg2 = (float)(g1-g0)/(y1-y0);
float db2 = (float)(b1-b0)/(y1-y0);
float drldy, dgldy, dbldy;
float drrdy, dgrdy, dbrdy;
if( dxdy1 < dxdy2 )
{
dxldy = dxdy1;
dxrdy = dxdy2;
drldy = dr1; dgldy = dg1; dbldy = db1;
// left (r,g,b)
drrdy = dr2; dgrdy = dg2; dbrdy = db2;
// right (r,g,b)
}
else
{
dxldy = dxdy2;
dxrdy = dxdy1;
drldy = dr2; dgldy = dg2; dbldy = db2;
// left (r,g,b)
drrdy = dr1; dgrdy = dg1; dbrdy = db1;
// right (r,g,b)
}
float r_left = r0;
float r_right = r0;
float g_left = g0;
float g_right = g0;
float b_left = b0;
float b_right = b0;
// Top of the triangle
for(int
y=y0; y<y2; y++)
{
float dr = (r_right - r_left)/(xr_edge
- xl_edge);
float dg = (g_right - g_left)/(xr_edge
- xl_edge);
float db = (b_right - b_left)/(xr_edge
- xl_edge);
float pr = r_left;
float pg = g_left;
float pb = b_left;
for(int
x=xl_edge; x<xr_edge; x++)
{
pr = pr + dr;
pg = pg + dg;
pb = pb + db;
setpixel(pBits, w, h, pitch,
x, y, TO_RGB(pr,pg,pb) );
}//end for loop x
xl_edge = xl_edge + dxldy;
xr_edge = xr_edge + dxrdy;
r_left += drldy;
r_right += drrdy;
g_left += dgldy;
g_right += dgrdy;
b_left += dbldy;
b_right += dbrdy;
}//
end for loop y
// Bottom half of the triangle
if( dxdy1 < dxdy2 )
{
dxldy = (float)(x2-x1)/(y2-y1);
drldy = (r2-r1)/(y2-y1);
dgldy = (g2-g1)/(y2-y1);
dbldy = (b2-b1)/(y2-y1);
}
else
{
dxrdy = (float)(x2-x1)/(y2-y1);
drrdy = (r2-r1)/(y2-y1);
dgrdy = (g2-g1)/(y2-y1);
dbrdy = (b2-b1)/(y2-y1);
}
for(int
y=y2; y<y1; y++)
{
float dr = (r_right - r_left)/(xr_edge
- xl_edge);
float dg = (g_right - g_left)/(xr_edge
- xl_edge);
float db = (b_right - b_left)/(xr_edge
- xl_edge);
float pr = r_left;
float pg = g_left;
float pb = b_left;
for(int
x=xl_edge; x<xr_edge; x++)
{
pr = pr + dr;
pg = pg + dg;
pb = pb + db;
setpixel(pBits, w, h, pitch,
x, y, TO_RGB(pr,pg,pb) );
}//end for loop x
xl_edge = xl_edge + dxldy;
xr_edge = xr_edge + dxrdy;
r_left += drldy;
r_right += drrdy;
g_left += dgldy;
g_right += dgrdy;
b_left += dbldy;
b_right += dbrdy;
}//
end for loop y
/*
// Debug Info - puts the y pos into the window title
extern HWND hWnd;
char buf[200];
sprintf(buf, "y0: %d, y2: %d, y1:%d", y0, y2, y1);
SetWindowText(hWnd, buf);
*/
}//
End of Draw_Gouraud_Triangle(..)
//
This is where we call our Triangle Draw function from, and is responsible
for capturing the mouse
// and
altering one of the triangles coordinates values.
void
Render(unsigned int*
pBits, int w, int
h, int pitch)
{
// Clear our screen to black
cls(pBits, w, h, pitch);
int x0=100, y0=100;
static int
x1=90;
static int
y1=100;
int x2=260, y2=350;
extern HWND hWnd;
POINT mousePos;
GetCursorPos(&mousePos);
ScreenToClient(hWnd, &mousePos);
SetCursor(LoadCursor (NULL, IDC_CROSS)) ;
// This just makes sure our cursor is inside our
window.
if( (mousePos.y < h) && (mousePos.x>0) && (mousePos.x<w)
&& (mousePos.y>0) )
{
char buf[200];
sprintf(buf, "x: %d, y: %d", mousePos.x, mousePos.y);
//SetWindowText(hWnd, buf);
x1 = mousePos.x;
y1 = mousePos.y;
}//
End of if mousePos...etc
Draw_Gouraud_Triangle(pBits, w, h, pitch,
x0, y0, 0xff, 0x00, 0x00, // x,y
(point) - red, greed blue (colour)
x1, y1, 0x00, 0xff, 0x00,
x2, y2, 0x00, 0x00, 0xff );
}//
end of Render(..) |