Debugging
WebGL Lint
WebGL lint wraps the WebGL API and checks for many common usage errors. For more info see the WebGL lint website.
Spector.js
Spector.js is a system that provides a UI for inspecting your WebGL usage. It can be used as both a devtools plugin for Chrome and Firefox or as a library. As a library it's possible to inspect your WebGL startup code. As a devtool you can generally only inspect things once your app is running. Therefore, if you're trying to track down an issue that happens during initialization it can be better to use Spector.js as a library so that you can programmatically enable it at your program's initialization time.
Programmatically Debugging WebGL applications
WebGL's error reporting mechanism involves calling getError and checking for errors. As it can be burdensome to put a getError call after every WebGL function call here is small library to help with make this easier.
https://github.com/KhronosGroup/WebGLDeveloperTools
To use the library, clone the repository, put src/debug/webgl-debug.js on your server, and include it with
<script src="webgl-debug.js"></script>
Then you can wrap your WebGLRenderingContext in an object that checks all calls like this
ctx = WebGLDebugUtils.makeDebugContext(canvas.getContext("webgl"));
This will make any GL errors show up in your browser JavaScript console.
If you want to do something else, like throw an exception you can pass in your own error handling function.
function throwOnGLError(err, funcName, args) {
throw WebGLDebugUtils.glEnumToString(err) + " was caused by call to: " + funcName;
};
gl = canvas.getContext(...);
gl = WebGLDebugUtils.makeDebugContext(gl, throwOnGLError);
Showing every WebGL function call
Download the webgl-debug library mentioned above. Then make a function to print the calls like this
function logGLCall(functionName, args) {
console.log("gl." + functionName + "(" +
WebGLDebugUtils.glFunctionArgsToString(functionName, args) + ")");
}
gl = canvas.getContext(...);
gl = WebGLDebugUtils.makeDebugContext(gl, undefined, logGLCall);
Checking that none of your arguments are undefined
One of the interesting choices of JavaScript is that it will try to coerce values of 1 type into another. This can make it hard to find bugs. For example if you do something like this
var textureInfo = {
tex: gl.createTexture()
}
gl.bindTexture(gl.TEXTURE_2D, textureInfo.tx);
Notice the typo? It's 'tex' at the top but 'tx' at the bottom. 'tx' is undefined but the rules of JavaScript require that to be silently coerced into NULL which is a valid argument.
You can check for errors like this by adding a function that checks for undefined on all arguments passed to WebGL.
function validateNoneOfTheArgsAreUndefined(functionName, args) {
for (var ii = 0; ii < args.length; ++ii) {
if (args[ii] === undefined) {
console.error("undefined passed to gl." + functionName + "(" +
WebGLDebugUtils.glFunctionArgsToString(functionName, args) + ")");
}
}
}
gl = canvas.getContext(...);
gl = WebGLDebugUtils.makeDebugContext(
gl, undefined, validateNoneOfTheArgsAreUndefined);
Combine all 3 techniques above
function logAndValidate(functionName, args) {
logGLCall(functionName, args);
validateNoneOfTheArgsAreUndefined (functionName, args);
}
gl = canvas.getContext(...);
gl = WebGLDebugUtils.makeDebugContext(gl, throwOnGLError, logAndValidate);
See a sample of the above techniques
https://github.com/KhronosGroup/WebGLDeveloperTools/blob/master/src/debug/debug-sample.html
Printing Errors and other constants
WebGL uses many constants and returns errors as numbers. It's often easier to display those numbers as strings. With that in mind you can call WebGLDebugUtils.glEnumToString to convert a WebGL constant to a string.
Example:
WebGLDebugUtils.init(ctx);
alert(WebGLDebugUtils.glEnumToString(ctx.getError()));