diff options
| -rw-r--r-- | AnimationRender/AnimationRender.c | 26 | ||||
| -rw-r--r-- | AnimationRender/AnimationRender.h | 9 | ||||
| -rw-r--r-- | AnimationRender/F_Draw.c | 21 | ||||
| -rw-r--r-- | AnimationRender/F_Draw.h | 17 | ||||
| -rw-r--r-- | AnimationRender/F_Interpolate.c | 33 | ||||
| -rw-r--r-- | AnimationRender/F_Interpolate.h | 20 | ||||
| -rw-r--r-- | AnimationRender/FrameCallback.h | 22 | ||||
| -rw-r--r-- | global.h | 4 | ||||
| -rw-r--r-- | graphics.c | 37 |
9 files changed, 176 insertions, 13 deletions
diff --git a/AnimationRender/AnimationRender.c b/AnimationRender/AnimationRender.c new file mode 100644 index 0000000..8974ba3 --- /dev/null +++ b/AnimationRender/AnimationRender.c @@ -0,0 +1,26 @@ +#include "AnimationRender.h" +#include "FrameCallback.h" + +void RenderAnimation(u32 width, u32 height, u32 totalFrames, const FrameCallback** callbacks, usize sizeCallbacks) { + RGBImage frameBuffer = RGBImage_new(width, height); + + struct FrameContext fc; + fc.startFrame = 0; + fc.endFrame = totalFrames; + fc.frameBuffer = frameBuffer; + + for (u32 f = 0; f < totalFrames; ++f) { + fc.frame = f; + for (usize i = 0; i < sizeCallbacks; ++i) { + // Soft context reset + if (callbacks[i] == NULL) { + fc.startFrame = 0; + fc.endFrame = totalFrames; + } + else + callbacks[i]->callback(callbacks[i]->callback_self, &fc); + } + } + + RGBImage_delete(&frameBuffer); +} diff --git a/AnimationRender/AnimationRender.h b/AnimationRender/AnimationRender.h new file mode 100644 index 0000000..19545ee --- /dev/null +++ b/AnimationRender/AnimationRender.h @@ -0,0 +1,9 @@ +#ifndef _ANIMATION_RENDER +#define _ANIMATION_RENDER + +#include "../global.h" +#include "FrameCallback.h" + +void RenderAnimation(u32 width, u32 height, u32 totalFrames, const FrameCallback** callbacks, usize sizeCallbacks); + +#endif /* _ANIMATION_RENDER */ diff --git a/AnimationRender/F_Draw.c b/AnimationRender/F_Draw.c new file mode 100644 index 0000000..fb90883 --- /dev/null +++ b/AnimationRender/F_Draw.c @@ -0,0 +1,21 @@ +#include "F_Draw.h" +#include "../FrameRender/FrameRender.h" +#include <stdlib.h> +#include <string.h> + +void Draw_callback(Draw* self, struct FrameContext* fc) { + if (self->startFrame <= fc->frame && fc->frame <= self->endFrame) { + RenderFrame(fc->frameBuffer, self->callbacks, self->sizeCallbacks); + ppm6_write(stdout, fc->frameBuffer); + } +} + +FrameCallback* Draw_setup(Draw obj) { + FrameCallback* fca = malloc(sizeof(struct FrameCallback)); + + fca->callback = (FrameCallback_callback)Draw_callback; + fca->callback_self = malloc(sizeof(obj)); + memcpy(fca->callback_self, &obj, sizeof(obj)); + + return fca; +} diff --git a/AnimationRender/F_Draw.h b/AnimationRender/F_Draw.h new file mode 100644 index 0000000..729cec9 --- /dev/null +++ b/AnimationRender/F_Draw.h @@ -0,0 +1,17 @@ +#ifndef F_DRAW +#define F_DRAW + +#include "../global.h" +#include "../FrameRender/PixelCallback.h" +#include "FrameCallback.h" + +typedef struct Draw { + u32 startFrame; + u32 endFrame; + const PixelCallback** callbacks; + usize sizeCallbacks; +} Draw; + +FrameCallback* Draw_setup(Draw obj); + +#endif /* F_DRAW */ diff --git a/AnimationRender/F_Interpolate.c b/AnimationRender/F_Interpolate.c new file mode 100644 index 0000000..cc72163 --- /dev/null +++ b/AnimationRender/F_Interpolate.c @@ -0,0 +1,33 @@ +#include "F_Interpolate.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void Interpolate_callback(Interpolate* self, struct FrameContext* fc) { + if (self->interpolate == NULL) { + fprintf(stderr, "Interpolation function cannot be NULL!\n"); + return; + } + + double p = (double)(fc->frame - fc->startFrame) / (fc->endFrame - fc->startFrame); + + if (0.0 <= p && p <= 1.0) + self->interpolate(self->value, self->startValue, self->endValue, p); +} + +FrameCallback* Interpolate_setup(Interpolate obj) { + FrameCallback* fca = malloc(sizeof(struct FrameCallback)); + + fca->callback = (FrameCallback_callback)Interpolate_callback; + fca->callback_self = malloc(sizeof(obj)); + memcpy(fca->callback_self, &obj, sizeof(obj)); + + return fca; +} + +#define NUM_INTERPOLATE(a, b, perc) ((a) * (1.0 - (perc)) + (b) * (perc)) + +void Interpolate_TransformCenter(TransformCenter* value, const TransformCenter* start, const TransformCenter* end, double progress) { + value->centerX = NUM_INTERPOLATE(start->centerX, end->centerX, progress); + value->centerY = NUM_INTERPOLATE(start->centerY, end->centerY, progress); +} diff --git a/AnimationRender/F_Interpolate.h b/AnimationRender/F_Interpolate.h new file mode 100644 index 0000000..502fbb4 --- /dev/null +++ b/AnimationRender/F_Interpolate.h @@ -0,0 +1,20 @@ +#ifndef F_INTERPOLATE +#define F_INTERPOLATE + +#include "FrameCallback.h" +#include "../FrameRender/P_TransformCenter.h" + +typedef void (*f_interpolate)(void* value, const void* start, const void* end, double progress); + +typedef struct Interpolate { + f_interpolate interpolate; + void* value; + const void* startValue; + const void* endValue; +} Interpolate; + +FrameCallback* Interpolate_setup(Interpolate obj); + +void Interpolate_TransformCenter(TransformCenter* value, const TransformCenter* start, const TransformCenter* end, double progress); + +#endif /* F_INTERPOLATE */ diff --git a/AnimationRender/FrameCallback.h b/AnimationRender/FrameCallback.h new file mode 100644 index 0000000..b3292bb --- /dev/null +++ b/AnimationRender/FrameCallback.h @@ -0,0 +1,22 @@ +#ifndef _FRAME_CALLBACK +#define _FRAME_CALLBACK + +#include "../global.h" +#include "../RGBImage.h" + +struct FrameContext { + u32 frame; + u32 startFrame; + u32 endFrame; + + RGBImage frameBuffer; +}; + +typedef void (*FrameCallback_callback)(void* self, struct FrameContext* fc); + +typedef struct FrameCallback { + FrameCallback_callback callback; + void* callback_self; +} FrameCallback; + +#endif /* _FRAME_CALLBACK */ @@ -3,10 +3,6 @@ #include <stdint.h> -typedef uint8_t bool; -#define false 0 -#define true 1 - typedef int32_t i32; typedef uint32_t u32; typedef uint32_t usize; @@ -2,6 +2,9 @@ * gcc -std=c99 *.c -lm && ./a.out | ffmpeg -r 30 -i - output.mp4 */ +#include "AnimationRender/AnimationRender.h" +#include "AnimationRender/F_Draw.h" +#include "AnimationRender/F_Interpolate.h" #include "FrameRender/FrameRender.h" #include "FrameRender/P_Checker.h" #include "FrameRender/P_Circle.h" @@ -9,13 +12,16 @@ #include "FrameRender/P_Square.h" #include "FrameRender/P_TransformCenter.h" #include "FrameRender/P_TransformRotate.h" +#include "FrameRender/PixelCallback.h" #include "RGBImage.h" -#include "math.h" #include <stdlib.h> +# define M_PI 3.14159265358979323846 /* pi */ + int main() { - RGBImage frame = RGBImage_new(512, 512); + u32 width = 512; + u32 height = 512; RGBImage bclc = ppm_read(fopen("bclc.ppm", "rb")); @@ -24,28 +30,28 @@ main() { .squareSize = 64, .colorA = 0xFF000000, .colorB = 0xFFFF00FF, }), TransformCenter_setup((TransformCenter){ - .centerX = frame.width / 2, .centerY = frame.height / 2, + .centerX = width / 2, .centerY = height / 2, }), Square_setup((Square){ .width = 100, .height = 100, .color = 0xFFFFFF00, }), NULL, TransformRotate_setup((TransformRotate){ - .angle = M_PI_4 / 2, + .angle = M_PI / 8, }), Square_setup((Square){ .width = 200, .height = 200, .color = 0xFF00FFFF, }), NULL, TransformCenter_setup((TransformCenter){ - .centerX = frame.width * 3/4, .centerY = frame.height / 2, + .centerX = width * 3/4, .centerY = height / 2, }), Circle_setup((Circle){ .radius = 50, .color = 0x80FFFFFF, }), NULL, TransformCenter_setup((TransformCenter){ - .centerX = frame.width / 8, .centerY = frame.height * 3/5, + .centerX = width / 8, .centerY = height * 3/5, }), Image_setup((Image){ .img = bclc, @@ -54,10 +60,23 @@ main() { }; u32 sizeCallbacks = sizeof(callbacks) / sizeof(*callbacks); - RenderFrame(frame, (const PixelCallback**)callbacks, sizeCallbacks); - ppm6_write(stdout, frame); + TransformCenter img1 = { .centerX = width / 8, .centerY = height * 3/5 }, + img2 = { .centerX = height * 3/5, .centerY = width / 8 }; + const FrameCallback* frameCallbacks[] = { + Interpolate_setup((Interpolate){ + .startValue = &img1, .endValue = &img2, + .value = callbacks[10]->callback_self, + .interpolate = (f_interpolate)Interpolate_TransformCenter, + }), + Draw_setup((Draw){ + .startFrame = 0, .endFrame = 150, + .callbacks = (const PixelCallback**)callbacks, .sizeCallbacks = sizeCallbacks, + }), + }; + u32 sizeFrameCallbacks = sizeof(frameCallbacks) / sizeof(*frameCallbacks); + + RenderAnimation(width, height, 150, frameCallbacks, sizeFrameCallbacks); - RGBImage_delete(&frame); RGBImage_delete(&bclc); for (u32 i = 0; i < sizeCallbacks; ++i) { if (callbacks[i] == NULL) continue; |
