line drawing
This commit is contained in:
parent
aaedea1dec
commit
6b54264d86
5 changed files with 72 additions and 4 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
||||||
main
|
main
|
||||||
*.o
|
*.o
|
||||||
|
*.ppm
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# libpaint
|
# libpaint
|
||||||
|
|
||||||
Software rasterizer
|
Software rasterizer
|
||||||
|
|
1
main.c
1
main.c
|
@ -5,6 +5,7 @@ int main() {
|
||||||
lp_painter *painter = lp_painter_create(512, 512);
|
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(255, 0, 0), 0, 0, 512, 512);
|
||||||
lp_painter_fill_rect(painter, lp_rgb(0, 0, 255), 0, 25, 103, 40);
|
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_save_ppm(painter, "./surface.ppm");
|
||||||
lp_painter_free(painter);
|
lp_painter_free(painter);
|
||||||
}
|
}
|
||||||
|
|
69
painter.c
69
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));
|
lp_pixel *buf = malloc(width * height * sizeof(lp_pixel));
|
||||||
|
|
||||||
painter->buf = buf;
|
painter->buf = buf;
|
||||||
|
painter->buf_length = width * height;
|
||||||
painter->width = width;
|
painter->width = width;
|
||||||
painter->height = height;
|
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) {
|
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 y = pos_y; y < pos_y + height; y++) {
|
||||||
for (size_t x = pos_x; x < pos_x + width; x++) {
|
for (size_t x = pos_x; x < pos_x + width; x++) {
|
||||||
size_t index = y * painter->width + x;
|
lp_painter_put_pixel(painter, fill_color, pos_x, pos_y);
|
||||||
painter->buf[index] = fill_color;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,13 @@ typedef struct lp_painter {
|
||||||
lp_pixel *buf;
|
lp_pixel *buf;
|
||||||
size_t width;
|
size_t width;
|
||||||
size_t height;
|
size_t height;
|
||||||
|
size_t buf_length;
|
||||||
} lp_painter;
|
} lp_painter;
|
||||||
|
|
||||||
lp_painter *lp_painter_create();
|
lp_painter *lp_painter_create();
|
||||||
void lp_painter_free(lp_painter *painter);
|
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_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_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
|
#endif
|
Loading…
Reference in a new issue