Created
May 20, 2019 12:15
-
-
Save aolo2/1e2fffec52f677c5ea420ca982f20e3b to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| static s32 | |
| orient_2d(s32 ax, s32 ay, s32 bx, s32 by, s32 x, s32 y) | |
| { | |
| return(bx - ax) * (y - ay) - (by - ay) * (x - ax); | |
| } | |
| static void | |
| fill_triangle(struct framebuffer *fb, | |
| s32 v0x, s32 v0y, s32 v1x, s32 v1y, s32 v2x, s32 v2y) | |
| { | |
| // NOTE: ensure CCW orientation | |
| s32 sarea = (v0x * v1y - v1x * v0y | |
| + v1x * v2y - v2x * v1y | |
| + v2x * v0y - v0x * v2y); | |
| if (sarea < 0) { | |
| SWAP(v2x, v1x); | |
| SWAP(v2y, v1y); | |
| } | |
| // NOTE: compute the AABB | |
| s32 min_x = MIN(v0x, MIN(v1x, v2x)); | |
| s32 min_y = MIN(v0y, MIN(v1y, v2y)); | |
| s32 max_x = MAX(v0x, MAX(v1x, v2x)); | |
| s32 max_y = MAX(v0y, MAX(v1y, v2y)); | |
| // NOTE: clip against screen bounds | |
| min_x = MAX(min_x, 0); | |
| min_y = MAX(min_y, 0); | |
| max_x = MIN(max_x, fb->width - 1); | |
| max_y = MIN(max_y, fb->height - 1); | |
| u32 *base; | |
| for (s32 y = min_y; y <= max_y; ++y) { | |
| base = (u32 *) fb->pixels + y * fb->width + min_x; | |
| for (s32 x = min_x; x <= max_x; ++x) { | |
| s32 w0 = orient_2d(v1x, v1y, v2x, v2y, x, y); | |
| s32 w1 = orient_2d(v2x, v2y, v0x, v0y, x, y); | |
| s32 w2 = orient_2d(v0x, v0y, v1x, v1y, x, y); | |
| if (w0 >= 0 && w1 >= 0 && w2 >= 0) { | |
| *base = 0xFFFFFFFF; | |
| } | |
| ++base; | |
| } | |
| } | |
| } | |
| static void | |
| bresenham_plot_high(struct framebuffer *fb, | |
| s32 x0, s32 y0, s32 x1, s32 y1) | |
| { | |
| u32 *base = (u32 *) fb->pixels + y0 * fb->width + x0; | |
| s32 dx = x1 - x0; | |
| s32 dy = y1 - y0; | |
| s32 xi = 1; | |
| if (dx < 0) { | |
| xi = -1; | |
| dx = -dx; | |
| } | |
| s32 D = 2 * dx - dy; | |
| s32 x = x0; | |
| for (s32 y = y0; y <= y1; ++y) { | |
| *base = 0xFFFFFFFF; | |
| if (D > 0) { | |
| x += xi; | |
| base += xi; | |
| D -= 2 * dy; | |
| } | |
| D += 2 * dx; | |
| base += fb->width; | |
| } | |
| } | |
| static void | |
| bresenham_plot_low(struct framebuffer *fb, | |
| s32 x0, s32 y0, s32 x1, s32 y1) | |
| { | |
| u32 *base = (u32 *) fb->pixels + y0 * fb->width + x0; | |
| s32 dx = x1 - x0; | |
| s32 dy = y1 - y0; | |
| s32 yi = 1; | |
| if (dy < 0) { | |
| yi = -1; | |
| dy = -dy; | |
| } | |
| s32 D = 2 * dy - dx; | |
| s32 y = y0; | |
| for (s32 x = x0; x <= x1; ++x) { | |
| *base = 0xFFFFFFFF; | |
| if (D > 0) { | |
| y += yi; | |
| base += fb->width * yi; | |
| D -= 2 * dx; | |
| } | |
| D += 2 * dy; | |
| ++base; | |
| } | |
| } | |
| static void | |
| bresenham_line(struct framebuffer *fb, | |
| s32 x0, s32 y0, s32 x1, s32 y1) | |
| { | |
| if (abs(y1 - y0) < abs(x1 - x0)) { | |
| if (x0 > x1) { | |
| bresenham_plot_low(fb, x1, y1, x0, y0); | |
| } else { | |
| bresenham_plot_low(fb, x0, y0, x1, y1); | |
| } | |
| } else { | |
| if (y0 > y1) { | |
| bresenham_plot_high(fb, x1, y1, x0, y0); | |
| } else { | |
| bresenham_plot_high(fb, x0, y0, x1, y1); | |
| } | |
| } | |
| } | |
| static void | |
| bresenham_circle_symmetric_draw(struct framebuffer *fb, | |
| s32 cx, s32 cy, s32 x, s32 y) | |
| { | |
| u32 *base = fb->pixels; | |
| base[(cy + y) * fb->width + cx + x] = 0xFFFFFFFF; | |
| base[(cy + y) * fb->width + cx - x] = 0xFFFFFFFF; | |
| base[(cy - y) * fb->width + cx + x] = 0xFFFFFFFF; | |
| base[(cy - y) * fb->width + cx - x] = 0xFFFFFFFF; | |
| base[(cy + x) * fb->width + cx + y] = 0xFFFFFFFF; | |
| base[(cy + x) * fb->width + cx - y] = 0xFFFFFFFF; | |
| base[(cy - x) * fb->width + cx + y] = 0xFFFFFFFF; | |
| base[(cy - x) * fb->width + cx - y] = 0xFFFFFFFF; | |
| } | |
| static void | |
| bresenham_circle(struct framebuffer *fb, | |
| s32 cx, s32 cy, s32 r) | |
| { | |
| s32 x = 0; | |
| s32 y = r; | |
| s32 D = 3 - 2 * r; | |
| bresenham_circle_symmetric_draw(fb, cx, cy, x, y); | |
| while (y >= x) { | |
| ++x; | |
| if (D > 0) { | |
| --y; | |
| D += ((x - y) << 2) + 10; | |
| } else { | |
| D += (x << 2) + 6; | |
| } | |
| bresenham_circle_symmetric_draw(fb, cx, cy, x, y); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment