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(); | |
| } | |
| } | |