1
0
Fork
You've already forked LabGL
0
No description
  • C++ 67.5%
  • Zig 9.6%
  • C 9%
  • Objective-C++ 6.2%
  • Python 4.5%
  • Other 3.2%
2026年07月07日 23:51:46 -07:00
assets Reconcile sRGB 8-bit storage; complete labfx Metal MSL; fix float textures 2026年07月04日 00:33:56 -07:00
bindings big update of the pathspeed demo 2026年06月25日 00:40:49 -07:00
cmake First commit: color space management 2026年07月04日 23:40:30 -07:00
docs Add SRGB texture formats 2026年07月05日 20:24:24 -07:00
examples Metal: render root to persistent scene 2026年07月05日 23:15:43 -07:00
fonts showcase camera management 2026年07月02日 23:25:32 -07:00
include/labgl Metal: render root to persistent scene 2026年07月05日 23:15:43 -07:00
showcase fix path smoothness issue 2026年07月07日 23:51:46 -07:00
src Metal: render root to persistent scene 2026年07月05日 23:15:43 -07:00
support add an imgui palette linearizer 2026年07月05日 18:22:16 -07:00
tests Factor LabVfx to support, clean up warnings 2026年06月01日 20:37:09 -07:00
vendor Add capture annotations, make par torus more robust 2026年06月24日 18:43:15 -07:00
zlgl Revise labgl/imgui to be dylibs 2026年05月15日 23:35:35 -07:00
.clangd initial code 2026年03月23日 20:58:50 -07:00
.gitignore Stop tracking generated compile_commands.json 2026年06月16日 13:32:07 -07:00
CMakeLists.txt Lighting pipeine test 2026年07月05日 17:51:49 -07:00
compile_commands.json Stop tracking generated compile_commands.json 2026年06月16日 13:32:07 -07:00
LICENSE.md initial code 2026年03月23日 20:58:50 -07:00
README.md Add vfx readback and erasers. port sprite demo to use the vfx infrastructure 2026年05月30日 13:12:20 -07:00

LabGL

This project starts with a fun idea, creating a fantasy graphics platform in the same spirit as QuadPlay and PICO-8. In this case, the fantasy is this:

What if GL 1.1 was the best version of OpenGL ever created?

LabGL is an immediate-mode graphics library with a classic GL 1 API surface — glBegin / glEnd, glVertex, glColor, glMatrix — reimagined over modern OpenGL and Metal. The same GL code compiles to either backend without changes.

The dispatch layer is a thin macro shim: every glFoo(...) call expands toLABGLDISPATCH_glFoo(...), which the active backend implements. The original idea for the structure is due to Eric Johnston at LucasArts. He created a library called LecGL during the development of Star Wars Episode 1 Racer, for Nintendo 64. The library functioned as a portability layer, allowing prototyping on Silicon Graphics hardware, and deployment on shipping console hardware.

LabGL therefore originated as a recreation of the general concept but geared towards rapid and fun prototyping today. It's subsequently grown with features such as text rendering, things that I always wished graphics APIs just provided straight out of the box without fuss. It is a fantasy graphics platform after all!


Showcase

Font Demo — Slug GPU font rendering + LaTeX math

Renders text directly from TrueType/OpenType outlines on the GPU using Eric Lengyel's Slug algorithm. Rather than using pre-rasterized atlases, Slug saves a texture of curve crossings that allow a shader to render fonts on the GPU. The result is sub-pixel quality antialiased type at any size. The demo implements full OpenType shaping for complex scripts.

Font Demo Screenshot

Something I always wish for in every graphics API is straight forward text rendering, so I imagined my dream text render as if it was part of GL 1.1.

  • Multi-font rendering — CascadiaMono (monospace), Latin Modern Roman (serif), and STIX (Math) in a single frame
  • Stateful pen APIglFont() + glText() + glTextAt() + glTextAdvanceEm() for mid-line font and color switches
  • Animated size — point size driven by sin(t) each frame
  • Per-character color — animated rainbow cycling across a full alphabet
  • OpenType shaping — Devanagari Heart Sutra with conjunct consonants via kb_text_shape
  • LaTeX math — featureful inline math renderer: fractions, radicals, integrals, matrices, set theory

Tron Demo — "This is Unix!" filesystem visualizer

A perspective 3D view of your filesystem rendered as a glowing green vector city, inspired by the Jurassic Park / Tron aesthetic. It's not terribly useful, and the camera controls are terrible. It is fun to just knock things out with this olden API though.

Tron Demo Visualizer

  • Streets = directories (flat ground plane, path label on pavement)
  • Buildings = files (wireframe box; height ∝ log(size))
  • Filenames = Slug text labels above each building, tilted 15° back
  • Boids = Reynolds steering flock of ~40 agents flying overhead
  • Data clouds = floating wireframe tori for other mounted volumes

Controls: ESC/Q quit · mouse drag orbit · scroll zoom · Space pause · R re-scan


