OpenGL Go code verification

Getting seriously tricky stuff done in Go is, time and again, surprisingly simple:

Here's an interesting "convoluted custom use-case" I just had while working on go:ngine. So the engine is supposed to support OpenGL versions 3.2 or higher, but during development, 99% of the time I just run under OpenGL 4.2. To stay in the flow, I don't want to consult the GL specs every time I use a GL function or enumeration. At the same time, when I push to GitHub, I'd like to make sure any and all GL function or enumeration references in all go:ngine sources are either GL 3.2 or lower, or else wrapped in some conditional logic (ie. "only go ahead here if client GL version supports it")...

So for talking to OpenGL, go:ngine uses the fantastic GoGL binding. Specifically it uses the gl42 sub-package — don't worry, that package even works under OpenGL 3.2! — at least, if we (A) ignore the version-related error (but not any other kind of error) returned by gl42.Init() and (B) ensure we don't use API functions or enum values newer than the detected run-time GL version. So part (A) is easy, but ensuring (B) at all times (when mostly I happily develop using just my 4.2-capable GPU) could over time become an issue. What to do?

Ideally: a simple code checker

that I would run just occasionally — every other week, or right before major commits. It would:

  1. run over the entire go:ngine code-base
  2. for each .go source file, collect all its references to the gl42 package
  3. record the name of every gl42 function or enum value referenced (ignoring GL types here since from what I gather none have been added ever since 3.2)
  4. then for each such tracked reference, check a GL Specification XML file for the minimum version that would support it
    • if the version for the func/enum reference is 3.2 or lower, ignore it
    • otherwise, keep it and later show a summary like this:
      GL v4.2 used 4x:
          function TexStorage2D:
          function TexStorage3D:
          function TexStorage1D:
      GL v4.0 used 2x:
          enum TESS_CONTROL_SHADER:

The above is actually real output of said tool, because I just wrote it today in just a few hours and guess what..

..only a 100 lines or so in total!

That's why I find Go amazingly fun to work with... (OK, maybe JavaScript could have done all this half the space, but I like statically-typed native-compiled code so anyway and Go's strict compiler saved me from a few bugs just right there today.)

  • Parsing all .go source files was surprisingly simple just working off the go/ast and go/parser package examples.
  • Parsing the XML GL-specification file using the encoding/xml package would have been a major pain point, but before even taking the trouble to write out all XML tags as Go structs (I didn't really want to "unmarshal" anything, thanks very much...), I luckily came across the awesome go-pkg-xmlx package — it made loading and searching the 1.4MB spec file painless and also crucially, Just-Worked right off the bat! (go:ngine also uses his Go GLFW binding, which also works a charm across platforms. Yay!)

If you wanna see (or use) the code to parse the .go source tree, load the XML spec and checks any and all gogl/gl42 references across a given code-base against specific OpenGL versions, it's right here on GitHub.