globjects wraps OpenGL 3.0 objects so shaders and programs become C++ types
C++ library strictly wrapping OpenGL objects.
At a glance
- What is it?
- globjects is a cross-platform C++ wrapper for OpenGL 3.0 and higher that turns shaders, programs, buffers and textures into owned objects, checks GL and shader errors automatically, and leans on glbinding and GLM for the raw calls and math. Its release tags stopped in 2016 even though the repository itself was pushed to in August 2026, which tells you how to weigh it.
- Who is it for?
- Adopt globjects when you are writing C++ against OpenGL 3.0 or newer and want object lifetime, error checking and GLM math handled for you, especially in a codebase that already uses glbinding. Do not adopt it for a new project that needs a current OpenGL version, because the wrapper targets 3.0 and higher while the published release tags are from 2016 and the Ubuntu package path names distributions that are long out of support.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 79 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
From raw calls to objects with a lifetime
globjects is described as a cross-platform C++ wrapper for OpenGL API objects, and the README is specific about the version floor: it provides object-oriented interfaces to the OpenGL API, 3.0 and higher.
The problem it addresses is one of shape rather than of capability. Raw OpenGL is a set of global functions operating on integer handles, and the handle is an unsigned int that has to be tracked by hand. Nothing in the API connects a shader to the program that uses it, nothing releases it, and nothing tells you that a call failed except a separate glGetError you may or may not remember to make.
The README's example makes the difference concrete. The raw version creates a program, creates two shaders, sets their sources, compiles them, attaches them, links the program, uses it and sets a uniform, in a dozen lines of global calls with local handles.
With globjects the same work is:
// globjects API
auto program = new Program();
program->attach(
Shader::fromString(GL_VERTEX_SHADER, vertexShaderSource),
Shader::fromString(GL_FRAGMENT_SHADER, fragmentShaderSource)
);
program->setUniform("extent", glm::vec2(1.0f, 0.5f)));The shaders are temporary objects that attach themselves to the program, the uniform is set by name with a GLM vector rather than a location lookup and two floats, and the whole thing reads as one operation instead of five.
One detail in that snippet is worth copying exactly rather than fixing: the closing parenthesis count on the setUniform line is unbalanced in the README. If you take the example from the documentation, expect to correct that line when you paste it.
Error checking, shader compilation and link failures
The README states plainly what the wrapper does about failures, and it is conditional. If enabled, the code checks for GL errors with glGetError after each call, checks shaders for compilation errors, and checks the program for linker errors.
That conditional matters more than it first appears. Error checking in a wrapper like this is not free, and a per-call glGetError is a synchronous round trip into the driver. A renderer that issues thousands of calls per frame will feel the difference, which is why the checking is a flag rather than a permanent property of the API.
The three levels are also different in kind. A GL error is a runtime status flag, so the check is a query. A shader compilation error is a condition the wrapper can detect at the point of compiling, and the source of the shader is right there, so the error can name the file and line. A program link error is the same idea at the program level: the shaders compiled but the program does not work, and the usual cause is a varying that one side declares and the other does not.
Handling those at the point of creation rather than at the point of use is the real value of the wrapper. In raw OpenGL, a shader that fails to compile typically returns zero, and a program that fails to link returns zero, and if you do not check, the failure shows up later as a black screen or an undefined draw call, with no link back to the cause.
The API reference also documents error handling as a first class area, with a dedicated Error section alongside Debug Message, so the project treats diagnostics as part of the interface rather than as an afterthought.
glbinding and GLM do the underlying work
The architecture is layered and the README is clear about where each piece sits. globjects adds an abstraction layer to glbinding and to GLM, and the stated effect is that it reduces the amount of OpenGL code required for rendering and facilitates coherent OpenGL use.
glbinding is the foundation. It generates the actual OpenGL function bindings, which is what makes it possible for the wrapper to call a specific OpenGL version's entry points on a system where the loader only exposes an older set. GLM is the mathematics library, and it is why the uniform example passes a `glm::vec2` rather than two floats and a pointer.
There is a third project in the stack that the README mentions only in passing but the build system reveals: cpplocate, the dependency locator that finds installed packages. The Dockerfile stages it and glbinding as separate build images and passes them into the build through `cpplocate_DIR` and `glbinding_DIR` environment variables, so the dependency search is a configured part of the build rather than something the compiler guesses.
The second promise in that same README paragraph is the more interesting one. Missing features of specific OpenGL drivers are partially simulated or even emulated at run-time. That is a claim about the compatibility layer, and it is the kind of claim worth pressing on: emulating a missing driver feature in software is not always possible, and where it is, it can cost more than the feature saves.
The object model is documented in the API reference with a dedicated section on reference pointers as a memory model, which is the mechanism that lets a shader be attached to a program and then go out of scope, and a section on shader templates, which is how a shader can be compiled with different parameters without duplicating source.
The wrapped object list, and what each one covers
The API reference is organised by OpenGL object, and reading the list tells you how complete the coverage is.
There is the global functions area, then Buffer, Texture, State, Error, Debug Message, Framebuffer, Named String, Program, Program Pipeline, Query, Renderbuffer, Sampler, Shader, Sync, Transform Feedback, Uniform, Uniform Block, Vertex Array and Vertex Attribute Binding.
That is the object set from OpenGL 3.0 and later, including the modern parts that raw OpenGL examples often skip: program pipelines for separable shaders, named strings for the shading language include mechanism, transform feedback for capturing vertex output, sync objects for fences and timers, and queries for occlusion and pipeline statistics.
Vertex Array and Vertex Attribute Binding together cover the split that OpenGL 3.0 introduced, where vertex array objects own the attribute state and the vertex attribute binding API decouples buffer bindings from format descriptions. That is the part of the API that most hand written OpenGL gets wrong, because the pre-3.0 style of setting up attributes on every draw call is still widely copied, and a wrapper is where that mistake stops being repeated.
State, Error and Debug Message are not objects in the same sense. They are the parts of the API that describe the context rather than a resource, and having them as first class members means a renderer can query the current state or turn on debug output through the same object model as everything else.
Installing on Ubuntu, and building from source
The README gives three routes: download the source and compile it, use one of the pre-compiled releases, or use a package manager. For systems providing package managers, the project says it generally strives for packages in them.
On Ubuntu, globjects is provided through a personal package archive. The instructions name the current PPA for Ubuntu 16.04, 15.10 and 15.04, and a separate backports PPA for Ubuntu 14.04, and the install sequence is:
> sudo apt-add-repository ppa:cginternals/ppa
> sudo apt-get update
> sudo apt-get install libglobjects-examples-glfw
> # start example
> /usr/share/globjects/computeshaderThe package name includes the GLFW examples, which tells you that the distribution channel ships the example programs alongside the library. Running the compute shader example is the quickest way to see the library work on your machine.
On Windows, the README describes either downloading an installer, such as the x64 installer for Visual Studio 2015, or extracting one of the pre-compiled archives, with separate runtime, examples and dev packages. The three-way split is the usual distinction between what an application needs at run time and what a developer needs to compile against.
The source build uses CMake with a `configure` script at the repository root, and the Dockerfile shows the flow. The build runs `./configure`, then a second configure with the options for building examples and not building tests, then `cmake --build build`. The install stage configures the install prefix and builds the install target.
The options are visible in the Dockerfile line itself: `-DOPTION_BUILD_TESTS=Off -DOPTION_BUILD_EXAMPLES=On`. So the build system has explicit switches for tests and examples, and the Docker image deliberately skips tests and includes examples, which is a sensible split for a shipped image.
The release tags tell you how to interpret all of this. The most recent are v1.0.0 from 2016-11-18, v0.5.0 from 2016-04-14 and v0.4.2 from 2014-11-26, while the documentation site carries both a stable build at v1.1 and a master build, and the last push to the repository was on 2026-08-05. The code is being worked on; the packaged artefacts are not.
When the raw API is the better choice
globjects is a wrapper, and the honest question is when you want one.
The wrapper earns its place when your codebase is large enough that the boilerplate is a real cost and small enough that the extra abstraction does not get in the way. A renderer with dozens of shaders and buffers benefits from automatic error checking and from object lifetime, and a team that already uses glbinding has the lower layers in place.
It is the wrong tool in a few specific situations. If you need an OpenGL version newer than the 3.0-era object set the wrapper models, and the README gives no hint that new object types have been added since the tags, you are reading a wrapper whose object list is bounded. If you are writing a one-off visualisation with three draw calls, the wrapper's overhead and its dependency on glbinding and GLM are more than the boilerplate you would have written.
There is also the simulation trade-off to keep in mind. The README says missing driver features are partially simulated or emulated at run-time, which is a benefit for portability and a cost when you are chasing frame time, because an emulated feature runs slower than a real one and the difference is invisible until you profile.
The alternative approach is to write the raw calls yourself over glbinding, keeping the bindings but not the object model. You get the version-aware entry points and the GLM math, and you keep full control of state changes and error handling, at the cost of writing the handle tracking and the create/delete pairs by hand. A third path is a higher level engine or scene graph, which goes further in the opposite direction and hides OpenGL behind a different API entirely.
Between those, globjects sits at the point where the API shape has changed but the control has not. That is a narrow, deliberate position, and it is worth being explicit that the value is convenience and safety rather than capability.
Editorial conclusion
Adopt globjects when you are writing C++ against OpenGL 3.0 or newer and want object lifetime, error checking and GLM math handled for you, especially in a codebase that already uses glbinding. Do not adopt it for a new project that needs a current OpenGL version, because the wrapper targets 3.0 and higher while the published release tags are from 2016 and the Ubuntu package path names distributions that are long out of support. Verify first that the glbinding and GLM versions you use match what the wrapper expects, that the error-checking and shader-template features are enabled the way you want, since the README notes that the checks only run if enabled, and that the source you build from the `master` branch is what you tested, since the last push was on 2026-08-05 and the most recent tag is v1.0.0 from 2016.
Frequently asked questions
What is globjects and what OpenGL versions does it support?
globjects is a cross-platform C++ wrapper for OpenGL API objects, providing object-oriented interfaces to the OpenGL API for version 3.0 and higher. It adds an abstraction layer over glbinding and GLM and reduces the amount of OpenGL code required for rendering.
How do I install globjects on Ubuntu?
Through the project's personal package archive: add the PPA with `sudo apt-add-repository ppa:cginternals/ppa`, run `sudo apt-get update`, then `sudo apt-get install libglobjects-examples-glfw`. The README names the current PPA for Ubuntu 16.04, 15.10 and 15.04, and a backports PPA for Ubuntu 14.04.
Does globjects check for OpenGL errors automatically?
It does so when enabled. The README says that, if enabled, the code checks for GL errors with glGetError after each call, checks shaders for compilation errors and checks the program for linker errors.
What does globjects depend on?
It adds an abstraction layer over glbinding, which provides the generated OpenGL function bindings, and over GLM for the mathematics. The build also uses cpplocate to locate the installed dependencies, with the paths passed in through `cpplocate_DIR` and `glbinding_DIR` in the Dockerfile.
How do I build globjects from source?
Use the `configure` script and CMake. The Dockerfile shows the sequence: run `./configure`, then a second configure with options such as `-DOPTION_BUILD_TESTS=Off -DOPTION_BUILD_EXAMPLES=On`, then `cmake --build build`, and for an install a configure with the install prefix followed by `cmake --build build --target install`.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/cginternals-globjects)Was this useful?