meta-gl
A thin, type-safe C++20 wrapper over OpenGL ES 2.0 – 3.2 and WebGL.
Replace raw GLenum parameters with strongly-typed enum class values, zero overhead.
C++20 OpenGL ES 2.0+ WebGL 1 / 2 Emscripten Header-only enums CMake
What is meta-gl?
meta-gl is a low-level, procedural C++ library that wraps the OpenGL ES API.
It does not own GPU resources, does not create windows, and does not manage contexts.
Its single purpose is to make raw OpenGL calls safer by replacing untyped GLenum
integer parameters with enum class types that are impossible to mix accidentally.
Every public function in the metagl namespace maps one-to-one to a raw
gl* call. There is no abstraction layer, no virtual dispatch, no heap allocation.
The compiler can inline everything; the binary output is identical to hand-written GL code.
Key Features
89 enum classes
Every OpenGL parameter domain has its own enum class:
BufferTarget, ShaderType, TextureWrapMode,
BlendFactor, and 85 more. Mixing them is a compile error.
Typed handle wrappers
Lightweight structs (TextureId, BufferId, ProgramId)
wrap raw GLuint so you can't pass a texture handle where a buffer handle is expected.
std::span for data
Buffer upload functions accept std::span<const T> instead of
raw pointer + size pairs, eliminating a whole class of size-mismatch bugs.
Zero-overhead
All enum conversions are static_cast. All wrappers are thin inline calls.
No virtual dispatch, no heap allocation, no RTTI. Debug build overhead is opt-in.
Debug call logging
Define METAGLDEBUG to enable per-call logging of function names,
typed arguments (enum names, not integers), and return values. Zero cost when disabled.
Context & capability tracking
Detect ES version, WebGL version, and extension support at runtime. The context generation counter lets you detect stale handles after context loss.
Layering
meta-gl is the bottom layer of a two-level graphics library stack:
// Host application provides GL context + GetProcAddress easy-gl // OOP/RAII resource classes (namespace easygl) └── meta-gl // Procedural safe API (namespace metagl) └── actual OpenGL ES driver
- meta-gl — procedural, no resource ownership, safe enums,
std::span. - easy-gl — OOP/RAII wrappers built on top of meta-gl. easy-gl depends on meta-gl, never the reverse.
Quick Start
// 1. Add to your CMakeLists.txt: add_subdirectory(../meta-gl meta-gl) target_link_libraries(my-target PRIVATE meta-gl::meta-gl) // 2. Initialize once after context creation: #include <metagl/metagl.hpp> bool ok = metagl::Initialize(SDL_GL_GetProcAddress); if (!ok) { /* handle failure */ } // 3. Call wrapper functions in the metagl namespace: metagl::glClearColor(0.1f, 0.1f, 0.1f, 1.0f); metagl::glClear(metagl::ClearBufferBit::Color | metagl::ClearBufferBit::Depth); GLuint shader = metagl::glCreateShader(metagl::ShaderType::Vertex); metagl::glBindBuffer(metagl::BufferTarget::Array, vbo);
Public Headers
| Header | Contents |
|---|---|
metagl/metagl.hpp | Umbrella header — include this in application code |
metagl/Types.hpp | GL type aliases (GLuint, GLint, GlGetProcAddressFn, …) |
metagl/Enums.hpp | All 89 enum class wrappers for GL constants |
metagl/EnumNames.hpp | Generated to_string() overloads for every enumerator |
metagl/Functions.hpp | Declarations of all ~400 metagl::gl* wrapper functions |
metagl/Loader.hpp | Initialize(), IsInitialized(), IsFunctionAvailable() |
metagl/Context.hpp | Context info, status, and generation tracking |
metagl/Capabilities.hpp | Runtime ES/WebGL version and extension detection |
metagl/Debug.hpp | Optional per-call debug logging (zero cost when disabled) |
metagl/Emscripten.hpp | WebGL-specific helpers and Emscripten integration |
Supported Targets
| Platform | API | Notes |
|---|---|---|
| Linux / Android / Raspberry Pi | OpenGL ES 2.0 – 3.2 | EGL or GLFW context |
| Web (Emscripten) | WebGL 1 / WebGL 2 | Maps to GLES 2 / GLES 3 |
| Desktop (Mesa / ANGLE) | OpenGL ES 3.x via ANGLE | Windows / macOS compatibility |
Note: Plain desktop OpenGL (non-ES) and OpenGL ES older than 2.0 are not supported.