Cross-platform game engine in Rust.

Overview

macroquad

Github Actions Docs Crates.io version Discord chat

macroquad is a simple and easy to use game library for Rust programming language, heavily inspired by raylib.

macroquad attempts to avoid any Rust-specific programming concepts like lifetimes/borrowing, making it very friendly for Rust beginners. See the docs.

Features

  • Same code for all supported platforms, no platform dependent defines required
  • Efficient 2D rendering with automatic geometry batching
  • Minimal amount of dependencies: build after cargo clean takes only 16s on x230(~6years old laptop)
  • Immediate mode UI library included
  • Single command deploy for both WASM and Android build instructions

Supported platforms

  • PC: Windows/Linux/MacOs
  • HTML5
  • Android
  • IOS

Build instructions

Setting up a macroquad project

Macroquad is a normal rust dependency, therefore an empty macroquad project may be created with:

# Create empty cargo project
cargo init --bin

Add macroquad as a dependency to Cargo.toml:

[dependencies]
macroquad = "0.3"

Put some macroquad code in src/main.rs:

use macroquad::prelude::*;

#[macroquad::main("BasicShapes")]
async fn main() {
    loop {
        clear_background(RED);

        draw_line(40.0, 40.0, 100.0, 200.0, 15.0, BLUE);
        draw_rectangle(screen_width() / 2.0 - 60.0, 100.0, 120.0, 60.0, GREEN);
        draw_circle(screen_width() - 30.0, screen_height() - 30.0, 15.0, YELLOW);

        draw_text("IT WORKS!", 20.0, 20.0, 30.0, DARKGRAY);

        next_frame().await
    }
}

And to run it natively:

cargo run

For more examples take a look on Macroquad examples folder

linux

# ubuntu system dependencies
apt install pkg-config libx11-dev libxi-dev libgl1-mesa-dev libasound2-dev

# fedora system dependencies
dnf install libX11-devel libXi-devel mesa-libGL-devel alsa-lib-devel

# arch linux system dependencies
 pacman -S pkg-config libx11 libxi mesa-libgl alsa-lib

windows

On windows both MSVC and GNU target are supported, no additional dependencies required.

Also cross-compilation to windows from linux is supported:

rustup target add x86_64-pc-windows-gnu

cargo run --target x86_64-pc-windows-gnu

wasm

rustup target add wasm32-unknown-unknown
cargo build --target wasm32-unknown-unknown

This will produce .wasm file in target/debug/wasm32-unknown-unknown/CRATENAME.wasm or in target/release/wasm32-unknown-unknown/CRATENAME.wasm if built with --release.

And then use the following .html to load it:

index.html
TITLE ">
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>TITLEtitle>
    <style>
        html,
        body,
        canvas {
            margin: 0px;
            padding: 0px;
            width: 100%;
            height: 100%;
            overflow: hidden;
            position: absolute;
            background: black;
            z-index: 0;
        }
    style>
head>

<body>
    <canvas id="glcanvas" tabindex='1'>canvas>
    
    <script src="https://not-fl3.github.io/miniquad-samples/mq_js_bundle.js">script>
    <script>load("CRATENAME.wasm");script>  body> html>

One of the ways to server static .wasm and .html:

cargo install basic-http-server
basic-http-server .
tips Adding the following snippet to your Cargo.toml ensures that all dependencies compile in release even in debug mode. In macroquad, this has the effect of making images load several times faster and your applications much more performant, while keeping compile times miraculously low.
[profile.dev.package.'*']
opt-level = 3

async/await

While macroquad attempts to use as few Rust-specific concepts as possible, .await in all examples looks a bit scary. Rust's async/await is used to solve just one problem - cross platform main loop organization.

details

The problem: on WASM and android it's not really easy to organize the main loop like this:

fn main() {
    // do some initialization

    // start main loop
    loop {
        // handle input

        // update logic

        // draw frame
    }
}

It is fixable on Android with threads, but on web there is not way to "pause" and "resume" WASM execution, so no WASM code should block ever. While that loop is blocking for the entire game execution! The C++ solution for that problem: https://kripken.github.io/blog/wasm/2019/07/16/asyncify.html

But in Rust we have async/await. Rust's futures is basically a continuations - future's stack may be store into a variable to later pause/resume execution of future's code.

async/await in macroquad is used without any external dependencies - no runtime, executor or even futures-rs are involved. It's just a way to preserve main's stack on WASM and keep the code cross platform without any WASM-specific main loop.

