RDR8/raylib-rs

Rust bindings for raylib

★ 0Forks 0RustGitHub ↗Compare

README

raylib-rs

raylib-rs is a simple, minimal Rust binding for raylib 2.0. It currently targets the stable Rust toolchain, version 1.26 or higher.

This is more or less a 1:1 mapping of C functions to Rust functions. However, resources are automatically cleaned up when they go out of scope (or when std::mem::drop is called), just like all other resources in Rust. This means that "Unload" functions are not exposed (and not necessary). Additional changes include:

  • Model::set_material, Material::set_shader, and MaterialMap::set_texture methods were added since one cannot set the fields directly. Also enforces correct ownership semantics.
  • Font::from_data, Font::set_chars, and Font::set_texture methods were added to create a Font from loaded CharInfo data.
  • SubText and FormatText are omitted, and are instead covered by Rust's string slicing and Rust's format! macro, respectively.

Disclaimer: I created this binding as a way to learn Rust. There may be some things I can do better, or make more ergonomic for users. Feel free to make suggestions!

Installation

So far, I have only tested on Windows. Tips on making things work smoothly on all platforms is appreciated.

(the git path below is temporary until raylib-rs is published to crates.io)

  1. Add the dependency to your Cargo.toml:
[dependencies]
raylib-rs = { git = "https://github.com/deltaphc/raylib-rs" }
  1. Download raylib 2.0 from https://github.com/raysan5/raylib/releases/tag/2.0.0, and pick the one that matches your Rust toolchain. MSVC with MSVC, MinGW with GNU, 32-bit or 64-bit.

  2. Copy libraylib.a (for MinGW) or raylib.lib (for MSVC) to the appropriate path in your Rust toolchain.

    • For rustup/MSVC: .rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib
    • For rustup/GNU: .rustup\toolchains\stable-x86_64-pc-windows-gnu\lib\rustlib\x86_64-pc-windows-gnu\lib
  3. Start coding!

extern crate raylib_rs;
use raylib_rs as ray; // or raylib_rs::* if you prefer

fn main() {
    ray::init_window(640, 480, "raylib-rs");

    while !ray::window_should_close() {
        ray::begin_drawing();

        ray::clear_background(ray::WHITE);
        ray::draw_text("Hello, world!", 12, 12, 20, ray::BLACK);

        ray::end_drawing();
    }

    ray::close_window();
}

Tech Notes

  • Structs holding resources have RAII/move semantics, including: Image, Texture2D, RenderTexture2D, Font, Mesh, Shader, Material, Model, Wave, Sound, Music, and AudioStream.
  • Functions dealing with string data take in &str and/or return an owned String, for the sake of safety.
  • In C, LoadFontData returns a pointer to a heap-allocated array of CharInfo structs. In this Rust binding, said array is copied into an owned Vec<CharInfo>, the original data is freed, and the owned Vec is returned.
  • In C, GetDroppedFiles returns a pointer to an array of strings owned by raylib. Again, for safety and also ease of use, this binding copies said array into a Vec<String> which is returned to the caller.
  • TraceLog functionality is actually reimplemented in Rust since the language does not have variadic functions in safe code, nor a way to unpack sequences into arguments (to my knowledge). However, since format! is variadic, one could use that macro in combination with trace_log to achieve the same effect.
  • The raw FFI binding was initially generated by bindgen and then hand-tweaked a bit.
  • I've tried to make linking automatic, though I've only tested on Windows. Other platforms may have other considerations.

Extras

  • In addition to the base library, there is also a convenient ease module which contains various interpolation/easing functions ported from raylib's easings.h, as well as a Tween struct to assist in using these functions.
  • Equivalent math and vector operations, ported from raymath.h, are impled on the various Vector and Matrix types. Operator overloading is used for more intuitive design.

Future Goals

  • Port raylib examples over to Rust.
  • Perhaps use Rust enums instead of consts.
  • More tests.
  • More platform testing.
  • Even more testing.
  • Physac port?

Issues