planet-wars/frontend/www/webgl/renderer.ts

127 lines
3.4 KiB
TypeScript
Raw Normal View History

2019-09-16 21:18:01 +02:00
import { IndexBuffer } from './buffer';
2019-09-19 17:52:48 +02:00
import { Shader, Uniform1i, Uniform } from './shader';
2019-09-16 21:18:01 +02:00
import { VertexArray } from './vertexBufferLayout';
import { Texture } from './texture';
2019-09-19 17:52:48 +02:00
import { Dictionary } from './util';
2019-09-16 21:18:01 +02:00
export interface Renderable {
getUniforms() : Dictionary<Uniform>;
2019-09-16 21:18:01 +02:00
render(gl: WebGLRenderingContext): void;
}
export class RenderShit implements Renderable {
2019-09-20 17:48:00 +02:00
ibo: IndexBuffer;
va: VertexArray;
shader: Shader;
2019-09-16 21:18:01 +02:00
textures: Texture[];
2019-09-20 17:48:00 +02:00
uniforms: Dictionary<Uniform>;
constructor(
ibo: IndexBuffer,
va: VertexArray,
shader: Shader,
textures: Texture[],
uniforms: Dictionary<Uniform>,
) {
this.ibo = ibo;
this.va = va;
this.shader = shader;
this.textures = textures;
this.uniforms = uniforms;
}
getUniforms(): Dictionary<Uniform> {
return this.uniforms;
}
2019-09-20 17:48:00 +02:00
render(gl: WebGLRenderingContext): void {
const indexBuffer = this.ibo;
const vertexArray = this.va;
const uniforms = this.uniforms;
const shader = this.shader;
const textures = this.textures;
let texLocation = 0;
for (let texture of textures) {
shader.uniform(gl, texture.name, new Uniform1i(texLocation));
texture.bind(gl, texLocation);
texLocation ++;
// if (texLocation > maxTextures) {
// console.error("Using too many textures, this is not supported yet\nUndefined behaviour!");
// }
}
if (vertexArray && shader && uniforms) {
for(let key in uniforms) {
shader.uniform(gl, key, uniforms[key]);
}
vertexArray.bind(gl, shader);
if (indexBuffer) {
indexBuffer.bind(gl);
gl.drawElements(gl.TRIANGLES, indexBuffer.getCount(), gl.UNSIGNED_SHORT, 0);
} else {
console.error("IndexBuffer is required to render, for now");
}
}
}
}
export class Renderer {
renderables: [Renderable, boolean][];
2019-09-16 21:18:01 +02:00
constructor() {
2019-09-20 17:48:00 +02:00
this.renderables = [];
2019-09-19 17:52:48 +02:00
}
updateUniform(i: number, f: (uniforms: Dictionary<Uniform>) => void) {
f(this.renderables[i][0].getUniforms());
2019-09-16 21:18:01 +02:00
}
2019-09-20 17:48:00 +02:00
disableRenderShift(i: number) {
this.renderables[i][1] = false;
2019-09-16 21:18:01 +02:00
}
2019-09-20 17:48:00 +02:00
enableRendershit(i: number) {
this.renderables[i][1] = true;
2019-09-20 17:48:00 +02:00
}
addRenderable(item: Renderable): number {
this.renderables.push([item, true]);
return this.renderables.length - 1;
}
2019-09-16 21:18:01 +02:00
2019-09-20 17:48:00 +02:00
addToDraw(indexBuffer: IndexBuffer, vertexArray: VertexArray, shader: Shader, uniforms?: Dictionary<Uniform>, texture?: Texture[]): number {
return this.addRenderable(
2019-09-20 17:48:00 +02:00
new RenderShit(
indexBuffer,
vertexArray,
shader,
texture || [],
uniforms || {},
)
);
2019-09-16 21:18:01 +02:00
}
2019-09-19 17:52:48 +02:00
render(gl: WebGLRenderingContext, frameBuffer?: WebGLFramebuffer, width?: number, height?: number) {
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.viewport(0, 0, width || gl.canvas.width, height || gl.canvas.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
2019-09-16 21:18:01 +02:00
const maxTextures = gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS);
2019-09-19 17:52:48 +02:00
for (let [r, e] of this.renderables) {
if (!e) continue;
2019-09-20 17:48:00 +02:00
r.render(gl);
2019-09-16 21:18:01 +02:00
}
2019-09-20 17:48:00 +02:00
2019-09-16 21:18:01 +02:00
}
}