Banjo API 1.0.0-rc.2
Low-level C99 game development API
Loading...
Searching...
No Matches
shaders.c
Go to the documentation of this file.
1
15
16#include <banjo/app.h>
17#include <banjo/main.h>
18#include <banjo/bitmap.h>
19#include <banjo/event.h>
20#include <banjo/log.h>
21#include <banjo/shader.h>
22#include <banjo/system.h>
23#include <banjo/time.h>
24#include <banjo/window.h>
25
26#define CANVAS_W 512
27#define CANVAS_H 512
28
30// Helper function that generates RGB colours using cosine waves. This creates
31// smooth colour gradients for the shader. BJ_F() creates floating-point literals
32// (32-bit or 64-bit depending on build configuration).
34 const bj_real f = BJ_F(6.28318);
35
36 const bj_vec3 a = { BJ_F(0.5), BJ_F(0.5), BJ_F(0.5) };
37 const bj_vec3 b = { BJ_F(0.5), BJ_F(0.5), BJ_F(0.5) };
38 const bj_vec3 c = { BJ_F(1.0), BJ_F(1.0), BJ_F(1.0) };
39 const bj_vec3 d = { BJ_F(0.263), BJ_F(0.416), BJ_F(0.557) };
40
41 return (bj_vec3) {
42 .x = a.x + b.x * bj_cos(f * (c.x * t + d.x)),
43 .y = a.y + b.y * bj_cos(f * (c.y * t + d.y)),
44 .z = a.z + b.z * bj_cos(f * (c.z * t + d.z)),
45 };
46
47 }
48
49// Shader function signature: receives fragment coordinates and outputs a colour.
50// This function runs once per pixel in the bitmap.
51// Parameters:
52// - frag_color: Output RGB colour (values 0.0-1.0)
53// - frag_coords: Pixel coordinates normalised to -1.0 to 1.0 range
54// - data: User data pointer (we pass the current time for animation)
55// Returns: 1 to write the pixel, 0 to skip it
56int shader_code(bj_vec3* frag_color, const bj_vec2 frag_coords, void* data) {
57 bj_real time = *(bj_real*)data;
58
59 bj_vec3 final_color = { BJ_FZERO, BJ_FZERO, BJ_FZERO };
60
61 // The shader math below creates animated colourful patterns using distance
62 // fields, sine waves, and iterative coordinate transformations. This is
63 // typical procedural shader code - pure math creating visuals.
64 bj_vec2 uv = frag_coords;
65 const bj_real uv0_len = bj_vec2_len(uv);
66
67 for (bj_real i = BJ_FZERO; i < BJ_F(4.0); i += BJ_F(1.0)) {
68 bj_vec3 col = palette(uv0_len + i * BJ_F(0.4) + time * BJ_F(0.4));
69
70 uv = bj_vec2_scale(uv, BJ_F(1.5));
71 uv = bj_vec2_map(uv, bj_fract);
72 uv = bj_vec2_sub(uv, (bj_vec2){ BJ_F(0.5), BJ_F(0.5) });
73
74 const bj_real d = bj_pow(
75 BJ_F(0.01) / (
76 bj_abs(
77 bj_sin(
78 bj_vec2_len(uv) * bj_exp(-uv0_len) * BJ_F(8.0) + time
79 ) / BJ_F(8.0)
80 )
81 ),
82 BJ_F(1.2)
83 );
84
85 col = bj_vec3_scale(col, d);
86 final_color = bj_vec3_add(final_color, col);
87 }
88
89 // Write the computed colour to the output pixel.
90 *frag_color = final_color;
91 return 1;
92}
93
94// Each paint re-runs the shader against the current run time. The
95// animation is driven by the time value, so just invalidating the
96// window once per step is enough to advance the visual.
97static void on_draw(
98 struct bj_window* w,
99 struct bj_render_target* target,
100 const struct bj_rect* dirty,
101 void* user_data
102) {
103 (void)w; (void)dirty; (void)user_data;
104 bj_real time = (bj_real)bj_run_time();
105
106 // bj_shader_bitmap() applies the shader function to every pixel in the bitmap.
107 // Parameters: target bitmap, shader function, user data, flags
108 // BJ_SHADER_STANDARD_FLAGS normalises coordinates to -1.0 to 1.0 range.
109 // This is where the magic happens - the shader runs on all 512x512 = 262,144 pixels.
111}
112
113static void* setup(struct bj_app* app, void* init_data) {
114 (void)init_data;
115
116 if (!bj_begin(BJ_VIDEO_SYSTEM, 0)) {
117 bj_quit_app(app, 1);
118 return 0;
119 }
120
121 window = bj_bind_window("Shader Art Coding Introduction", 1000, 500, CANVAS_W, CANVAS_H, 0, 0);
122
126 return 0;
127}
128
129static void step(struct bj_app* app, struct bj_tick_info tick, void* user_data) {
130 (void)tick;
131 (void)user_data;
134
136 bj_quit_app(app, 0);
137 }
138}
139
140static void teardown(struct bj_app* app, void* user_data) {
141 (void)user_data;
143 bj_end();
144}
145
146int main(int argc, char* argv[]) {
147 (void)argc; (void)argv;
148 return bj_run_app(setup, step, 0, teardown, 0);
149}
Application lifecycle: callback-driven setup, step, and teardown.
int main(int argc, char *argv[])
Definition audio_pcm.c:177
static void step(struct bj_app *app, struct bj_tick_info tick, void *user_data)
Definition audio_pcm.c:144
static void teardown(struct bj_app *app, void *user_data)
Definition audio_pcm.c:170
bj_audio_play_note_data data
Definition audio_pcm.c:104
static void * setup(struct bj_app *app, void *init_data)
Definition audio_pcm.c:107
Header file for Bitmap type.
static void on_draw(struct bj_window *w, struct bj_render_target *target, const struct bj_rect *dirty, void *user_data)
Definition bitmap_blit.c:32
bj_window * window
Definition bitmap_blit.c:24
Sytem event management API.
int bj_run_app(bj_app_setup_fn setup, bj_app_step_fn step, bj_app_fixed_step_fn fixed_step, bj_app_teardown_fn teardown, void *init_data)
Drive the application lifecycle.
void bj_quit_app(struct bj_app *app, int exit_code)
Signal the given application to exit on the next iteration.
Timing snapshot handed to the step and fixed-step callbacks.
Definition app.h:106
struct bj_render_target bj_render_target
Definition api.h:346
struct bj_window bj_window
Definition api.h:354
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
X component.
Definition vec.h:65
bj_real z
Z component.
Definition vec.h:67
bj_real y
Y component.
Definition vec.h:66
static bj_real bj_vec2_len(struct bj_vec2 v)
Euclidean length: sqrt(x^2 + y^2).
Definition vec.h:219
static struct bj_vec3 bj_vec3_scale(struct bj_vec3 v, bj_real s)
Uniform scaling by a scalar: v * s.
Definition vec.h:411
static struct bj_vec2 bj_vec2_map(struct bj_vec2 a, bj_real(*f)(bj_real))
Apply a scalar function component-wise: (f(x), f(y)).
Definition vec.h:101
static struct bj_vec2 bj_vec2_sub(const struct bj_vec2 lhs, const struct bj_vec2 rhs)
Component-wise subtraction: lhs - rhs.
Definition vec.h:146
#define bj_sin
Sine.
Definition math.h:246
#define BJ_FZERO
Zero constant in bj_real.
Definition math.h:89
static struct bj_vec3 bj_vec3_add(struct bj_vec3 lhs, struct bj_vec3 rhs)
Component-wise addition: lhs + rhs.
Definition vec.h:358
#define bj_abs
Absolute value.
Definition math.h:233
static bj_real bj_fract(bj_real x)
Fractional part of x.
Definition math.h:298
#define bj_pow
Power.
Definition math.h:244
#define bj_exp
Exponential.
Definition math.h:238
#define bj_cos
Cosine.
Definition math.h:237
static struct bj_vec2 bj_vec2_scale(struct bj_vec2 v, bj_real s)
Uniform scaling by a scalar: v * s.
Definition vec.h:160
#define BJ_F(x)
Literal suffix helper for bj_real when float is selected.
Definition math.h:78
float bj_real
Selected real type for float configuration.
Definition math.h:76
Axis-aligned rectangle: a top-left corner plus a width and height.
Definition rect.h:33
2D vector of bj_real components.
Definition vec.h:51
3D vector of bj_real components.
Definition vec.h:64
#define BJ_SHADER_STANDARD_FLAGS
Flagset alias for bj_shader_bitmap.
Definition shader.h:162
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)
Initialises the system.
void bj_end(void)
De-initialises the system.
@ BJ_VIDEO_SYSTEM
Definition system.h:81
double bj_run_time(void)
Gets the current time in seconds since Banjo initialisation.
void bj_set_draw_callback(struct bj_window *window, bj_window_draw_fn fn, void *user_data)
Register the redraw callback for window.
static void bj_invalidate_window(struct bj_window *window)
Mark the whole window as needing a repaint.
Definition window.h:470
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.
struct bj_bitmap * bj_render_target_bitmap(struct bj_render_target *target)
Reach the software framebuffer behind a render target.
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() replacement with platform-aware entry shim.
Basic shader-like bitmap manipulation.
int shader_code(bj_vec3 *frag_color, const bj_vec2 frag_coords, void *data)
Definition shaders.c:56
static bj_vec3 palette(bj_real t)
Definition shaders.c:33
#define CANVAS_W
Definition shaders.c:26
#define CANVAS_H
Definition shaders.c:27
Header file for system interactions.
Header file for time manipulation utilities.
Header file for bj_window type.