From 6a63e2c0e1f37c502501e1b611e8dc289476c1f2 Mon Sep 17 00:00:00 2001 From: Syndamia Date: Sat, 28 Mar 2026 21:13:27 +0200 Subject: feat: Add Checker, Image, Circle; properly handle transparency --- FrameRender/P_Checker.c | 26 ++++++++++++++++++++++++++ FrameRender/P_Checker.h | 14 ++++++++++++++ FrameRender/P_Circle.c | 20 ++++++++++++++++++++ FrameRender/P_Circle.h | 13 +++++++++++++ FrameRender/P_Image.c | 22 ++++++++++++++++++++++ FrameRender/P_Image.h | 13 +++++++++++++ FrameRender/P_Square.c | 2 +- FrameRender/P_TransformRotate.c | 23 +++++++++++++++++++++++ FrameRender/P_TransformRotate.h | 13 +++++++++++++ RGBImage.c | 9 ++++++++- RGBImage.h | 4 ++-- graphics.c | 33 +++++++++++++++++++++++++++++++-- 12 files changed, 186 insertions(+), 6 deletions(-) create mode 100644 FrameRender/P_Checker.c create mode 100644 FrameRender/P_Checker.h create mode 100644 FrameRender/P_Circle.c create mode 100644 FrameRender/P_Circle.h create mode 100644 FrameRender/P_Image.c create mode 100644 FrameRender/P_Image.h create mode 100644 FrameRender/P_TransformRotate.c create mode 100644 FrameRender/P_TransformRotate.h diff --git a/FrameRender/P_Checker.c b/FrameRender/P_Checker.c new file mode 100644 index 0000000..74862f0 --- /dev/null +++ b/FrameRender/P_Checker.c @@ -0,0 +1,26 @@ +#include "P_Checker.h" +#include "PixelCallback.h" +#include +#include + +void Checker_callback(Checker* self, struct PixelContext* fc) { + u32 x = fc->x / self->squareSize; + u32 y = fc->y / self->squareSize; + + if ((x + y) % 2 == 0) { + ARGB_merge(&fc->pixel, self->colorA); + } + else { + ARGB_merge(&fc->pixel, self->colorB); + } +} + +PixelCallback* Checker_setup(Checker obj) { + PixelCallback* pca = malloc(sizeof(struct PixelCallback)); + + pca->callback = (PixelCallback_callback)Checker_callback; + pca->callback_self = malloc(sizeof(obj)); + memcpy(pca->callback_self, &obj, sizeof(obj)); + + return pca; +} diff --git a/FrameRender/P_Checker.h b/FrameRender/P_Checker.h new file mode 100644 index 0000000..731e55a --- /dev/null +++ b/FrameRender/P_Checker.h @@ -0,0 +1,14 @@ +#ifndef P_CHECKER_PATTERN +#define P_CHECKER_PATTERN + +#include "PixelCallback.h" + +typedef struct Checker { + u32 squareSize; + color colorA; + color colorB; +} Checker; + +PixelCallback* Checker_setup(Checker obj); + +#endif /* P_CHECKER_PATTERN */ diff --git a/FrameRender/P_Circle.c b/FrameRender/P_Circle.c new file mode 100644 index 0000000..421904d --- /dev/null +++ b/FrameRender/P_Circle.c @@ -0,0 +1,20 @@ +#include "P_Circle.h" +#include "PixelCallback.h" +#include +#include + +void Circle_callback(Circle* self, struct PixelContext* fc) { + if (fc->x * fc->x + fc->y *fc->y <= self->radius * self->radius) { + ARGB_merge(&fc->pixel, self->color); + } +} + +PixelCallback* Circle_setup(Circle obj) { + PixelCallback* pca = malloc(sizeof(struct PixelCallback)); + + pca->callback = (PixelCallback_callback)Circle_callback; + pca->callback_self = malloc(sizeof(obj)); + memcpy(pca->callback_self, &obj, sizeof(obj)); + + return pca; +} diff --git a/FrameRender/P_Circle.h b/FrameRender/P_Circle.h new file mode 100644 index 0000000..1a6af4a --- /dev/null +++ b/FrameRender/P_Circle.h @@ -0,0 +1,13 @@ +#ifndef P_CIRCLE +#define P_CIRCLE + +#include "PixelCallback.h" + +typedef struct Circle { + u32 radius; + color color; +} Circle; + +PixelCallback* Circle_setup(Circle obj); + +#endif /* P_CIRCLE */ diff --git a/FrameRender/P_Image.c b/FrameRender/P_Image.c new file mode 100644 index 0000000..b95bbd7 --- /dev/null +++ b/FrameRender/P_Image.c @@ -0,0 +1,22 @@ +#include "P_Image.h" +#include "PixelCallback.h" +#include +#include + +void Image_callback(Image* self, struct PixelContext* fc) { + if (0 <= fc->x && fc->x < self->img.width * self->scale && + 0 <= fc->y && fc->y < self->img.height * self->scale) + { + ARGB_mergeARGB(&fc->pixel, *RGBImage_at(self->img, fc->y / self->scale, fc->x / self->scale)); + } +} + +PixelCallback* Image_setup(Image obj) { + PixelCallback* pca = malloc(sizeof(struct PixelCallback)); + + pca->callback = (PixelCallback_callback)Image_callback; + pca->callback_self = malloc(sizeof(obj)); + memcpy(pca->callback_self, &obj, sizeof(obj)); + + return pca; +} diff --git a/FrameRender/P_Image.h b/FrameRender/P_Image.h new file mode 100644 index 0000000..609a7cf --- /dev/null +++ b/FrameRender/P_Image.h @@ -0,0 +1,13 @@ +#ifndef P_IMAGE +#define P_IMAGE + +#include "PixelCallback.h" + +typedef struct Image { + RGBImage img; + double scale; +} Image; + +PixelCallback* Image_setup(Image obj); + +#endif /* P_IMAGE */ diff --git a/FrameRender/P_Square.c b/FrameRender/P_Square.c index 7865370..f5dbef7 100644 --- a/FrameRender/P_Square.c +++ b/FrameRender/P_Square.c @@ -7,7 +7,7 @@ void Square_callback(Square* self, struct PixelContext* fc) { if (0 <= fc->x && fc->x <= self->width && 0 <= fc->y && fc->y <= self->height) { - ARGB_set(&fc->pixel, self->color); + ARGB_merge(&fc->pixel, self->color); } } diff --git a/FrameRender/P_TransformRotate.c b/FrameRender/P_TransformRotate.c new file mode 100644 index 0000000..562c814 --- /dev/null +++ b/FrameRender/P_TransformRotate.c @@ -0,0 +1,23 @@ +#include "P_TransformRotate.h" +#include "PixelCallback.h" +#include +#include +#include + +void TransformRotate_callback(TransformRotate* self, struct PixelContext* pc) { + u32 xR = pc->x * cos(self->angle) + pc->y * sin(self->angle); + u32 yR = - pc->x * sin(self->angle) + pc->y * cos(self->angle); + + pc->x = xR; + pc->y = yR; +} + +PixelCallback* TransformRotate_setup(TransformRotate obj) { + PixelCallback* pca = malloc(sizeof(struct PixelCallback)); + + pca->callback = (PixelCallback_callback)TransformRotate_callback; + pca->callback_self = malloc(sizeof(obj)); + memcpy(pca->callback_self, &obj, sizeof(obj)); + + return pca; +} diff --git a/FrameRender/P_TransformRotate.h b/FrameRender/P_TransformRotate.h new file mode 100644 index 0000000..0a2cc88 --- /dev/null +++ b/FrameRender/P_TransformRotate.h @@ -0,0 +1,13 @@ +#ifndef P_TRANSFORMROTATE +#define P_TRANSFORMROTATE + +#include "PixelCallback.h" +#include "../global.h" + +typedef struct TransformRotate { + double angle; +} TransformRotate; + +PixelCallback* TransformRotate_setup(TransformRotate obj); + +#endif /* P_TRANSFORMROTATE */ diff --git a/RGBImage.c b/RGBImage.c index 8f6c8d2..2896d72 100644 --- a/RGBImage.c +++ b/RGBImage.c @@ -12,7 +12,14 @@ ARGB_set(ARGB* rgb, color color) { } void -ARGB_merge(ARGB* bottom, ARGB top) { +ARGB_merge(ARGB* bottom, color top) { + ARGB temp; + ARGB_set(&temp, top); + ARGB_mergeARGB(bottom, temp); +} + +void +ARGB_mergeARGB(ARGB* bottom, ARGB top) { bottom->a = 255; double perc = top.a / 255.0; diff --git a/RGBImage.h b/RGBImage.h index b54b72b..d3e5642 100644 --- a/RGBImage.h +++ b/RGBImage.h @@ -14,8 +14,8 @@ typedef struct ARGB { byte b; } ARGB; -void ARGB_set(ARGB* rgb, color color); -void ARGB_merge(ARGB* bottom, ARGB top); +void ARGB_merge(ARGB* bottom, color top); +void ARGB_mergeARGB(ARGB* bottom, ARGB top); typedef struct RGBImage { u32 width; diff --git a/graphics.c b/graphics.c index 6281f6f..d5f16e4 100644 --- a/graphics.c +++ b/graphics.c @@ -3,26 +3,54 @@ */ #include "FrameRender/FrameRender.h" +#include "FrameRender/P_Checker.h" +#include "FrameRender/P_Circle.h" +#include "FrameRender/P_Image.h" #include "FrameRender/P_Square.h" #include "FrameRender/P_TransformCenter.h" +#include "FrameRender/P_TransformRotate.h" #include "RGBImage.h" +#include "math.h" #include int main() { RGBImage frame = RGBImage_new(512, 512); + RGBImage bclc = ppm_read(fopen("bclc.ppm", "rb")); + PixelCallback* callbacks[] = { + Checker_setup((Checker){ + .squareSize = 64, .colorA = 0xFF000000, .colorB = 0xFFFF00FF, + }), TransformCenter_setup((TransformCenter){ - .centerX = frame.width / 2, .centerY = frame.width / 2, + .centerX = frame.width / 2, .centerY = frame.height / 2, }), Square_setup((Square){ - .width = 100, .height = 100, .color = 0xFFFF0000, + .width = 100, .height = 100, .color = 0xFFFFFF00, }), NULL, + TransformRotate_setup((TransformRotate){ + .angle = M_PI_4 / 2, + }), Square_setup((Square){ .width = 200, .height = 200, .color = 0xFF00FFFF, }), + NULL, + TransformCenter_setup((TransformCenter){ + .centerX = frame.width * 3/4, .centerY = frame.height / 2, + }), + Circle_setup((Circle){ + .radius = 50, .color = 0x80FFFFFF, + }), + NULL, + TransformCenter_setup((TransformCenter){ + .centerX = frame.width / 8, .centerY = frame.height * 3/5, + }), + Image_setup((Image){ + .img = bclc, + .scale = 0.2, + }), }; u32 sizeCallbacks = sizeof(callbacks) / sizeof(*callbacks); @@ -30,6 +58,7 @@ main() { ppm6_write(stdout, frame); RGBImage_delete(&frame); + RGBImage_delete(&bclc); for (u32 i = 0; i < sizeCallbacks; ++i) { if (callbacks[i] == NULL) continue; free(callbacks[i]->callback_self); -- cgit v1.2.3