| 1 | // A Signed Distance Field rendering demo, ported from https://github.com/floooh/sokol-samples/blob/master/sapp/sdf-sapp.c |
| 2 | // which in turn is based on https://iquilezles.org/articles/mandelbulb/ and https://www.shadertoy.com/view/ltfSWn |
| 3 | // vtest build: misc-tooling // needs .h files that are produced by `v shader` |
| 4 | import sokol.sapp |
| 5 | import sokol.gfx |
| 6 | |
| 7 | #include "@VMODROOT/sdf.h" # It should be generated with `v shader .` |
| 8 | |
| 9 | fn C.sdf_shader_desc(gfx.Backend) &gfx.ShaderDesc |
| 10 | |
| 11 | @[packed] |
| 12 | struct C.vs_params_t { |
| 13 | mut: |
| 14 | aspect f32 |
| 15 | time f32 |
| 16 | } |
| 17 | |
| 18 | struct State { |
| 19 | mut: |
| 20 | pip gfx.Pipeline |
| 21 | bind gfx.Bindings |
| 22 | paction gfx.PassAction |
| 23 | params C.vs_params_t |
| 24 | } |
| 25 | |
| 26 | fn init(mut state State) { |
| 27 | gfx.setup(sapp.create_desc()) |
| 28 | |
| 29 | fsq_verts := [f32(-1.0), -3.0, 3.0, 1.0, -1.0, 1.0]! |
| 30 | state.bind.vertex_buffers[0] = gfx.make_buffer(gfx.BufferDesc{ |
| 31 | label: c'fsq vertices' |
| 32 | data: gfx.Range{&fsq_verts[0], sizeof(fsq_verts)} |
| 33 | }) |
| 34 | |
| 35 | mut pipeline := gfx.PipelineDesc{} |
| 36 | pipeline.layout.attrs[C.ATTR_vs_position].format = .float2 |
| 37 | pipeline.shader = gfx.make_shader(voidptr(C.sdf_shader_desc(gfx.query_backend()))) |
| 38 | state.pip = gfx.make_pipeline(&pipeline) |
| 39 | |
| 40 | // No need to clear the window, since the shader will overwrite the whole framebuffer |
| 41 | state.paction.colors[0].load_action = .dontcare |
| 42 | } |
| 43 | |
| 44 | fn frame(mut state State) { |
| 45 | w, h := sapp.width(), sapp.height() |
| 46 | state.params.time += f32(sapp.frame_duration()) |
| 47 | state.params.aspect = f32(w) / f32(h) |
| 48 | gfx.begin_pass(sapp.create_default_pass(state.paction)) |
| 49 | gfx.apply_pipeline(state.pip) |
| 50 | gfx.apply_bindings(state.bind) |
| 51 | gfx.apply_uniforms(.vs, C.SLOT_vs_params, gfx.Range{&state.params, sizeof(state.params)}) |
| 52 | gfx.draw(0, 3, 1) |
| 53 | gfx.end_pass() |
| 54 | gfx.commit() |
| 55 | } |
| 56 | |
| 57 | fn main() { |
| 58 | sapp.run(sapp.Desc{ |
| 59 | window_title: c'SDF Rendering' |
| 60 | width: 512 |
| 61 | height: 512 |
| 62 | frame_userdata_cb: frame |
| 63 | init_userdata_cb: init |
| 64 | cleanup_cb: gfx.shutdown |
| 65 | icon: sapp.IconDesc{ |
| 66 | sokol_default: true |
| 67 | } |
| 68 | user_data: &State{} |
| 69 | }) |
| 70 | } |
| 71 | |