Use Our Code #2: WebGL Type Info (and some bad engineering)

Our team is making a custom WebGL engine for this jam, and we hope that you can benefit from our work. Today, I'd like to share a little file that may save you some time if you're working with shaders.

The Code

Last jam, I spent a lot of time trying to manually synchronize uniform and attribute names between shaders and my webgl engine code. I was always forgetting names and making typos. So, this time, I would like to auto-generate and auto-verify uniform and attribute types.

With webgl functions like getActiveUniform and getActiveAttrib, you can inspect shaders to find out what types of uniforms and attributes should be attached to them. Unfortunately for anyone planning to use that information, the types of those variables are returned in opaque OpenGL codes like 0x8B51. So, I made a JS file containing an object with entries like this:

javascript GL_TYPES = { ... 0x8B51:{ TypedArray : Float32Array, name : "FLOAT_VEC3", nbytes : 12, nelements : 3, uniformv : "uniform3fv", }, ... }

With GL_TYPES[mysterious_opaque_code], you can get a typed array constructor appropriate for the data type, a human-readable name (which happens to comply with WebGL nomenclature), the number of bytes per item, the number of primitive elements per instance, and the name of the uniform upload function that should be called to upload an instance of the type to a shader. As a bonus, there's another object GL_TYPE_CODES, which maps names to codes (superfluously if you have a webgl context, but helpfully if you don't.) If you're writing code to dynamically read info from shaders, this file might save you a lot of typing, and even more spec-reading. Again, here's a link to the file. I hope that it saves you some time.

The Bad Engineering

From a wellspring of laziness, I wrote a python script to generate the file from some tabular data cut-and-pasted from MDN. Humorously, the code-generating script comes in at 175 lines: producing a 212-line file, saving little typing... and costing a lot of thinking. Now, I'm all for laziness and replacing typing with thinking, but in retrospect it may have been better to generate the object in Javascript on page load. Having a python script that generates javascript code that gets put in the repo alongside the generator seems over-complicated.

Secondly, it turns out that integers can't be used as keys in a Javascript object. Implicitly, they're getting converted to strings. That shouldn't cause any problems (because they will also get implicitly converted on lookup), but it does poke a hole in my plans for a super-efficient lookup table; and it severely weakens the case for static code generation. In retrospect I should have used a Map, or maybe a sparse array.