From 01ab4fea185b451ed2d281a21ae62ba8c85e5237 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Mon, 18 Nov 2019 01:55:16 -0800 Subject: swab: add a perlin noise visualization This maps a different Z-slice through the noise field to each color channel. The slices are moved up and down through the field over time, and the size of the area each color samples is tweaked a bit to make them less coherent with the noise field cells. It could be improved, but I think the output is already neat enough to be worth sharing. --- src/modules/Makefile.am | 2 +- src/modules/swab/Makefile.am | 3 + src/modules/swab/swab.c | 147 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 src/modules/swab/Makefile.am create mode 100644 src/modules/swab/swab.c (limited to 'src/modules') diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index fa913a0..0ab81b7 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -1 +1 @@ -SUBDIRS = flui2d julia pixbounce plasma ray roto rtv snow sparkler stars submit +SUBDIRS = flui2d julia pixbounce plasma ray roto rtv snow sparkler stars submit swab diff --git a/src/modules/swab/Makefile.am b/src/modules/swab/Makefile.am new file mode 100644 index 0000000..4db914b --- /dev/null +++ b/src/modules/swab/Makefile.am @@ -0,0 +1,3 @@ +noinst_LIBRARIES = libswab.a +libswab_a_SOURCES = swab.c +libswab_a_CPPFLAGS = -I@top_srcdir@/src -I@top_srcdir@/src/libs diff --git a/src/modules/swab/swab.c b/src/modules/swab/swab.c new file mode 100644 index 0000000..6528900 --- /dev/null +++ b/src/modules/swab/swab.c @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2019 - Vito Caputo - + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#include "din/din.h" + +#include "fb.h" +#include "rototiller.h" +#include "util.h" + + +typedef struct swab_context_t { + din_t *din; + float r; + unsigned n_cpus; +} swab_context_t; + +typedef struct color_t { + float r,g,b; +} color_t; + + +/* convert a color into a packed, 32-bit rgb pixel value (taken from libs/ray/ray_color.h) */ +static inline uint32_t color_to_uint32(color_t color) { + uint32_t pixel; + + if (color.r > 1.0f) color.r = 1.0f; + if (color.g > 1.0f) color.g = 1.0f; + if (color.b > 1.0f) color.b = 1.0f; + + if (color.r < .0f) color.r = .0f; + if (color.g < .0f) color.g = .0f; + if (color.b < .0f) color.b = .0f; + + pixel = (uint32_t)(color.r * 255.0f); + pixel <<= 8; + pixel |= (uint32_t)(color.g * 255.0f); + pixel <<= 8; + pixel |= (uint32_t)(color.b * 255.0f); + + return pixel; +} + + +static void * swab_create_context(void) +{ + swab_context_t *ctxt; + + ctxt = calloc(1, sizeof(swab_context_t)); + if (!ctxt) + return NULL; + + ctxt->din = din_new(12, 12, 100); + if (!ctxt->din) { + free(ctxt); + return NULL; + } + + return ctxt; +} + + +static void swab_destroy_context(void *context) +{ + swab_context_t *ctxt = context; + + din_free(ctxt->din); + free(ctxt); +} + + +static int swab_fragmenter(void *context, const fb_fragment_t *fragment, unsigned num, fb_fragment_t *res_fragment) +{ + swab_context_t *ctxt = context; + + return fb_fragment_slice_single(fragment, ctxt->n_cpus, num, res_fragment); +} + + +static void swab_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter) +{ + swab_context_t *ctxt = context; + + *res_fragmenter = swab_fragmenter; + + ctxt->r += .0001f; + ctxt->n_cpus = n_cpus; +} + + +static void swab_render_fragment(void *context, fb_fragment_t *fragment) +{ + swab_context_t *ctxt = context; + float cos_r = cos(ctxt->r); + float sin_r = sin(ctxt->r); + float z1 = cos_r; + float z2 = sin_r; + float xscale = 1.f / (float)fragment->frame_width; + float yscale = 1.f / (float)fragment->frame_height; + + for (int y = fragment->y; y < fragment->y + fragment->height; y++) { + for (int x = fragment->x; x < fragment->x + fragment->width; x++) { + color_t color; + uint32_t pixel; + float t; + + t = din(ctxt->din, (v3f_t){ .x = (float)x * xscale * .5f, .y = (float)y * yscale * .5f, .z = -z2 }) * 33.f; + + color.r = din(ctxt->din, (v3f_t){ .x = (float)x * xscale * .7f, .y = (float)y * yscale * .7f, .z = z1 }) * t; + color.g = din(ctxt->din, (v3f_t){ .x = (float)x * xscale * .93f, .y = (float)y * yscale * .93f, .z = -z1 }) * t; + color.b = din(ctxt->din, (v3f_t){ .x = (float)x * xscale * .81f, .y = (float)y * yscale * .81f, .z = z2 }) * t; + + pixel = color_to_uint32(color); + fb_fragment_put_pixel_unchecked(fragment, x, y, pixel); + } + } +} + + +rototiller_module_t swab_module = { + .create_context = swab_create_context, + .destroy_context = swab_destroy_context, + .prepare_frame = swab_prepare_frame, + .render_fragment = swab_render_fragment, + .name = "swab", + .description = "Colorful perlin-noise visualization (threaded)", + .author = "Vito Caputo ", + .license = "GPLv3", +}; -- cgit v1.2.3