import BoundingRectangle from "../Core/BoundingRectangle.js"; import Color from "../Core/Color.js"; import defined from "../Core/defined.js"; import destroyObject from "../Core/destroyObject.js"; import DeveloperError from "../Core/DeveloperError.js"; import Pass from "../Renderer/Pass.js"; import RenderState from "../Renderer/RenderState.js"; import ShaderSource from "../Renderer/ShaderSource.js"; import ViewportQuadFS from "../Shaders/ViewportQuadFS.js"; import BlendingState from "./BlendingState.js"; import Material from "./Material.js"; /** * A viewport aligned quad. * * @alias ViewportQuad * @constructor * * @param {BoundingRectangle} [rectangle] The {@link BoundingRectangle} defining the quad's position within the viewport. * @param {Material} [material] The {@link Material} defining the surface appearance of the viewport quad. * * @example * const viewportQuad = new Cesium.ViewportQuad(new Cesium.BoundingRectangle(0, 0, 80, 40)); * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 0.0, 0.0, 1.0); */ function ViewportQuad(rectangle, material) { /** * Determines if the viewport quad primitive will be shown. * * @type {Boolean} * @default true */ this.show = true; if (!defined(rectangle)) { rectangle = new BoundingRectangle(); } /** * The BoundingRectangle defining the quad's position within the viewport. * * @type {BoundingRectangle} * * @example * viewportQuad.rectangle = new Cesium.BoundingRectangle(0, 0, 80, 40); */ this.rectangle = BoundingRectangle.clone(rectangle); if (!defined(material)) { material = Material.fromType(Material.ColorType, { color: new Color(1.0, 1.0, 1.0, 1.0), }); } /** * The surface appearance of the viewport quad. This can be one of several built-in {@link Material} objects or a custom material, scripted with * {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}. *

* The default material is Material.ColorType. *

* * @type Material * * @example * // 1. Change the color of the default material to yellow * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0); * * // 2. Change material to horizontal stripes * viewportQuad.material = Cesium.Material.fromType(Cesium.Material.StripeType); * * @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric} */ this.material = material; this._material = undefined; this._overlayCommand = undefined; this._rs = undefined; } /** * Called when {@link Viewer} or {@link CesiumWidget} render the scene to * get the draw commands needed to render this primitive. *

* Do not call this function directly. This is documented just to * list the exceptions that may be propagated when the scene is rendered: *

* * @exception {DeveloperError} this.material must be defined. * @exception {DeveloperError} this.rectangle must be defined. */ ViewportQuad.prototype.update = function (frameState) { if (!this.show) { return; } //>>includeStart('debug', pragmas.debug); if (!defined(this.material)) { throw new DeveloperError("this.material must be defined."); } if (!defined(this.rectangle)) { throw new DeveloperError("this.rectangle must be defined."); } //>>includeEnd('debug'); const rs = this._rs; if (!defined(rs) || !BoundingRectangle.equals(rs.viewport, this.rectangle)) { this._rs = RenderState.fromCache({ blending: BlendingState.ALPHA_BLEND, viewport: this.rectangle, }); } const pass = frameState.passes; if (pass.render) { const context = frameState.context; if (this._material !== this.material || !defined(this._overlayCommand)) { // Recompile shader when material changes this._material = this.material; if (defined(this._overlayCommand)) { this._overlayCommand.shaderProgram.destroy(); } const fs = new ShaderSource({ sources: [this._material.shaderSource, ViewportQuadFS], }); this._overlayCommand = context.createViewportQuadCommand(fs, { renderState: this._rs, uniformMap: this._material._uniforms, owner: this, }); this._overlayCommand.pass = Pass.OVERLAY; } this._material.update(context); this._overlayCommand.renderState = this._rs; this._overlayCommand.uniformMap = this._material._uniforms; frameState.commandList.push(this._overlayCommand); } }; /** * 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. * * @returns {Boolean} True if this object was destroyed; otherwise, false. * * @see ViewportQuad#destroy */ ViewportQuad.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. * * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called. * * * @example * quad = quad && quad.destroy(); * * @see ViewportQuad#isDestroyed */ ViewportQuad.prototype.destroy = function () { if (defined(this._overlayCommand)) { this._overlayCommand.shaderProgram = this._overlayCommand.shaderProgram && this._overlayCommand.shaderProgram.destroy(); } return destroyObject(this); }; export default ViewportQuad;