miniquad
repository·master·Indexed 24 days ago
https://github.com/not-fl3/miniquadA 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.
What's inside miniquad
- 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.
Supported Platforms and Graphics APIs
masterMiniquad 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
Build for WASM (WebAssembly)
masterTo target the web, add the
wasm32-unknown-unknowntarget and build the example. To serve the resulting.wasmand.htmlfiles, you can usebasic-http-server.Build command:
rustup target add wasm32-unknown-unknown cargo build --example quad --target wasm32-unknown-unknownServing the files:
cargo install basic-http-server basic-http-server .Build and run examples on Windows
masterMiniquad 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 quadUsing 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 quadCross-compile Windows targets from Linux
masterYou can cross-compile for Windows from a Linux host by adding the
x86_64-pc-windows-gnutarget 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-gnuBuild and run examples on Linux
masterTo run the
quadexample on Linux, use cargo:cargo run --example quadOn NixOS, you can use the provided
shell.nixto set up a development environment.Run on iOS Simulator
masterTo run your game on the iOS simulator, follow these steps to create an
.appbundle, copy your binary and assets, and install it viaxcrun.- 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 - Copy assets (if applicable):
cp -r assets MyGame.app - 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 - 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- Create the app directory and build the target:
Build for Android using Docker
masterThe recommended way to build for Android is using Docker with a modified version of
cargo-apk. This command builds thequadexample and places the APK intarget/android-artifacts/(debug|release)/apk.docker run --rm -v $(pwd)":/root/src" -w /root/src notfl3/cargo-apk cargo quad-apk build --example quadWith
log-implenabled, all log calls are forwarded to theadbconsole. No code modifications are required for Android.Manage the Frame Lifecycle
masterThe rendering lifecycle follows this pattern:
- Begin Pass: Use
begin_default_passto render to the screen orbegin_pass(Some(render_pass), action)to render to an offscreen target. - Clear: Use
clearto reset color, depth, or stencil buffers. - Draw: Apply pipeline, bindings, uniforms, and call
draw. - End Pass: Call
end_render_passto finish the current pass. - Commit: Call
commit_frameto finalize the frame.
- Begin Pass: Use
Load WASM in HTML
masterWhen building for WASM, use the following HTML structure to load your compiled
.wasmfile. Ensure thegl.jsscript 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>Create and manage GPU buffers
masterBuffers are used to store vertex, index, or uniform data. Use
new_bufferto create a resource andbuffer_updateto 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), );Apply Pipeline and Bindings
masterTo render, you must apply a
Pipelineand set theBindings(buffers and textures).- Pipeline: Created via
new_pipelinewith buffer layouts, vertex attributes, a shader, and pipeline parameters. Apply it usingapply_pipeline. - Bindings: Use
apply_bindingsto set vertex buffers, an index buffer, and textures. You can also useapply_bindings_from_slicefor manual control. - Uniforms: Use
apply_uniformsto upload uniform data. - Viewport/Scissor: Use
apply_viewportandapply_scissor_rectto define the rendering area. These should be applied afterbegin_pass.
- Pipeline: Created via