summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2019-11-18 01:55:16 -0800
committerVito Caputo <vcaputo@pengaru.com>2019-11-18 01:59:13 -0800
commit01ab4fea185b451ed2d281a21ae62ba8c85e5237 (patch)
tree01ce924ffc86627c3b98a2460584cff5902aca66
parent975c81262faa7ed06de56974064fd918a088bc1b (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--README1
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/modules/Makefile.am2
-rw-r--r--src/modules/swab/Makefile.am3
-rw-r--r--src/modules/swab/swab.c147
-rw-r--r--src/rototiller.c2
7 files changed, 156 insertions, 2 deletions
diff --git a/README b/README
index b67b7b1..5f6ee69 100644
--- a/README
+++ b/README
@@ -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 {
© All Rights Reserved