This is the most popular method of rendering triangles in the world of 3D....99% of all triangle rendering is done using Gouraud shading, so I think we should have a looksy....and believe me it looks cool :)
Gouraud Solid Triangle.
So how does it work? Well its very similar to how you would render a sold triangle using interpolation of the coordinates....but as well as interpolating the x and y....we also interpolate the red, green and blue. Now looking at the code is only going to scare you unless you understand the basics of how to interpolate from one point to the next, so if you've not gone over the previous tutorial on rendering a solid triangle I would recomend doing it first...the code is more or less identical...but this one has loads of colour interpolation stuff added in.
Test out the demo program, it should work without any problems - as you move the cursor around your triangle will resize. Again error checking has been cut down to almost nothing... but it seems okay and has no serious problems. Hopefully the underlying principles of how it works can be seen in this code.
Code Sample
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
/* // 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
It looks like a lot, and it is... the best thing to do, is to break it up! Don't let that code intimidate you....as I had to do, I printed it out and spent a while with a pencil doodling some thinking and testing it out on the pc. But once you understand how it works....the only other thing worth doing is? is? what is it? Well its optimisation.... all of those float to int conversions taking place might need a bit of fixing.... which is what we'll do next.
Things to Try
• Using Fixed Point Math For Optimisation
Visitor:
Copyright (c) 2002-2025 xbdev.net - All rights reserved.
Designated articles, tutorials and software are the property of their respective owners.