87 lines
2 KiB
TypeScript
87 lines
2 KiB
TypeScript
import { mat4, vec2 } from 'gl-matrix';
|
|
|
|
import Shaders from './Shaders';
|
|
|
|
export default class Renderer {
|
|
private readonly gl: WebGLRenderingContext;
|
|
private readonly shaders: Shaders;
|
|
|
|
private readonly center: vec2 = vec2.create();
|
|
private readonly translation: vec2 = vec2.create();
|
|
private readonly viewport: mat4 = mat4.create();
|
|
|
|
constructor(private readonly canvas: HTMLCanvasElement) {
|
|
this.gl = this.mkContext();
|
|
|
|
this.shaders = new Shaders(this.gl);
|
|
|
|
this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
|
|
|
|
this.gl.enable(this.gl.BLEND);
|
|
this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
|
|
this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
|
|
|
|
this.setSize();
|
|
}
|
|
|
|
public createBuffer(): WebGLBuffer {
|
|
const ret = this.gl.createBuffer();
|
|
if (!ret)
|
|
throw new Error('unable to create buffer');
|
|
|
|
return ret;
|
|
}
|
|
|
|
public getContext(): WebGLRenderingContext {
|
|
return this.gl;
|
|
}
|
|
|
|
public getVertexPosLoc(): number {
|
|
return this.shaders.vertexPosLoc;
|
|
}
|
|
|
|
public getTextureCoordLoc(): number {
|
|
return this.shaders.textureCoordLoc;
|
|
}
|
|
|
|
public getSamplerLoc(): WebGLUniformLocation {
|
|
return this.shaders.samplerLoc;
|
|
}
|
|
|
|
public setCenter(v: vec2|number[]) {
|
|
vec2.copy(this.center, v);
|
|
}
|
|
|
|
public setTranslation(v: vec2|number[]) {
|
|
vec2.sub(this.translation, v, this.center);
|
|
this.gl.uniform2fv(this.shaders.translateLoc, this.translation);
|
|
}
|
|
|
|
public clear(): void {
|
|
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
|
|
this.setTranslation([0, 0]);
|
|
}
|
|
|
|
private mkContext(): WebGLRenderingContext {
|
|
const gl = (
|
|
this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl')
|
|
);
|
|
if (!gl)
|
|
throw new Error('unable to initialize WebGL context');
|
|
|
|
return gl;
|
|
}
|
|
|
|
private setSize(): void {
|
|
const w = this.canvas.width;
|
|
const h = this.canvas.height;
|
|
|
|
this.gl.viewport(0, 0, w, h);
|
|
this.clear();
|
|
|
|
mat4.identity(this.viewport);
|
|
mat4.scale(this.viewport, this.viewport, [2 * 64 / w, -2 * 64 / h, 1.0]);
|
|
this.gl.uniformMatrix4fv(this.shaders.viewportLoc, false, this.viewport);
|
|
}
|
|
}
|