UNPKG

@doegis/core

Version:

DOE GIS API

3 lines (1 loc) 5.83 kB
import e from"../../../../../core/Logger.js";import{disposeMaybe as t,isSome as r,isNone as i}from"../../../../../core/maybe.js";import{WGLSymbologyType as a}from"../enums.js";import s from"../VertexStream.js";import u from"./WGLGeometryBrushMarker.js";import{Effect as n}from"../effects/Effect.js";import{assertRendererSchema as o}from"../techniques/utils.js";import{ContextType as h}from"../../../../webgl/context-util.js";import{CompareFunction as c,DataType as l,BlendFactor as f,ClearBufferBit as m,TextureType as d,TextureWrapMode as p,RenderbufferFormat as _,PixelFormat as b,PixelType as g,TextureSamplingMode as F}from"../../../../webgl/enums.js";import{FramebufferObject as w}from"../../../../webgl/FramebufferObject.js";import{loadHeatmapTextureConfiguration as T}from"../../../../webgl/heatmapTextureUtils.js";import{Renderbuffer as E}from"../../../../webgl/Renderbuffer.js";import{Texture as O}from"../../../../webgl/Texture.js";const S=e.getLogger("esri.views.2d.engine.webgl.brushes.WGLBrushHeatmap");function x(e){return"heatmap"===e.type}class B extends u{constructor(){super(...arguments),this.brushEffect=new y}supportsSymbology(e){return e===a.HEATMAP}dispose(){super.dispose(),this.brushEffect.dispose(),this.brushEffect=null}prepareState(){}drawGeometry(e,t,r,i){const{defines:a}=this.brushEffect.loadQualityProfile(e.context);super.drawGeometry(e,t,r,i?[...i,...a]:a)}_drawMarkers(e,t,r,i,a,s,u){const{context:n,rendererInfo:h,state:f}=e,{rendererSchema:m}=h;o(m,"heatmap");const{referenceScale:d,radius:p,isFieldActive:_}=m,b=p*(0!==d?d/f.scale:1);r.setUniform1f("u_radius",b),u||(r.setUniform1f("u_isFieldActive",_),n.setStencilFunction(c.GEQUAL,t.stencilRef,255)),n.drawElements(i,a,l.UNSIGNED_INT,s)}}const v={vsPath:"heatmap/heatmapResolve",fsPath:"heatmap/heatmapResolve",attributes:new Map([["a_position",0]])};class y extends n{constructor(){super(...arguments),this.name=this.constructor.name}createOptions({passOptions:e}){return e}dispose(){this._prevFBO=null,this._accumulateOutputTexture=t(this._accumulateOutputTexture),r(this._accumulateFramebuffer)&&this._accumulateFramebuffer.detachDepthStencilBuffer(),this._accumulateOutputStencilBuffer=t(this._accumulateOutputStencilBuffer),this._accumulateFramebuffer=t(this._accumulateFramebuffer),this._resolveGradientTexture=t(this._resolveGradientTexture),this._tileQuad=t(this._tileQuad)}bind(e){const{context:t,rendererInfo:i,passOptions:a}=e,{rendererSchema:s}=i;!(r(a)&&"hittest"===a.type)&&x(s)&&(this._prevFBO=t.getBoundFramebufferObject(),this._prevViewport=t.getViewport(),o(s,"heatmap"),this._loadResources(e),this._updateResources(t,s),t.bindFramebuffer(this._accumulateFramebuffer),t.setViewport(0,0,this._accumulateFramebuffer.width,this._accumulateFramebuffer.height),t.setStencilTestEnabled(!0),t.setBlendingEnabled(!0),t.setBlendFunction(f.ONE,f.ONE),t.setClearColor(0,0,0,0),t.clear(m.COLOR_BUFFER_BIT))}unbind(){this._prevFBO=null,this._prevViewport=null}draw(e){const{context:t,painter:i,rendererInfo:a,passOptions:s}=e,{rendererSchema:u}=a;if(r(s)&&"hittest"===s.type||!x(u))return;const{defines:n}=this.loadQualityProfile(t),o=i.materialManager.getProgram(v,n);t.useProgram(o),t.bindFramebuffer(this._prevFBO),t.setViewport(0,0,this._prevViewport.width,this._prevViewport.height),t.setBlendFunction(f.ONE,f.ONE_MINUS_SRC_ALPHA),t.setStencilTestEnabled(!1);const{radius:h,minDensity:c,densityRange:l}=u;t.bindTexture(this._accumulateOutputTexture,8),t.bindTexture(this._resolveGradientTexture,9),o.setUniform1i("u_texture",8),o.setUniform1i("u_gradient",9),o.setUniform2f("u_densityMinAndInvRange",c,1/l),o.setUniform1f("u_densityNormalization",3/(h*h*Math.PI)),this._tileQuad.draw()}_loadResources({context:e,painter:t}){const{dataType:r,samplingMode:i,pixelFormat:a,internalFormat:u,shadingRate:n,requiresSharedStencilBuffer:o}=this.loadQualityProfile(e),{width:h,height:c}=this._prevViewport,l=h*n,f=c*n;this._accumulateOutputTexture??(this._accumulateOutputTexture=new O(e,{target:d.TEXTURE_2D,pixelFormat:a,internalFormat:u,dataType:r,samplingMode:i,wrapMode:p.CLAMP_TO_EDGE,width:l,height:f})),o||(this._accumulateOutputStencilBuffer??(this._accumulateOutputStencilBuffer=new E(e,{width:l,height:f,internalFormat:_.DEPTH_STENCIL}))),this._accumulateFramebuffer??(this._accumulateFramebuffer=new w(e,{},this._accumulateOutputTexture,o?t.getSharedStencilBuffer():this._accumulateOutputStencilBuffer)),this._resolveGradientTexture??(this._resolveGradientTexture=new O(e,{target:d.TEXTURE_2D,pixelFormat:b.RGBA,dataType:g.UNSIGNED_BYTE,samplingMode:F.LINEAR,wrapMode:p.CLAMP_TO_EDGE})),this._tileQuad??(this._tileQuad=new s(e,[0,0,1,0,0,1,1,1]))}_updateResources(e,t){const{gradientHash:i,gradient:a}=t;this._prevGradientHash!==i&&(this._resolveGradientTexture.resize(a.length/4,1),this._resolveGradientTexture.setData(a),this._prevGradientHash=i);const{shadingRate:s,requiresSharedStencilBuffer:u}=this.loadQualityProfile(e),{width:n,height:o}=this._prevViewport,h=n*s,c=o*s,{width:l,height:f}=this._accumulateFramebuffer;if(l!==h||f!==c){const e=this._accumulateFramebuffer.depthStencilAttachment;if(u&&r(e)){const{width:t,height:r}=e.descriptor;t===h&&r===c||(S.errorOnce("Attempted to resize shared stencil buffer! Detaching instead."),this._accumulateFramebuffer.detachDepthStencilBuffer())}this._accumulateFramebuffer.resize(h,c)}u||e.blitFramebuffer(this._prevFBO,this._accumulateFramebuffer,0,0,this._prevFBO.width,this._prevFBO.height,0,0,this._accumulateFramebuffer.width,this._accumulateFramebuffer.height,m.STENCIL_BUFFER_BIT,F.NEAREST)}loadQualityProfile(e){if(i(this._qualityProfile)){const t=T(e,S),r=e.type===h.WEBGL1;this._qualityProfile={...t,requiresSharedStencilBuffer:r,shadingRate:r?1:.25,defines:t.dataType!==g.FLOAT?["heatmapPrecisionHalfFloat"]:[]}}return this._qualityProfile}}export{B as default};