import Check from "../Core/Check.js"; import createGuid from "../Core/createGuid.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; /** * A collection of {@link PostProcessStage}s or other post-process composite stages that execute together logically. *
* All stages are executed in the order of the array. The input texture changes based on the value of inputPreviousStageTexture
.
* If inputPreviousStageTexture
is true
, the input to each stage is the output texture rendered to by the scene or of the stage that executed before it.
* If inputPreviousStageTexture
is false
, the input texture is the same for each stage in the composite. The input texture is the texture rendered to by the scene
* or the output texture of the previous stage.
*
undefined
; in which case, get each stage to set uniform values.
* @memberof PostProcessStageComposite.prototype
* @type {Object}
*/
uniforms: {
get: function () {
return this._uniforms;
},
},
/**
* All post-process stages are executed in the order of the array. The input texture changes based on the value of inputPreviousStageTexture
.
* If inputPreviousStageTexture
is true
, the input to each stage is the output texture rendered to by the scene or of the stage that executed before it.
* If inputPreviousStageTexture
is false
, the input texture is the same for each stage in the composite. The input texture is the texture rendered to by the scene
* or the output texture of the previous stage.
*
* @memberof PostProcessStageComposite.prototype
* @type {Boolean}
* @readonly
*/
inputPreviousStageTexture: {
get: function () {
return this._inputPreviousStageTexture;
},
},
/**
* The number of post-process stages in this composite.
*
* @memberof PostProcessStageComposite.prototype
* @type {Number}
* @readonly
*/
length: {
get: function () {
return this._stages.length;
},
},
/**
* The features selected for applying the post-process.
*
* @memberof PostProcessStageComposite.prototype
* @type {Array}
*/
selected: {
get: function () {
return this._selected;
},
set: function (value) {
this._selected = value;
},
},
/**
* @private
*/
parentSelected: {
get: function () {
return this._parentSelected;
},
set: function (value) {
this._parentSelected = value;
},
},
});
/**
* @private
*/
PostProcessStageComposite.prototype._isSupported = function (context) {
var stages = this._stages;
var length = stages.length;
for (var i = 0; i < length; ++i) {
if (!stages[i]._isSupported(context)) {
return false;
}
}
return true;
};
/**
* Gets the post-process stage at index
*
* @param {Number} index The index of the post-process stage or composite.
* @return {PostProcessStage|PostProcessStageComposite} The post-process stage or composite at index.
*
* @exception {DeveloperError} index must be greater than or equal to 0.
* @exception {DeveloperError} index must be less than {@link PostProcessStageComposite#length}.
*/
PostProcessStageComposite.prototype.get = function (index) {
//>>includeStart('debug', pragmas.debug);
Check.typeOf.number.greaterThanOrEquals("index", index, 0);
Check.typeOf.number.lessThan("index", index, this.length);
//>>includeEnd('debug');
return this._stages[index];
};
function isSelectedTextureDirty(stage) {
var length = defined(stage._selected) ? stage._selected.length : 0;
var parentLength = defined(stage._parentSelected) ? stage._parentSelected : 0;
var dirty =
stage._selected !== stage._selectedShadow ||
length !== stage._selectedLength;
dirty =
dirty ||
stage._parentSelected !== stage._parentSelectedShadow ||
parentLength !== stage._parentSelectedLength;
if (defined(stage._selected) && defined(stage._parentSelected)) {
stage._combinedSelected = stage._selected.concat(stage._parentSelected);
} else if (defined(stage._parentSelected)) {
stage._combinedSelected = stage._parentSelected;
} else {
stage._combinedSelected = stage._selected;
}
if (!dirty && defined(stage._combinedSelected)) {
if (!defined(stage._combinedSelectedShadow)) {
return true;
}
length = stage._combinedSelected.length;
for (var i = 0; i < length; ++i) {
if (stage._combinedSelected[i] !== stage._combinedSelectedShadow[i]) {
return true;
}
}
}
return dirty;
}
/**
* A function that will be called before execute. Updates each post-process stage in the composite.
* @param {Context} context The context.
* @param {Boolean} useLogDepth Whether the scene uses a logarithmic depth buffer.
* @private
*/
PostProcessStageComposite.prototype.update = function (context, useLogDepth) {
this._selectedDirty = isSelectedTextureDirty(this);
this._selectedShadow = this._selected;
this._parentSelectedShadow = this._parentSelected;
this._combinedSelectedShadow = this._combinedSelected;
this._selectedLength = defined(this._selected) ? this._selected.length : 0;
this._parentSelectedLength = defined(this._parentSelected)
? this._parentSelected.length
: 0;
var stages = this._stages;
var length = stages.length;
for (var i = 0; i < length; ++i) {
var stage = stages[i];
if (this._selectedDirty) {
stage.parentSelected = this._combinedSelected;
}
stage.update(context, useLogDepth);
}
};
/**
* Returns true if this object was destroyed; otherwise, false.
*
* If this object was destroyed, it should not be used; calling any function other than
* isDestroyed
will result in a {@link DeveloperError} exception.
*
true
if this object was destroyed; otherwise, false
.
*
* @see PostProcessStageComposite#destroy
*/
PostProcessStageComposite.prototype.isDestroyed = function () {
return false;
};
/**
* Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
* release of WebGL resources, instead of relying on the garbage collector to destroy this object.
*
* Once an object is destroyed, it should not be used; calling any function other than
* isDestroyed
will result in a {@link DeveloperError} exception. Therefore,
* assign the return value (undefined
) to the object as done in the example.
*