gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Fast Polygon drawing

#7910 - Lupin - Sat Jun 28, 2003 10:26 am

How is it done? What's the fastest methode? Maybe there's an bresenham implementation for this?

#7911 - Torlus - Sat Jun 28, 2003 10:39 am

Do you mean filled polygons, or only edges drawing ?

If you're looking for an efficient flat-filled traingle drawer have a look at Dobby's one on his site : http://www.bits.bris.ac.uk/dooby/gba/.
His "gbalib" features such a drawer written in ARM assembly with nice optimisations.
_________________
GBA,GC,NGPC,GP32,FPGA,DS stuff at http://torlus.com/

#7926 - Lupin - Sat Jun 28, 2003 7:21 pm

thx, I'm going to take a look

#7955 - Lupin - Sun Jun 29, 2003 12:50 pm

Do you perhaps know some C++ code to draw triangles? I don't understand the asm code in this lib and it seems very complex.

#7966 - DekuTree64 - Sun Jun 29, 2003 4:31 pm

Well, the C tri-filler I made recently is on my other computer, but the basic algorithm is to sort the vertices according to y value (closest to top of screen, middle, closest to bottom) calculate the slope of each edge (x/y, since we're going one full y pixel at a time, unlike normal math, where the slope is the change in y per x unit (y/x)), then you add 1 to y, increment your starting/ending x values (basically draw 2 bresenham-lines, one on each side), and either fill from xStart to xEnd with your color, or save your xStart/xEnd pairs in a buffer (2 8-bit vals per y-line would work, since the screen is less than 255 px wide) to fill between later. Keep doing that until y is equal to the y of the middle vertex, recalculate the slope of the line from v2 to v3 (the slope of the long edge will be the same as before, so don't bother with it), and repeat until y == v3.y.
Here, I'll try to draw a picture...
Code:

               /\ <-top vertex
              /   \
middle-> \     \
                 \    \  <-this line's slope is the same for the top/bottom halves
you have to   \   \
 recalc this one \  \
 when you hit      \ \
 middle                  \<-bottom

And be sure to sheck if the long edge is on the left or right, when setting your xStart/xEnd/slopeStart/slopeEnd.
http://freespace.virgin.net/hugo.elias/graphics/x_main.htm has some grat tutorials on all sorts of graphics stuff, including polygons. He uses the edge buffer style, where you save the xs/xe pairs to draw later.
I use the draw-while-you-trace style, cause I think it's a little faster, and it works well with a C-buffer (where you keep track of xs/xe pairs that have already been drawn between, so you kind of draw 'underneath' everything on the screen). Edge buffer style's equivalent to that is an S-buffer, than does basically the same thing, but keeping track of spans to draw later. Don't worry about those until later though, just getting a simple tri-filler working is hard enough.
But as soon as you do, and start getting little cracks between your polys, read the thing about a 'perfect' scan converter at that site, and you'll be enlightened^^

#7968 - funkeejeffou - Sun Jun 29, 2003 5:05 pm

You must also considerate some other cases :
- if two vertex have the min y value
- if two vertex have the max y value
check in those cases if the x coordinate of the two concerned vertex are equal, if so then don't draw it cause it is degenerate.
In the case where the 3 y are different, check if the middle point lies on the long segment defined by the max and min point. If so do not draw it cause it's degenrate.
Otherwise, as Dekuthree said, check the location of the long segment (left or right of the screen) and interpolate.

There are many optimisations concerning the poly fillers (depending mostly how you wanna fill your poly : flat, gouraud or texture), check the articles on www.gamedev.net, some are really good.