UNPKG

playcanvas

Version:

PlayCanvas WebGL game engine

193 lines (190 loc) 5.38 kB
import { PIXELFORMAT_DEPTH, PIXELFORMAT_DEPTH16, PIXELFORMAT_DEPTHSTENCIL, PIXELFORMAT_R32F, isSrgbPixelFormat } from './constants.js'; import { TextureUtils } from './texture-utils.js'; let id = 0; class RenderTarget { constructor(options = {}){ this.id = id++; const device = options.colorBuffer?.device ?? options.colorBuffers?.[0].device ?? options.depthBuffer?.device ?? options.graphicsDevice; this._device = device; const { maxSamples } = this._device; this._samples = Math.min(options.samples ?? 1, maxSamples); if (device.isWebGPU) { this._samples = this._samples > 1 ? maxSamples : 1; } this._colorBuffer = options.colorBuffer; if (options.colorBuffer) { this._colorBuffers = [ options.colorBuffer ]; } this._depthBuffer = options.depthBuffer; this._face = options.face ?? 0; if (this._depthBuffer) { const format = this._depthBuffer._format; if (format === PIXELFORMAT_DEPTH || format === PIXELFORMAT_DEPTH16) { this._depth = true; this._stencil = false; } else if (format === PIXELFORMAT_DEPTHSTENCIL) { this._depth = true; this._stencil = true; } else if (format === PIXELFORMAT_R32F && this._depthBuffer.device.isWebGPU && this._samples > 1) { this._depth = true; this._stencil = false; } else { this._depth = false; this._stencil = false; } } else { this._depth = options.depth ?? true; this._stencil = options.stencil ?? false; } if (options.colorBuffers) { if (!this._colorBuffers) { this._colorBuffers = [ ...options.colorBuffers ]; this._colorBuffer = options.colorBuffers[0]; } } this.autoResolve = options.autoResolve ?? true; this.name = options.name; if (!this.name) { this.name = this._colorBuffer?.name; } if (!this.name) { this.name = this._depthBuffer?.name; } if (!this.name) { this.name = 'Untitled'; } this.flipY = options.flipY ?? false; this._mipLevel = options.mipLevel ?? 0; if (this._mipLevel > 0 && this._depth) { this._mipLevel = 0; } this._mipmaps = options.mipLevel === undefined; this.validateMrt(); this.impl = device.createRenderTargetImpl(this); } destroy() { const device = this._device; if (device) { device.targets.delete(this); if (device.renderTarget === this) { device.setRenderTarget(null); } this.destroyFrameBuffers(); } } destroyFrameBuffers() { const device = this._device; if (device) { this.impl.destroy(device); } } destroyTextureBuffers() { this._depthBuffer?.destroy(); this._depthBuffer = null; this._colorBuffers?.forEach((colorBuffer)=>{ colorBuffer.destroy(); }); this._colorBuffers = null; this._colorBuffer = null; } resize(width, height) { if (this.width !== width || this.height !== height) { if (this.mipLevel > 0) { return; } const device = this._device; this.destroyFrameBuffers(); if (device.renderTarget === this) { device.setRenderTarget(null); } this._depthBuffer?.resize(width, height); this._colorBuffers?.forEach((colorBuffer)=>{ colorBuffer.resize(width, height); }); this.validateMrt(); this.impl = device.createRenderTargetImpl(this); } } validateMrt() {} init() { this.impl.init(this._device, this); } get initialized() { return this.impl.initialized; } get device() { return this._device; } loseContext() { this.impl.loseContext(); } resolve(color = true, depth = !!this._depthBuffer) { if (this._device && this._samples > 1) { this.impl.resolve(this._device, this, color, depth); } } copy(source, color, depth) { if (!this._device) { if (source._device) { this._device = source._device; } else { return false; } } const success = this._device.copyRenderTarget(source, this, color, depth); return success; } get samples() { return this._samples; } get depth() { return this._depth; } get stencil() { return this._stencil; } get colorBuffer() { return this._colorBuffer; } getColorBuffer(index) { return this._colorBuffers?.[index]; } get depthBuffer() { return this._depthBuffer; } get face() { return this._face; } get mipLevel() { return this._mipLevel; } get mipmaps() { return this._mipmaps; } get width() { let width = this._colorBuffer?.width || this._depthBuffer?.width || this._device.width; if (this._mipLevel > 0) { width = TextureUtils.calcLevelDimension(width, this._mipLevel); } return width; } get height() { let height = this._colorBuffer?.height || this._depthBuffer?.height || this._device.height; if (this._mipLevel > 0) { height = TextureUtils.calcLevelDimension(height, this._mipLevel); } return height; } isColorBufferSrgb(index = 0) { if (this.device.backBuffer === this) { return isSrgbPixelFormat(this.device.backBufferFormat); } const colorBuffer = this.getColorBuffer(index); return colorBuffer ? isSrgbPixelFormat(colorBuffer.format) : false; } } export { RenderTarget };