Zigglgen, Zig OpenGL binding generator

After over a year of doing smaller personal projects I’m excited to finally present my first real Zig project that may actually be useful to someone else: zigglgen

zigglgen is an OpenGL binding generator that is written in Zig and fully integrated with the Zig package manager and build system. Adding zigglgen to your project is super easy:

1. Run zig fetch to add the zigglgen package to your build.zig.zon manifest:

zig fetch https://github.com/castholm/zigglgen/releases/download/v0.1.0/zigglgen.tar.gz --save

2. Generate a set of OpenGL bindings in your build.zig build script:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const exe = b.addExecutable(...);

    // Choose the OpenGL API, version, profile and extensions you want to generate bindings for.
    const gl_bindings = @import("zigglgen").generateBindingsModule(b, .{
        .api = .gl,
        .version = .@"4.1",
        .profile = .core,
        .extensions = &.{ .ARB_clip_control, .NV_scissor_exclusive },
    });

    // Import the generated module.
    exe.root_module.addImport("gl", gl_bindings);

    b.installArtifact(exe);
}

3. Initialize OpenGL and start issuing commands:

const windowing = @import(...);
const gl = @import("gl");

// Procedure table that will hold OpenGL functions loaded at runtime.
var procs: gl.ProcTable = undefined;

pub fn main() !void {
    // Create an OpenGL context using a windowing system of your choice.
    var context = windowing.createContext(...);
    defer context.destroy();

    // Make the OpenGL context current on the calling thread.
    windowing.makeContextCurrent(context);
    defer windowing.makeContextCurrent(null);

    // Initialize the procedure table.
    if (!procs.init(windowing.getProcAddress)) return error.InitFailed;

    // Make the procedure table current on the calling thread.
    gl.makeProcTableCurrent(&procs);
    defer gl.makeProcTableCurrent(null);

    // Issue OpenGL commands to your heart's content!
    const alpha: gl.float = 1;
    gl.ClearColor(1, 1, 1, alpha);
    gl.Clear(gl.COLOR_BUFFER_BIT);
 }

For a complete example project that creates a window using mach-glfw and draws a triangle to it, check out the zigglgen-example/ subdirectory of the main zigglgen repository.

screenshot

I also wrote some more information about why OpenGL binding generators are necessary in a Zig NEWS article.

Even if you have no use for OpenGL you might want to refer to zigglgen as an example of a Zig package that generates code. Outside of the specifics of translating definitions from the OpenGL API registry to Zig, the implementation is relatively light and straightforward.

If you have any comments or questions, please leave them below and I’ll happily reply :smile:

16 Likes

Excited to try it out!

1 Like