Spaces:
Running
Running
import type { Scene } from "../core/Scene"; | |
import { FadeInPass } from "./webgl/passes/FadeInPass"; | |
import { Camera } from "../cameras/Camera"; | |
import { Color32 } from "../math/Color32"; | |
import { ShaderProgram } from "./webgl/programs/ShaderProgram"; | |
import { RenderProgram } from "./webgl/programs/RenderProgram"; | |
import { ShaderPass } from "./webgl/passes/ShaderPass"; | |
export class WebGLRenderer { | |
private _canvas: HTMLCanvasElement; | |
private _gl: WebGL2RenderingContext; | |
private _backgroundColor: Color32 = new Color32(); | |
private _renderProgram: RenderProgram; | |
addProgram: (program: ShaderProgram) => void; | |
removeProgram: (program: ShaderProgram) => void; | |
resize: () => void; | |
setSize: (width: number, height: number) => void; | |
render: (scene: Scene, camera: Camera) => void; | |
dispose: () => void; | |
constructor(optionalCanvas: HTMLCanvasElement | null = null, optionalRenderPasses: ShaderPass[] | null = null) { | |
const canvas: HTMLCanvasElement = optionalCanvas || document.createElement("canvas"); | |
if (!optionalCanvas) { | |
canvas.style.display = "block"; | |
canvas.style.boxSizing = "border-box"; | |
canvas.style.width = "100%"; | |
canvas.style.height = "100%"; | |
canvas.style.margin = "0"; | |
canvas.style.padding = "0"; | |
document.body.appendChild(canvas); | |
} | |
canvas.style.background = this._backgroundColor.toHexString(); | |
this._canvas = canvas; | |
this._gl = canvas.getContext("webgl2", { antialias: false }) as WebGL2RenderingContext; | |
const renderPasses = optionalRenderPasses || []; | |
if (!optionalRenderPasses) { | |
renderPasses.push(new FadeInPass()); | |
} | |
this._renderProgram = new RenderProgram(this, renderPasses); | |
const programs = [this._renderProgram] as ShaderProgram[]; | |
this.resize = () => { | |
const width = canvas.clientWidth; | |
const height = canvas.clientHeight; | |
if (canvas.width !== width || canvas.height !== height) { | |
this.setSize(width, height); | |
} | |
}; | |
this.setSize = (width: number, height: number) => { | |
canvas.width = width; | |
canvas.height = height; | |
this._gl.viewport(0, 0, canvas.width, canvas.height); | |
for (const program of programs) { | |
program.resize(); | |
} | |
}; | |
this.render = (scene: Scene, camera: Camera) => { | |
for (const program of programs) { | |
program.render(scene, camera); | |
} | |
}; | |
this.dispose = () => { | |
for (const program of programs) { | |
program.dispose(); | |
} | |
}; | |
this.addProgram = (program: ShaderProgram) => { | |
programs.push(program); | |
}; | |
this.removeProgram = (program: ShaderProgram) => { | |
const index = programs.indexOf(program); | |
if (index < 0) { | |
throw new Error("Program not found"); | |
} | |
programs.splice(index, 1); | |
}; | |
this.resize(); | |
} | |
get canvas() { | |
return this._canvas; | |
} | |
get gl() { | |
return this._gl; | |
} | |
get renderProgram() { | |
return this._renderProgram; | |
} | |
get backgroundColor() { | |
return this._backgroundColor; | |
} | |
set backgroundColor(value: Color32) { | |
this._backgroundColor = value; | |
this._canvas.style.background = value.toHexString(); | |
} | |
} | |