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

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

HeaderContents
metagl/metagl.hppUmbrella header — include this in application code
metagl/Types.hppGL type aliases (GLuint, GLint, GlGetProcAddressFn, …)
metagl/Enums.hppAll 89 enum class wrappers for GL constants
metagl/EnumNames.hppGenerated to_string() overloads for every enumerator
metagl/Functions.hppDeclarations of all ~400 metagl::gl* wrapper functions
metagl/Loader.hppInitialize(), IsInitialized(), IsFunctionAvailable()
metagl/Context.hppContext info, status, and generation tracking
metagl/Capabilities.hppRuntime ES/WebGL version and extension detection
metagl/Debug.hppOptional per-call debug logging (zero cost when disabled)
metagl/Emscripten.hppWebGL-specific helpers and Emscripten integration

Supported Targets

PlatformAPINotes
Linux / Android / Raspberry PiOpenGL ES 2.0 – 3.2EGL or GLFW context
Web (Emscripten)WebGL 1 / WebGL 2Maps to GLES 2 / GLES 3
Desktop (Mesa / ANGLE)OpenGL ES 3.x via ANGLEWindows / macOS compatibility

Note: Plain desktop OpenGL (non-ES) and OpenGL ES older than 2.0 are not supported.