webglue

Crates.iowebglue
lib.rswebglue
version0.1.0
created_at2025-10-13 11:41:06.191095+00
updated_at2025-10-13 11:41:06.191095+00
descriptionOpenGL ES 3.0 / WebGL2 wrapper for Rust and WebAssembly
homepage
repositoryhttps://github.com/top-5/webglue
max_upload_size
id1880405
size125,042
Top-5 (top-5)

documentation

README

webglue

WebGL2 wrapper for Rust and WebAssembly

License Rust WASM

Overview

webglue is a WebGL2 wrapper for Rust that compiles to WebAssembly, providing an OpenGL-like API for browser-based 3D graphics.

โš ๏ธ This crate is WASM-only and must be compiled with --target wasm32-unknown-unknown.

Built on top of glow, webglue translates familiar OpenGL function calls into WebGL2 operations, with a handle registry to bridge between u32 IDs and glow's opaque handles.

Key Features

  • ๐ŸŽฏ 70+ WebGL2 functions - Comprehensive rendering pipeline
  • ๐Ÿš€ Instanced rendering - DrawElementsInstanced for high-performance graphics
  • ๐Ÿ“ Matrix math library - Perspective, lookAt, rotate, translate, scale operations
  • ๐Ÿ“ฆ Optional GLTF support - Load and render GLTF/GLB 3D models
  • ๐Ÿ”„ Handle-based registry - Bridges u32 IDs โ†” glow's opaque WebGL handles
  • โšก Optimized builds - ~105KB WASM (gzipped with LTO)

Quick Start

1. Add to your Cargo.toml

[dependencies]
webglue = "0.1"

# Optional: Enable GLTF model loading
webglue = { version = "0.1", features = ["gltf"] }

2. Build for WebAssembly

cargo build --target wasm32-unknown-unknown --release
# Or use wasm-pack
wasm-pack build --target web --release

3. Basic Usage

use webglue as gl;

unsafe {
    // Initialize once with WebGL2 context
    gl::init_with_webgl2_context(webgl2_context);

    // Create and bind buffer
    let mut vbo = 0;
    gl::GenBuffers(1, &mut vbo);
    gl::BindBuffer(gl::ARRAY_BUFFER, vbo);
    
    // Upload vertex data
    gl::BufferData(
        gl::ARRAY_BUFFER,
        (vertices.len() * 4) as isize,
        vertices.as_ptr() as *const _,
        gl::STATIC_DRAW
    );
    
    // Setup vertex attributes
    gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE, 0, std::ptr::null());
    gl::EnableVertexAttribArray(0);
    
    // Draw
    gl::DrawArrays(gl::TRIANGLES, 0, vertex_count as i32);
}

Implemented WebGL2 Functions

Buffer Management (5)

  • GenBuffers, DeleteBuffers, BindBuffer, BufferData, BufferSubData

Vertex Arrays (7)

  • GenVertexArrays, DeleteVertexArrays, BindVertexArray
  • EnableVertexAttribArray, DisableVertexAttribArray
  • VertexAttribPointer, VertexAttribDivisor

Shaders & Programs (13)

  • CreateShader, DeleteShader, ShaderSource, CompileShader
  • CreateProgram, DeleteProgram, AttachShader, LinkProgram, UseProgram
  • GetShaderiv, GetShaderInfoLog, GetProgramiv, GetProgramInfoLog

Uniforms (10)

  • GetUniformLocation
  • Uniform1f, Uniform1i, Uniform2f, Uniform3f, Uniform4f
  • Uniform3fv, Uniform4fv
  • UniformMatrix3fv, UniformMatrix4fv

Textures (9)

  • GenTextures, DeleteTextures, BindTexture, ActiveTexture
  • TexImage2D, TexSubImage2D, TexParameteri
  • GenerateMipmap, PixelStorei

Drawing (3)

  • DrawArrays, DrawElements, DrawElementsInstanced โšก

Framebuffers & Renderbuffers (6)

  • GenFramebuffers, BindFramebuffer, FramebufferTexture2D
  • GenRenderbuffers, BindRenderbuffer, RenderbufferStorage

State Management (11)

  • Enable, Disable, Viewport, Clear, ClearColor
  • DepthMask, BlendFunc, BlendFuncSeparate, Finish
  • ReadPixels, PointSize (stub)

Queries (5)

  • GetError, GetGraphicsResetStatus, GetIntegerv, GetString, GetStringi

Total: 70+ functions โœ…

Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Your Rust/WASM Application         โ”‚
โ”‚   (OpenGL-style function calls)      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚   webglue      โ”‚
          โ”‚   wrapper.rs   โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚ Handle Registryโ”‚
          โ”‚ (u32 โ†” Handle) โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚     glow       โ”‚
          โ”‚  (Rustโ†’WebGL)  โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                 โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚    WebGL2      โ”‚
          โ”‚   (Browser)    โ”‚
          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why Handle Registry?

