8Observer8

Let's create WebGL examples for practice

Recommended Posts

WebGL 1.0. Square translation using WASD and arrow keys

https://jsfiddle.net/tqnfyy53/

025_square_translation_using_keys.gif.fd3fa5d0b832905cc796aeea056f3fc5.gif

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 1.0. Square translation using WASD and arrow keys</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #aaaaaa;
        }
    </style>
</head>

<body>
    <p>Click here to active the window</p>
    <p>Use WASD or arrow keys</p>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `attribute vec2 a_Position;
            uniform mat4 u_ModelMatrix;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
            }`;

        var fragmentShaderSource =
            `precision mediump float;
            uniform vec3 u_Color;

            void main()
            {
                gl_FragColor = vec4(u_Color, 1.0);
            }`;

        var gl = document.getElementById("renderCanvas").getContext("webgl");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var vertices = new Float32Array([
            -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(a_Position);

        var u_Color = gl.getUniformLocation(program, "u_Color");
        gl.uniform3f(u_Color, 0.635, 0.450, 0.125);

        var modelMatrix = mat4.create();
        var pos = { x: 0.1, y: 0.1 };
        var step = 0.2;

        window.addEventListener('keydown', function (event)
        {
            if (event.keyCode === 87 || event.keyCode === 38) // W, Up
                pos.y += step;
            else if (event.keyCode === 65 || event.keyCode === 37) // A, Left
                pos.x -= step;
            else if (event.keyCode === 83 || event.keyCode === 40) // S, Down
                pos.y -= step;
            else if (event.keyCode === 68 || event.keyCode === 39) // D, Right
                pos.x += step;
            draw(pos);
        });

        draw(pos);

        function draw(pos)
        {
            mat4.identity(modelMatrix);
            mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(pos.x, pos.y, 0.0));
            mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(0.2, 0.2, 0.2));

            var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

            gl.clearColor(0.898, 0.984, 0.905, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

WebGL 2.0. Square translation using WASD and arrow keys

https://jsfiddle.net/14z5m5hh/

025_square_translation_using_keys.gif.84898fbef854266f216fc41524a8ba1e.gif

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 2.0. Square translation using WASD and arrow keys</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #aaaaaa;
        }
    </style>
</head>

<body>
    <p>Click here to active the window</p>
    <p>Use WASD or arrow keys</p>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `#version 300 es
            
            in vec2 a_Position;
            uniform mat4 u_ModelMatrix;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
            }`;

        var fragmentShaderSource =
            `#version 300 es
            
            precision mediump float;
            uniform vec3 u_Color;
            out vec4 fragColor;

            void main()
            {
                fragColor = vec4(u_Color, 1.0);
            }`;

        var gl = document.getElementById("renderCanvas").getContext("webgl2");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var vertices = new Float32Array([
            -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(a_Position);

        var u_Color = gl.getUniformLocation(program, "u_Color");
        gl.uniform3f(u_Color, 0.635, 0.450, 0.125);

        var modelMatrix = mat4.create();
        var pos = { x: 0.1, y: 0.1 };
        var step = 0.2;

        window.addEventListener('keydown', function (event)
        {
            if (event.keyCode === 87 || event.keyCode === 38) // W, Up
                pos.y += step;
            else if (event.keyCode === 65 || event.keyCode === 37) // A, Left
                pos.x -= step;
            else if (event.keyCode === 83 || event.keyCode === 40) // S, Down
                pos.y -= step;
            else if (event.keyCode === 68 || event.keyCode === 39) // D, Right
                pos.x += step;
            draw(pos);
        });

        draw(pos);

        function draw(pos)
        {
            mat4.identity(modelMatrix);
            mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(pos.x, pos.y, 0.0));
            mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(0.2, 0.2, 0.2));

            var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

            gl.clearColor(0.898, 0.984, 0.905, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

WebGL 1.0. Applying a texture to a square

https://jsfiddle.net/zjydm1ev/

026_applying_a_texture_to_a_square.png.61a92dc9f4031ebd13a184620a71d98d.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 1.0. Applying a texture to a square</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #aaaaaa;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `
            attribute vec2 a_Position;
            attribute vec2 a_TexCoord;
            uniform mat4 u_ModelMatrix;
            varying vec2 v_TexCoord;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
                v_TexCoord = a_TexCoord;
            }`;

        var fragmentShaderSource =
            `
            precision mediump float;
            uniform sampler2D u_Sampler;
            varying vec2 v_TexCoord;

            void main()
            {
                gl_FragColor = texture2D(u_Sampler, v_TexCoord);
            }`;

        var gl = document.getElementById("renderCanvas").getContext("webgl");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var verticesAndTexCoords = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,    // (x, y), (u, v)
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, verticesAndTexCoords, gl.STATIC_DRAW);

        var FSIZE = verticesAndTexCoords.BYTES_PER_ELEMENT;

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 4 * FSIZE, 0);
        gl.enableVertexAttribArray(a_Position);

        var a_TexCoord = gl.getAttribLocation(program, "a_TexCoord");
        gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * FSIZE, 2 * FSIZE);
        gl.enableVertexAttribArray(a_TexCoord);

        var image = new Image();

        image.onload = function ()
        {
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
            gl.activeTexture(gl.TEXTURE0);

            var texture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

            var u_Sampler = gl.getUniformLocation(program, "u_Sampler");
            gl.uniform1i(u_Sampler, 0);

            var modelMatrix = mat4.create();
            mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(1.5, 1.5, 1.5));

            var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

            gl.clearColor(0.898, 0.984, 0.905, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
        image.crossOrigin = "";
        image.src = 'https://dl.dropboxusercontent.com/s/xi091ya34qqzda2/lightblueflower.jpg';
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

WebGL 2.0. Applying a texture to a square

https://jsfiddle.net/gd2uo3jg/

026_applying_a_texture_to_a_square.png.701a7c799df8e118d3e907b4c717930f.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 2.0. Applying a texture to a square</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #aaaaaa;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `#version 300 es

            in vec2 a_Position;
            in vec2 a_TexCoord;
            uniform mat4 u_ModelMatrix;
            out vec2 v_TexCoord;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
                v_TexCoord = a_TexCoord;
            }`;

        var fragmentShaderSource =
            `#version 300 es

            precision mediump float;
            uniform sampler2D u_Sampler;
            in vec2 v_TexCoord;
            out vec4 fragColor;

            void main()
            {
                fragColor = texture(u_Sampler, v_TexCoord);
            }`;

        var gl = document.getElementById("renderCanvas").getContext("webgl2");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var verticesAndTexCoords = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,    // (x, y), (u, v)
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, verticesAndTexCoords, gl.STATIC_DRAW);

        var FSIZE = verticesAndTexCoords.BYTES_PER_ELEMENT;

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 4 * FSIZE, 0);
        gl.enableVertexAttribArray(a_Position);

        var a_TexCoord = gl.getAttribLocation(program, "a_TexCoord");
        gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * FSIZE, 2 * FSIZE);
        gl.enableVertexAttribArray(a_TexCoord);

        var image = new Image();

        image.onload = function ()
        {
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
            gl.activeTexture(gl.TEXTURE0);

            var texture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texImage2D(gl.TEXTURE_2D , 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);

            var u_Sampler = gl.getUniformLocation(program, "u_Sampler");
            gl.uniform1i(u_Sampler, 0);

            var modelMatrix = mat4.create();
            mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(1.5, 1.5, 1.5));

            var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

            gl.clearColor(0.898, 0.984, 0.905, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
        image.crossOrigin = "";
        image.src = 'https://dl.dropboxusercontent.com/s/xi091ya34qqzda2/lightblueflower.jpg';
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

WebGL 1.0. Rotation animation

https://jsfiddle.net/8Observer8/gLpowbe2/

27_rotation_animation.gif.b1930dbb4733e834ca378924bcddad03.gif

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 1.0. Rotation animation</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #a8bdc4;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `attribute vec2 a_Position;
            uniform mat4 u_ModelMatrix;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
            }`;

        var fragmentShaderSource =
            `precision mediump float;
            uniform vec3 u_Color;

            void main()
            {
                gl_FragColor = vec4(u_Color, 1.0);
            }`;

        var canvas = document.getElementById("renderCanvas");
        var gl = canvas.getContext("webgl");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var vertices = new Float32Array([
            -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(a_Position);

        var u_Color = gl.getUniformLocation(program, "u_Color");
        gl.uniform3f(u_Color, 0.207, 0.635, 0.125);

        var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");

        gl.clearColor(0.894, 0.976, 0.886, 1.0);

        var ANGLE_STEP = 45.0; // Rotation angle (degrees/second)
        var g_last = Date.now();

        var currentAngle = 0.0;
        var modelMatrix = mat4.create();

        var tick = function ()
        {
            currentAngle = animate(currentAngle);  // Update the rotation angle
            draw(4, currentAngle, modelMatrix, u_ModelMatrix);   // Draw the triangle
            requestAnimationFrame(tick, canvas); // Request that the browser calls tick
        };
        tick();

        function draw(n, currentAngle, modelMatrix, u_ModelMatrix)
        {
            mat4.identity(modelMatrix);
            mat4.rotateZ(modelMatrix, modelMatrix, currentAngle * Math.PI / 180);
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
        }

        function animate(angle)
        {
            // Calculate the elapsed time
            var now = Date.now();
            var elapsed = now - g_last;
            g_last = now;
            // Update the current rotation angle (adjusted by the elapsed time)
            var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
            return newAngle %= 360;
        }
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

WebGL 2.0. Rotation animation

https://jsfiddle.net/8Observer8/fLumroxa/

27_rotation_animation.gif.59e50fcfbc368276bec110ab11d1e575.gif

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>WebGL 2.0. Rotation animation</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.4.0/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #a8bdc4;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `#version 300 es

            in vec2 a_Position;
            uniform mat4 u_ModelMatrix;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
            }`;

        var fragmentShaderSource =
            `#version 300 es
            
            precision mediump float;
            uniform vec3 u_Color;
            out vec4 fragColor;

            void main()
            {
                fragColor = vec4(u_Color, 1.0);
            }`;

        var canvas = document.getElementById("renderCanvas");
        var gl = canvas.getContext("webgl2");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var vertices = new Float32Array([
            -0.5, 0.5, -0.5, -0.5, 0.5, 0.5, 0.5, -0.5
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(a_Position);

        var u_Color = gl.getUniformLocation(program, "u_Color");
        gl.uniform3f(u_Color, 0.207, 0.635, 0.125);

        var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");

        gl.clearColor(0.894, 0.976, 0.886, 1.0);

        var ANGLE_STEP = 45.0; // Rotation angle (degrees/second)
        var g_last = Date.now();

        var currentAngle = 0.0;
        var modelMatrix = mat4.create();

        var tick = function ()
        {
            currentAngle = animate(currentAngle);  // Update the rotation angle
            draw(4, currentAngle, modelMatrix, u_ModelMatrix);   // Draw the triangle
            requestAnimationFrame(tick, canvas); // Request that the browser calls tick
        };
        tick();

        function draw(n, currentAngle, modelMatrix, u_ModelMatrix)
        {
            mat4.identity(modelMatrix);
            mat4.rotateZ(modelMatrix, modelMatrix, currentAngle * Math.PI / 180);
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);
            gl.clear(gl.COLOR_BUFFER_BIT);
            gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
        }

        function animate(angle)
        {
            // Calculate the elapsed time
            var now = Date.now();
            var elapsed = now - g_last;
            g_last = now;
            // Update the current rotation angle (adjusted by the elapsed time)
            var newAngle = angle + (ANGLE_STEP * elapsed) / 1000.0;
            return newAngle %= 360;
        }
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites
I know how to improve workflow, productive of coding and code quality of our web Applications and Games. We can write specifications by Jasmine framework. I wrote a simple example how to write specs for Kata from CodeWars in TypeScript. It may be usefull for JS-developers too. See my short description and project on GitHub: https://goo.gl/DsuLXY This is an example how to run Jasmine Unit Tests in TS on Playground: https://goo.gl/Jrk6Zk I will rewrite my Snake Game to 3D with Unit Tests. I will give you a link on GitHub. Happy Coding!
grasshopper-summation-tdd-ts-200x500.png.da699ed9a483519f95dba238fa0faffe.png

Share this post


Link to post
Share on other sites

Textured Rectangle with Transforms using ES5, WebGL 1.0, glMatrix

Playground

textured-rect-with-transforms-webgl-es5-webgl.png.fbbfe189461679d608a73760632aabec.png

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Textured Rectangle with Transforms using WebGL 1.0, ES5</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min.js"></script>
    <style>
        #renderCanvas {
            border: 5px solid #aaaaaa;
        }
    </style>
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>

    <script>
        var vertexShaderSource =
            `
            attribute vec2 a_Position;
            attribute vec2 a_TexCoord;
            uniform mat4 u_ModelMatrix;
            varying vec2 v_TexCoord;

            void main()
            {
                gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
                v_TexCoord = a_TexCoord;
            }`;

        var fragmentShaderSource =
            `
            precision mediump float;
            uniform sampler2D u_Sampler;
            varying vec2 v_TexCoord;

            void main()
            {
                gl_FragColor = texture2D(u_Sampler, v_TexCoord);
            }`;

        var gl = document.getElementById("renderCanvas").getContext("webgl");

        var vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, vertexShaderSource);
        gl.compileShader(vShader);

        var fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, fragmentShaderSource);
        gl.compileShader(fShader);

        var program = gl.createProgram();
        gl.attachShader(program, vShader);
        gl.attachShader(program, fShader);
        gl.linkProgram(program);
        gl.useProgram(program);

        var verticesAndTexCoords = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,    // (x, y), (u, v)
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0
        ]);

        var vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, verticesAndTexCoords, gl.STATIC_DRAW);

        var FSIZE = verticesAndTexCoords.BYTES_PER_ELEMENT;

        var a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 4 * FSIZE, 0);
        gl.enableVertexAttribArray(a_Position);

        var a_TexCoord = gl.getAttribLocation(program, "a_TexCoord");
        gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * FSIZE, 2 * FSIZE);
        gl.enableVertexAttribArray(a_TexCoord);

        gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

        // Allows transperency with textures.
        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

        var image = new Image();

        image.onload = function()
        {
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
            gl.activeTexture(gl.TEXTURE0);

            var texture = gl.createTexture();
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

            var u_Sampler = gl.getUniformLocation(program, "u_Sampler");
            gl.uniform1i(u_Sampler, 0);

            var modelMatrix = mat4.create();
            mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(0, 0.5, 0));
            mat4.rotateZ(modelMatrix, modelMatrix, 20.0 * Math.PI / 180.0);
            mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(1 * 2.0, 1, 1));

            var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
            gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

            gl.clearColor(0.898, 0.984, 0.905, 1.0);
            gl.clear(gl.COLOR_BUFFER_BIT);

            gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
        }
        image.crossOrigin = "";
        image.src = "https://dl.dropboxusercontent.com/s/nxvziah1a7n9txd/256px-WebGL_Logo.svg.png";
    </script>
</body>

</html>

 

Share this post


Link to post
Share on other sites

Textured Rectangle with Transforms using Webgl2, glMatrix, and TypeScript

Playground: https://plnkr.co/edit/OxENcZjrW1SeaGi3ncy9?p=preview

Source code: textured-rect-with-transforms-webgl2-typescript.zip

textured-rect-with-transforms-webgl-es5-webgl.png.4be7928c3195e9da7472967225a59a37.png

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Textured Rectangle with Transforms using WebGL 2.0, glMatrix, and TypeScript</title>
    <script data-main="dist/RequireConfig" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js"></script>
    <link rel="stylesheet" href="css/style.css">
</head>

<body>
    <canvas id="renderCanvas" width="250" height="250"></canvas>
</body>

</html>

style.css

#renderCanvas {
    border: 5px solid #aaaaaa;
}

Program.ts

import { Scene } from "./Scene";

class Program
{
    public static Main(): void
    {
        let scene = new Scene("renderCanvas");
    }
}
Program.Main();

RequireConfig.ts

requirejs.config({
    baseUrl: "dist",
    paths: {
        "gl-matrix": "https://cdnjs.cloudflare.com/ajax/libs/gl-matrix/2.8.1/gl-matrix-min"
    }
});

requirejs(["Program"], (Program) =>
{

});

Scene.ts

import { ShaderProgram } from "./ShaderProgram";
import { mat4, vec3 } from "gl-matrix";

export class Scene
{
    private _shaderProgram: ShaderProgram;

    public constructor(canvasName: string)
    {
        this._shaderProgram = new ShaderProgram(canvasName);
        let gl = this._shaderProgram.GetGL();

        this.Init();
    }

    private Init()
    {
        var verticesAndTexCoords = new Float32Array([
            -0.5, 0.5, 0.0, 1.0,    // (x, y), (u, v)
            -0.5, -0.5, 0.0, 0.0,
            0.5, 0.5, 1.0, 1.0,
            0.5, -0.5, 1.0, 0.0
        ]);

        let gl = this._shaderProgram.GetGL();
        let program = this._shaderProgram.GetProgram();

        let vbo = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
        gl.bufferData(gl.ARRAY_BUFFER, verticesAndTexCoords, gl.STATIC_DRAW);

        let FSIZE = verticesAndTexCoords.BYTES_PER_ELEMENT;

        let a_Position = gl.getAttribLocation(program, "a_Position");
        gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 4 * FSIZE, 0);
        gl.enableVertexAttribArray(a_Position);

        let a_TexCoord = gl.getAttribLocation(program, "a_TexCoord");
        gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, 4 * FSIZE, 2 * FSIZE);
        gl.enableVertexAttribArray(a_TexCoord);

        gl.enable(gl.BLEND);
        gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

        let image = new Image();
        image.onload = () => { this.OnImageLoaded(image); };
        image.crossOrigin = "";
        image.src = "https://dl.dropboxusercontent.com/s/nxvziah1a7n9txd/256px-WebGL_Logo.svg.png";
    }

    private OnImageLoaded(image: HTMLImageElement)
    {
        let gl = this._shaderProgram.GetGL();
        let program = this._shaderProgram.GetProgram();

        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
        gl.activeTexture(gl.TEXTURE0);

        var texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, texture);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

        var u_Sampler = gl.getUniformLocation(program, "u_Sampler");
        gl.uniform1i(u_Sampler, 0);

        var modelMatrix = mat4.create();
        mat4.translate(modelMatrix, modelMatrix, vec3.fromValues(0, 0.5, 0));
        mat4.rotateZ(modelMatrix, modelMatrix, 20.0 * Math.PI / 180.0);
        mat4.scale(modelMatrix, modelMatrix, vec3.fromValues(1 * 2.0, 1, 1));

        var u_ModelMatrix = gl.getUniformLocation(program, "u_ModelMatrix");
        gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);

        gl.clearColor(0.898, 0.984, 0.905, 1.0);
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    }
}

ShaderProgram.ts


export class ShaderProgram
{
    private _gl: WebGLRenderingContext;
    private _program: WebGLProgram;

    private _vertexShaderSource =
    `#version 300 es

    in vec2 a_Position;
    in vec2 a_TexCoord;
    uniform mat4 u_ModelMatrix;
    out vec2 v_TexCoord;

    void main()
    {
        gl_Position = u_ModelMatrix * vec4(a_Position, 0.0, 1.0);
        v_TexCoord = a_TexCoord;
    }`;

    private _fragmentShaderSource =
    `#version 300 es

    precision mediump float;
    uniform sampler2D u_Sampler;
    in vec2 v_TexCoord;
    out vec4 fragColor;

    void main()
    {
        fragColor = texture(u_Sampler, v_TexCoord);
    }`;

    public constructor(canvasName: string)
    {
        let canvas = document.getElementById(canvasName) as HTMLCanvasElement;
        this._gl = canvas.getContext("webgl2") as WebGLRenderingContext;

        let gl = this._gl;

        let vShader = gl.createShader(gl.VERTEX_SHADER);
        gl.shaderSource(vShader, this._vertexShaderSource);
        gl.compileShader(vShader);

        let fShader = gl.createShader(gl.FRAGMENT_SHADER);
        gl.shaderSource(fShader, this._fragmentShaderSource);
        gl.compileShader(fShader);

        this._program = gl.createProgram();
        gl.attachShader(this._program, vShader);
        gl.attachShader(this._program, fShader);
        gl.linkProgram(this._program);
        gl.useProgram(this._program);
    }

    public GetGL(): WebGLRenderingContext
    {
        return this._gl;
    }

    public GetProgram(): WebGLProgram
    {
        return this._program;
    }
}

package.json

{
  "name": "textured-rect-with-transforms-webgl2-typescript",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/gl-matrix": "^2.4.4",
    "@types/requirejs": "^2.1.31"
  }
}

tsconfig.json

{
    "compilerOptions": {
        "module": "amd",
        "sourceMap": true,
        "outDir": "dist",
        "target": "es5"
    },
    "exclude": [
        "node_modules"
    ]
}

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.