in truth, there's a lot of per-pixel color munging going on in these
triangle renderers. maybe too much? we're doing a lot of operations that
are constantly deconstructing argb32 colors and then reconstructing, and
then deconstructing+reconstructing again. and some of the time we were
doing this as floats, via the "normalized" conversion functions. this
seemed to be adding a bit of "color jitter" that could be visible
at run-time when triangles were being animated somehow (e.g. resized).
also, the whole "inverse area" thing, while probably a bit of a
micro-optimization at best, was causing its own little bit of visible
"color jitter" sometimes, probably due to an increased level of
floating-point inaccuracy when representing the area as a fraction
like that.
improve in the readability sense, not performance i don't think, since
this style of iterator looping is what the slice fill method does
anyway i'm pretty sure
i'm not *entirely* sold on this particular enum-based api, but i think
it could work. in the future i'd likely ALSO want something that could
work with triangle data as an offset from a larger buffer, but we can
solve that problem later when it comes up.
mainly i just didn't want to have a bunch of different triangle_2d
function variants exposed. same justification as with the blit enums,
basically.
the difference is important to note since most articles discussing
implementations of barycentric triangle rasterization show a test
for positive w0/w1/w2 to determine if you're inside the triangle or not.
they also usually use a slightly different formula in the `cross`
function if they assume counter-clockwise vertex winding.
since i'll admit i still don't *fully* grasp the math behind the edge
functions and that stuff that is used to calculate the a01/b01/a12/...
values, i wasn't sure how to adjust these for counter-clockwise winding
to keep a positive w0/w1/w2 check. so the simple solution is to use
the `cross` function as it is now, calculate a01/b01/a12/b12/a20/b20
as we are now, and do a negative w0/w1/w2 check and we get to keep
counter-clockwise vertex winding which i prefer. hooray!
to be honest, i'm not sure how this compiled successfully before, since
the value being passed in via Bitmap::triangle_2d_custom is clearly of
type `&mut PixelType` ... ? either way, this is now written consistently
and we get to remove an unnecessary unsafe block
i unfortunately feel like i should really force myself to use rustfmt
even though i very much dislike it. most rust developers seem to use it
so i should probably get used to it ...
however, case-in-point for me is the amount of times i used either
#[rustfmt::skip] or adding a blank `//` comment to force separate
lines, etc, really proves how terrible basing almost all of your
formatting rules on arbitrary length thresholds really is. code
formatting is far more subjective than that.