Mercurial > audlegacy-plugins
diff src/paranormal-ng/cmaps.c @ 2078:1fa3c8cd366a
paranormal-ng: a GL visualiser. lots to do, most stuff won't work, but hey, this will do cool stuff too soon
author | William Pitcock <nenolod@atheme.org> |
---|---|
date | Mon, 15 Oct 2007 06:20:13 -0500 |
parents | |
children | f1b6f1b2cdb3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/paranormal-ng/cmaps.c Mon Oct 15 06:20:13 2007 -0500 @@ -0,0 +1,202 @@ +/* + * paranormal: iterated pipeline-driven visualization plugin + * Copyright (c) 2006, 2007 William Pitcock <nenolod@dereferenced.org> + * Portions copyright (c) 2001 Jamie Gennis <jgennis@mindspring.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; under version 2 of the License. + * + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <config.h> + +#include <glib.h> + +#include "paranormal.h" +#include "actuators.h" + +#include "libcalc/calc.h" + +#define STD_CMAP_OPTS { "low_index", "The lowest index of the \ +color map that should be altered", OPT_TYPE_COLOR_INDEX, { ival: 0 } },\ +{ "high_index", "The highest index of the color map that should be \ +altered", OPT_TYPE_COLOR_INDEX, { ival: 255 } } + +static struct pn_color black = {0, 0, 0}; +static struct pn_color white = {255, 255, 255}; + +/* **************** cmap generation funcs **************** */ +static void +cmap_gen_gradient (int step, const struct pn_color *a, + const struct pn_color *b, + struct pn_color *c) +{ + c->r = a->r + step * ((((float)b->r) - ((float)a->r)) / 256.0); + c->g = a->g + step * ((((float)b->g) - ((float)a->g)) / 256.0); + c->b = a->b + step * ((((float)b->b) - ((float)a->b)) / 256.0); +} + +/* **************** cmap_gradient **************** */ +static struct pn_actuator_option_desc cmap_gradient_opts[] = +{ + STD_CMAP_OPTS, + { "lcolor", "The low color used in the gradient generation", + OPT_TYPE_COLOR, { cval: {0, 0, 0} } }, + { "hcolor", "The high color used in the gradient generation", + OPT_TYPE_COLOR, { cval: {0, 0, 0} } }, + { NULL } +}; + +static void +cmap_gradient_exec (const struct pn_actuator_option *opts, + gpointer data) +{ + int i; + + for (i=opts[0].val.ival; i<=opts[1].val.ival; i++) + cmap_gen_gradient (((i-opts[0].val.ival)<<8)/(opts[1].val.ival + - opts[0].val.ival), + &opts[2].val.cval, &opts[3].val.cval, + &pn_image_data->cmap[i]); +} + +struct pn_actuator_desc builtin_cmap_gradient = +{ + "cmap_gradient", + "Normal colourmap", + "Sets the colormap to a gradient going from <lcolor> to " + "<hcolor>", + 0, cmap_gradient_opts, + NULL, NULL, cmap_gradient_exec +}; + +/* **************** cmap_bwgradient **************** */ +static struct pn_actuator_option_desc cmap_bwgradient_opts[] = +{ + STD_CMAP_OPTS, + { "color", "The intermediate color to use in the gradient", + OPT_TYPE_COLOR, { cval: {191, 191, 191} } }, + { NULL } +}; + +static void +cmap_bwgradient_exec (const struct pn_actuator_option *opts, + gpointer data) +{ + int i; + + for (i=opts[0].val.ival; i<128 && i<=opts[1].val.ival; i++) + cmap_gen_gradient (i<<1, &black, &opts[2].val.cval, + &pn_image_data->cmap[i]); + + for (i=128; i<256 && i<=opts[1].val.ival; i++) + cmap_gen_gradient ((i-128)<<1, &opts[2].val.cval, &white, + &pn_image_data->cmap[i]); +} + +struct pn_actuator_desc builtin_cmap_bwgradient = +{ + "cmap_bwgradient", + "Value-based colourmap", + "Sets the colormap to a gradient going from black to " + "white, via an intermediate color", + 0, cmap_bwgradient_opts, + NULL, NULL, cmap_bwgradient_exec +}; + +/* **************** cmap_dynamic **************** */ +static struct pn_actuator_option_desc cmap_dynamic_opts[] = +{ + STD_CMAP_OPTS, + { "script", "The script to run on each step.", + OPT_TYPE_STRING, { sval: "red = red + 0.01; blue = blue + 0.01; green = green + 0.01;" } }, + { NULL } +}; + +typedef struct { + expression_t *expr; + symbol_dict_t *dict; +} PnDynamicColourmapData; + +static void +cmap_dynamic_init(gpointer *data) +{ + *data = g_new0(PnDynamicColourmapData, 1); +} + +static void +cmap_dynamic_cleanup(gpointer data) +{ + PnDynamicColourmapData *d = (PnDynamicColourmapData *) data; + + if (d->expr) + expr_free(d->expr); + if (d->dict) + dict_free(d->dict); + + g_free(d); +} + +static void +cmap_dynamic_exec(const struct pn_actuator_option *opts, + gpointer data) +{ + PnDynamicColourmapData *d = (PnDynamicColourmapData *) data; + gint i, j; + gdouble *rf, *bf, *gf, *inf; + gint rn, bn, gn; + + if (!d->dict && !d->expr) + { + d->dict = dict_new(); + if (!d->dict) + return; + + d->expr = expr_compile_string(opts[2].val.sval, d->dict); + if (!d->expr) + { + dict_free(d->dict); + d->dict = NULL; + return; + } + } + + rf = dict_variable(d->dict, "red"); + gf = dict_variable(d->dict, "green"); + bf = dict_variable(d->dict, "blue"); + inf = dict_variable(d->dict, "index"); + + for (i = opts[0].val.ival; i < 255 && i <= opts[1].val.ival; i++) + { + *inf = ((gdouble)i / 255.0); + + expr_execute(d->expr, d->dict); + + /* Convert rf/bf/gf to realworld values. */ + rn = (gdouble)(*rf * 255); + gn = (gdouble)(*gf * 255); + bn = (gdouble)(*bf * 255); + + pn_image_data->cmap[i].r = rn; + pn_image_data->cmap[i].g = gn; + pn_image_data->cmap[i].b = bn; + } +} + +struct pn_actuator_desc builtin_cmap_dynamic = +{ + "cmap_dynamic", + "Dynamic Colourmap", + "Scriptable colourmap modifier.", + 0, cmap_dynamic_opts, + cmap_dynamic_init, cmap_dynamic_cleanup, cmap_dynamic_exec +};