Created
August 22, 2014 13:26
-
-
Save dwilliamson/cd1e1d531d7172a2ccca to your computer and use it in GitHub Desktop.
Dumb but accurate triangle rasteriser with top-left fill
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void RasteriseTriangle3(char* buffer, int width, int height, float2 v0, float2 v1, float2 v2) | |
{ | |
// Sort vertices along the y-axis, lowest first | |
if (v1.y < v0.y) | |
std::swap(v0, v1); | |
if (v2.y < v1.y) | |
std::swap(v1, v2); | |
if (v1.y < v0.y) | |
std::swap(v0, v1); | |
// Setup top half gradients | |
float dxdy1 = (v1.x - v0.x) / (v1.y - v0.y); | |
float dxdy2 = (v2.x - v0.x) / (v2.y - v0.y); | |
// Round-up the start/end y for top-left fill convention | |
int y = (int)ceil(v0.y); | |
int nb_y_steps = (int)ceil(v1.y) - y; | |
buffer += (int)y * width; | |
// Start x with a pre-step based on how much rounding was performed for fill convention | |
float x1 = v0.x + dxdy1 * (y - v0.y); | |
float x2 = v0.x + dxdy2 * (y - v0.y); | |
// Draw the two halves of the triangle | |
for (int i = 0; i < 2; i++) | |
{ | |
for (int y_step = 0; y_step < nb_y_steps; y_step++) | |
{ | |
// Determine which edge is left/right | |
float l = x1, r = x2; | |
if (r < l) | |
std::swap(l, r); | |
// Round-up the start/end x for top-left fill convention | |
int left = (int)ceil(l); | |
int right = (int)ceil(r); | |
memset(buffer + left, 255, right - left); | |
// Increment for next line | |
buffer += width; | |
x1 += dxdy1; | |
x2 += dxdy2; | |
} | |
// Setup gradient, y-steps and x with pre-step for the final edge | |
dxdy1 = (v2.x - v1.x) / (v2.y - v1.y); | |
y = (int)ceil(v1.y); | |
nb_y_steps = (int)ceil(v2.y) - y; | |
x1 = v1.x + dxdy1 * (y - v1.y); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment