2 years ago
#76101
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