WebGL via glow uses opaque handles (glow::Buffer, glow::Program, etc.), not u32 IDs like desktop OpenGL. The registry:

  • Translates u32 IDs โ†” opaque glow handles
  • Maintains OpenGL-style API compatibility
  • Uses slab for efficient O(1) lookups
  • Minimal overhead - direct index-to-handle mapping

Math Library

Built-in 4x4 matrix operations for 3D graphics:

use webglue::math::*;

// Projection matrix
let proj = perspective(45.0_f32.to_radians(), aspect_ratio, 0.1, 100.0);

// View matrix
let view = look_at(
    &[0.0, 2.0, 5.0],  // camera position
    &[0.0, 0.0, 0.0],  // look at target
    &[0.0, 1.0, 0.0],  // up vector
);

// Model transformations
let model = Mat4::identity()
    .rotate_y(angle)
    .translate(&[x, y, z])
    .scale(&[sx, sy, sz]);

// Combined MVP matrix
let mvp = proj * view * model;

// Upload to shader uniform
unsafe {
    gl::UniformMatrix4fv(mvp_loc, 1, gl::FALSE, mvp.as_ptr());
}

Available operations:

  • perspective(), orthographic() - Projection matrices
  • look_at() - View matrix from camera parameters
  • Mat4::identity(), translate(), rotate_x/y/z(), scale() - Transforms
  • Matrix multiplication with * operator

GLTF Model Loading

With the gltf feature enabled, you can load and render 3D models:

use webglue::gltf_model::GltfModel;

// Load GLTF model from URL
let model = GltfModel::load_from_url("models/scene.gltf").await?;

// Render in your draw loop
unsafe {
    model.render();
}

Supports:

  • GLTF 2.0 and GLB binary format
  • Embedded textures and images
  • Multiple meshes and materials
  • Extensions: KHR_lights_punctual, extras, names

Performance

WebGL2 instanced rendering provides massive performance gains for repeated geometry:

Rendering Method Draw Calls Objects Performance
Individual DrawArrays 1,000 1,000 ~15-30 FPS
DrawElementsInstanced 1 1,000 60 FPS
DrawElementsInstanced 1 10,000 60 FPS

Speedup: 100-500x for scenes with many similar objects ๐Ÿš€

Demo & Examples

The repository includes a comprehensive Vite-based demo application in demo/:

cd demo
npm install
npm run dev

Live Demo: Opens interactive showcase with multiple samples:

  • Textured Sphere - Earth texture mapping with UV coordinates
  • Textured Cube - 3D cube with image textures
  • Colored Cube - RGB vertex colors
  • Instanced Rendering - 1000+ objects in a single draw call
  • GLTF Models - Load and render 3D scenes (Box, FlightHelmet, Head)
  • Primitives - Sphere, cone geometry generation
  • Matrix Transforms - Rotation, translation, scaling
  • Blend Modes - BlendFunc and BlendFuncSeparate demos

Building

Library Build (WASM target required)

# Build library for WebAssembly
cargo build --target wasm32-unknown-unknown --release

# With GLTF feature
cargo build --target wasm32-unknown-unknown --release --features gltf

# Run unit tests (on host target)
cargo test --lib

Using wasm-pack (Recommended)

# Install wasm-pack
cargo install wasm-pack

# Build for web
wasm-pack build --target web --release --out-dir pkg

# The pkg/ directory is ready to import in JavaScript:
# import init, * as wasm from './pkg/webglue.js';

Size Optimization

Release builds are optimized for size:

  • LTO enabled - Link-time optimization
  • Single codegen unit - Maximum optimization
  • Result: ~105KB WASM (gzipped)

Cargo.toml configuration:

[profile.release]
opt-level = 3
lto = true
codegen-units = 1

Version Status

Dependency Current Latest Notes
glow 0.16 0.16.0 โœ… Up to date
slab 0.4 0.4.11 โœ… Up to date
gltf 1.4 1.4.1 โš ๏ธ Consider updating
wasm-bindgen 0.2 0.2.104 โš ๏ธ Consider updating
web-sys 0.3 0.3.81 โš ๏ธ Consider updating

Run cargo update to get latest compatible versions within semver ranges.

License

Copyright ยฉ 2025 Top-5

Licensed under the Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)

Contributing

Contributions welcome! Priority areas:

  • ๐Ÿ”ง Update to latest dependency versions (gltf 1.4.1, wasm-bindgen 0.2.104, etc.)
  • ๐Ÿ“š More WebGL2 functions (additional state management, queries)
  • ๐Ÿงฎ Extended math utilities (quaternions, frustum culling)
  • ๐Ÿ“ฆ More GLTF features (animations, skinning)
  • ๐Ÿ“– Documentation and examples
  • ๐Ÿงช Test coverage improvements

Credits

Built on top of excellent Rust crates:

Commit count: 0

cargo fmt