miniquad

repository·master·Indexed 24 days ago

https://github.com/not-fl3/miniquad

A lightweight, cross-platform graphics abstraction library (version 0.4.11) providing a consistent GPU interface across desktop, web, and mobile platforms. It supports Windows (OpenGL 3, 2.2), Linux (OpenGL, GLES), macOS (OpenGL 3, Metal), iOS (GLES, Metal), Android (GLES), and WASM (WebGL 1). The library features a minimal dependency design and includes the EventHandler trait for processing user input and application lifecycle events.

Tokens
7.9K
Snippets
20
Records
42
Agent score
85%

What's inside miniquad

  1. Overview of Miniquad

    master
    Miniquad is a lightweight graphics abstraction library designed to provide a consistent API across different platforms with a GPU. It aims to minimize dependencies and code complexity while maintaining high performance and cross-platform compatibility.
  2. Supported Platforms and Graphics APIs

    master

    Miniquad supports a wide range of platforms and graphics backends:

    • Windows: OpenGL 3, OpenGL 2.2
    • Linux: OpenGL 2.2, OpenGL 3, GLES 2, GLES 3
    • macOS: OpenGL 3, Metal
    • iOS: GLES 2, GLES 3, Metal
    • WASM: WebGL 1 (tested on iOS Safari, Firefox, Chrome)
    • Android: GLES 2, GLES 3
  3. Build for WASM (WebAssembly)

    master

    To target the web, add the wasm32-unknown-unknown target and build the example. To serve the resulting .wasm and .html files, you can use basic-http-server.

    Build command:

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

    Serving the files:

    cargo install basic-http-server
    basic-http-server .
  4. Build and run examples on Windows

    master

    Miniquad supports both MSVC and GNU targets on Windows. First, add the desired target, then run the example.

    Using MSVC:

    rustup target add x86_64-pc-windows-msvc
    cargo run --example quad

    Using GNU:

    rustup target add x86_64-pc-windows-gnu
    cargo run --example quad
    # both MSVC and GNU target is supported:
    rustup target add x86_64-pc-windows-msvc
    # or
    rustup target add x86_64-pc-windows-gnu
    
    cargo run --example quad
  5. Cross-compile Windows targets from Linux

    master

    You can cross-compile for Windows from a Linux host by adding the x86_64-pc-windows-gnu target and running the example with that target specified.

    rustup target add x86_64-pc-windows-gnu
    cargo run --example quad --target x86_64-pc-windows-gnu
    # windows target from linux host:
    # this is how windows builds are tested from linux machine:
    rustup target add x86_64-pc-windows-gnu
    cargo run --example quad --target x86_64-pc-windows-gnu
  6. Run on iOS Simulator

    master

    To run your game on the iOS simulator, follow these steps to create an .app bundle, copy your binary and assets, and install it via xcrun.

    1. Create the app directory and build the target:
      mkdir MyGame.app
      cargo build --target x86_64-apple-ios --release
      cp target/release/mygame MyGame.app
    2. Copy assets (if applicable):
      cp -r assets MyGame.app
    3. Create the Info.plist:
      cat > MyGame.app/Info.plist << EOF
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
      <key>CFBundleExecutable</key>
      <string>mygame</string>
      <key>CFBundleIdentifier</key>
      <string>com.mygame</string>
      <key>CFBundleName</key>
      <string>mygame</string>
      <key>CFBundleVersion</key>
      <string>1</string>
      <key>CFBundleShortVersionString</key>
      <string>1.0</string>
      </dict>
      </plist>
      EOF
    4. Install and launch:
      xcrun simctl install booted MyGame.app/
      xcrun simctl launch booted com.mygame
    mkdir MyGame.app
    cargo build --target x86_64-apple-ios --release
    cp target/release/mygame MyGame.app
    # only if the game have any assets
    cp -r assets MyGame.app
    cat > MyGame.app/Info.plist << EOF
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>CFBundleExecutable</key>
    <string>mygame</string>
    <key>CFBundleIdentifier</key>
    <string>com.mygame</string>
    <key>CFBundleName</key>
    <string>mygame</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    </dict>
    </plist>
    EOF
    
    xcrun simctl install booted MyGame.app/
    xcrun simctl launch booted com.mygame
  7. Build for Android using Docker

    master

    The recommended way to build for Android is using Docker with a modified version of cargo-apk. This command builds the quad example and places the APK in target/android-artifacts/(debug|release)/apk.

    docker run --rm -v $(pwd)":/root/src" -w /root/src notfl3/cargo-apk cargo quad-apk build --example quad

    With log-impl enabled, all log calls are forwarded to the adb console. No code modifications are required for Android.

  8. Manage the Frame Lifecycle

    master

    The rendering lifecycle follows this pattern:

    1. Begin Pass: Use begin_default_pass to render to the screen or begin_pass(Some(render_pass), action) to render to an offscreen target.
    2. Clear: Use clear to reset color, depth, or stencil buffers.
    3. Draw: Apply pipeline, bindings, uniforms, and call draw.
    4. End Pass: Call end_render_pass to finish the current pass.
    5. Commit: Call commit_frame to finalize the frame.
  9. Load WASM in HTML

    master

    When building for WASM, use the following HTML structure to load your compiled .wasm file. Ensure the gl.js script source matches the version used by Miniquad samples.

    <html lang="en">
    
    <head>
        <meta charset="utf-8">
        <title>TITLE</title>
        <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>
        <!-- Minified and statically hosted version of https://github.com/not-fl3/miniquad/blob/master/native/sapp-wasm/js/gl.js -->
        <script src="https://not-fl3.github.io/miniquad-samples/gl.js"></script>
        <script>load("quad.wasm");</script> <!-- Your compiled wasm file -->
    </body>
    
    </html>
  10. Create and manage GPU buffers

    master

    Buffers are used to store vertex, index, or uniform data. Use new_buffer to create a resource and buffer_update to modify its contents.

    #[repr(C)]
    struct Vertex {
        pos: Vec2,
        uv: Vec2,
    }
    let vertices: [Vertex; 4] = [
        Vertex { pos : Vec2 { x: -0.5, y: -0.5 }, uv: Vec2 { x: 0., y: 0. } },
        Vertex { pos : Vec2 { x:  0.5, y: -0.5 }, uv: Vec2 { x: 0., y: 1. } },
        Vertex { pos : Vec2 { x:  0.5, y:  0.5 }, uv: Vec2 { x: 1., y: 1. } },
        Vertex { pos : Vec2 { x: -0.5, y:  0.5 }, uv: Vec2 { x: 0., y: 1. },
    ];
    let buffer = ctx.new_buffer(
        BufferType::VertexBuffer,
        BufferUsage::Immutable,
        BufferSource::slice(&vertices),
    );
  11. Apply Pipeline and Bindings

    master

    To render, you must apply a Pipeline and set the Bindings (buffers and textures).

    • Pipeline: Created via new_pipeline with buffer layouts, vertex attributes, a shader, and pipeline parameters. Apply it using apply_pipeline.
    • Bindings: Use apply_bindings to set vertex buffers, an index buffer, and textures. You can also use apply_bindings_from_slice for manual control.
    • Uniforms: Use apply_uniforms to upload uniform data.
    • Viewport/Scissor: Use apply_viewport and apply_scissor_rect to define the rendering area. These should be applied after begin_pass.