Panel Viewer — Clay UI + LabLayout declarative panels

A three-panel application layout built with Clay and driven by a declarative LabLayout spec string. Demonstrates embedding a 3D L-system viewport inside a 2D UI chrome.

L-System Viewer

  • Toolbar, left inspector, main 3D viewport, right panel
  • Layout declared as a YAML-like DSL parsed once at startup
  • Clay handles all 2D hit-testing and hover highlighting
  • VoxTree L-system renders live inside the Viewport element

Capture and Playback

LabGL has a built-in call-capture system. Every LABGLDISPATCH_* call can be recorded into a .lglcap text file alongside a binary .lglblob sidecar. Captures are human-readable, diffable, and suitable for unit tests or QA hand-off.

What gets captured

  • Immediate-mode draw callsglBegin/glEnd, vertex/color/normal/texcoord
  • State changes — enable/disable, blend, depth, cull, scissor, viewport
  • Matrix operations — push/pop, translate, rotate, scale, frustum, ortho, lookAt
  • Lighting and materials — per-light parameters, global ambient, material properties, color material mode
  • Font/textglFont/glText calls (Slug GPU text)
  • Vertex array drawsglDrawElements/glDrawArrays geometry stored in the .lglblob sidecar with hash-based deduplication (instanced meshes stored once)
  • Texture uploadsglTexImage2D pixel data stored in the .lglblob with dedup

State preamble

A capture begins with a full snapshot of g_labglState — all enable bits, lighting, materials, viewport, depth, blend, etc. — decomposed into equivalent GL text commands. This ensures captures are self-contained and replay correctly regardless of the GL context they were recorded from.

Usage

In panel_viewer, press the capture key to record a single frame:

labgl_captureStart(buf);
labgl_captureEmitPreamble(); // snapshot current state
// ... render frame ...
labgl_captureStop();
labgl_captureSave(buf, "frame.lglcap");

Play it back with the playback / playback_metal targets:

./build/playback_metal frame.lglcap

See docs/capture-system.md for the full API reference, file format details, and using captures as a performance tool (memoizing procedural generation, offline baking, future optimization passes).

See docs/debugging-facilities.md for annotations, hazard detection, state dumps, breakpoint hooks, and capture stats.

See docs/quickstart.md for a full project overview, architecture walkthrough, and context reload.


Building

Linux prerequisites (Ubuntu / Debian)

sudo apt install build-essential cmake libx11-dev libxrandr-dev libxcursor-dev libxi-dev libgl-dev zlib1g-dev

Desktop Build

git clone https://codeberg.org/meshula/LabGL.git
cd LabGL
cmake -B build
cmake --build build

iOS Build

To configure:

 cd build-ios
 cmake .. \
 -DCMAKE_SYSTEM_NAME=iOS \
 -DCMAKE_OSX_SYSROOT=iphoneos \
 -DCMAKE_OSX_ARCHITECTURES=arm64 \
 -DCMAKE_OSX_DEPLOYMENT_TARGET=16.0 \
 -DLABGL_BUILD_VOXTREE=OFF \
 -DLABGL_ENABLE_IMGUI=OFF

To build:

cmake -B build-ios
cmake --build build-ios

Dependencies (FreeType, GLM, LabText, LabCamera — plus OpenVDB + TBB for the optional voxtree build) are resolved find_package-first, so an installed copy is used when available; CMake FetchContent is the automatic fallback when one isn't found. This keeps configure offline whenever the libraries are already present.

Certain third-party libraries are vendored in vendor/: Clay, RGFW, glad.

To build the voxtree CLI (L-System to OpenVDB voxelizer), enable the optional OpenVDB + TBB dependencies:

cmake -B build -DLABGL_BUILD_VOXTREE=ON

Targets

Target Description
hello_triangle / hello_triangle_metal Minimal immediate-mode example
tex_demo / tex_demo_metal Procedural texture + UV mapping example
font_demo / font_demo_metal Font + math showcase
tron_demo / tron_demo_metal Filesystem visualizer
panel_viewer / panel_viewer_metal Clay UI panel layout
playback / playback_metal Replay a .lglcap capture file
voxtree L-System → OpenVDB CLI tool (requires -DLABGL_BUILD_VOXTREE=ON)
voxtree_viewer / voxtree_viewer_metal Interactive VoxTree viewer

Metal targets are macOS-only. All OpenGL targets work on macOS and Linux.

Testing

LabGL ships a small ctest-based unit suite under tests/. Each test compiles the specific pure-CPU source under test directly into its own executable, so the suite runs headless — no GL/Metal context or windowing dependencies required.

cmake -B build
cmake --build build
ctest --test-dir build --output-on-failure

Configure with -DLABGL_BUILD_TESTS=OFF to skip building the suite. Add a new test by dropping a .cpp into tests/ and registering it in tests/CMakeLists.txt via the labgl_add_test() helper.


