智慧水务管理系统 - 精河县供水工程综合管理平台

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  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 ClearCommand from "../Renderer/ClearCommand.js";
  6. import FramebufferManager from "../Renderer/FramebufferManager.js";
  7. import PixelDatatype from "../Renderer/PixelDatatype.js";
  8. import RenderState from "../Renderer/RenderState.js";
  9. import PassThrough from "../Shaders/PostProcessStages/PassThrough.js";
  10. import PassThroughDepth from "../Shaders/PostProcessStages/PassThroughDepth.js";
  11. import BlendingState from "./BlendingState.js";
  12. import StencilConstants from "./StencilConstants.js";
  13. import StencilFunction from "./StencilFunction.js";
  14. import StencilOperation from "./StencilOperation.js";
  15. /**
  16. * @alias GlobeDepth
  17. * @constructor
  18. *
  19. * @private
  20. */
  21. function GlobeDepth() {
  22. this._picking = false;
  23. this._numSamples = 1;
  24. this._tempCopyDepthTexture = undefined;
  25. this._pickColorFramebuffer = new FramebufferManager({
  26. depthStencil: true,
  27. supportsDepthTexture: true,
  28. });
  29. this._outputFramebuffer = new FramebufferManager({
  30. depthStencil: true,
  31. supportsDepthTexture: true,
  32. });
  33. this._copyDepthFramebuffer = new FramebufferManager();
  34. this._tempCopyDepthFramebuffer = new FramebufferManager();
  35. this._updateDepthFramebuffer = new FramebufferManager({
  36. createColorAttachments: false,
  37. createDepthAttachments: false,
  38. depthStencil: true,
  39. });
  40. this._clearGlobeColorCommand = undefined;
  41. this._copyColorCommand = undefined;
  42. this._copyDepthCommand = undefined;
  43. this._tempCopyDepthCommand = undefined;
  44. this._updateDepthCommand = undefined;
  45. this._viewport = new BoundingRectangle();
  46. this._rs = undefined;
  47. this._rsBlend = undefined;
  48. this._rsUpdate = undefined;
  49. this._useScissorTest = false;
  50. this._scissorRectangle = undefined;
  51. this._useHdr = undefined;
  52. this._clearGlobeDepth = undefined;
  53. }
  54. Object.defineProperties(GlobeDepth.prototype, {
  55. colorFramebufferManager: {
  56. get: function () {
  57. return this._picking
  58. ? this._pickColorFramebuffer
  59. : this._outputFramebuffer;
  60. },
  61. },
  62. framebuffer: {
  63. get: function () {
  64. return this.colorFramebufferManager.framebuffer;
  65. },
  66. },
  67. depthStencilTexture: {
  68. get: function () {
  69. return this.colorFramebufferManager.getDepthStencilTexture();
  70. },
  71. },
  72. picking: {
  73. get: function () {
  74. return this._picking;
  75. },
  76. set: function (value) {
  77. this._picking = value;
  78. },
  79. },
  80. });
  81. function updateCopyCommands(globeDepth, context, width, height, passState) {
  82. const viewport = globeDepth._viewport;
  83. viewport.width = width;
  84. viewport.height = height;
  85. const useScissorTest = !BoundingRectangle.equals(
  86. viewport,
  87. passState.viewport,
  88. );
  89. let updateScissor = useScissorTest !== globeDepth._useScissorTest;
  90. globeDepth._useScissorTest = useScissorTest;
  91. if (
  92. !BoundingRectangle.equals(globeDepth._scissorRectangle, passState.viewport)
  93. ) {
  94. globeDepth._scissorRectangle = BoundingRectangle.clone(
  95. passState.viewport,
  96. globeDepth._scissorRectangle,
  97. );
  98. updateScissor = true;
  99. }
  100. if (
  101. !defined(globeDepth._rs) ||
  102. !BoundingRectangle.equals(viewport, globeDepth._rs.viewport) ||
  103. updateScissor
  104. ) {
  105. globeDepth._rs = RenderState.fromCache({
  106. viewport: viewport,
  107. scissorTest: {
  108. enabled: globeDepth._useScissorTest,
  109. rectangle: globeDepth._scissorRectangle,
  110. },
  111. });
  112. globeDepth._rsBlend = RenderState.fromCache({
  113. viewport: viewport,
  114. scissorTest: {
  115. enabled: globeDepth._useScissorTest,
  116. rectangle: globeDepth._scissorRectangle,
  117. },
  118. blending: BlendingState.ALPHA_BLEND,
  119. });
  120. // Copy packed depth only if the 3D Tiles bit is set
  121. globeDepth._rsUpdate = RenderState.fromCache({
  122. viewport: viewport,
  123. scissorTest: {
  124. enabled: globeDepth._useScissorTest,
  125. rectangle: globeDepth._scissorRectangle,
  126. },
  127. stencilTest: {
  128. enabled: true,
  129. frontFunction: StencilFunction.EQUAL,
  130. frontOperation: {
  131. fail: StencilOperation.KEEP,
  132. zFail: StencilOperation.KEEP,
  133. zPass: StencilOperation.KEEP,
  134. },
  135. backFunction: StencilFunction.NEVER,
  136. reference: StencilConstants.CESIUM_3D_TILE_MASK,
  137. mask: StencilConstants.CESIUM_3D_TILE_MASK,
  138. },
  139. });
  140. }
  141. if (!defined(globeDepth._copyDepthCommand)) {
  142. globeDepth._copyDepthCommand = context.createViewportQuadCommand(
  143. PassThroughDepth,
  144. {
  145. uniformMap: {
  146. u_depthTexture: function () {
  147. return globeDepth.colorFramebufferManager.getDepthStencilTexture();
  148. },
  149. },
  150. owner: globeDepth,
  151. },
  152. );
  153. }
  154. globeDepth._copyDepthCommand.framebuffer =
  155. globeDepth._copyDepthFramebuffer.framebuffer;
  156. globeDepth._copyDepthCommand.renderState = globeDepth._rs;
  157. if (!defined(globeDepth._copyColorCommand)) {
  158. globeDepth._copyColorCommand = context.createViewportQuadCommand(
  159. PassThrough,
  160. {
  161. uniformMap: {
  162. colorTexture: function () {
  163. return globeDepth.colorFramebufferManager.getColorTexture();
  164. },
  165. },
  166. owner: globeDepth,
  167. },
  168. );
  169. }
  170. globeDepth._copyColorCommand.renderState = globeDepth._rs;
  171. if (!defined(globeDepth._tempCopyDepthCommand)) {
  172. globeDepth._tempCopyDepthCommand = context.createViewportQuadCommand(
  173. PassThroughDepth,
  174. {
  175. uniformMap: {
  176. u_depthTexture: function () {
  177. return globeDepth._tempCopyDepthTexture;
  178. },
  179. },
  180. owner: globeDepth,
  181. },
  182. );
  183. }
  184. globeDepth._tempCopyDepthCommand.framebuffer =
  185. globeDepth._tempCopyDepthFramebuffer.framebuffer;
  186. globeDepth._tempCopyDepthCommand.renderState = globeDepth._rs;
  187. if (!defined(globeDepth._updateDepthCommand)) {
  188. globeDepth._updateDepthCommand = context.createViewportQuadCommand(
  189. PassThrough,
  190. {
  191. uniformMap: {
  192. colorTexture: function () {
  193. return globeDepth._tempCopyDepthFramebuffer.getColorTexture();
  194. },
  195. },
  196. owner: globeDepth,
  197. },
  198. );
  199. }
  200. globeDepth._updateDepthCommand.framebuffer =
  201. globeDepth._updateDepthFramebuffer.framebuffer;
  202. globeDepth._updateDepthCommand.renderState = globeDepth._rsUpdate;
  203. if (!defined(globeDepth._clearGlobeColorCommand)) {
  204. globeDepth._clearGlobeColorCommand = new ClearCommand({
  205. color: new Color(0.0, 0.0, 0.0, 0.0),
  206. stencil: 0.0,
  207. owner: globeDepth,
  208. });
  209. }
  210. globeDepth._clearGlobeColorCommand.framebuffer = globeDepth.framebuffer;
  211. }
  212. /**
  213. * Update framebuffers and render state.
  214. *
  215. * @param {Context} context The context used for rendering.
  216. * @param {PassState} passState Rendering state for subsequent render passes.
  217. * @param {BoundingRectangle} viewport The viewport for the rendering.
  218. * @param {number} numSamples The number of samples for multi-sample anti-aliasing (MSAA).
  219. * @param {boolean} hdr <code>true</code> if the color output needs to be floating point for HDR rendering.
  220. * @param {boolean} clearGlobeDepth <code>true</code> if the depth buffer should be cleared before rendering 3D Tiles and opaque entities.
  221. *
  222. * @private
  223. */
  224. GlobeDepth.prototype.update = function (
  225. context,
  226. passState,
  227. viewport,
  228. numSamples,
  229. hdr,
  230. clearGlobeDepth,
  231. ) {
  232. const { width, height } = viewport;
  233. const pixelDatatype = hdr
  234. ? context.halfFloatingPointTexture
  235. ? PixelDatatype.HALF_FLOAT
  236. : PixelDatatype.FLOAT
  237. : PixelDatatype.UNSIGNED_BYTE;
  238. this._numSamples = numSamples;
  239. if (this.picking) {
  240. this._pickColorFramebuffer.update(context, width, height);
  241. } else {
  242. this._outputFramebuffer.update(
  243. context,
  244. width,
  245. height,
  246. numSamples,
  247. pixelDatatype,
  248. );
  249. }
  250. this._copyDepthFramebuffer.update(context, width, height);
  251. updateCopyCommands(this, context, width, height, passState);
  252. context.uniformState.globeDepthTexture = undefined;
  253. this._clearGlobeDepth = clearGlobeDepth;
  254. };
  255. /**
  256. * If using MSAA, resolve the stencil.
  257. *
  258. * @param {Context} context
  259. * @param {boolean} blitStencil <code>true</code> if the stencil has been set.
  260. *
  261. * @private
  262. */
  263. GlobeDepth.prototype.prepareColorTextures = function (context, blitStencil) {
  264. if (!this.picking && this._numSamples > 1) {
  265. this._outputFramebuffer.prepareTextures(context, blitStencil);
  266. }
  267. };
  268. GlobeDepth.prototype.executeCopyDepth = function (context, passState) {
  269. if (defined(this._copyDepthCommand)) {
  270. this.prepareColorTextures(context);
  271. this._copyDepthCommand.execute(context, passState);
  272. context.uniformState.globeDepthTexture =
  273. this._copyDepthFramebuffer.getColorTexture();
  274. }
  275. };
  276. /**
  277. * Update the existing depth texture using a stencil.
  278. *
  279. * @param {Context} context The context used for rendering.
  280. * @param {PassState} passState Render state for subsequent rendering passes.
  281. * @param {Texture} [depthTexture] The depth texture to copy.
  282. */
  283. GlobeDepth.prototype.executeUpdateDepth = function (
  284. context,
  285. passState,
  286. depthTexture,
  287. ) {
  288. const depthTextureToCopy = defined(depthTexture)
  289. ? depthTexture
  290. : passState.framebuffer.depthStencilTexture;
  291. if (
  292. !this._clearGlobeDepth &&
  293. depthTextureToCopy === this.colorFramebufferManager.getDepthStencilTexture()
  294. ) {
  295. // Fast path - the depth texture can be copied normally.
  296. if (defined(this._copyDepthCommand)) {
  297. this._copyDepthCommand.execute(context, passState);
  298. }
  299. return;
  300. }
  301. if (!defined(this._updateDepthCommand)) {
  302. return;
  303. }
  304. // First copy the depth to a temporary globe depth texture, then update the
  305. // main globe depth texture where the stencil bit for 3D Tiles is set.
  306. // This preserves the original globe depth except where 3D Tiles is rendered.
  307. // The additional texture and framebuffer resources are created on demand.
  308. const updateDepthFramebuffer = this._updateDepthFramebuffer;
  309. if (
  310. !defined(updateDepthFramebuffer.framebuffer) ||
  311. updateDepthFramebuffer.getDepthStencilTexture() !== depthTextureToCopy ||
  312. updateDepthFramebuffer.getColorTexture() !==
  313. this._copyDepthFramebuffer.getColorTexture()
  314. ) {
  315. const colorTexture = this._copyDepthFramebuffer.getColorTexture();
  316. const { width, height } = colorTexture;
  317. this._tempCopyDepthFramebuffer.destroy();
  318. this._tempCopyDepthFramebuffer.update(context, width, height);
  319. updateDepthFramebuffer.setColorTexture(colorTexture, 0);
  320. updateDepthFramebuffer.setDepthStencilTexture(depthTextureToCopy);
  321. updateDepthFramebuffer.update(context, width, height);
  322. updateCopyCommands(this, context, width, height, passState);
  323. }
  324. this._tempCopyDepthTexture = depthTextureToCopy;
  325. this._tempCopyDepthCommand.execute(context, passState);
  326. this._updateDepthCommand.execute(context, passState);
  327. };
  328. GlobeDepth.prototype.executeCopyColor = function (context, passState) {
  329. if (defined(this._copyColorCommand)) {
  330. this._copyColorCommand.execute(context, passState);
  331. }
  332. };
  333. GlobeDepth.prototype.clear = function (context, passState, clearColor) {
  334. const clear = this._clearGlobeColorCommand;
  335. if (defined(clear)) {
  336. Color.clone(clearColor, clear.color);
  337. this.colorFramebufferManager.clear(context, clear, passState);
  338. }
  339. };
  340. GlobeDepth.prototype.isDestroyed = function () {
  341. return false;
  342. };
  343. GlobeDepth.prototype.destroy = function () {
  344. this._pickColorFramebuffer.destroy();
  345. this._outputFramebuffer.destroy();
  346. this._copyDepthFramebuffer.destroy();
  347. this._tempCopyDepthFramebuffer.destroy();
  348. this._updateDepthFramebuffer.destroy();
  349. if (defined(this._copyColorCommand)) {
  350. this._copyColorCommand.shaderProgram =
  351. this._copyColorCommand.shaderProgram.destroy();
  352. }
  353. if (defined(this._copyDepthCommand)) {
  354. this._copyDepthCommand.shaderProgram =
  355. this._copyDepthCommand.shaderProgram.destroy();
  356. }
  357. if (defined(this._tempCopyDepthCommand)) {
  358. this._tempCopyDepthCommand.shaderProgram =
  359. this._tempCopyDepthCommand.shaderProgram.destroy();
  360. }
  361. if (defined(this._updateDepthCommand)) {
  362. this._updateDepthCommand.shaderProgram =
  363. this._updateDepthCommand.shaderProgram.destroy();
  364. }
  365. return destroyObject(this);
  366. };
  367. export default GlobeDepth;