easy-gl › Architecture

Architecture

Two-layer design

easy-gl is built on top of meta-gl, not directly on raw OpenGL. Understanding this layering is important for knowing where to add new features and why certain design choices were made.

Raw OpenGL / OpenGL ES API
meta-gl
Procedural, type-safe wrapper. Replaces raw enums with enum class, provides typed handles, exposes std::span-based APIs. No RAII, no ownership.
easy-gl
OOP RAII layer. Each resource class owns a GPU handle. Move-only. Convenience methods that delegate to meta-gl. Device class for global render state.
Your application code

Why meta-gl as the intermediary?

Raw OpenGL uses integers for nearly everything: handles, enums, targets, formats. meta-gl wraps all of these into strongly typed C++ types. easy-gl inherits this type safety automatically by reusing meta-gl types in its own API.

When easy-gl needs to call OpenGL, it calls a meta-gl function rather than gl* directly. This means:

// easy-gl calls meta-gl, not raw OpenGL:
meta::bindTexture(meta::TextureTarget::Texture2D, handle_);

// NOT this:
glBindTexture(GL_TEXTURE_2D, handle_);
If you find a place in easy-gl where a raw gl* call is used but meta-gl already wraps it, that is a bug worth fixing.

Types re-exported from meta-gl

easy-gl's Types.hpp re-exports all meta-gl enum types under the easygl namespace using type aliases. You never need to use the metagl:: namespace in application code — use easygl:: for everything.

// Types.hpp — partial list
using BufferTarget   = metagl::BufferTarget;
using TextureTarget  = metagl::TextureTarget;
using ShaderType     = metagl::ShaderType;
using PrimitiveType  = metagl::PrimitiveType;
// ... and many more

Device vs resource classes

easy-gl separates two kinds of concerns:

KindClassResponsibility
Global stateDeviceViewport, blend, depth, stencil, cull, draw calls, compute, debug, error query.
GPU resourceBuffer, Texture, Program, …Own a single GPU handle. Create, bind, upload data, destroy.

There is no global state hidden in resource classes. You explicitly call device.set_viewport(), device.set_blend_enabled(), etc.

Namespace

Everything in easy-gl lives in the easygl namespace. There are no sub-namespaces except easygl::detail, which contains internal helpers not part of the public API.

Header structure

HeaderContents
easygl/easygl.hppUmbrella header — includes everything.
easygl/Types.hppType aliases for all meta-gl enums used by easy-gl.
easygl/Device.hppDevice class.
easygl/Config.hppConfiguration struct.
easygl/Capabilities.hppCapability detection.
easygl/ContextInfo.hppGL vendor/version query result.
easygl/Feature.hppFeature enum.
easygl/Exception.hppException type.
easygl/Buffer.hppBuffer resource class.
easygl/Texture.hppTexture resource class.
easygl/Shader.hppShader resource class.
easygl/Program.hppProgram resource class.
easygl/VertexArray.hppVertexArray resource class.
easygl/Framebuffer.hppFramebuffer resource class.
easygl/Renderbuffer.hppRenderbuffer resource class.
easygl/Sampler.hppSampler object resource class.
easygl/Query.hppQuery resource class.
easygl/Sync.hppSync fence resource class.
easygl/TransformFeedback.hppTransformFeedback resource class.
easygl/detail/NonCopyable.hppInternal base for move-only resources.