import { BaseFramebuffer } from "./BaseFramebuffer";
import type { IBaseFramebufferParams } from "./BaseFramebuffer";
import { Handler } from "./Handler";
interface IMultisampleParams extends IBaseFramebufferParams {
msaa?: number;
internalFormat?: string;
}
/**
* Class represents multisample framebuffer.
* @class
* @param {Handler} handler - WebGL handler.
* @param {Object} [options] - Framebuffer options:
*/
export class Multisample extends BaseFramebuffer {
protected _internalFormat: string;
protected _msaa: number;
protected _glFilter: number;
public renderbuffers: WebGLRenderbuffer[];
constructor(handler: Handler, options: IMultisampleParams = {}) {
super(handler, options);
this._internalFormat = options.internalFormat ? options.internalFormat.toUpperCase() : "RGBA8";
this._msaa = options.msaa != undefined ? options.msaa : 4;
this._glFilter = 0;
this.renderbuffers = new Array(this._size);
}
public override destroy() {
let gl = this.handler.gl;
if (!gl) return;
for (let i = 0; i < this.renderbuffers.length; i++) {
gl.deleteRenderbuffer(this.renderbuffers[i]);
}
this.renderbuffers = new Array(this._size);
gl.deleteFramebuffer(this._fbo);
if (this._depthRenderbuffer) {
gl.deleteRenderbuffer(this._depthRenderbuffer);
}
this._depthRenderbuffer = null;
this._fbo = null;
this._active = false;
}
/**
* Framebuffer initialization.
* @public
*/
public override init() {
let gl = this.handler.gl;
if (!gl) return;
this._glFilter = (gl as any)[this._filter];
this._fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, this._fbo);
let colorAttachments = [];
for (let i = 0; i < this.renderbuffers.length; i++) {
let rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
if (this._msaa > 0) {
gl.renderbufferStorageMultisample(
gl.RENDERBUFFER,
this._msaa,
(gl as any)[this._internalFormat],
this._width,
this._height
);
} else {
gl.renderbufferStorage(gl.RENDERBUFFER, (gl as any)[this._internalFormat], this._width, this._height);
}
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0 + i, gl.RENDERBUFFER, rb);
colorAttachments.push(gl.COLOR_ATTACHMENT0 + i);
this.renderbuffers[i] = rb!;
gl.bindRenderbuffer(gl.RENDERBUFFER, null!);
}
gl.drawBuffers(colorAttachments);
if (this._useDepth) {
let depthRenderbuffer = this.sharedDepthRenderbuffer;
if (!depthRenderbuffer) {
this._depthRenderbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, this._depthRenderbuffer);
if (this._msaa > 0) {
gl.renderbufferStorageMultisample(
gl.RENDERBUFFER,
this._msaa,
(gl as any)[this._depthComponent],
this._width,
this._height
);
} else {
gl.renderbufferStorage(
gl.RENDERBUFFER,
(gl as any)[this._depthComponent],
this._width,
this._height
);
}
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
depthRenderbuffer = this._depthRenderbuffer;
}
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthRenderbuffer);
}
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
}
public blitTo(framebuffer: BaseFramebuffer, attachmentIndex: number = 0) {
BaseFramebuffer.blitTo(framebuffer, this, attachmentIndex, this.handler.gl!.COLOR_BUFFER_BIT, this._glFilter);
}
}