@doegis/core
Version:
DOE GIS API
3 lines (1 loc) • 4.92 kB
JavaScript
import{disposeMaybe as e,isSome as t,isNone as o}from"../../../../../core/maybe.js";import r from"../../../../../core/RandomLCG.js";import{TEXTURE_BINDING_RENDERER_0 as s,TEXTURE_BINDING_RENDERER_1 as i,TILE_SIZE as n}from"../definitions.js";import{WGLGeometryType as d,WGLSymbologyType as a}from"../enums.js";import l from"./WGLGeometryBrushFill.js";import{assertRendererSchema as _}from"../techniques/utils.js";import{BufferObject as u}from"../../../../webgl/BufferObject.js";import{DataType as m,PrimitiveType as h,TextureType as c,PixelFormat as f,PixelType as T,TextureSamplingMode as p,TextureWrapMode as x,TargetType as w,DepthStencilTargetType as D,RenderbufferFormat as y,Usage as g}from"../../../../webgl/enums.js";import{FramebufferObject as S}from"../../../../webgl/FramebufferObject.js";import{Renderbuffer as b}from"../../../../webgl/Renderbuffer.js";import{Texture as E}from"../../../../webgl/Texture.js";import{VertexArrayObject as F}from"../../../../webgl/VertexArrayObject.js";class O extends l{constructor(){super(...arguments),this._dotTextureSize=0,this._dotTextures=null,this._dotSamplers=new Int32Array([s,i]),this._dotVAO=null,this._dotDesc={vsPath:"dot/dot",fsPath:"dot/dot",attributes:new Map([["a_pos",0]])}}dispose(){super.dispose(),this._disposeTextures(),this._dotFBO=e(this._dotFBO),this._dotVAO=e(this._dotVAO)}getGeometryType(){return d.FILL}supportsSymbology(e){return e===a.DOT_DENSITY}_drawFills(e,o,r,s,i,n){const{passOptions:d}=e;if(t(d)&&"hittest"===d.type)super._drawFills(e,o,r,s,i,n);else{const t=this._drawDotLocations(e,o,r,i,n);this._drawDotDensity(e,o,t)}}_drawDotDensity(e,o,r){const{context:s,painter:i,rendererInfo:n,requestRender:d,allowDelayedRender:a}=e,l=i.materialManager.getProgram(this._dotDesc);if(a&&t(d)&&!l.compiled)return void d();const{rendererSchema:u}=n;_(u,"dot-density");const c=this._createDotDensityMesh(s,this._dotDesc.attributes,{geometry:[{name:"a_pos",count:2,type:m.SHORT,divisor:0,normalized:!1,offset:0,stride:4}]});s.setStencilTestEnabled(!0),s.useProgram(l),l.setUniform1f("u_tileZoomFactor",1),l.setUniform1i("u_texture",this._dotSamplers[0]),l.setUniform1f("u_dotSize",Math.max(u.dotSize,1)),l.setUniform1f("u_pixelRatio",window.devicePixelRatio),this._setSharedUniforms(l,e,o),s.bindTexture(r,this._dotSamplers[0]),s.bindVAO(c),s.drawArrays(h.POINTS,0,262144)}_drawDotLocations(e,t,o,r,s){const{context:i,rendererInfo:d,requiredLevel:a}=e,l=i.getViewport(),{rendererSchema:u}=d;_(u,"dot-density");const{dotScale:c,colors:f,activeDots:T,backgroundColor:p,dotValue:x}=u;i.setViewport(0,0,512,512);const w=i.getBoundFramebufferObject(),D=this._createFBO(i);i.bindFramebuffer(D),i.setClearColor(0,0,0,0),i.clear(i.gl.COLOR_BUFFER_BIT|i.gl.STENCIL_BUFFER_BIT),i.setStencilTestEnabled(!1);const y=1/2**(a-t.key.level),g=n,S=g*window.devicePixelRatio*g*window.devicePixelRatio,b=1/y*(1/y),E=c?e.state.scale/c:1;return o.setUniform1f("u_tileZoomFactor",y),o.setUniform1f("u_tileDotsOverArea",S/(n*window.devicePixelRatio*n*window.devicePixelRatio)),o.setUniformMatrix4fv("u_dotColors",f),o.setUniform4fv("u_isActive",T),o.setUniform4fv("u_dotBackgroundColor",p),o.setUniform1f("u_dotValue",Math.max(1,x*E*b)),this._bindDotDensityTextures(i,o,d,g),i.drawElements(h.TRIANGLES,r,m.UNSIGNED_INT,s),i.setViewport(l.x,l.y,l.width,l.height),i.bindFramebuffer(w),D.colorTexture}_createFBO(e){if(o(this._dotFBO)){const t=512,o=512,r={target:c.TEXTURE_2D,pixelFormat:f.RGBA,dataType:T.UNSIGNED_BYTE,samplingMode:p.NEAREST,wrapMode:x.CLAMP_TO_EDGE,width:t,height:o},s={colorTarget:w.TEXTURE,depthStencilTarget:D.DEPTH_STENCIL_RENDER_BUFFER},i=new b(e,{width:t,height:o,internalFormat:y.DEPTH_STENCIL});this._dotFBO=new S(e,s,r,i)}return this._dotFBO}_disposeTextures(){if(this._dotTextures){for(let e=0;e<this._dotTextures.length;e++)this._dotTextures[e].dispose();this._dotTextures=null}}_bindDotDensityTextures(e,t,o,r){const{rendererSchema:s}=o;_(s,"dot-density");const i=this._createDotDensityTextures(e,r,s.seed);t.setUniform1iv("u_dotTextures",this._dotSamplers);for(let n=0;n<i.length;n++)e.bindTexture(i[n],this._dotSamplers[n])}_createDotDensityMesh(e,t,r){if(o(this._dotVAO)){const o=2,s=new Int16Array(262144*o);for(let e=0;e<512;e++)for(let t=0;t<512;t++)s[o*(t+512*e)]=t,s[o*(t+512*e)+1]=e;const i=u.createVertex(e,g.STATIC_DRAW,s);this._dotVAO=new F(e,t,r,{geometry:i},null)}return this._dotVAO}_createDotDensityTextures(e,t,o){if(this._dotTextureSize===t&&this._seed===o||(this._disposeTextures(),this._dotTextureSize=t,this._seed=o),null===this._dotTextures){const s=new r(o);this._dotTextures=[this._allocDotDensityTexture(e,t,s),this._allocDotDensityTexture(e,t,s)]}return this._dotTextures}_allocDotDensityTexture(e,t,o){const r=new Float32Array(t*t*4);for(let s=0;s<r.length;s++)r[s]=o.getFloat();return new E(e,{wrapMode:x.REPEAT,pixelFormat:f.RGBA,dataType:T.FLOAT,samplingMode:p.NEAREST,width:t,height:t},r)}}export{O as default};