summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-06-27 12:07:33 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-08-07 06:54:59 -0700
commit8d990b8929964fcf88a023128dc26f27a13f264c (patch)
treec4004a2de6d6d267e20d6162d7b603f025837961 /src/modules
parent206251e387038697c013e7efea3782d81fd910b8 (diff)
modules/drizzle: experimenting with the new snapshotting
This arguably doesn't require snapshotting to work, since it's doing a rudimentary in-place single pixel alpha-blended replacement using a single pixel at the same location. But the moment it startus using multiple adjacent super-samples, the snapshot becomes necessary. If it gets further complicated with displacements and maybe bump-mapping or something, then the samples can become quite distant from the pixel being written, spreading out into neighboring fragments being rendered simultaneously etc. These are all cause for snapshotting... For now though it's a very simple implementation that at least makes drizzle overlayable, while also providing a smoke test for the new snapshotting functionality.
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/drizzle/drizzle.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/modules/drizzle/drizzle.c b/src/modules/drizzle/drizzle.c
index fff59bd..57b2664 100644
--- a/src/modules/drizzle/drizzle.c
+++ b/src/modules/drizzle/drizzle.c
@@ -43,6 +43,7 @@ typedef struct drizzle_setup_t {
typedef struct drizzle_context_t {
til_module_context_t til_module_context;
+ til_fb_fragment_t *snapshot;
puddle_t *puddle;
drizzle_setup_t setup;
} drizzle_context_t;
@@ -127,6 +128,31 @@ static void drizzle_prepare_frame(til_module_context_t *context, unsigned ticks,
}
puddle_tick(ctxt->puddle, ctxt->setup.viscosity);
+
+ if ((*fragment_ptr)->cleared)
+ ctxt->snapshot = til_fb_fragment_snapshot(fragment_ptr, 0);
+}
+
+
+/* TODO: this probably should also go through a gamma correction */
+static inline uint32_t pixel_mult_scalar(uint32_t pixel, float t)
+{
+ float r, g, b;
+
+ if (t > 1.f)
+ t = 1.f;
+ if (t < 0.f)
+ t = 0.f;
+
+ r = (pixel >> 16) & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel & 0xff);
+
+ r *= t;
+ g *= t;
+ b *= t;
+
+ return ((uint32_t)r) << 16 | ((uint32_t)g) << 8 | ((uint32_t)b);
}
@@ -139,6 +165,26 @@ static void drizzle_render_fragment(til_module_context_t *context, unsigned tick
float yf = 1.f / (float)fragment->frame_height;
v2f_t coord;
+ if (ctxt->snapshot) {
+ coord.y = yf * (float)fragment->y;
+ for (int y = fragment->y; y < fragment->y + fragment->height; y++) {
+
+ coord.x = xf * (float)fragment->x;
+ for (int x = fragment->x; x < fragment->x + fragment->width; x++) {
+ float t = puddle_sample(ctxt->puddle, &coord);
+ uint32_t pixel = pixel_mult_scalar(til_fb_fragment_get_pixel_unchecked(ctxt->snapshot, x, y), t);
+
+ til_fb_fragment_put_pixel_unchecked(fragment, 0, x, y, pixel);
+
+ coord.x += xf;
+ }
+
+ coord.y += yf;
+ }
+
+ return;
+ }
+
coord.y = yf * (float)fragment->y;
for (int y = fragment->y; y < fragment->y + fragment->height; y++) {
@@ -160,6 +206,15 @@ static void drizzle_render_fragment(til_module_context_t *context, unsigned tick
}
+static void drizzle_finish_frame(til_module_context_t *context, unsigned int ticks, til_fb_fragment_t **fragment_ptr)
+{
+ drizzle_context_t *ctxt = (drizzle_context_t *)context;
+
+ if (ctxt->snapshot)
+ ctxt->snapshot = til_fb_fragment_reclaim(ctxt->snapshot);
+}
+
+
static int drizzle_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup)
{
const char *viscosity;
@@ -208,8 +263,10 @@ til_module_t drizzle_module = {
.destroy_context = drizzle_destroy_context,
.prepare_frame = drizzle_prepare_frame,
.render_fragment = drizzle_render_fragment,
+ .finish_frame = drizzle_finish_frame,
.name = "drizzle",
.description = "Classic 2D rain effect (threaded (poorly))",
.author = "Vito Caputo <vcaputo@pengaru.com>",
.setup = drizzle_setup,
+ .flags = TIL_MODULE_OVERLAYABLE,
};
© All Rights Reserved