playcanvas
Version:
PlayCanvas WebGL game engine
174 lines (171 loc) • 4.59 kB
JavaScript
import { Color } from '../../core/math/color.js';
import { isIntegerPixelFormat } from './constants.js';
class ColorAttachmentOps {
constructor(){
this.clearValue = new Color(0, 0, 0, 1);
this.clearValueLinear = new Color(0, 0, 0, 1);
this.clear = false;
this.store = false;
this.resolve = true;
this.genMipmaps = false;
}
}
class DepthStencilAttachmentOps {
constructor(){
this.clearDepthValue = 1;
this.clearStencilValue = 0;
this.clearDepth = false;
this.clearStencil = false;
this.storeDepth = false;
this.resolveDepth = false;
this.storeStencil = false;
}
}
class RenderPass {
get colorOps() {
return this.colorArrayOps[0];
}
constructor(graphicsDevice){
this._enabled = true;
this._skipStart = false;
this._skipEnd = false;
this.executeEnabled = true;
this.samples = 0;
this.colorArrayOps = [];
this.requiresCubemaps = true;
this.fullSizeClearRect = true;
this.beforePasses = [];
this.afterPasses = [];
this.device = graphicsDevice;
}
set name(value) {
this._name = value;
}
get name() {
if (!this._name) {
this._name = this.constructor.name;
}
return this._name;
}
set scaleX(value) {
this._options.scaleX = value;
}
get scaleX() {
return this._options.scaleX;
}
set scaleY(value) {
this._options.scaleY = value;
}
get scaleY() {
return this._options.scaleY;
}
set options(value) {
this._options = value;
if (value) {
this.scaleX = this.scaleX ?? 1;
this.scaleY = this.scaleY ?? 1;
}
}
get options() {
return this._options;
}
init(renderTarget = null, options) {
this.options = options;
this.renderTarget = renderTarget;
this.samples = Math.max(this.renderTarget ? this.renderTarget.samples : this.device.samples, 1);
this.allocateAttachments();
this.postInit();
}
allocateAttachments() {
const rt = this.renderTarget;
this.depthStencilOps = new DepthStencilAttachmentOps();
if (rt?.depthBuffer) {
this.depthStencilOps.storeDepth = true;
}
const numColorOps = rt ? rt._colorBuffers?.length ?? 0 : 1;
this.colorArrayOps.length = 0;
for(let i = 0; i < numColorOps; i++){
const colorOps = new ColorAttachmentOps();
this.colorArrayOps[i] = colorOps;
if (this.samples === 1) {
colorOps.store = true;
colorOps.resolve = false;
}
const colorBuffer = this.renderTarget?._colorBuffers?.[i];
if (this.renderTarget?.mipmaps && colorBuffer?.mipmaps) {
const intFormat = isIntegerPixelFormat(colorBuffer._format);
colorOps.genMipmaps = !intFormat;
}
}
}
destroy() {}
postInit() {}
frameUpdate() {
if (this._options && this.renderTarget) {
const resizeSource = this._options.resizeSource ?? this.device.backBuffer;
const width = Math.floor(resizeSource.width * this.scaleX);
const height = Math.floor(resizeSource.height * this.scaleY);
this.renderTarget.resize(width, height);
}
}
before() {}
execute() {}
after() {}
onEnable() {}
onDisable() {}
set enabled(value) {
if (this._enabled !== value) {
this._enabled = value;
if (value) {
this.onEnable();
} else {
this.onDisable();
}
}
}
get enabled() {
return this._enabled;
}
setClearColor(color) {
const count = this.colorArrayOps.length;
for(let i = 0; i < count; i++){
const colorOps = this.colorArrayOps[i];
if (color) {
colorOps.clearValue.copy(color);
colorOps.clearValueLinear.linear(color);
}
colorOps.clear = !!color;
}
}
setClearDepth(depthValue) {
if (depthValue !== undefined) {
this.depthStencilOps.clearDepthValue = depthValue;
}
this.depthStencilOps.clearDepth = depthValue !== undefined;
}
setClearStencil(stencilValue) {
if (stencilValue !== undefined) {
this.depthStencilOps.clearStencilValue = stencilValue;
}
this.depthStencilOps.clearStencil = stencilValue !== undefined;
}
render() {
if (this.enabled) {
const device = this.device;
const realPass = this.renderTarget !== undefined;
this.before();
if (this.executeEnabled) {
if (realPass && !this._skipStart) {
device.startRenderPass(this);
}
this.execute();
if (realPass && !this._skipEnd) {
device.endRenderPass(this);
}
}
this.after();
device.renderPassIndex++;
}
}
}
export { RenderPass };