123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438 |
- import Check from "../Core/Check.js";
- import defaultValue from "../Core/defaultValue.js";
- import defined from "../Core/defined.js";
- import destroyObject from "../Core/destroyObject.js";
- import DeveloperError from "../Core/DeveloperError.js";
- import PixelFormat from "../Core/PixelFormat.js";
- import ContextLimits from "./ContextLimits.js";
- import PixelDatatype from "./PixelDatatype.js";
- function attachTexture(framebuffer, attachment, texture) {
- var gl = framebuffer._gl;
- gl.framebufferTexture2D(
- gl.FRAMEBUFFER,
- attachment,
- texture._target,
- texture._texture,
- 0
- );
- }
- function attachRenderbuffer(framebuffer, attachment, renderbuffer) {
- var gl = framebuffer._gl;
- gl.framebufferRenderbuffer(
- gl.FRAMEBUFFER,
- attachment,
- gl.RENDERBUFFER,
- renderbuffer._getRenderbuffer()
- );
- }
- function Framebuffer(options) {
- options = defaultValue(options, defaultValue.EMPTY_OBJECT);
- var context = options.context;
-
- Check.defined("options.context", context);
-
- var gl = context._gl;
- var maximumColorAttachments = ContextLimits.maximumColorAttachments;
- this._gl = gl;
- this._framebuffer = gl.createFramebuffer();
- this._colorTextures = [];
- this._colorRenderbuffers = [];
- this._activeColorAttachments = [];
- this._depthTexture = undefined;
- this._depthRenderbuffer = undefined;
- this._stencilRenderbuffer = undefined;
- this._depthStencilTexture = undefined;
- this._depthStencilRenderbuffer = undefined;
-
- this.destroyAttachments = defaultValue(options.destroyAttachments, true);
-
-
-
- if (defined(options.colorTextures) && defined(options.colorRenderbuffers)) {
- throw new DeveloperError(
- "Cannot have both color texture and color renderbuffer attachments."
- );
- }
- if (defined(options.depthTexture) && defined(options.depthRenderbuffer)) {
- throw new DeveloperError(
- "Cannot have both a depth texture and depth renderbuffer attachment."
- );
- }
- if (
- defined(options.depthStencilTexture) &&
- defined(options.depthStencilRenderbuffer)
- ) {
- throw new DeveloperError(
- "Cannot have both a depth-stencil texture and depth-stencil renderbuffer attachment."
- );
- }
-
-
- var depthAttachment =
- defined(options.depthTexture) || defined(options.depthRenderbuffer);
- var depthStencilAttachment =
- defined(options.depthStencilTexture) ||
- defined(options.depthStencilRenderbuffer);
-
- if (depthAttachment && depthStencilAttachment) {
- throw new DeveloperError(
- "Cannot have both a depth and depth-stencil attachment."
- );
- }
- if (defined(options.stencilRenderbuffer) && depthStencilAttachment) {
- throw new DeveloperError(
- "Cannot have both a stencil and depth-stencil attachment."
- );
- }
- if (depthAttachment && defined(options.stencilRenderbuffer)) {
- throw new DeveloperError(
- "Cannot have both a depth and stencil attachment."
- );
- }
-
-
- this._bind();
- var texture;
- var renderbuffer;
- var i;
- var length;
- var attachmentEnum;
- if (defined(options.colorTextures)) {
- var textures = options.colorTextures;
- length = this._colorTextures.length = this._activeColorAttachments.length =
- textures.length;
-
- if (length > maximumColorAttachments) {
- throw new DeveloperError(
- "The number of color attachments exceeds the number supported."
- );
- }
-
- for (i = 0; i < length; ++i) {
- texture = textures[i];
-
- if (!PixelFormat.isColorFormat(texture.pixelFormat)) {
- throw new DeveloperError(
- "The color-texture pixel-format must be a color format."
- );
- }
- if (
- texture.pixelDatatype === PixelDatatype.FLOAT &&
- !context.colorBufferFloat
- ) {
- throw new DeveloperError(
- "The color texture pixel datatype is FLOAT and the WebGL implementation does not support the EXT_color_buffer_float or WEBGL_color_buffer_float extensions. See Context.colorBufferFloat."
- );
- }
- if (
- texture.pixelDatatype === PixelDatatype.HALF_FLOAT &&
- !context.colorBufferHalfFloat
- ) {
- throw new DeveloperError(
- "The color texture pixel datatype is HALF_FLOAT and the WebGL implementation does not support the EXT_color_buffer_half_float extension. See Context.colorBufferHalfFloat."
- );
- }
-
- attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i;
- attachTexture(this, attachmentEnum, texture);
- this._activeColorAttachments[i] = attachmentEnum;
- this._colorTextures[i] = texture;
- }
- }
- if (defined(options.colorRenderbuffers)) {
- var renderbuffers = options.colorRenderbuffers;
- length = this._colorRenderbuffers.length = this._activeColorAttachments.length =
- renderbuffers.length;
-
- if (length > maximumColorAttachments) {
- throw new DeveloperError(
- "The number of color attachments exceeds the number supported."
- );
- }
-
- for (i = 0; i < length; ++i) {
- renderbuffer = renderbuffers[i];
- attachmentEnum = this._gl.COLOR_ATTACHMENT0 + i;
- attachRenderbuffer(this, attachmentEnum, renderbuffer);
- this._activeColorAttachments[i] = attachmentEnum;
- this._colorRenderbuffers[i] = renderbuffer;
- }
- }
- if (defined(options.depthTexture)) {
- texture = options.depthTexture;
-
- if (texture.pixelFormat !== PixelFormat.DEPTH_COMPONENT) {
- throw new DeveloperError(
- "The depth-texture pixel-format must be DEPTH_COMPONENT."
- );
- }
-
- attachTexture(this, this._gl.DEPTH_ATTACHMENT, texture);
- this._depthTexture = texture;
- }
- if (defined(options.depthRenderbuffer)) {
- renderbuffer = options.depthRenderbuffer;
- attachRenderbuffer(this, this._gl.DEPTH_ATTACHMENT, renderbuffer);
- this._depthRenderbuffer = renderbuffer;
- }
- if (defined(options.stencilRenderbuffer)) {
- renderbuffer = options.stencilRenderbuffer;
- attachRenderbuffer(this, this._gl.STENCIL_ATTACHMENT, renderbuffer);
- this._stencilRenderbuffer = renderbuffer;
- }
- if (defined(options.depthStencilTexture)) {
- texture = options.depthStencilTexture;
-
- if (texture.pixelFormat !== PixelFormat.DEPTH_STENCIL) {
- throw new DeveloperError(
- "The depth-stencil pixel-format must be DEPTH_STENCIL."
- );
- }
-
- attachTexture(this, this._gl.DEPTH_STENCIL_ATTACHMENT, texture);
- this._depthStencilTexture = texture;
- }
- if (defined(options.depthStencilRenderbuffer)) {
- renderbuffer = options.depthStencilRenderbuffer;
- attachRenderbuffer(this, this._gl.DEPTH_STENCIL_ATTACHMENT, renderbuffer);
- this._depthStencilRenderbuffer = renderbuffer;
- }
- this._unBind();
- }
- Object.defineProperties(Framebuffer.prototype, {
-
- status: {
- get: function () {
- this._bind();
- var status = this._gl.checkFramebufferStatus(this._gl.FRAMEBUFFER);
- this._unBind();
- return status;
- },
- },
- numberOfColorAttachments: {
- get: function () {
- return this._activeColorAttachments.length;
- },
- },
- depthTexture: {
- get: function () {
- return this._depthTexture;
- },
- },
- depthRenderbuffer: {
- get: function () {
- return this._depthRenderbuffer;
- },
- },
- stencilRenderbuffer: {
- get: function () {
- return this._stencilRenderbuffer;
- },
- },
- depthStencilTexture: {
- get: function () {
- return this._depthStencilTexture;
- },
- },
- depthStencilRenderbuffer: {
- get: function () {
- return this._depthStencilRenderbuffer;
- },
- },
-
- hasDepthAttachment: {
- get: function () {
- return !!(
- this.depthTexture ||
- this.depthRenderbuffer ||
- this.depthStencilTexture ||
- this.depthStencilRenderbuffer
- );
- },
- },
- });
- Framebuffer.prototype._bind = function () {
- var gl = this._gl;
- gl.bindFramebuffer(gl.FRAMEBUFFER, this._framebuffer);
- };
- Framebuffer.prototype._unBind = function () {
- var gl = this._gl;
- gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- };
- Framebuffer.prototype._getActiveColorAttachments = function () {
- return this._activeColorAttachments;
- };
- Framebuffer.prototype.getColorTexture = function (index) {
-
- if (!defined(index) || index < 0 || index >= this._colorTextures.length) {
- throw new DeveloperError(
- "index is required, must be greater than or equal to zero and must be less than the number of color attachments."
- );
- }
-
- return this._colorTextures[index];
- };
- Framebuffer.prototype.getColorRenderbuffer = function (index) {
-
- if (
- !defined(index) ||
- index < 0 ||
- index >= this._colorRenderbuffers.length
- ) {
- throw new DeveloperError(
- "index is required, must be greater than or equal to zero and must be less than the number of color attachments."
- );
- }
-
- return this._colorRenderbuffers[index];
- };
- Framebuffer.prototype.isDestroyed = function () {
- return false;
- };
- Framebuffer.prototype.destroy = function () {
- if (this.destroyAttachments) {
-
- var i = 0;
- var textures = this._colorTextures;
- var length = textures.length;
- for (; i < length; ++i) {
- var texture = textures[i];
- if (defined(texture)) {
- texture.destroy();
- }
- }
- var renderbuffers = this._colorRenderbuffers;
- length = renderbuffers.length;
- for (i = 0; i < length; ++i) {
- var renderbuffer = renderbuffers[i];
- if (defined(renderbuffer)) {
- renderbuffer.destroy();
- }
- }
- this._depthTexture = this._depthTexture && this._depthTexture.destroy();
- this._depthRenderbuffer =
- this._depthRenderbuffer && this._depthRenderbuffer.destroy();
- this._stencilRenderbuffer =
- this._stencilRenderbuffer && this._stencilRenderbuffer.destroy();
- this._depthStencilTexture =
- this._depthStencilTexture && this._depthStencilTexture.destroy();
- this._depthStencilRenderbuffer =
- this._depthStencilRenderbuffer &&
- this._depthStencilRenderbuffer.destroy();
- }
- this._gl.deleteFramebuffer(this._framebuffer);
- return destroyObject(this);
- };
- export default Framebuffer;
|