/* * Copyright (C) 2019 - Vito Caputo - * * 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 . */ #include #include #include #include #include #include #include "til.h" #include "til_fb.h" #include "til_module_context.h" #include "til_util.h" #include "din/din.h" typedef struct swab_context_t { til_module_context_t til_module_context; din_t *din; float r; } swab_context_t; typedef struct color_t { float r,g,b; } color_t; typedef struct v3f_t { float x, y, z; } v3f_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 til_module_context_t * swab_create_context(unsigned seed, unsigned ticks, unsigned n_cpus, char *path, til_setup_t *setup) { swab_context_t *ctxt; ctxt = til_module_context_new(sizeof(swab_context_t), seed, ticks, n_cpus, path); if (!ctxt) return NULL; ctxt->din = din_new(12, 12, 100, seed); if (!ctxt->din) { free(ctxt); return NULL; } return &ctxt->til_module_context; } static void swab_destroy_context(til_module_context_t *context) { swab_context_t *ctxt = (swab_context_t *)context; din_free(ctxt->din); free(ctxt); } static void swab_prepare_frame(til_module_context_t *context, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan) { swab_context_t *ctxt = (swab_context_t *)context; *res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_tile64 }; ctxt->r += .0001f; } static void swab_render_fragment(til_module_context_t *context, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr) { swab_context_t *ctxt = (swab_context_t *)context; til_fb_fragment_t *fragment = *fragment_ptr; 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++) { float yscaled = (float)y * yscale; for (int x = fragment->x; x < fragment->x + fragment->width; x++) { float xscaled = (float)x * xscale; color_t color; uint32_t pixel; float t; t = din(ctxt->din, &(v3f_t){ .x = xscaled * .5f, .y = yscaled * .5f, .z = -z2 }) * 33.f; color.r = din(ctxt->din, &(v3f_t){ .x = xscaled * .7f, .y = yscaled * .7f, .z = z1 }) * t; color.g = din(ctxt->din, &(v3f_t){ .x = xscaled * .93f, .y = yscaled * .93f, .z = -z1 }) * t; color.b = din(ctxt->din, &(v3f_t){ .x = xscaled * .81f, .y = yscaled * .81f, .z = z2 }) * t; pixel = color_to_uint32(color); til_fb_fragment_put_pixel_unchecked(fragment, 0, x, y, pixel); } } } til_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 ", };