gl3w generates an OpenGL core profile loader from the Khronos header
Simple OpenGL core profile loading
At a glance
- What is it?
- gl3w is a small Python generator that downloads the Khronos glcorearb.h header and turns it into gl3w.h and gl3w.c, giving a C project direct access to the OpenGL core profile with three functions of API. It is public domain code with no releases to plan against.
- Who is it for?
- Adopt gl3w if you are writing C or C++ against the OpenGL core profile and want a loader you can vendor and regenerate yourself, and skip it if your target already provides OpenGL headers through a system package and you never need to pin a core profile version. Before relying on it, run gl3w_gen.py yourself and commit the generated gl3w.h and gl3w.c, because the repository ships no releases and the last push was on 2026-08-17.
- Can I use it commercially?
- Yes. Unlicense 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 67 days ago.
- What is it written in?
- Mainly Python, 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
The loader is generated from glcorearb.h, not written by hand
gl3w is described as the easiest way to get your hands on the functionality offered by the OpenGL core profile specification, and the way it does that is by generating a loader rather than shipping a hand-written one.
Its main part is a simple Python script, gl3w_gen.py, that downloads the Khronos supported glcorearb.h header and generates gl3w.h and gl3w.c from it. Those two generated files can then be added and linked into a project, statically or dynamically.
The distinction matters for anyone who has wrestled with OpenGL headers on different platforms. The alternative approach is to rely on the OpenGL headers and loader that the system provides, which differ between Linux distributions, macOS and Windows and change when the driver stack updates. Generating from the Khronos registry header means the set of entry points is defined by one upstream file that you fetch and pin, and the result is a self-contained C file you can commit to your repository.
The cost of that approach is that you own the generated code. If the upstream header changes, somebody has to run the generator again, and the commit that does so is your responsibility.
The generator needs Python 2.7 or newer and accepts two options
The requirements section is brief. gl3w_gen.py requires Python version 2.7 or newer, and it is also compatible with Python 3.x. The Python 3 port is credited to Arthur Tombs in the credits list, and Daniel Cousens is credited for code contributions.
The script takes two optional arguments, and they cover the two decisions you actually have to make. The --ext flag includes the GL Extensions in the output header, which you want if your project loads extensions outside the core profile. The --root=outputdir argument sets the location for the output to something other than the current working directory, which matters when the generator runs from a build system that expects files in a particular place.
Nothing else is configurable, and that is a reasonable scope. There is no list of extensions to cherry-pick, no version filter for the core profile, and no way to exclude a function. Either you take the header as Khronos publishes it or you do not use the generator.
The repository is small and conventional for a C project. The top level holds CMakeLists.txt, a cmake/ directory, an SConstruct file for SCons, the src/ directory with the sources, the generator script, the UNLICENSE file and the README.
Three functions cover initialization, version checks and extensions
The API reference is deliberately minimal. It consists of just three functions.
The first, int gl3wInit(void), initializes the library. It should be called once after an OpenGL context has been created, returns 0 when gl3w was initialized successfully and non-zero if there was an error.
The second, int gl3wIsSupported(int major, int minor), returns 1 when the OpenGL core profile version major.minor is available and 0 otherwise. This is the function that makes the core profile workable, because it lets a program check for the version it needs at run time rather than assuming what the driver provides.
The third, GL3WglProc gl3wGetProcAddress(const char *proc), returns the address of an OpenGL extension function. The documentation is candid that you will generally not need it, since gl3w loads all functions defined in the OpenGL core profile on initialization, and it exists to let you load extensions that sit outside the core profile.
That last point is the one design decision with teeth. Loading everything in the core profile at initialization means a fixed, complete set of entry points with no lazy resolution, at the cost of resolving functions your application never calls. Extensions, by contrast, are resolved on demand. The --ext flag exists for projects that want extension declarations in the header rather than resolving each one by hand.
GL/gl3w.h has to come before any other OpenGL header
The example in the README is a glut program, and the ordering requirement is stated plainly: GL/gl3w.h must be included before any other OpenGL related headers.
#include <stdio.h>
#include <GL/gl3w.h>
#include <GL/glut.h>The reason is structural. The generated header declares the core profile entry points itself, and when the platform headers come first they declare the same symbols with a different calling convention, which produces conflicting declarations at compile time. Putting gl3w.h first avoids that collision, and it is the kind of requirement that only shows up as a confusing compile error if you get it wrong.
The rest of the example shows the intended startup order. The glut setup runs first, glutInit, glutInitDisplayMode, glutInitWindowSize and glutCreateWindow, and only then is gl3wInit called, because a context has to exist before the loader can resolve anything.
if (gl3wInit()) {
fprintf(stderr, "failed to initialize OpenGL\n");
return -1;
}
if (!gl3wIsSupported(3, 2)) {
fprintf(stderr, "OpenGL 3.2 not supported\n");
return -1;
}
printf("OpenGL %s, GLSL %s\n", glGetString(GL_VERSION),
glGetString(GL_SHADING_LANGUAGE_VERSION));The version check follows immediately, and the program prints the OpenGL and GLSL version strings once it knows it can proceed.
Fetching gl3w into a CMake build with FetchContent
For projects already on CMake, the README shows how to pull the repository in during configuration, so there is no submodule to maintain by hand.
include(FetchContent)
FetchContent_Declare(
gl3w
GIT_REPOSITORY https://github.com/skaslev/gl3w.git
GIT_TAG master
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
EXCLUDE_FROM_ALL
)
FetchContent_MakeAvailable(gl3w)
# Declare your target that needs gl3w here
target_link_libraries(<target> PRIVATE gl3w)The FetchContent_Declare block points at the Git repository with GIT_TAG set to master and GIT_SHALLOW set to TRUE, and EXCLUDE_FROM_ALL keeps the fetched project out of the default build so it does not get compiled unless something needs it. FetchContent_MakeAvailable then makes the target available, and the last line links it into your own target.
Pinning GIT_TAG to master is the weak point in this snippet. The repository publishes no GitHub releases, so there is no tag to pin to and no version number to record in your build definition. A build that tracks master picks up whatever the maintainer pushed, and the generated gl3w.h and gl3w.c inside the fetched tree may not match the header state your project expects. Vendoring the generated files and committing them is the more predictable arrangement, at the cost of taking on the regeneration work yourself.
Public domain code with a maintainer of last resort
The licence is the simplest thing about the project. gl3w is in the public domain, with the details in the UNLICENSE file, and the README carries a public domain mark image. There is no attribution requirement and no copyleft obligation, which removes the usual friction around vendoring generated code into a commercial project.
The credits list shows where the work came from. Slavomir Kaslev wrote the initial implementation, Kelvin McDowell and Sjors Gielen added Mac OS X support, Travis Gesslein contributed patches regarding glcorearb.h, Arthur Tombs ported the project to Python 3, and Daniel Cousens made code contributions. OpenGL is noted as a registered trademark of SGI.
The maintenance picture is thinner than the feature set. The last push was on 2026-08-17 and the repository is not archived, so work has been happening, but there are no GitHub releases and no version tags to cite. The project is small enough that this is understandable, and small enough that the risk is real: if the maintainer moves on, the Khronos header keeps changing and the generator stops matching what current drivers expose.
For a project this size, treating the generator as the upstream dependency and the generated C files as your own vendored artefact is the arrangement that survives the maintainer leaving.
Editorial conclusion
Adopt gl3w if you are writing C or C++ against the OpenGL core profile and want a loader you can vendor and regenerate yourself, and skip it if your target already provides OpenGL headers through a system package and you never need to pin a core profile version. Before relying on it, run gl3w_gen.py yourself and commit the generated gl3w.h and gl3w.c, because the repository ships no releases and the last push was on 2026-08-17.
Frequently asked questions
What does gl3w do and what does it generate?
gl3w is a simple OpenGL core profile loader generator. Its main part is gl3w_gen.py, a Python script that downloads the Khronos supported glcorearb.h header and generates gl3w.h and gl3w.c from it, which you then link into your project.
Which Python version does gl3w_gen.py need?
It requires Python version 2.7 or newer and is also compatible with Python 3.x.
What functions does the gl3w API expose?
Just three: gl3wInit, which initializes the library once an OpenGL context exists and returns 0 on success, gl3wIsSupported, which reports whether a given core profile version is available, and gl3wGetProcAddress, which resolves extension functions outside the core profile.
How do I include gl3w in a CMake project?
The README shows using FetchContent with GIT_REPOSITORY pointing at https://github.com/skaslev/gl3w.git and GIT_TAG set to master, then FetchContent_MakeAvailable(gl3w) and linking the gl3w target with target_link_libraries.
Can I include the OpenGL extensions in the gl3w output?
Yes. The generator takes an --ext argument to include the GL Extensions in the output header, and --root=outputdir to write the output somewhere other than the current working directory.
What licence is gl3w released under?
It is in the public domain, with the details in the UNLICENSE file at the root of the repository.
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/skaslev-gl3w)Was this useful?