diff options
| author | Vito Caputo <vcaputo@pengaru.com> | 2020-07-31 16:54:31 -0700 |
|---|---|---|
| committer | Vito Caputo <vcaputo@pengaru.com> | 2020-07-31 16:54:31 -0700 |
| commit | 94de2291e005f1c646fd779e8d32b2820e22e071 (patch) | |
| tree | 988bb9fde53a73edf948dd14fec07802a2f42406 /src/cache-node.c | |
| parent | cd7e9ebd9675461f59d5f7a9c7c0a9a1a0536d12 (diff) | |
*: initial implementation of pig
This is nothing to write home about, but it provides a little sandbox for
developing shader-generated textures in the spirit of shadertoy or the
demoscene tool bonzomatic.
It's more oriented towards developing shaders for use with libstage in
the small games I've been hacking on.
Diffstat (limited to 'src/cache-node.c')
| -rw-r--r-- | src/cache-node.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/src/cache-node.c b/src/cache-node.c new file mode 100644 index 0000000..6bcb85d --- /dev/null +++ b/src/cache-node.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2018-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 <assert.h> +#include <stdlib.h> + +#include <stage.h> + +#include "cache.h" +#include "cache-node.h" +#include "macros.h" + + +typedef struct cache_node_t { + cache_t *cache; + const m4f_t *model_x, *view_x, *projection_x; +} cache_node_t; + + +/* Prepare is where the cache node maintains the cache. It calls a stage + * render on the attached stage as part of the outer stage's prepare phase. + */ +static void cache_node_prepare(stage_t *stage, void *object, float alpha, void *render_ctxt) +{ + cache_node_t *cache_node = object; + + assert(cache_node); + + if (cache_update(cache_node->cache, alpha, render_ctxt)) + stage_dirty(stage); +} + + +/* Render simply renders a cached texture onto the screen */ +static void cache_node_render(const stage_t *stage, void *object, float alpha, void *render_ctxt) +{ + cache_node_t *cache_node = object; + + assert(stage); + assert(cache_node); + + cache_render(cache_node->cache, alpha, cache_node->model_x, cache_node->view_x, cache_node->projection_x); +} + + +static void cache_node_free(const stage_t *stage, void *object) +{ + cache_node_t *cache_node = object; + + assert(cache_node); + + cache_free(cache_node->cache); + free(cache_node); +} + + +static const stage_ops_t cache_node_ops = { + .prepare_func = cache_node_prepare, + .render_func = cache_node_render, + .free_func = cache_node_free, +}; + + +/* return a cache node from an already established cache, with a potentially unique transform */ +stage_t * cache_node_new_cache(stage_conf_t *conf, cache_t *cache, const m4f_t *model_x, const m4f_t *view_x, const m4f_t *projection_x) +{ + cache_node_t *cache_node; + stage_t *s; + + assert(conf); + + cache_node = calloc(1, sizeof(cache_node_t)); + fatal_if(!cache_node, "Unable to allocate cache node \"%s\"", conf->name); + + cache_node->cache = cache; + cache_node->model_x = model_x; + cache_node->view_x = view_x; + cache_node->projection_x = projection_x; + + s = stage_new(conf, &cache_node_ops, cache_node); + fatal_if(!s, "Unable to create stage \"%s\"", conf->name); + + cache_ref(cache); + + return s; +} + + +/* return a cache node from a stage + * The cache node takes ownership of the supplied stage, and will + * free it when the cache node is freed. + * When the associated stage is dirty, the cache gets updated with its rendered + * output on a subsequent render, in the prepare hook. + * + * region specifies, in ndc coordinates, the region of the canvas as rendered by the associated stage to cache. + * transform specifies the transformation to apply to the two triangles used for mapping the cached texture. + * The triangles used for mapping the texture form a section of a unit cube @ coordinates -1,-1,0 .. +1,+1,0, so + * if you supply an identity matrix for transform, the cached texture is drawn fullscreen. + * + * Either region and/or transform may be NULL. When region is NULL, it's assumed to be -1,-1..+1,+1. When + * transform is NULL, it's assumed to be an identity matrix. So supplying NULL for both caches the full canvas, + * and draws it directly back into the full canvas. + */ +stage_t * cache_node_new_stage(stage_conf_t *conf, stage_t *stage, const bb2f_t *region, const m4f_t *model_x, const m4f_t *view_x, const m4f_t *projection_x) +{ + cache_t *cache; + + assert(conf); + + cache = cache_new(stage, region); + fatal_if(!cache, "Unable to allocate cache \"%s\"", conf->name); + + return cache_node_new_cache(conf, cache, model_x, view_x, projection_x); +} |
