2 years ago

#76101

test-img

User One

WebGL requestAnimationFrame is drawing a blank screen

I'm trying to build a small 2d game and right now I'm stuck at a small progress bar. I'm trying to make it so whenever someone goes to the game, a progress bar will be animated by going to the other end. I learned that I should use requestAnimationFrame and change the dimensions of the rectangle, and pass in a function parameter, but when I tried it, it didn't work out. Here is the code:

beta.js

import { setStyle } from "./ui.js";
import * as g from './globals.js';
import Gl from "./gl.js";
import Load from "./load.js";

class Beta {
    canvas: HTMLCanvasElement;
    gl!: WebGL2RenderingContext;
    glHandler!: Gl;
    buildVersion!: number;

    constructor() {
        this.buildVersion = 1.00000;

        this.canvas = document.getElementById('betaMain') as HTMLCanvasElement;

        this.gl = this.canvas.getContext('webgl2') as WebGL2RenderingContext;
        this.glHandler = new Gl(this.gl);

        this._setWindowDefaults();
        this._setListeners();

        this.gl.clearColor(0.1, 0.1, 0.1, 1);
        this.gl.clear(this.gl.COLOR_BUFFER_BIT);
    }

    load() {
        const load = new Load(this.glHandler);
        load.drawLoaderBase();
        load.drawLoaderProgress();
    }

    _resizeCanvas() {
        this.canvas.width = window.innerWidth;
        this.canvas.height = window.innerHeight;
    }

    _setWindowDefaults() {
        this._resizeCanvas();
        g.updateGlobalCenters();
        g.updateGlobalDimensions();

        setStyle(document.body, 'margin', '0px');
        setStyle(document.body, 'padding', '0px');
        setStyle(document.body, 'overflow', 'hidden');
    }

    _setListeners() {
        $(window).on('resize', () => {
            this._resizeCanvas();
            g.updateGlobalCenters();
            g.updateGlobalDimensions();
        });
    }
}

$(window).on('load', () => {
    const beta = new Beta();
    beta.load();
});

load.js

import Gl from "./gl.js";

class Load {
    glHandler: Gl;
    gl: WebGL2RenderingContext;
    current: number;
    max: number;
    jump: number;
    start: any | undefined;
    previousTimeStamp: any | undefined;

    constructor(glHandler: Gl) {
        this.glHandler = glHandler;
        this.gl = glHandler.gl;

        this.max = 0.8;
        this.current = -0.8;
        this.jump = 0.01;
    }

    drawLoaderBase() {
        this.glHandler.drawQuad([
            -0.8, 0.01, 0.0,
            -0.8, -0.01, 0.0,
            0.8, -0.01, 0.0,
            0.8, 0.01, 0.0
        ], [0.15, 0.15, 0.15, 1]);
    }

    drawLoaderProgress() {
        this.glHandler.drawQuad([
            -0.8, 0.005, -1.0,
            -0.8, -0.005, -1.0,
            this.current, -0.005, -1.0,
            this.current, 0.005, -1.0
        ], [0.2, 0.2, 0.2, 1]);
        this.current += this.jump
    }
}

export default Load;

and gl.js (this is a file I created, hoping it could make reusable gl code).

class Gl {
    gl: WebGL2RenderingContext;

    constructor(gl: WebGL2RenderingContext) {
        this.gl = gl;
        if (gl === null) {
            alert('Unable to initiate WebGL. Your browser or machine may not suppport it.');
            return;
        }
    }

    drawQuad(vertices: Array<number>, color: Array<number>) {
        const indices = [3, 2, 1, 3, 1, 0];

        const vertextShaderSource = `
            attribute vec3 coordinates;
            void main(void) {
                gl_Position = vec4(coordinates, 1.0);
            }
        `;

        const fragmentShaderSource = `
            void main(void) {
                gl_FragColor = vec4(0.3, 0.3, 0.3, 1);
            }
        `;

        const vertexBuffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
        this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(vertices), this.gl.STATIC_DRAW);
        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, null);

        const indexBuffer = this.gl.createBuffer();
        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), this.gl.STATIC_DRAW);
        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, null);

        const vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER)!;
        this.gl.shaderSource(vertexShader, vertextShaderSource);
        this.gl.compileShader(vertexShader);

        const fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER)!;
        this.gl.shaderSource(fragmentShader, fragmentShaderSource);
        this.gl.compileShader(fragmentShader);

        const shaderProgram = this.gl.createProgram()!;
        this.gl.attachShader(shaderProgram, vertexShader);
        this.gl.attachShader(shaderProgram, fragmentShader);
        this.gl.linkProgram(shaderProgram);

        this.gl.useProgram(shaderProgram);

        this.gl.bindBuffer(this.gl.ARRAY_BUFFER, vertexBuffer);
        this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, indexBuffer);

        const coord = this.gl.getAttribLocation(shaderProgram, 'coordinates');

        const drawScene = () => {
            this.gl.vertexAttribPointer(coord, 3, this.gl.FLOAT, false, 0, 0);
            this.gl.enableVertexAttribArray(coord);

            this.gl.enable(this.gl.DEPTH_TEST);

            this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);

            this.gl.drawElements(this.gl.TRIANGLES, indices.length, this.gl.UNSIGNED_SHORT, 0);
            requestAnimationFrame(drawScene);
        }

        drawScene();
    }

    get glContext() {
        return this.gl;
    }
}

export default Gl;

Sorry that there are many lines of code that are not related. The many parts I think are important is the drawQuad function. I have tried to wrap some parts of the function in a drawscene method, and call request animation frame in there, but that didn't work. I also searched online and it said do not use setInterval. I would like to have a way to make the rectangle animate by resizing it's width.

Thanks.

javascript

animation

webgl

0 Answers

Your Answer

Accepted video resources