diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2022-06-07 19:02:35 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2022-06-07 21:12:34 -0700 |
commit | d944160f1d6a25710b298442972a8562ffc62942 (patch) | |
tree | 1712b8768ac97db6b28b2065638454c8a6b54f84 | |
parent | 6d1d7f95529d826ea916ac80d236f5e8616daf64 (diff) |
modules/moire: implement rudimentary moire module
This introduces a very naive unoptimized moire interference
pattern module, it's rather slow complete with a sqrtf() per
pixel per center.
-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/moire/Makefile.am | 3 | ||||
-rw-r--r-- | src/modules/moire/moire.c | 173 | ||||
-rw-r--r-- | src/til.c | 2 |
6 files changed, 181 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 23b8bad..d7e2d1b 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,7 @@ AC_CONFIG_FILES([ src/modules/flui2d/Makefile src/modules/julia/Makefile src/modules/meta2d/Makefile + src/modules/moire/Makefile src/modules/montage/Makefile src/modules/pixbounce/Makefile src/modules/plasma/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index 1641711..65b7626 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -3,7 +3,7 @@ SUBDIRS = libs modules noinst_LTLIBRARIES = libtil.la libtil_la_SOURCES = til_args.c til_args.h til_fb.c til_fb.h til_knobs.h til.c til.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_threads.c til_threads.h til_util.c til_util.h libtil_la_CPPFLAGS = -I@top_srcdir@/src -libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la +libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la if ENABLE_ROTOTILLER bin_PROGRAMS = rototiller diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index d00ac7b..83adbc5 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -1 +1 @@ -SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d montage pixbounce plasma plato ray roto rtv shapes snow sparkler spiro stars submit swab swarm voronoi +SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d moire montage pixbounce plasma plato ray roto rtv shapes snow sparkler spiro stars submit swab swarm voronoi diff --git a/src/modules/moire/Makefile.am b/src/modules/moire/Makefile.am new file mode 100644 index 0000000..9d72068 --- /dev/null +++ b/src/modules/moire/Makefile.am @@ -0,0 +1,3 @@ +noinst_LTLIBRARIES = libmoire.la +libmoire_la_SOURCES = moire.c +libmoire_la_CPPFLAGS = -I@top_srcdir@/src diff --git a/src/modules/moire/moire.c b/src/modules/moire/moire.c new file mode 100644 index 0000000..1678170 --- /dev/null +++ b/src/modules/moire/moire.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2022 - 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 2 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 <errno.h> +#include <math.h> +#include <stdlib.h> +#include <unistd.h> + +#include "til.h" +#include "til_fb.h" +#include "til_module_context.h" + +#define MOIRE_DEFAULT_CENTERS 2 + +typedef struct moire_setup_t { + til_setup_t til_setup; + unsigned n_centers; +} moire_setup_t; + +typedef struct moire_center_t { + float x, y; + float seed; + float dir; +} moire_center_t; + +typedef struct moire_context_t { + til_module_context_t til_module_context; + moire_setup_t setup; + moire_center_t centers[]; +} moire_context_t; + +static moire_setup_t moire_default_setup = { + .n_centers = MOIRE_DEFAULT_CENTERS, +}; + + +static til_module_context_t * moire_create_context(unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup) +{ + moire_context_t *ctxt; + + if (!setup) + setup = &moire_default_setup.til_setup; + + ctxt = til_module_context_new(sizeof(moire_context_t) + ((moire_setup_t *)setup)->n_centers * sizeof(moire_center_t), seed, n_cpus); + if (!ctxt) + return NULL; + + ctxt->setup = *(moire_setup_t *)setup; + + for (unsigned i = 0; i < ((moire_setup_t *)setup)->n_centers; i++) { + ctxt->centers[i].seed = rand_r(&seed) * (1.f / (float)RAND_MAX) * 2 * M_PI; + ctxt->centers[i].dir = (rand_r(&seed) * (2.f / (float)RAND_MAX) - 1.f); + ctxt->centers[i].x = cosf(ctxt->centers[i].seed + (float)ticks * .001f * ctxt->centers[i].dir); + ctxt->centers[i].y = sinf(ctxt->centers[i].seed + (float)ticks * .001f * ctxt->centers[i].dir); + } + + return &ctxt->til_module_context; +} + + +static void moire_prepare_frame(til_module_context_t *context, unsigned ticks, til_fb_fragment_t *fragment, til_fragmenter_t *res_fragmenter) +{ + moire_context_t *ctxt = (moire_context_t *)context; + + *res_fragmenter = til_fragmenter_slice_per_cpu; + + for (unsigned i = 0; i < ctxt->setup.n_centers; i++) { + ctxt->centers[i].x = cosf(ctxt->centers[i].seed + (float)ticks * .001f * ctxt->centers[i].dir); + ctxt->centers[i].y = sinf(ctxt->centers[i].seed + (float)ticks * .001f * ctxt->centers[i].dir); + } +} + + +static void moire_render_fragment(til_module_context_t *context, unsigned ticks, unsigned cpu, til_fb_fragment_t *fragment) +{ + moire_context_t *ctxt = (moire_context_t *)context; + float xf = 2.f / (float)fragment->frame_width; + float yf = 2.f / (float)fragment->frame_height; + float cx, cy; + + /* TODO: optimize */ + cy = yf * (float)fragment->y - 1.f; + for (int y = fragment->y; y < fragment->y + fragment->height; y++, cy += yf) { + + cx = xf * (float)fragment->x - 1.f; + for (int x = fragment->x; x < fragment->x + fragment->width; x++, cx += xf) { + int filled = 0; + + for (unsigned i = 0; i < ctxt->setup.n_centers; i++) { + float dx, dy; + + dx = cx - ctxt->centers[i].x; + dy = cy - ctxt->centers[i].y; + + if (cosf(sqrtf(dx * dx + dy * dy) * 50.f) < 0.f) + filled ^= 1; + } + + if (filled) + til_fb_fragment_put_pixel_unchecked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, x, y, 0xffffffff); + else if (!fragment->cleared) + til_fb_fragment_put_pixel_unchecked(fragment, 0, x, y, 0x00000000); + } + } +} + + +static int moire_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 *centers; + const char *values[] = { + "2", + "3", + "4", + "5", + NULL + }; + int r; + + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Number of radial centers", + .key = "centers", + .regex = "\\.[0-9]+", + .preferred = TIL_SETTINGS_STR(MOIRE_DEFAULT_CENTERS), + .values = values, + .annotations = NULL + }, + ¢ers, + res_setting, + res_desc); + if (r) + return r; + + if (res_setup) { + moire_setup_t *setup; + + setup = til_setup_new(sizeof(*setup), (void(*)(til_setup_t *))free); + if (!setup) + return -ENOMEM; + + sscanf(centers, "%u", &setup->n_centers); + + *res_setup = &setup->til_setup; + } + + return 0; +} + + +til_module_t moire_module = { + .create_context = moire_create_context, + .prepare_frame = moire_prepare_frame, + .render_fragment = moire_render_fragment, + .setup = moire_setup, + .name = "moire", + .description = "2D Moire interference patterns (threaded)", + .author = "Vito Caputo <vcaputo@pengaru.com>", + .flags = TIL_MODULE_OVERLAYABLE, +}; @@ -31,6 +31,7 @@ extern til_module_t drizzle_module; extern til_module_t flui2d_module; extern til_module_t julia_module; extern til_module_t meta2d_module; +extern til_module_t moire_module; extern til_module_t montage_module; extern til_module_t pixbounce_module; extern til_module_t plasma_module; @@ -56,6 +57,7 @@ static const til_module_t *modules[] = { &flui2d_module, &julia_module, &meta2d_module, + &moire_module, &montage_module, &pixbounce_module, &plasma_module, |