Repository Layout

LabGL/
├── include/labgl/ # Public headers
├── src/labgl/
│ ├── core/ # Font, math, dispatch core
│ ├── capture/ # Call capture, blob sidecar, playback
│ └── backend/
│ ├── opengl/ # OpenGL backend
│ └── metal/ # Metal backend (macOS)
├── fonts/ # Bundled fonts (Latin Modern, CascadiaMono, STIX Two Math, Noto)
├── showcase/ # Feature showcase programs
│ ├── font_demo.cpp # Slug font + LaTeX math
│ ├── tron_demo.cpp # Filesystem visualizer
│ ├── panel_viewer.cpp # Clay UI panel layout
│ └── voxtree/ # L-System → OpenVDB app
├── examples/ # Minimal usage examples
│ ├── hello_triangle/ # Immediate-mode triangle
│ └── tex_demo.cpp # Procedural texture + UV mapping
├── tests/ # ctest unit suite (test_harness.h + test_*.cpp)
├── docs/ # Documentation
│ ├── quickstart.md # Project overview + context reload
│ ├── capture-system.md # Capture API, file format, performance
│ ├── debugging-facilities.md # Annotations, hazards, dumps, breaks, stats
│ ├── slug-algorithm.md # Slug GPU text algorithm
│ └── lablayout-algorithm.md # LabLayout + Clay UI system
├── support/ # Shared glue (RGFW impl TU, path resolver)
└── vendor/ # Third-party: Clay, RGFW, glad, kb

The LabGL Idea

GL 1's immediate mode API is expressive, readable, and easy to prototype with. Its fatal flaw was performance — batching and state management were left entirely to the application. LabGL addresses this:

  • The dispatch layer records commands into typed buffers
  • glEnd() flushes the buffer through triple-buffered backend draw calls
  • Backends are swappable: OpenGL and Metal today, WebGPU or Vulkan tomorrow

The font system extends this philosophy: glBegin(GL_FONT) / glText() / glEnd() batches all glyphs for a frame and draws them in a single Slug pass. The math renderer composes TeX box-model layout on top of the same font primitives; there's no separate math pipeline, just LabGL draw calls.


License

All files copyright (c) 2026 Nick Porcino, and released under a BSD 3-clause license. Certain files as noted are covered by their own licenses.

Thanks

Special thanks to Eric Lengyel for teaching us the Slug technique. Special thanks to Michael Nicolella and Patrick Doane for brainstorming and helpful suggestions.

LabGL builds on the following third-party libraries and fonts.

Rendering algorithms

Slug — GPU font rendering algorithm by Eric Lengyel Reference shaders: https://github.com/EricLengyel/Slug Paper: https://jcgt.org/published/0006/02/02/ (JCGT 2017) License: dual MIT / Apache 2.0. The patent has been dedicated to the public domain. Credit is required if the code is distributed.

Text shaping

kb_text_shape — single-header Unicode text segmentation and OpenType shaping, by Jimmy Lefevre https://github.com/jlefevre/kb (part of the kb single-header library collection) License: zlib

FreeType — font loading and outline extraction https://freetype.org License: FreeType License (BSD-style) / GPLv2

UI and windowing

Clay — immediate-mode UI layout library by Nic Barker https://github.com/nicbarker/clay License: zlib

RGFW — single-header cross-platform windowing by ColleagueRiley https://github.com/ColleagueRiley/RGFW License: zlib

glad2 — GL loader generator https://github.com/Dav1dde/glad License: generated code is WTFPL / CC0; loader itself is Apache 2.0

Math and geometry

GLM — OpenGL Mathematics library https://github.com/g-truc/glm License: MIT

par_shapes — triangle mesh generation, by Philip Rideout https://github.com/prideout/par License: MIT

LabCamera — interactive camera controller, by Nick Porcino https://github.com/meshula/LabCamera License: MIT

LabText — text utilities, by Nick Porcino https://github.com/meshula/LabText License: MIT

OpenVDB — sparse volumetric data structure (used by the VoxTree demo) https://www.openvdb.org License: MPL 2.0

oneTBB — Intel Threading Building Blocks (OpenVDB dependency) https://github.com/oneapi-src/oneTBB License: Apache 2.0

Fonts

Cascadia Mono — monospace programming font by Microsoft https://github.com/microsoft/cascadia-code License: SIL Open Font License 1.1

Latin Modern — TeX math serif family, derived from Computer Modern, by B. Jackowski & J.M. Nowacki / GUST https://www.gust.org.pl/projects/e-foundry/latin-modern License: GUST Font License (permissive, similar to LPPL)

STIX Two Math — mathematical OpenType font by the STIX Fonts Project https://github.com/stipub/stixfonts License: SIL Open Font License 1.1

Noto Sans Devanagari — Devanagari script font by Google https://github.com/google/fonts/tree/main/ofl/notosansdevanagari License: SIL Open Font License 1.1