Community

  • Quads Discord server - a place to chat with the library's devs and other community members.
  • Awesome Quads - a curated list of links to miniquad/macroquad-related code & resources.

Platinum sponsors

Macroquad is supported by:

Comments
  • Allow users to use arbitrary futures

    Allow users to use arbitrary futures

    fixes #286

    In the future (haha), when we get a pending future, we could even consider sleeping/yielding the current thread until a waker has been invoked.

    Some background on why I hit this:

    I had to wait for a callback in some js code that I invoked. I didn't want to just loop until the value is created (not even sure that would work), so I tried implementing a future. I did a trivial one first, that didn't use wakers and just returned pending as long as there was no value. That just caused the entire macroquad state to get stuck somewhere, since I wasn't using the ExecState datastructure. I didn't know about that yet, so I tried implementing a waker system by sending a boxed waker to js and creating a wasm callback that js can call in order to wake the waker. So good so far, but then the wasm crashed with an index out of bounds. Some debugging later I land in the resume function and am trying to understand what is going on. Some research on futures, contexts and wakers later I opened #286. It wasn't quite as easy as I thought in the issue, but this PR has no user-visible changes, except that custom futures now work.

    If you like this change, I could later also add some helpers (probably to sapp-jsutils) to make it easier for people to write their own futures that wrap a js callback/promise.

    opened by oli-obk 20
  • Using wasm with macroquad

    Using wasm with macroquad

    I came by this library because I heard its very simple and can compile into wasm. I copied one of the examples and it worked but when i tried to put it on web with the instructions, i kept seeing the same error. I even cloned one of the examples and did the exact steps and i got the same error. The error was : image Please help!!

    opened by ZeroTixDev 16
  • Constrain Mouse To Window (For First Person Camera infinite mouse scrolling)

    Constrain Mouse To Window (For First Person Camera infinite mouse scrolling)

    I'm trying to get a first person 3D camera to work. Currently, I can successfully fly around the world and look using the mouse.

    However, when the mouse reaches the edge of the screen, it hits the edge and no longer gives any mouse position information.

    There are 2 ways to solve this that I can see:

    1. Keep sending mouse events when mouse is outside the window.
    2. Allow the user to set the mouse position so they can control wrapping the mouse when it goes outside the window.

    I don't know if Sokol uses GLFW but in Raylib (GLFW), I have this same problem on Linux. Not quite sure how to solve it without a way to set the cursor position.

    Note: I have used the ctx.set_cursor_grab(true) and ctx.show_mouse(false) functions and it doesn't change the above behavior.

    Alternatively, if another 3D example could be created that tests the mouse look and screen border interaction that would be amazing.

    Here is what I've got so far for reference:

    use macroquad::prelude::*;
    // use glam::vec3;
    
    const MOVE_SPEED: f32 = 0.1;
    const LOOK_SPEED: f32 = 0.1;
    
    
    fn conf() -> Conf
    {
        Conf {
            window_title: String::from("Macroquad"),
            window_width: 1260,
            window_height: 768,
            fullscreen: true,
            ..Default::default()
        }
    }
    
    #[macroquad::main(conf)]
    async fn main() {
        let InternalGlContext { quad_context: ctx, ..} = unsafe { get_internal_gl() };
    
        ctx.show_mouse(false);
        ctx.set_cursor_grab(true);
    
        let dirt = load_texture("Dirt.png").await;
        dirt.set_filter(ctx, FilterMode::Nearest);
    
        let mut x = 0.0;
        let mut switch = false;
        let bounds = 8.0;
    
    
        let world_up = vec3(0.0, 1.0, 0.0);
        let mut yaw: f32 = 0.0;
        let mut pitch: f32 = 0.0;
    
        let mut facing = vec3(
            yaw.cos() * 1.0,
            0.0,
            yaw.sin() * 1.0
        ).normalize();
    
        let mut front = vec3(
            yaw.cos() * pitch.cos(),
            pitch.sin(),
            yaw.sin() * pitch.cos()
        ).normalize();
        let mut right = front.cross(world_up).normalize();
        let mut up;
    
        let mut position = vec3(0.0, 1.0, 0.0);
        let mut last_mouse_position: Vec2 = mouse_position().into();
    
        let mut own_mouse_position = vec2(0.0, 0.0);
    
        loop {
            let delta = get_frame_time();
            
            if is_key_pressed(KeyCode::Escape) { break; }
    
            if is_key_down(KeyCode::Up) { position += front * MOVE_SPEED; }
            if is_key_down(KeyCode::Down) { position -= front * MOVE_SPEED; }
            if is_key_down(KeyCode::Left) { position -= right * MOVE_SPEED; }
            if is_key_down(KeyCode::Right) { position += right * MOVE_SPEED; }
    
            let mouse_position: Vec2 = mouse_position().into();
            let mouse_delta = mouse_position - last_mouse_position;
            last_mouse_position = mouse_position;
    
            yaw += mouse_delta.x * delta * LOOK_SPEED;
            pitch += mouse_delta.y * delta * -LOOK_SPEED;
    
            pitch = if pitch > 1.5 { 1.5 } else { pitch };
            pitch = if pitch < -1.5 { -1.5 } else { pitch };
    
            facing = vec3(
                yaw.cos() * 1.0,
                0.0,
                yaw.sin() * 1.0
            ).normalize();
        
            front = vec3(
                yaw.cos() * pitch.cos(),
                pitch.sin(),
                yaw.sin() * pitch.cos()
            ).normalize();
    
            right = front.cross(world_up).normalize();
            up = right.cross(front).normalize();
    
    
            x += if switch { 0.04 } else { -0.04 };
            if x >= bounds || x <= -bounds { switch = !switch; }
    
            clear_background(Color::new(1.0, 0.7, 0.0, 1.0));
    
            // Going 3d!
    
            set_camera(Camera3D {
                position: position,
                up: up,
                target: position + front,
                ..Default::default()
            });
    
            draw_grid(20, 1.);
    
            draw_line_3d(vec3(x, 0.0, x), vec3(5.0, 5.0, 5.0), Color::new(1.0, 1.0, 0.0, 1.0));
    
            draw_cube_wires(vec3(0., 1., -6.), vec3(2., 2., 2.), DARKGREEN);
            draw_cube_wires(vec3(0., 1., 6.), vec3(2., 2., 2.), DARKBLUE);
            draw_cube_wires(vec3(2., 1., 2.), vec3(2., 2., 2.), YELLOW);
    
            draw_cube(vec3(x, 1., x), vec3(2., 2., 2.), dirt, WHITE);
    
            // Back to screen space, render some text
    
            set_default_camera();
            draw_text("WELCOME TO 3D WORLD", 10.0, 20.0, 30.0, BLACK);
    
            draw_text(format!("X: {} Y: {}", own_mouse_position.x, own_mouse_position.y).as_str(), 10.0, 48.0, 30.0, BLACK);
            draw_text(format!("X: {} Y: {}", mouse_position.x, mouse_position.y).as_str(), 10.0, 48.0 + 18.0, 30.0, BLACK);
    
            next_frame().await
        }
    }
    
    opened by Pebaz 14
  • [Question] How to limit FPS?

    [Question] How to limit FPS?

    I want to test wether delta time in my game works as expected and want to test the game on different fps, but there's no function to do that, can you add one, please? It's not even necessary for it to work on all platforms, just desktop would be nice, for debugging and stuff.

    opened by alexmozaidze 12
  • screen_width/height wrong before resize

    screen_width/height wrong before resize

    easiest to see in the camera example (note the debug logging for the screen size I added)

    use macroquad::prelude::*;
    
    #[macroquad::main("Camera")]
    async fn main() {
        loop {
            clear_background(RED);
    
            // Render some primitives in camera space
    
            debug!("size: {},{}",screen_width() ,screen_height());
    
            set_camera(Camera2D {
                zoom: vec2(1., screen_width() / screen_height()),
                ..Default::default()
            });
            draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
            draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
            draw_circle(0., 0., 0.1, YELLOW);
    
            // Back to screen space, render some text
    
            set_default_camera();
            draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
    
            next_frame().await
        }
    }
    

    leads to this output:

    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    size: 1600,1200
    resize_event: 807,606
    size: 807,606
    ....
    

    the window looks like this before I resize (this is not 1600x1200): image

    after a tiny resize it has the correct values and the camera works: image

    note that I am testing this on MacOS

    opened by extrawurst 10
  • Android keyboard support

    Android keyboard support

    On android, there is currently no way to input anything that takes keyboard input, not even with a bluetooth keyboard. If that could be implemented, then people would be able to make android apps much easier.

    opened by sonicrules1234 9
  • button hitbox is offset from where the button actually is

    button hitbox is offset from where the button actually is

    using this code

    use macroquad::prelude::*;
    use macroquad::math::vec2;
    use macroquad::ui::{root_ui, widgets};
    #[macroquad::main("button testing")]
    async fn main() {
        loop {
            clear_background(BLACK);
            if widgets::Button::new("push me").size(vec2(100.0, 100.0)).position(vec2(100.0, 100.0)).ui(&mut *root_ui()) {
                println!("button was pushed");
            }
            next_frame().await;
        }
    }
    

    This shows up The yellow rectangle was added in by me to show approximately where the button could be clicked, and it doesn't line up with the actual button button testing The hitbox (clickbox?) seems to have different offsets if I move the button to different parts of the screen. However, it always offsets towards the top left of the button. any help?

    help wanted 
    opened by Eisverygoodletter 8
  • shadertoy example

    shadertoy example

    Could not run shadertoy example. rustc spits out this

    thread 'main' panicked at 'Not such texture: rust.png', src/texture.rs:20:50
    

    But the error message is clear and reason is obvious, so I sorted it out. But the question remains. Would not it be better to update paths to run from the root of the crate, without going under /examples? Totally for you to decide. The demo is AWESOME. Especially when I am learning shaders now and able to understand how it works.

    opened by alekspickle 8
  • Problem building WASM

    Problem building WASM

    Looking into using macroquad for a WASM prototype. For some reason the WASM build seems to be failing on a missing import.

    image

    Just following the documentation, and double checked everything. gl.js which is placed online maybe outdated?

    Great work on the implementation, and fundamental choices.

    opened by boymaas 8
  • Implemented Hexadecimal to RGBA color conversion

    Implemented Hexadecimal to RGBA color conversion

    • Added hexadecimal.rs file with: hex_to_u8 and hex_pair_to_u8 functions

    • added Color::from_hex that converts a hexadecimal str in the format of "#RRGGBB" or "#RRGGBBAA"

    • I know the code isn't the best, but I've wanted this function for a while

    opened by eboatwright 6
  • Docker build for android:

    Docker build for android: "failed to fetch `https://github.com/rust-lang/crates.io-index`"

    It seems docker build has some certificates related issue:

    docker run --rm -v $(pwd):/root/src -w /root/src notfl3/cargo-apk cargo quad-apk build --release
        Updating crates.io index
    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Unable to update registry `crates-io`
    
    Caused by:
        0: failed to fetch `https://github.com/rust-lang/crates.io-index`
        1: network failure seems to have happened
           if a proxy or similar is necessary `net.git-fetch-with-cli` may help here
           https://doc.rust-lang.org/cargo/reference/config.html#netgit-fetch-with-cli
        2: the SSL certificate is invalid; class=Ssl (16); code=Certificate (-17)', src/ops/build/util.rs:202:6
    
    opened by geloizi 6
  • Request: New Image::set_image_data() to match the existing Image::get_image_data()

    Request: New Image::set_image_data() to match the existing Image::get_image_data()

    Background of request

    Currently Image::get_image_data() is defined as fn(&self) -> &[[u8; 4]], which is great. However Image::update() is defined as fn update(&mut self, colors: &[Color]).

    This creates a situation where you are forced to create a &[Color] array in order to update the image.

    Suggestion

    I would like to request a Image::set_image_data() which would be defined as something like fn set_image_data(&mut self, data: [[u8; 4]]). This makes easy to understand "get/set" functions and minimal type changes are forced.

    opened by Alendri 0
  • Macroquad camera follow Player

    Macroquad camera follow Player

    Hello, I want to ask about camera follow player. I've tried but my camera still can't follow the player movement. How to fix it? My code is like this. I've tried to follow like raylib but my camera still can't follow player movement. Thank you for help

    use macroquad::prelude::*;
    
    struct Player {
        position: Vec2,
        size: Vec2,
    }
    
    
    #[macroquad::main("Camera")]
    async fn main() {
        request_new_screen_size(800.0, 450.0);
    
        let mut player = Player {
            position: vec2(400.0, 280.0),
            
            size: vec2(40.0, 40.0),
        };
    
        let mut camera = Camera2D {
            target : player.position,
            offset : vec2(screen_width() / 2.0, screen_height() / 2.0),
            rotation : 0.0,
            zoom : vec2(1.0 /screen_width(), -1.0 / screen_height()),
            render_target : Some(render_target(player.position.x as u32, player.position.y as u32)),
            viewport : None
        };
    
        loop {
    
            if is_key_down(KeyCode::Right) {
                player.position.x += 1.0 ;
            }
            if is_key_down(KeyCode::Left) {
                player.position.x -= 1.0 ;
            }
            if is_key_down(KeyCode::Down) {
                player.position.y += 1.0;
            }
            if is_key_down(KeyCode::Up) {
                player.position.y -= 1.0;
            }
    
            camera.target = vec2(player.position.x + 20.0, player.position.y + 20.0);
    
            clear_background(LIGHTGRAY);
    
            set_camera(&camera);
            
            draw_rectangle(
                player.position.x,
                player.position.y,
                player.size.x,
                player.size.y,
                RED,
            );
    
            set_default_camera();
    
            draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
    
            next_frame().await
        }
    }
    

    The result like this image

    opened by Ananta98 1
  • Initial tree_node offset different (*not* high-dpi related)

    Initial tree_node offset different (*not* high-dpi related)

    I'm using the example UI code to illustrate this minor issue.

    Here's a cropped and enlarged screenshot showing the tree_nodes: enlarged_and_cropped

    I've intentionally prepended every item with the lowercase letter e to make it easier to spot the different offset. Every item, except the first one, is shifted by one pixel (but not cumulatively).

    This is not related to the high-dpi-problem: Not only is the behavior the same regardless of the display I used. I tried this with the most recent commit c82a67c (which includes #530 and #540) as well as with the version 0.3.23 (which is before the high-dpi-related fixes #464 and #522).

    P.S. You're doing a great job on macroquad, please don't interpret my issues as finicky ;-)

    opened by afischl 0
  • Regression in 0.3.14: UI layouts incorrectly when parent is smaller than child

    Regression in 0.3.14: UI layouts incorrectly when parent is smaller than child

    Regressed when moving from 0.3.13 to 0.3.14. When an UI element (here a Group is smaller or equal to its parent size, it moves down by its height.

    Minimum working example:

    fn conf() -> Conf {
        Conf {
            window_width: 800,
            ..Default::default()
        }
    }
    
    #[macroquad::main(conf)]
    async fn main() {
        loop {
            clear_background(GREEN);
            
            root_ui().group(hash!(), vec2(800.0, 200.0), |ui| {
                ui.label(vec2(20.0, 30.0), "Hello world");
            });
    
            next_frame().await
        }
    }
    

    | Version | Larger | Smaller | |-|-|-| | 0.3.13 | image < | image > | 0.3.14 - 0.3.25, master #50c8feb | image | image

    Discovered in Noxime/steamworks-rs#113

    opened by Noxime 0
  • Playing OGG files crashes in WASM on Safari/iOS

    Playing OGG files crashes in WASM on Safari/iOS

    Playing an OGG file crashes in Safari on Mac. It seems to be the same issue for iOS, as nothing happens, but I haven't checked the console. It works fine in Firefox and Chrome on Mac, as well as natively on Mac.

    Browser: Safari Version 16.1 (18614.2.9.1.12) OS: MacOS 13.0.1 (22A400) Ventura CPU: Apple M1 Max

    Macroquad: 0.3.25 quad-snd: 0.2.5

    Error message from javascript console in Safari:

    [Error] Failed to decode audio buffer – null
    	(anonymous function) (mq_js_bundle.js:1532)
    [Error] Unhandled Promise Rejection: EncodingError: Decoding failed
    	(anonymous function)
    	rejectPromise
    

    I've made a minimal example, which is basically just loading the test.ogg file from the quad-snd repo and playing it.

    #[macroquad::main("Safari sound issue")]
    async fn main() {
        let sound = load_sound("assets/test.ogg").await.unwrap();
        play_sound(
            sound,
            PlaySoundParams {
                looped: true,
                volume: 1.,
            },
        );
        loop {
            next_frame().await;
        }
    }
    

    Full example with compiled WASM demo: https://github.com/ollej/macroquad-safarisoundissue

    opened by ollej 4
Owner
Fedor Logachev
Fedor Logachev
Cross-platform compute shader engine

wgpu-compute-toy This is the compute shader engine for https://compute.toys As well as running on the web via WebAssembly and WebGPU, it can run nativ

compute.toys 37 May 9, 2023
Neutral cross-platform Rust game template

Rust Game Template Neutral cross-platform Rust game template. Build tool This project uses cargo-make task runner. It's required to build the project.

null 0 Feb 5, 2022
A cross platform classic RPG game creator written in Rust.

Eldiron - Classic RPG Creation Create RPGs for every platform with Eldiron. Eldiron v1 will be able to create games similar to the classic Ultima seri

Markus Moenig 164 Jan 2, 2023
A safe, fast and cross-platform 2D component-based game framework written in rust

shura shura is a safe, fast and cross-platform 2D component-based game framework written in rust. shura helps you to manage big games with a component

Andri 28 Jan 17, 2023
This is a cross-platform tool to historicize different branches/depots/manifests and generating pseudocode for it to compare different game updates

CSHP This is a cross-platform tool to historicize different branches/depots/manifests and generating pseudocode for it to compare different game updat

raizo 6 Jan 28, 2022
Minecraft-esque voxel engine prototype made with the bevy game engine. Pending bevy 0.6 release to undergo a full rewrite.

vx_bevy A voxel engine prototype made using the Bevy game engine. Goals and features Very basic worldgen Animated chunk loading (ala cube world) Optim

Lucas Arriesse 125 Dec 31, 2022
2-player game made with Rust and "ggez" engine, based on "Conway's Game of Life"

fight-for-your-life A 2-player game based on the "Conway's Game of Life", made with Rust and the game engine "ggez". Create shapes on the grid that wi

Petros 3 Oct 25, 2021
A game of snake written in Rust using the Bevy game engine, targeting WebGL2

Snake using the Bevy Game Engine Prerequisites cargo install cargo-make Build and serve WASM version Set your local ip address in Makefile.toml (loca

Michael Dorst 0 Dec 26, 2021
2d Endless Runner Game made with Bevy Game Engine

Cute-runner A 2d Endless Runner Game made with Bevy Game Engine. Table of contents Project Infos Usage Screenshots Disclaimer Project Infos Date: Sept

JoaoMarinho 2 Jul 15, 2022
A game made in one week for the Bevy engine's first game jam

¿Quien es el MechaBurro? An entry for the first Bevy game jam following the theme of "Unfair Advantage." It was made in one week using the wonderful B

mike 20 Dec 23, 2022
A Client/Server game networking plugin using QUIC, for the Bevy game engine.

Bevy Quinnet A Client/Server game networking plugin using QUIC, for the Bevy game engine. Bevy Quinnet QUIC as a game networking protocol Features Roa

Gilles Henaux 65 Feb 20, 2023
Solana Game Server is a decentralized game server running on Solana, designed for game developers

Solana Game Server* is the first decentralized Game Server (aka web3 game server) designed for game devs. (Think web3 SDK for game developers as a ser

Tardigrade Life Sciences, Inc 16 Dec 1, 2022
Cross-platform (including wasm) persistent key value store plugin for rust games/apps

bevy_pkv bevy_pkv is a cross-platform persistent key value store for rust apps. Use it for storing things like settings, save games etc. Currently, it

Johan Klokkhammer Helsing 25 Jan 9, 2023
Cross platform rendering in Rust

Miniquad Miniquad is a manifestation of a dream in a world where we do not need a deep dependencies tree and thousands lines of code to draw things wi

Fedor Logachev 937 Jan 4, 2023
Tiny cross-platform webview library for C/C++/Golang. Uses WebKit (Gtk/Cocoa) and Edge (Windows)

webview A tiny cross-platform webview library for C/C++/Golang to build modern cross-platform GUIs. Also, there are Rust bindings, Python bindings, Ni

webview 10.8k Jan 9, 2023
IDE for cross-platform software development

Diversity Space IDE for cross-platform software development | 日本語 | English | Русский | READMEの英語版とロシア語版はDeepl翻訳を使用して翻訳されています Английская и русская вер

latteS 0 Feb 23, 2022
A cross platform (wasm included) networking library!

bootleg_networking A cross platform (wasm included) networking library! A networking plugin for the Bevy game engine that wraps around bevy_networking

William Batista 51 Jan 1, 2023
A lightweight, cross-platform epub reader.

Pend Pend is a program for reading EPUB files. Check out the web demo! Preview Image(s) Installation Building Pend is simple & easy. You should be abl

bx100 11 Oct 17, 2022
Cross-platform GPU-accelerated viewer for the Mandelbrot set and similar (escape-time) fractals

fractal_viewer A cross-platform, GPU-accelerated viewer for the Mandelbrot Set and related fractals. Try it online! Usage Scroll wheel to zoom, click

null 5 Jan 8, 2023