@cesium/engine
Version:
CesiumJS is a JavaScript library for creating 3D globes and 2D maps in a web browser without a plugin.
137 lines (123 loc) • 4.06 kB
JavaScript
import Check from "../Core/Check.js";
import Frozen from "../Core/Frozen.js";
import defined from "../Core/defined.js";
import destroyObject from "../Core/destroyObject.js";
import DeveloperError from "../Core/DeveloperError.js";
import Framebuffer from "./Framebuffer.js";
/**
* Creates a multisampling wrapper around two framebuffers with optional initial
* color and depth-stencil attachments. The first framebuffer has multisampled
* renderbuffer attachments and is bound to READ_FRAMEBUFFER during the blit. The
* second is bound to DRAW_FRAMEBUFFER during the blit, and has texture attachments
* to store the copied pixels.
*
* @param {object} options Object with the following properties:
* @param {Context} options.context
* @param {number} options.width
* @param {number} options.height
* @param {Texture[]} [options.colorTextures]
* @param {Renderbuffer[]} [options.colorRenderbuffers]
* @param {Texture} [options.depthStencilTexture]
* @param {Renderbuffer} [options.depthStencilRenderbuffer]
* @param {boolean} [options.destroyAttachments]
*
* @exception {DeveloperError} Both color renderbuffer and texture attachments must be provided.
* @exception {DeveloperError} Both depth-stencil renderbuffer and texture attachments must be provided.
*
* @private
* @constructor
*/
function MultisampleFramebuffer(options) {
options = options ?? Frozen.EMPTY_OBJECT;
const {
context,
width,
height,
colorRenderbuffers,
colorTextures,
depthStencilRenderbuffer,
depthStencilTexture,
destroyAttachments,
} = options;
//>>includeStart('debug', pragmas.debug);
Check.defined("options.context", context);
Check.defined("options.width", width);
Check.defined("options.height", height);
//>>includeEnd('debug');
this._width = width;
this._height = height;
if (defined(colorRenderbuffers) !== defined(colorTextures)) {
throw new DeveloperError(
"Both color renderbuffer and texture attachments must be provided.",
);
}
if (defined(depthStencilRenderbuffer) !== defined(depthStencilTexture)) {
throw new DeveloperError(
"Both depth-stencil renderbuffer and texture attachments must be provided.",
);
}
this._renderFramebuffer = new Framebuffer({
context: context,
colorRenderbuffers: colorRenderbuffers,
depthStencilRenderbuffer: depthStencilRenderbuffer,
destroyAttachments: destroyAttachments,
});
this._colorFramebuffer = new Framebuffer({
context: context,
colorTextures: colorTextures,
depthStencilTexture: depthStencilTexture,
destroyAttachments: destroyAttachments,
});
}
MultisampleFramebuffer.prototype.getRenderFramebuffer = function () {
return this._renderFramebuffer;
};
MultisampleFramebuffer.prototype.getColorFramebuffer = function () {
return this._colorFramebuffer;
};
/**
* Copy from the render framebuffer to the color framebuffer, resolving the stencil.
*
* @param {Context} context
* @param {boolean} blitStencil <code>true</code> if the stencil mask should be applied.
*
* @private
*/
MultisampleFramebuffer.prototype.blitFramebuffers = function (
context,
blitStencil,
) {
this._renderFramebuffer.bindRead();
this._colorFramebuffer.bindDraw();
const gl = context._gl;
let mask = 0;
if (this._colorFramebuffer._colorTextures.length > 0) {
mask |= gl.COLOR_BUFFER_BIT;
}
if (defined(this._colorFramebuffer.depthStencilTexture)) {
mask |= gl.DEPTH_BUFFER_BIT | (blitStencil ? gl.STENCIL_BUFFER_BIT : 0);
}
gl.blitFramebuffer(
0,
0,
this._width,
this._height,
0,
0,
this._width,
this._height,
mask,
gl.NEAREST,
);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
};
MultisampleFramebuffer.prototype.isDestroyed = function () {
return false;
};
MultisampleFramebuffer.prototype.destroy = function () {
this._renderFramebuffer.destroy();
this._colorFramebuffer.destroy();
return destroyObject(this);
};
export default MultisampleFramebuffer;