From 6b54264d86a22d7e48e1696558a2a5bf46c84a65 Mon Sep 17 00:00:00 2001 From: hippoz <10706925-hippoz@users.noreply.gitlab.com> Date: Tue, 16 Aug 2022 20:42:14 +0300 Subject: [PATCH] line drawing --- .gitignore | 1 + README.md | 2 +- main.c | 1 + painter.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- painter.h | 3 ++- 5 files changed, 72 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 87e54c2..338fe5d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ main *.o +*.ppm diff --git a/README.md b/README.md index e6563ff..9c51e51 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ # libpaint -Software rasterizer \ No newline at end of file +Software rasterizer diff --git a/main.c b/main.c index 3af67ff..6ec86d2 100644 --- a/main.c +++ b/main.c @@ -5,6 +5,7 @@ int main() { lp_painter *painter = lp_painter_create(512, 512); lp_painter_fill_rect(painter, lp_rgb(255, 0, 0), 0, 0, 512, 512); lp_painter_fill_rect(painter, lp_rgb(0, 0, 255), 0, 25, 103, 40); + lp_painter_line(painter, lp_rgb(0, 255, 0), 0, 511, 511, 0); lp_painter_save_ppm(painter, "./surface.ppm"); lp_painter_free(painter); } diff --git a/painter.c b/painter.c index 870a0d1..fbc8d09 100644 --- a/painter.c +++ b/painter.c @@ -11,6 +11,7 @@ lp_painter *lp_painter_create(size_t width, size_t height) { lp_pixel *buf = malloc(width * height * sizeof(lp_pixel)); painter->buf = buf; + painter->buf_length = width * height; painter->width = width; painter->height = height; @@ -26,11 +27,75 @@ void lp_painter_free(lp_painter *painter) { } } +static inline void lp_painter_put_pixel(lp_painter *painter, lp_pixel color, size_t x, size_t y) { + size_t index = y * painter->width + x; + painter->buf[index] = color; +} + void lp_painter_fill_rect(lp_painter *painter, lp_pixel fill_color, size_t pos_x, size_t pos_y, size_t width, size_t height) { for (size_t y = pos_y; y < pos_y + height; y++) { for (size_t x = pos_x; x < pos_x + width; x++) { - size_t index = y * painter->width + x; - painter->buf[index] = fill_color; + lp_painter_put_pixel(painter, fill_color, pos_x, pos_y); + } + } +} + +void _lp_painter_line_low(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { + int32_t dx = x1 - x0; + int32_t dy = y1 - y0; + int32_t y_inc = 1; + if (dy < 0) { + y_inc = -1; + dy = -dy; + } + int32_t d = dy * 2 - dx; + int32_t y = y0; + + for (int32_t x = x0; x < x1; x++) { + lp_painter_put_pixel(p, color, x, y); + if (d > 0) { + y += y_inc; + d += 2 * (dy - dx); + } else { + d += 2 * dy; + } + } +} + + +void _lp_painter_line_high(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { + int32_t dx = x1 - x0; + int32_t dy = y1 - y0; + int32_t x_inc = 1; + if (dx < 0) { + x_inc = -1; + dx = -dx; + } + int32_t d = dx * 2 - dy; + int32_t x = x0; + + for (int32_t y = y0; y < y1; y++) { + lp_painter_put_pixel(p, color, x, y); + if (d > 0) { + x += x_inc; + d += 2 * (dx - dy); + } else { + d += 2 * dx; + } + } +} +void lp_painter_line(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1) { + if (abs(y1 - y0) < abs(x1 -x0)) { + if (x0 > x1) { + _lp_painter_line_low(p, color, x1, y1, x0, y0); + } else { + _lp_painter_line_low(p, color, x0, y0, x1, y1); + } + } else { + if (y0 > y1) { + _lp_painter_line_high(p, color, x1, y1, x0, y0); + } else { + _lp_painter_line_high(p, color, x0, y0, x1, y1); } } } diff --git a/painter.h b/painter.h index bfb3651..9d89e70 100644 --- a/painter.h +++ b/painter.h @@ -16,12 +16,13 @@ typedef struct lp_painter { lp_pixel *buf; size_t width; size_t height; + size_t buf_length; } lp_painter; lp_painter *lp_painter_create(); void lp_painter_free(lp_painter *painter); void lp_painter_fill_rect(lp_painter *painter, lp_pixel fill_color, size_t pos_x, size_t pos_y, size_t width, size_t height); void lp_painter_save_ppm(lp_painter *painter, const char *filename); - +void lp_painter_line(lp_painter *p, lp_pixel color, int32_t x0, int32_t y0, int32_t x1, int32_t y1); #endif \ No newline at end of file