Using Web-GL with Typescript

Sample 2 - 2 Triangles (Quad) using Vertex Shading via a colour buffer.


This example extends the previous example by adding a new buffer to store the vertex colours, the values in the buffer are used by the fragment shader.
At the bottom of the code sections, you can see an example of the code in action.
The new code sections are shown in bold, for the sake of brevity, unchanged sections are omitted and denoted by ...
The HTML code below contains the basic shader initialisation code for both the Vertex and Fragment shaders and attaches gl-matrix.js & the transpiled Typescript file: app.js.
The example can be downloaded from Github Git

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>TypeScript HTML App</title>
    <link rel="stylesheet" href="app.css" type="text/css" />

    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 aVertexPosition;
        attribute vec4 aVertexColor;
        uniform mat4 mVMatrix;
        uniform mat4 pMatrix;
        varying lowp vec4 vColor;

        void main(void) {
            gl_Position = pMatrix * mVMatrix * vec4(aVertexPosition, 1.0);
            vColor = aVertexColor;
        }
        </script>
    <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;
        varying lowp vec4 vColor;

        void main(void) {
            gl_FragColor = vColor;
        }
    </script>
    <script src="gl-matrix.js"></script>
    <script src="app.js"></script>
</head>
<body>
    <canvas id="CanvasGL" style="border: none;" width="500" height="500"></canvas>
</body>
</html>
The Typescript code below initialises the canvas, shaders, buffers and sets up the camera to draw a simple coloured Quad.

declare var mat4: any;
declare var vec3: any;

class Plane {

    ...

    private vertexPositionBuffer;
    private vertexIndexBuffer;
    private vertexColorBuffer;
    private vertices;
    private indices;
    private colors;
    constructor() {
        ...
    }

    ...

    private InitShaders() {
        ...

        this.gl.useProgram(this.shaderProgram);
        this.shaderProgram.vertexPositionAttribute = this.gl.getAttribLocation(this.shaderProgram, "aVertexPosition");
        this.gl.enableVertexAttribArray(this.shaderProgram.vertexPositionAttribute);
        // Bind the colour attribute
        this.shaderProgram.vertexColorAttribute = this.gl.getAttribLocation(this.shaderProgram, "aVertexColor");
        this.gl.enableVertexAttribArray(this.shaderProgram.vertexColorAttribute);
        this.shaderProgram.pMatrixUniform = this.gl.getUniformLocation(this.shaderProgram, "pMatrix");
        this.shaderProgram.mvMatrixUniform = this.gl.getUniformLocation(this.shaderProgram, "mVMatrix");
    }

    ...

    private InitBuffers() {
        this.vertexPositionBuffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);

        this.vertices = [
            -1.0, -1.0, 0.0,  //v0
             1.0, -1.0, 0.0,  //v1
             1.0,  1.0, 0.0,  //v2
            -1.0,  1.0, 0.0   //v3
        ];
        this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.vertices), this.gl.STATIC_DRAW);
        this.vertexPositionBuffer.itemSize = 3;
        this.vertexPositionBuffer.numItems = 4;

        this.vertexColorBuffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexColorBuffer);
        this.colors = [
            1.0, 1.0, 1.0, 1.0,
            1.0, 0.0, 0.0, 1.0,
            0.0, 1.0, 0.0, 1.0,
            0.0, 0.0, 1.0, 1.0
        ];
        this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(this.colors), this.gl.STATIC_DRAW);
        this.vertexColorBuffer.itemSize = 4;
        this.vertexColorBuffer.numItems = 4;
        this.vertexIndexBuffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
        this.indices = [0, 1, 2, 0, 2, 3];
        this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(this.indices), this.gl.STATIC_DRAW);

        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);
    }

    private DrawScene() {
        this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
        mat4.rotate(this.mvMatrix, this.mvMatrix, 0.01, vec3.fromValues(1, 0, 0));

        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexPositionBuffer);
        this.gl.vertexAttribPointer(this.shaderProgram.vertexPositionAttribute, this.vertexPositionBuffer.itemSize, this.gl.FLOAT,
            false, 0, 0);

        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexColorBuffer);
        this.gl.vertexAttribPointer(this.shaderProgram.vertexColorAttribute, this.vertexColorBuffer.itemSize, this.gl.FLOAT,
            false, 0, 0);
        this.SetMatrixUniforms();
        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.vertexIndexBuffer);
        this.gl.drawElements(this.gl.TRIANGLES, this.indices.length, this.gl.UNSIGNED_SHORT, 0);
    }

    ...

}

window.onload = () => {
    var plane = new Plane();
}