This code is terribly outdated.
There are "official" (and more importantly, auto-generated) Rust bindings now. Head over to sokol-rust to check them out.
This repository contains source code of the following Rust library crates:
- sokol (README) - Rust bindings to the sokol header-only, cross-platform libraries.
- sokol-imgui (README) - Rust bindings to the
sokol_imguiandsokol_gfx_imguiutility libraries. - sokol-sys (README) - system crate to compile native dependencies shared by other crates.
To complement the crates above:
- sokol-stb - a library for easy access to a subset of the stb libraries.
- sokol-samples - a number of examples ported from sokol-samples.
The current version compiles (and has been tested) with stable Rust (v1.34.1) on Windows (both MSVC and GNU toolchains), MacOS and Linux.
> git clone --recursive https://github.com/code-disaster/sokol-rs
> cd sokol-rs
> cargo build
The sokol-samples folder contains some examples ported from sokol-samples/sapp.
> cargo run --bin clear-sapp
In the C version of sokol_app, when compiled with SOKOL_NO_ENTRY, you call sapp_run(), passing callback function pointers for setup, frame updates, and cleanup.
In the Rust version, you call sokol::app::sapp_run(). This hands over control to the C library, which then will operate as usual. The C callbacks are implemented by sokol-rs. They are forwarded to your application via the SApp trait. User applications implement this trait to power the application loop.
Check the clear-sapp sample for a minimal implementation.
I tried to stay as close as possible to the source, while adjusting to the Rust naming conventions, as well as making the public API more convenient in places a direct port would be too cumbersome.
- Function names stay the same. No change here.
- Function signatures are identical most of the time. In some rare cases, I moved parameters out of structs and pass them as additional function parameters.
- Type names are renamed, e.g.
sapp_desc->SAppDesc. - Some identifiers, like "type", had to be renamed because they clash with reserved keywords in Rust.
- Element names in enums are shortened and changed to CamelCase, e.g.
sapp_event_type::SAPP_EVENTTYPE_RESIZEDbecomesSAppEventType::Resized. On the plus side, they are all totally type-safe now. - I tried to stay true to the C99-style struct initializers - check the samples to see what it looks like. Since Rust forces you to initialize all struct members, most of them enable
#[derive(Default)]so that you are still able to only set the options you are interested in - everything else can be initialized to sokol's default values with..Default::default(). - Arrays in structs, which are all fixed-sized in sokol, are initialized using
Vec<T>in public declarations. This is because they can be set conveniently withvec![], so you don't have to keep an eye on the array size, and/or spatterDefault::default()all over the place. (I tried to be clever and use macro magic to make this part even more convenient while not paying the Vec<> allocation overhead, but I'm not nearly clever enough with Rust... yet.)
In the Rust library, the app, gfx and audio modules are not as separable as their C counterparts. Essentially, sokol-rs assumes that you use them in conjunction.
sg_setup()usesappfunctions to configure the render backend.- If
saudio_setup()is told to use callbacks, the function callback is part of theSApptrait (and, as a matter of fact, managed by theappmodule in most parts).
The following libraries are implemented:
| header | Rust module | status | notes |
|---|---|---|---|
| sokol_app.h | sokol::app |
done | |
| sokol_args.h | n/a | n/a | low priority: there are many cmdline parsers for Rust already |
| sokol_audio.h | sokol::audio |
done | callback API via trait in sokol::app |
| sokol_gfx.h | sokol::gfx |
mostly done | trace hooks are enabled (and consumed by the sokol_gfx_imgui implementation in the sokol-imgui crate)missing: separate resource management, render contexts, user-provided buffers not implemented: sg_query_*_info() functions |
| sokol_time.h | sokol::time |
done |
Additionally, some utility libraries are available:
| header | Rust module | status | notes |
|---|---|---|---|
| sokol_gfx_imgui.h | sokol_imgui::gfx |
partially done |
sg_imgui_t is wrapped opaquely instead of replicated in Rustmissing: sg_imgui_draw_*_content and sg_imgui_draw_*_window functions |
| sokol_gl.h | n/a | n/a | no plans yet |
| sokol_imgui.h | sokol_imgui::imgui |
done |
gfxis configured to use the "native" render API on each platform:- Windows (MSVC): Direct3D 11
- Windows (not MSVC, tested with
x86_64-pc-windows-gnu): OpenGL 3.3 - MacOS: Metal
- Linux: OpenGL 3.3
x86_64-pc-windows-gnuuses GL33 because sokol_gfx fails to compile for Direct3D 11 with gcc on MinGW64. I didn't invest much time to figure out why.