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 {
|
|
|
|
render(gl: WebGLRenderingContext): void;
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Renderer {
|
|
|
|
renderables: Renderable[];
|
|
|
|
|
|
|
|
indexBuffers: IndexBuffer[];
|
|
|
|
vertexArrays: VertexArray[];
|
|
|
|
shaders: Shader[];
|
|
|
|
textures: Texture[];
|
2019-09-19 17:52:48 +02:00
|
|
|
uniforms: Dictionary<Uniform>[];
|
2019-09-16 21:18:01 +02:00
|
|
|
|
|
|
|
constructor() {
|
|
|
|
this.indexBuffers = [];
|
|
|
|
this.vertexArrays = [];
|
|
|
|
this.shaders = [];
|
|
|
|
this.textures = [];
|
2019-09-19 17:52:48 +02:00
|
|
|
this.uniforms = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
updateUniform(i: number, f: (uniforms: Dictionary<Uniform>) => void) {
|
|
|
|
f(this.uniforms[i]);
|
2019-09-16 21:18:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
addRenderable(item: Renderable) {
|
|
|
|
this.renderables.push(item);
|
|
|
|
}
|
|
|
|
|
2019-09-19 17:52:48 +02:00
|
|
|
addToDraw(indexBuffer: IndexBuffer, vertexArray: VertexArray, shader: Shader, uniforms: Dictionary<Uniform>,texture?: Texture): number {
|
2019-09-16 21:18:01 +02:00
|
|
|
this.indexBuffers.push(indexBuffer);
|
|
|
|
this.vertexArrays.push(vertexArray);
|
|
|
|
this.shaders.push(shader);
|
|
|
|
this.textures.push(texture);
|
|
|
|
|
2019-09-19 17:52:48 +02:00
|
|
|
this.uniforms.push(uniforms);
|
|
|
|
|
|
|
|
|
2019-09-16 21:18:01 +02:00
|
|
|
return this.indexBuffers.length - 1;
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
let texLocation = 0;
|
|
|
|
|
|
|
|
for(let i = 0; i < this.indexBuffers.length; i ++) {
|
|
|
|
const indexBuffer = this.indexBuffers[i];
|
|
|
|
const vertexArray = this.vertexArrays[i];
|
2019-09-19 17:52:48 +02:00
|
|
|
const uniforms = this.uniforms[i];
|
|
|
|
|
2019-09-16 21:18:01 +02:00
|
|
|
const shader = this.shaders[i];
|
|
|
|
const texture = this.textures[i];
|
|
|
|
|
|
|
|
if (texture) {
|
|
|
|
|
|
|
|
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!");
|
|
|
|
}
|
|
|
|
}
|
2019-09-19 17:52:48 +02:00
|
|
|
|
|
|
|
if (vertexArray && shader && uniforms) {
|
|
|
|
for(let key in uniforms) {
|
|
|
|
shader.uniform(gl, key, uniforms[key]);
|
|
|
|
}
|
|
|
|
|
2019-09-16 21:18:01 +02:00
|
|
|
vertexArray.bind(gl, shader);
|
2019-09-19 17:52:48 +02:00
|
|
|
|
2019-09-16 21:18:01 +02:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|