Lately I have just been fiddling with some smaller graphics things in my free time. Although I have graphics quite a bit, I have never written anything to interpolate color such as OpenGL does, so I wanted to give it a shot.
So I modified my bresenham line algorithm so that it interpolates the color of a line. It does it well, and I get good results.
I then decided that I wanted to do the same with triangles. So I wrote a function that essentially uses a scan-line fill algorithm, although it is not as full blown - and thus will really only work for triangles and not any arbitrary polygon.
The results I am getting a little bit less than satisfactory, however. They are not bad, per se, but it is definitely a much different result than what comes out of OpenGL when I have OpenGL render a color-interpolated triangle.
Here is an image (mine on the left, OpenGL on the right):
Attachment 7795
As you can see it is not quite as clean (and the colors are not in the correct order either - although that is a minor problem that I know how to fix and is not my main concern).
So here is how I do the scanline algorithm:
Code:
A triangle is defined by 3 points A, B, and C.
Step 1: retrieve a list of all points that form the line segments AB, AC, and BC.
Step 2: put all points into a master list.
Step 3: Order all points by their y-coordinate value
Step 3.1: Create a multimap with the key being the y-coord, and the vals being the points
Step 4: Iterate through the multimap
Step 4.1: For each y-coordinate in the multimap, look at the points associated with it.
Step 4.1.1: Draw an interpolated line from the point with the min x-coord to the point with the max x-coord for that specific y-coord
So that is my general algorithm. The logic seems good to me, but there must be some flaw somewhere. Here is my code. It is fairly short:
Code:
void triangle ( float *surface, point a, point b, point c, color sColor, color fColor, color gColor )
{
//Get the 3 edges of the triangle
vector <point> listA = linepoints ( a, b, sColor, fColor );
vector <point> listB = linepoints ( a, c, sColor, gColor );
vector <point> listC = linepoints ( b, c, fColor, gColor );
vector <point> master;
for ( int x = 0; x < listA.size(); x++ ) master.push_back ( listA[x] );
for ( int x = 0; x < listB.size(); x++ ) master.push_back ( listB[x] );
for ( int x = 0; x < listC.size(); x++ ) master.push_back ( listC[x] );
multimap <int, point> coordMap;
for ( int x = 0; x < master.size(); x++ )
coordMap.insert ( pair<int, point> ( master[x].y, master[x] ) );
multimap<int, point>::iterator myIter = coordMap.begin();
point min, max;
int curY;
curY = myIter->first;
min = myIter->second;
max = myIter->second;
while ( myIter != coordMap.end() )
{
if ( myIter->first != curY )
{
line ( surface, min, max, min.pColor, max.pColor );
curY = myIter->first;
min = myIter->second;
max = myIter->second;
}
else
{
if ( myIter->second.x < min.x )
min = myIter->second;
if ( myIter->second.x > max.x )
max = myIter->second;
}
myIter++;
}
}
Thanks for any help resolving this