Banjo API 0.0.1
C99 game development API
Loading...
Searching...
No Matches
shaders.c

Procedural graphics using pixel shaders.

Procedural graphics using pixel shaders.A shader is a function that runs on every pixel to compute its color. bj_shader_bitmap() applies a shader function to an entire bitmap, enabling procedural generation of images and animations purely through math. This is software-based (CPU) shader execution - conceptually similar to GPU fragment shaders but running on the CPU.

This shader comes from https://www.shadertoy.com/view/mtyGWy Designed by kishimisu at https://www.youtube.com/watch?v=f4s1h2YETNY

#define BJ_AUTOMAIN_CALLBACKS
#include <banjo/bitmap.h>
#include <banjo/event.h>
#include <banjo/log.h>
#include <banjo/main.h>
#include <banjo/renderer.h>
#include <banjo/shader.h>
#include <banjo/system.h>
#include <banjo/time.h>
#include <banjo/window.h>
#define CANVAS_W 512
#define CANVAS_H 512
// Helper function that generates RGB colors using cosine waves. This creates
// smooth color gradients for the shader. BJ_F() creates floating-point literals
// (32-bit or 64-bit depending on build configuration).
static bj_vec3 palette(bj_real t) {
const bj_real f = BJ_F(6.28318);
const bj_vec3 a = { BJ_F(0.5), BJ_F(0.5), BJ_F(0.5) };
const bj_vec3 b = { BJ_F(0.5), BJ_F(0.5), BJ_F(0.5) };
const bj_vec3 c = { BJ_F(1.0), BJ_F(1.0), BJ_F(1.0) };
const bj_vec3 d = { BJ_F(0.263), BJ_F(0.416), BJ_F(0.557) };
return (bj_vec3) {
.x = a.x + b.x * bj_cos(f * (c.x * t + d.x)),
.y = a.y + b.y * bj_cos(f * (c.y * t + d.y)),
.z = a.z + b.z * bj_cos(f * (c.z * t + d.z)),
};
}
// Shader function signature: receives fragment coordinates and outputs a color.
// This function runs once per pixel in the bitmap.
// Parameters:
// - frag_color: Output RGB color (values 0.0-1.0)
// - frag_coords: Pixel coordinates normalized to -1.0 to 1.0 range
// - data: User data pointer (we pass the current time for animation)
// Returns: 1 to write the pixel, 0 to skip it
int shader_code(bj_vec3* frag_color, const bj_vec2 frag_coords, void* data) {
bj_real time = *(bj_real*)data;
bj_vec3 final_color = { BJ_FZERO, BJ_FZERO, BJ_FZERO };
// The shader math below creates animated colorful patterns using distance
// fields, sine waves, and iterative coordinate transformations. This is
// typical procedural shader code - pure math creating visuals.
bj_vec2 uv = frag_coords;
const bj_real uv0_len = bj_vec2_len(uv);
for (bj_real i = BJ_FZERO; i < BJ_F(4.0); i += BJ_F(1.0)) {
bj_vec3 col = palette(uv0_len + i * BJ_F(0.4) + time * BJ_F(0.4));
uv = bj_vec2_scale(uv, BJ_F(1.5));
uv = bj_vec2_map(uv, bj_fract);
uv = bj_vec2_sub(uv, (bj_vec2){ BJ_F(0.5), BJ_F(0.5) });
const bj_real d = bj_pow(
BJ_F(0.01) / (
bj_vec2_len(uv) * bj_exp(-uv0_len) * BJ_F(8.0) + time
) / BJ_F(8.0)
)
),
BJ_F(1.2)
);
col = bj_vec3_scale(col, d);
final_color = bj_vec3_add(final_color, col);
}
// Write the computed color to the output pixel.
*frag_color = final_color;
return 1;
}
int bj_app_begin(void** user_data, int argc, char* argv[]) {
(void)user_data; (void)argc; (void)argv;
return bj_callback_exit_error;
}
window = bj_bind_window("Shader Art Coding Introduction", 1000, 500, CANVAS_W, CANVAS_H, 0, 0);
return bj_callback_continue;
}
int bj_app_iterate(void* user_data) {
(void)user_data;
// Get current runtime to animate the shader.
// bj_shader_bitmap() applies the shader function to every pixel in the bitmap.
// Parameters: target bitmap, shader function, user data, flags
// BJ_SHADER_STANDARD_FLAGS normalizes coordinates to -1.0 to 1.0 range.
// This is where the magic happens - the shader runs on all 512x512 = 262,144 pixels.
bj_sleep(15);
? bj_callback_exit_success
: bj_callback_continue;
}
int bj_app_end(void* user_data, int status) {
(void)user_data;
bj_end();
return status;
}
int bj_app_begin(void **user_data, int argc, char *argv[])
Definition audio_pcm.c:25
int bj_app_iterate(void *user_data)
Definition audio_pcm.c:60
int bj_app_end(void *user_data, int status)
Definition audio_pcm.c:84
bj_audio_play_note_data data
Definition audio_pcm.c:22
Header file for Bitmap type.
bj_renderer * renderer
Definition bitmap_blit.c:25
bj_window * window
Definition bitmap_blit.c:24
Sytem event management API.
struct bj_bitmap bj_bitmap
Definition api.h:270
struct bj_renderer bj_renderer
Definition api.h:288
struct bj_window bj_window
Definition api.h:296
void bj_dispatch_events(void)
Poll and dispatch all pending events.
void bj_close_on_escape(struct bj_window *window, const struct bj_key_event *event, void *user_data)
Handle the ESC key to close a window.
bj_key_callback_fn bj_set_key_callback(bj_key_callback_fn callback, void *user_data)
Set the global callback for keyboard key events.
bj_real x
Definition vec.h:39
bj_real z
Definition vec.h:41
bj_real y
Definition vec.h:40
static bj_real bj_vec2_len(struct bj_vec2 v)
Euclidean length (L2 norm) of a 2D vector.
Definition vec.h:154
static struct bj_vec3 bj_vec3_scale(struct bj_vec3 v, bj_real s)
Uniform scaling by scalar: res = v * s.
Definition vec.h:316
static struct bj_vec2 bj_vec2_map(struct bj_vec2 a, bj_real(*f)(bj_real))
Definition vec.h:61
static struct bj_vec2 bj_vec2_sub(const struct bj_vec2 lhs, const struct bj_vec2 rhs)
Component-wise subtraction of two 2D vectors: res = lhs - rhs.
Definition vec.h:101
#define bj_sin
Sine.
Definition math.h:221
#define BJ_FZERO
Zero constant in bj_real.
Definition math.h:64
static struct bj_vec3 bj_vec3_add(struct bj_vec3 lhs, struct bj_vec3 rhs)
Component-wise addition of two 3D vectors: res = lhs + rhs.
Definition vec.h:265
#define bj_abs
Absolute value.
Definition math.h:208
static bj_real bj_fract(bj_real x)
Fractional part of x.
Definition math.h:273
#define bj_pow
Power.
Definition math.h:219
#define bj_exp
Exponential.
Definition math.h:213
#define bj_cos
Cosine.
Definition math.h:212
static struct bj_vec2 bj_vec2_scale(struct bj_vec2 v, bj_real s)
Uniform scaling by scalar: res = v * s.
Definition vec.h:114
#define BJ_F(x)
Literal suffix helper for bj_real when float is selected.
Definition math.h:53
float bj_real
Selected real type for float configuration.
Definition math.h:51
struct bj_vec2: 2D vector of bj_real values.
Definition vec.h:26
struct bj_vec3: 3D vector of bj_real values.
Definition vec.h:38
void bj_present(struct bj_renderer *renderer, struct bj_window *window)
Present the framebuffer to a window.
struct bj_renderer * bj_create_renderer(enum bj_renderer_type type, struct bj_error **error)
Create a new renderer instance.
struct bj_bitmap * bj_get_framebuffer(struct bj_renderer *renderer)
Get the renderer's framebuffer.
bj_bool bj_renderer_configure(struct bj_renderer *renderer, struct bj_window *window, struct bj_error **error)
Configure a renderer for a specific window.
void bj_destroy_renderer(struct bj_renderer *renderer)
Destroy a renderer and free associated resources.
@ BJ_RENDERER_TYPE_SOFTWARE
Software (CPU-based) renderer.
Definition renderer.h:35
#define BJ_SHADER_STANDARD_FLAGS
Flagset alias for bj_shader_bitmap.
Definition shader.h:145
void bj_shader_bitmap(struct bj_bitmap *bitmap, bj_bitmap_shading_fn shader, void *data, uint8_t flags)
Applies a shader function to every pixel in a bitmap.
bj_bool bj_begin(int systems, struct bj_error **error)
Initializes the system.
void bj_end(void)
De-initializes the system.
@ BJ_VIDEO_SYSTEM
Definition system.h:20
void bj_sleep(int milliseconds)
Suspends the current thread for a specified duration.
double bj_run_time(void)
Gets the current time in seconds since Banjo initialization.
struct bj_window * bj_bind_window(const char *title, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint8_t flags, struct bj_error **error)
Create a new struct bj_window with the specified attributes.
bj_bool bj_should_close_window(struct bj_window *window)
Get the close flag state of a window.
void bj_unbind_window(struct bj_window *window)
Deletes a struct bj_window object and releases associated memory.
Logging utility functions.
Portable main substitution and application callback facilities.
bj_bitmap * framebuffer
Definition physics_kinematics.c:35
Rendering backend interface.
Basic shader-like bitmap manipulation.
int shader_code(bj_vec3 *frag_color, const bj_vec2 frag_coords, void *data)
Definition shaders.c:58
static bj_vec3 palette(bj_real t)
Definition shaders.c:35
#define CANVAS_W
Definition shaders.c:25
#define CANVAS_H
Definition shaders.c:26
Header file for system interactions.
Header file for time manipulation utilities.
Header file for bj_window type.