diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2019-11-18 01:55:16 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2019-11-18 01:59:13 -0800 |
commit | 01ab4fea185b451ed2d281a21ae62ba8c85e5237 (patch) | |
tree | 01ce924ffc86627c3b98a2460584cff5902aca66 | |
parent | 975c81262faa7ed06de56974064fd918a088bc1b (diff) |
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.
-rw-r--r-- | README | 1 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/swab/Makefile.am | 3 | ||||
-rw-r--r-- | src/modules/swab/swab.c | 147 | ||||
-rw-r--r-- | src/rototiller.c | 2 |
7 files changed, 156 insertions, 2 deletions
@@ -10,6 +10,7 @@ rototiller is, rendered entirely in software: pixbounce: a 2D bouncing pixmap demonstration rtv: a "Rototiller TV" slideshow meta-module snow: a "TV snow" / white noise effect + swab: a colorful perlin-noise visualization --- diff --git a/configure.ac b/configure.ac index 42db4fb..7a2f01e 100644 --- a/configure.ac +++ b/configure.ac @@ -52,5 +52,6 @@ AC_CONFIG_FILES([ src/modules/sparkler/Makefile src/modules/stars/Makefile src/modules/submit/Makefile + src/modules/swab/Makefile ]) AC_OUTPUT diff --git a/src/Makefile.am b/src/Makefile.am index ad45024..48b0a4c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,4 +4,4 @@ rototiller_SOURCES = fb.c fb.h fps.c fps.h rototiller.c rototiller.h sdl_fb.c se if ENABLE_DRM rototiller_SOURCES += drm_fb.c endif -rototiller_LDADD = modules/flui2d/libflui2d.a modules/julia/libjulia.a modules/pixbounce/libpixbounce.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/rtv/librtv.a modules/snow/libsnow.a modules/sparkler/libsparkler.a modules/stars/libstars.a modules/submit/libsubmit.a libs/grid/libgrid.a libs/ray/libray.a libs/txt/libtxt.a libs/ascii/libascii.a libs/din/libdin.a -lm +rototiller_LDADD = modules/flui2d/libflui2d.a modules/julia/libjulia.a modules/pixbounce/libpixbounce.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/rtv/librtv.a modules/snow/libsnow.a modules/sparkler/libsparkler.a modules/stars/libstars.a modules/submit/libsubmit.a modules/swab/libswab.a libs/grid/libgrid.a libs/ray/libray.a libs/txt/libtxt.a libs/ascii/libascii.a libs/din/libdin.a -lm 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 - <vcaputo@pengaru.com> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +#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 <vcaputo@pengaru.com>", + .license = "GPLv3", +}; diff --git a/src/rototiller.c b/src/rototiller.c index 92f29fe..74ba006 100644 --- a/src/rototiller.c +++ b/src/rototiller.c @@ -43,6 +43,7 @@ extern rototiller_module_t snow_module; extern rototiller_module_t sparkler_module; extern rototiller_module_t stars_module; extern rototiller_module_t submit_module; +extern rototiller_module_t swab_module; static const rototiller_module_t *modules[] = { &flui2d_module, @@ -56,6 +57,7 @@ static const rototiller_module_t *modules[] = { &sparkler_module, &stars_module, &submit_module, + &swab_module, }; typedef struct rototiller_t { |