ViewportQuad.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import BoundingRectangle from "../Core/BoundingRectangle.js";
  2. import Color from "../Core/Color.js";
  3. import defined from "../Core/defined.js";
  4. import destroyObject from "../Core/destroyObject.js";
  5. import DeveloperError from "../Core/DeveloperError.js";
  6. import Pass from "../Renderer/Pass.js";
  7. import RenderState from "../Renderer/RenderState.js";
  8. import ShaderSource from "../Renderer/ShaderSource.js";
  9. import ViewportQuadFS from "../Shaders/ViewportQuadFS.js";
  10. import BlendingState from "./BlendingState.js";
  11. import Material from "./Material.js";
  12. /**
  13. * A viewport aligned quad.
  14. *
  15. * @alias ViewportQuad
  16. * @constructor
  17. *
  18. * @param {BoundingRectangle} [rectangle] The {@link BoundingRectangle} defining the quad's position within the viewport.
  19. * @param {Material} [material] The {@link Material} defining the surface appearance of the viewport quad.
  20. *
  21. * @example
  22. * const viewportQuad = new Cesium.ViewportQuad(new Cesium.BoundingRectangle(0, 0, 80, 40));
  23. * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 0.0, 0.0, 1.0);
  24. */
  25. function ViewportQuad(rectangle, material) {
  26. /**
  27. * Determines if the viewport quad primitive will be shown.
  28. *
  29. * @type {boolean}
  30. * @default true
  31. */
  32. this.show = true;
  33. if (!defined(rectangle)) {
  34. rectangle = new BoundingRectangle();
  35. }
  36. /**
  37. * The BoundingRectangle defining the quad's position within the viewport.
  38. *
  39. * @type {BoundingRectangle}
  40. *
  41. * @example
  42. * viewportQuad.rectangle = new Cesium.BoundingRectangle(0, 0, 80, 40);
  43. */
  44. this.rectangle = BoundingRectangle.clone(rectangle);
  45. if (!defined(material)) {
  46. material = Material.fromType(Material.ColorType, {
  47. color: new Color(1.0, 1.0, 1.0, 1.0),
  48. });
  49. }
  50. /**
  51. * The surface appearance of the viewport quad. This can be one of several built-in {@link Material} objects or a custom material, scripted with
  52. * {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}.
  53. * <p>
  54. * The default material is <code>Material.ColorType</code>.
  55. * </p>
  56. *
  57. * @type Material
  58. *
  59. * @example
  60. * // 1. Change the color of the default material to yellow
  61. * viewportQuad.material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 1.0);
  62. *
  63. * // 2. Change material to horizontal stripes
  64. * viewportQuad.material = Cesium.Material.fromType(Cesium.Material.StripeType);
  65. *
  66. * @see {@link https://github.com/CesiumGS/cesium/wiki/Fabric|Fabric}
  67. */
  68. this.material = material;
  69. this._material = undefined;
  70. this._overlayCommand = undefined;
  71. this._rs = undefined;
  72. }
  73. /**
  74. * Called when {@link Viewer} or {@link CesiumWidget} render the scene to
  75. * get the draw commands needed to render this primitive.
  76. * <p>
  77. * Do not call this function directly. This is documented just to
  78. * list the exceptions that may be propagated when the scene is rendered:
  79. * </p>
  80. *
  81. * @exception {DeveloperError} this.material must be defined.
  82. * @exception {DeveloperError} this.rectangle must be defined.
  83. */
  84. ViewportQuad.prototype.update = function (frameState) {
  85. if (!this.show) {
  86. return;
  87. }
  88. //>>includeStart('debug', pragmas.debug);
  89. if (!defined(this.material)) {
  90. throw new DeveloperError("this.material must be defined.");
  91. }
  92. if (!defined(this.rectangle)) {
  93. throw new DeveloperError("this.rectangle must be defined.");
  94. }
  95. //>>includeEnd('debug');
  96. const rs = this._rs;
  97. if (!defined(rs) || !BoundingRectangle.equals(rs.viewport, this.rectangle)) {
  98. this._rs = RenderState.fromCache({
  99. blending: BlendingState.ALPHA_BLEND,
  100. viewport: this.rectangle,
  101. });
  102. }
  103. const pass = frameState.passes;
  104. if (pass.render) {
  105. const context = frameState.context;
  106. if (this._material !== this.material || !defined(this._overlayCommand)) {
  107. // Recompile shader when material changes
  108. this._material = this.material;
  109. if (defined(this._overlayCommand)) {
  110. this._overlayCommand.shaderProgram.destroy();
  111. }
  112. const fs = new ShaderSource({
  113. sources: [this._material.shaderSource, ViewportQuadFS],
  114. });
  115. this._overlayCommand = context.createViewportQuadCommand(fs, {
  116. renderState: this._rs,
  117. uniformMap: this._material._uniforms,
  118. owner: this,
  119. });
  120. this._overlayCommand.pass = Pass.OVERLAY;
  121. }
  122. this._material.update(context);
  123. this._overlayCommand.renderState = this._rs;
  124. this._overlayCommand.uniformMap = this._material._uniforms;
  125. frameState.commandList.push(this._overlayCommand);
  126. }
  127. };
  128. /**
  129. * Returns true if this object was destroyed; otherwise, false.
  130. * <br /><br />
  131. * If this object was destroyed, it should not be used; calling any function other than
  132. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
  133. *
  134. * @returns {boolean} True if this object was destroyed; otherwise, false.
  135. *
  136. * @see ViewportQuad#destroy
  137. */
  138. ViewportQuad.prototype.isDestroyed = function () {
  139. return false;
  140. };
  141. /**
  142. * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
  143. * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
  144. * <br /><br />
  145. * Once an object is destroyed, it should not be used; calling any function other than
  146. * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
  147. * assign the return value (<code>undefined</code>) to the object as done in the example.
  148. *
  149. * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
  150. *
  151. *
  152. * @example
  153. * quad = quad && quad.destroy();
  154. *
  155. * @see ViewportQuad#isDestroyed
  156. */
  157. ViewportQuad.prototype.destroy = function () {
  158. if (defined(this._overlayCommand)) {
  159. this._overlayCommand.shaderProgram =
  160. this._overlayCommand.shaderProgram &&
  161. this._overlayCommand.shaderProgram.destroy();
  162. }
  163. return destroyObject(this);
  164. };
  165. export default ViewportQuad;