AtlatestRepositorysigil-graphics
sigil-graphics / treeREADME.md
1
# sigil-graphics3
2D graphics, image loading, and font rendering for [Sigil](https://codeberg.org/sigil/sigil).5
Provides 2D rendering capabilities via sokol_gfx and sokol_gp, image loading (stb_image), and font rendering (stb_truetype).7
## Modules9
| Module | Purpose |10
|--------|---------|11
| `(sigil graphics)` | Core 2D rendering (shapes, transforms, textures) |12
| `(sigil graphics image)` | CPU-side image loading |13
| `(sigil graphics font)` | Font loading and text rendering |15
## System Prerequisites17
- No GL headers: the GL entry points sokol_gfx calls are loaded at run18
time through sigil-desktop (`src/c/gl_native_loader.h`, generated from the19
vendored `sokol_gfx.h` by `scripts/gen-gl-loader.sh`), and nothing links20
libGL. Building sigil-desktop needs the X11 and Wayland headers listed in21
`manifest.scm`.23
## Dependencies25
- sigil-stdlib26
- sigil-desktop (the window, GL context and input; GLFW. Named sigil-app27
through 0.9.x, pinned here as `name: "sigil-desktop"` at the old URL until28
the Codeberg repository is renamed)30
## Build32
```sh33
sigil deps install34
sigil build35
```37
## Render targets and custom shaders39
Offscreen rendering and custom fragment shaders (since v0.10.0) build a40
post-processing or simulation pipeline out of three pieces:42
```scheme43
(define rt (make-render-target 256 256)) ; 'linear sampling (default)44
(define grid (make-render-target 64 64 'nearest)) ; texel-exact when drawn46
(with-render-target rt47
(draw-filled-rect 0.0 0.0 256.0 256.0)) ; draws land in rt49
(define fx (load-shader VERT-SOURCE FRAG-SOURCE)) ; GLSL strings; optional 3rd arg50
; 'normal (default) | 'additive | 'none51
(with-shader fx52
(draw-render-target rt 0.0 0.0 256.0 256.0)) ; rt is channel 053
```55
The fragment shader samples channel 0 as `iTexChannel0_iSmpChannel0` (sokol_gp's56
name) and receives `texUV` and `iColor` from the vertex stage; the vertex shader is57
the sgp passthrough with `coord` at location 0 and `color` at location 1 (see58
`test/test-shader`). Natively the sources are `#version 410`; on the `web` config59
they are `#version 300 es` with precision qualifiers, so a package that builds for60
both prefixes the version line under `cond-expand`.62
### Uniforms and uniform arrays64
`load-shader` scans the fragment source for `uniform` declarations of `float`,65
`vec2`, `vec3`, `vec4` and `mat4`, scalar or array (`uniform vec4 palette[8];`, a66
literal count; a `lowp`/`mediump`/`highp` qualifier is fine). `sampler2D` is not a67
uniform-block entry. Up to 16 declarations (an array is one) and 512 bytes in total,68
both checked by `load-shader` (the error names the limit); a GLSL compile error69
is an error too, with sokol's log line before it. Entries are70
packed in declaration order.72
```scheme73
(set-shader-uniform fx 'u_radius 2.5) ; float74
(set-shader-uniform fx 'u_tint '(1.0 0.8 0.6 1.0)) ; vec4, list or vector75
(set-shader-uniform fx 'palette '((1 0 0 1) (0 1 0 1) ...)) ; vec4 palette[8]: nested,76
(set-shader-uniform fx 'levels #(0.0 0.25 0.5 1.0)) ; or flat, per element77
```79
The float count must match the declaration exactly; a mismatch is an error, not a80
partial write. Two uniforms are filled in for you on every `with-shader` entry:81
`u_time` (float, seconds since `gfx-setup`) and `u_resolution` (vec2: the virtual82
viewport, or the render target's size when the shader is bound inside83
`with-render-target`).85
### Textures from pixels87
```scheme88
(define tex (make-texture-from-pixels 4 4 bytes 'nearest)) ; RGBA8 bytevector,89
(update-texture tex other-bytes) ; top row first90
```92
`bytes` is exactly `width * height * 4` bytes (a size mismatch is an error). The93
texture draws with `draw-texture` / `draw-texture-region` like one from94
`load-texture`. sokol_gfx allows one upload per texture per frame (a frame ends at95
`end-frame`), and creating the texture is that frame's upload, so make the texture96
one frame before the first `update-texture`; a second upload in a frame is refused97
with an error that says so.99
### GPU simulations by ping-pong101
`with-shader` composes inside `with-render-target`: a step shader bound in a pass on102
target B can read target A through `draw-render-target`, and swapping the two each103
frame runs a cellular automaton with no cell state on the CPU. Load the step shader104
with `'none` blending so it overwrites the target (alpha blending would scale data105
channels), and read neighbours with106
`texelFetch(iTexChannel0_iSmpChannel0, ivec2(gl_FragCoord.xy) + offset, 0)` (the107
sampler's filter does not apply) and wrap on `u_resolution`. `test/test-shader-limits`108
is the worked example, verified pixel-for-pixel on native and in the browser; its109
README has the commands.111
Render targets on the `web` config work as of v0.11.3 (earlier releases refused112
every offscreen pass there, see the tag notes).115
## License117
BSD-3-Clause