One thing I've come to know about myself is that I learn best by doing. As such I will be documenting the process of learning WebGL from the roots to the leaves. I’ve set myself a curriculum to follow which begins with WebGL basics but also includes brush-up courses in trigonometry and linear algebra.

Of course no good technical blog post is complete without interactive examples so I will also be building a WebGL toolkit to abstract each function after I've learned them. In doing so I hope to end up with a useful library and documentation on the things I’ve learned to look back on later.

To begin I've written a single class WebglToolkit.Canvas which takes parameters for element, height, width, and color then initializes a canvas in the webgl context.

    /**
     * A class for initializing a canvas in webGL context
     * @class Canvas
     * @param {Object} config - configuration object
     * @param {string} config.element - The id of the canvas element to initialize
     * @param {number} config.height - The height of the canvas element
     * @param {number} config.width - The width of the canvas element
     * @param {array}  config.color - The initial background color [r, g, b, a]
     */

    export default class {
      constructor({
        element = null,
        height = null,
        width = null,
        color = [1.0, 1.0, 1.0, 1.0],
      }) {
        if (element === null) {
          console.log('Please pass a canvas element to initialize');
          return;
        }

        const canvas = document.getElementById(element);

        try {
          this.context = canvas.getContext('webgl');
          this.setElementDimensions(canvas, height, width);
          this.setContextDimensions(this.context, height, width);
          this.setCanvasBackground(this.context, color);
        } catch(e) {
          console.log('Could Not Initialize WebGL');
          console.error(e);
        }
      }

      setElementDimensions(canvas, height, width) {
        canvas.setAttribute('width', width);
        canvas.setAttribute('height', height);
      }

      setContextDimensions(context, height, width) {
        context.viewportWidth = height;
        context.viewportHeight = width;
      }

      setCanvasBackground(context, color) {
        context.clearColor(...color);
        context.clear(context.COLOR_BUFFER_BIT|context.DEPTH_BUFFER_BIT);
      }
    }
    

I considered using a pre-existing library like trusty old three.js for my examples but decided against it in the interest of truly understanding the inner working if WebGL. My first step was to create a repository and set it up in a modular fashion to allow for growth. I expect a shift in architecture as I implement more challenging features so for now I'm importing classes and making them available under the oh so creative name WebglToolkit

I've set up the project using babel and webpack (if you aren’t using ES6 you should look into Babel right away. There’s no reason you shouldn’t be experiencing the joy of fat arrow functions and destructuring, you deserve it!) Babel does a great job of converting your shiny new javascript syntax into plain old JavaScript which should work everywhere. I also set up jsdoc-to-markdown, a nice auto-documentation package which generates README files from doc blocks in the code. Last, I’ve created an examples folder which I can use for testing each feature as I develop or alter them.

You can check out the repository here WebglToolkit