Sokol
repository·master·Indexed 27 days ago
https://github.com/floooh/sokolA collection of lightweight, STB-style cross-platform C libraries for graphics, audio, app framework, and utilities. Designed for high portability with first-class support for WebAssembly, it includes core headers such as sokol_gfx.h for 3D-API wrapping, sokol_app.h for window and input management, sokol_audio.h for buffer-streaming audio, and sokol_fetch.h for asynchronous data streaming. The library provides a minimal footprint and supports multiple backends including GL, Metal, D3D11, and WebGPU.
What's inside Sokol
- Sokol is a collection of simple, STB-style cross-platform libraries written in C for C and C++ developers. It is designed with WebAssembly as a first-class citizen, providing minimal footprint on the web while remaining highly performant on native platforms. The core headers are standalone and can be used independently.
Parse arguments with sokol_args.h
mastersokol_args.h provides unified argument parsing for both native applications (using
argc/argv) and web applications (using URL query strings).Example:
https://example.com/?type=kc85_4is parsed identically to the command line argumenttype=kc85_4.#include "sokol_args.h" int main(int argc, char* argv[]) { sargs_setup(&(sargs_desc){ .argc=argc, .argv=argv }); if (sargs_exists("type")) { if (sargs_equals("type", "kc85_4")) { // logic for kc85_4 } } sargs_shutdown(); return 0; }Update language bindings using gen_all.py
masterTo update the language bindings for various languages (Zig, Nim, Odin, Rust, D, Jai, C3), ensure that
clangandpython3are installed and available in your system PATH.Follow these steps:
- Navigate to the
sokol/bindgendirectory. - Clone the target language repositories (e.g.,
sokol-zig,sokol-nim, etc.). - Execute the generation script
python3 gen_all.py.
cd sokol/bindgen git clone https://github.com/floooh/sokol-zig git clone https://github.com/floooh/sokol-nim git clone https://github.com/floooh/sokol-odin git clone https://github.com/floooh/sokol-rust git clone https://github.com/floooh/sokol-d git clone https://github.com/colinbellino/sokol-jai git clone https://github.com/floooh/sokol-c3 python3 gen_all.py- Navigate to the
Use sokol_app.h for cross-platform application wrapping
mastersokol_app.h provides a unified application entry point and window/canvas management for 3D rendering. It supports multiple platforms (Win32, MacOS, Linux, iOS, WASM, Android, UWP) and 3D APIs (GL3.3, Metal, D3D11, GLES3/WebGL2).
To use it, implement a
sokol_mainfunction that returns asapp_descstructure containing callbacks for initialization (init_cb), per-frame updates (frame_cb), and cleanup (cleanup_cb).#include "sokol_app.h" #include "sokol_gfx.h" #include "sokol_log.h" #include "sokol_glue.h" #include "triangle-sapp.glsl.h" static void init(void) { // initialization logic } void frame(void) { // per-frame rendering logic } void cleanup(void) { // cleanup logic } sapp_desc sokol_main(int argc, char* argv[]) { (void)argc; (void)argv; return (sapp_desc){ .init_cb = init, .frame_cb = frame, .cleanup_cb = cleanup, .width = 640, .height = 480, .window_title = "Triangle", .icon.sokol_default = true, .logger.func = slog_func, }; }Regenerate embedded shaders with shdgen
masterThe
shdgenscript is a helper used to regenerate embedded shaders. It requiresdenoto be available in your system path and a logged-ingh(GitHub CLI) client, as it generates HLSL binaries remotely using a GitHub Actions Windows VM.macOS Setup: Clone
https://github.com/floooh/sokol-tools-binto a location adjacent to thesokoldirectory before running the script.Warning: This tool is intended for internal use only and may not function correctly on all local environments.
deno run --allow-all shdgen.tsInstall dependencies on Windows via Scoop
masterIf you are on Windows, you can install the required dependencies (
llvmforclangandpython) using thescooppackage manager.scoop install llvm scoop install pythonUse sokol_audio.h for audio streaming
mastersokol_audio.h is a minimal API for streaming 32-bit float mono or stereo samples. It supports WASAPI (Windows), CoreAudio (macOS/iOS), ALSA (Linux), and WebAudio (Emscripten).
There are two models for providing audio data:
- Callback Model: Provide a
stream_cbfunction that is called in the audio thread to fill the buffer directly. - Push Model: Use
saudio_push()from your main loop or a separate thread to send small packets of audio data.
- Callback Model: Provide a
Use sokol_fetch.h to load files or stream HTTP data
mastersokol_fetch.h allows loading files from the local filesystem (native) or streaming data over HTTP (WASM/Emscripten).
Key Requirements:
- Call
sfetch_setup()during initialization. - Call
sfetch_dowork()once per frame to process asynchronous requests. - Call
sfetch_shutdown()during cleanup. - Use
sfetch_send()to initiate a request. The response is handled in a callback function.
#include "sokol_fetch.h" #include "sokol_log.h" static void response_callback(const sfetch_response_t* response); #define MAX_FILE_SIZE (1024*1024) static uint8_t buffer[MAX_FILE_SIZE]; static void init(void) { sfetch_setup(&(sfetch_desc_t){ .logger.func = slog_func }); sfetch_send(&(sfetch_request_t){ .path = "hello_world.txt", .callback = response_callback, .buffer_ptr = buffer, .buffer_size = sizeof(buffer) }); } static void frame(void) { sfetch_dowork(); } static void response_callback(const sfetch_response_t* response) { if (response->fetched) { const void* data = response->buffer_ptr; uint64_t data_size = response->fetched_size; } if (response->failed) { switch (response->error_code) { case SFETCH_ERROR_FILE_NOT_FOUND: ... case SFETCH_ERROR_BUFFER_TOO_SMALL: ... } } } static void shutdown(void) { sfetch_shutdown(); }- Call
Troubleshoot Sokol build and link errors
masterIf your Sokol integration fails to compile or link, check the following common configuration mismatches:
Implementation Definition
Define
SOKOL_IMPL(or the specific per-headerSOKOL_*_IMPL) in exactly one C or C++ translation unit before including the headers. All other files should include the headers without this define.Backend Selection
Select exactly one rendering backend in your implementation translation unit. Common defines include:
SOKOL_GLCORE(uses GLX on Linux by default; useSOKOL_FORCE_EGLfor EGL)SOKOL_GLES3(requires-s USE_WEBGL2=1for Emscripten WebGL2 builds)SOKOL_D3D11(MinGW/MSYS2 may need-ld3d11)SOKOL_METAL(macOS/iOS: compile implementation as Objective-C/Objective-C++.mor.mmand link required frameworks)SOKOL_WGPU(WebGPU)SOKOL_VULKAN
Note: If using
sokol_gfx.handsokol_app.htogether, they must use the same backend define.Shader Compatibility
Ensure generated shader headers are from a
sokol-shdcversion compatible with your Sokol headers and were generated for the same backend(s) selected at compile time.Run Zig samples after updating bindings
masterAfter updating the bindings, you can test the Zig implementation by running the provided samples using the Zig build system.
cd sokol/bindgen/sokol-zig zig build run-clear zig build run-triangle zig build run-cubeImplement the sokol_audio.h callback model
masterUse the callback model to generate audio directly in the audio thread. This is efficient for continuous streams like oscillators.
// the sample callback, running in audio thread static void stream_cb(float* buffer, int num_frames, int num_channels) { assert(1 == num_channels); static uint32_t count = 0; for (int i = 0; i < num_frames; i++) { buffer[i] = (count++ & (1<<3)) ? 0.5f : -0.5f; } } int main() { // init sokol-audio with default params saudio_setup(&(saudio_desc){ .stream_cb = stream_cb, .logger.func = slog_func, }); // run main loop ... // shutdown sokol-audio saudio_shutdown(); return 0; }Run shdgen from a specific feature branch
masterTo run the
shdgenshader regeneration script against a specific feature branch, use the--branchflag.deno run --allow-all shdgen.ts --branch [name]