module import { EdgeDisplayData , NodeDisplayData } from "../../../types" ; import { AbstractEdgeProgram } from "./common/edge" ; import { floatColor , canUse32BitsIndices } from "../../../utils" ; import vertexShaderSource from "../shaders/edge.clamped.vert.glsl" ; import fragmentShaderSource from "../shaders/edge.frag.glsl" ; import { RenderParams } from "./common/program" ; const POINTS = 4 , ATTRIBUTES = 6 , STRIDE = POINTS * ATTRIBUTES ; export default class EdgeClampedProgram extends AbstractEdgeProgram { IndicesArray : Uint32ArrayConstructor | Uint16ArrayConstructor ; indicesArray : Uint32Array | Uint16Array ; indicesBuffer : WebGLBuffer ; indicesType : GLenum ; positionLocation : GLint ; colorLocation : GLint ; normalLocation : GLint ; radiusLocation : GLint ; matrixLocation : WebGLUniformLocation ; sqrtZoomRatioLocation : WebGLUniformLocation ; correctionRatioLocation : WebGLUniformLocation ; canUse32BitsIndices : boolean ; constructor ( gl ) { super ( gl , vertexShaderSource , fragmentShaderSource , POINTS , ATTRIBUTES ) ; const indicesBuffer = gl . createBuffer ( ) ; if ( indicesBuffer === null ) throw new Error ( "EdgeClampedProgram: error while getting resolutionLocation" ) ; this . indicesBuffer = indicesBuffer ; this . positionLocation = gl . getAttribLocation ( this . program , "a_position" ) ; this . colorLocation = gl . getAttribLocation ( this . program , "a_color" ) ; this . normalLocation = gl . getAttribLocation ( this . program , "a_normal" ) ; this . radiusLocation = gl . getAttribLocation ( this . program , "a_radius" ) ; const matrixLocation = gl . getUniformLocation ( this . program , "u_matrix" ) ; if ( matrixLocation === null ) throw new Error ( "EdgeClampedProgram: error while getting matrixLocation" ) ; this . matrixLocation = matrixLocation ; const sqrtZoomRatioLocation = gl . getUniformLocation ( this . program , "u_sqrtZoomRatio" ) ; if ( sqrtZoomRatioLocation === null ) throw new Error ( "EdgeClampedProgram: error while getting cameraRatioLocation" ) ; this . sqrtZoomRatioLocation = sqrtZoomRatioLocation ; const correctionRatioLocation = gl . getUniformLocation ( this . program , "u_correctionRatio" ) ; if ( correctionRatioLocation === null ) throw new Error ( "EdgeClampedProgram: error while getting viewportRatioLocation" ) ; this . correctionRatioLocation = correctionRatioLocation ; this . canUse32BitsIndices = canUse32BitsIndices ( gl ) ; this . IndicesArray = this . canUse32BitsIndices ? Uint32Array : Uint16Array ; this . indicesArray = new this . IndicesArray ( ) ; this . indicesType = this . canUse32BitsIndices ? gl . UNSIGNED_INT : gl . UNSIGNED_SHORT ; this . bind ( ) ; } bind ( ) { const gl = this . gl ; gl . bindBuffer ( gl . ELEMENT_ARRAY_BUFFER , this . indicesBuffer ) ; gl . enableVertexAttribArray ( this . positionLocation ) ; gl . enableVertexAttribArray ( this . normalLocation ) ; gl . enableVertexAttribArray ( this . colorLocation ) ; gl . enableVertexAttribArray ( this . radiusLocation ) ; gl . vertexAttribPointer ( this . positionLocation , 2 , gl . FLOAT , false , ATTRIBUTES * Float32Array . BYTES_PER_ELEMENT , 0 ) ; gl . vertexAttribPointer ( this . normalLocation , 2 , gl . FLOAT , false , ATTRIBUTES * Float32Array . BYTES_PER_ELEMENT , 8 ) ; gl . vertexAttribPointer ( this . colorLocation , 4 , gl . UNSIGNED_BYTE , true , ATTRIBUTES * Float32Array . BYTES_PER_ELEMENT , 16 ) ; gl . vertexAttribPointer ( this . radiusLocation , 1 , gl . FLOAT , false , ATTRIBUTES * Float32Array . BYTES_PER_ELEMENT , 20 ) ; } process ( sourceData , targetData , data , hidden , offset ) { if ( hidden ) { for ( let i = offset * STRIDE , l = i + STRIDE ; i < l ; i ++ ) this . array [ i ] = 0 ; return ; } const thickness = data . size || 1 , x1 = sourceData . x , y1 = sourceData . y , x2 = targetData . x , y2 = targetData . y , radius = targetData . size || 1 , color = floatColor ( data . color ) ; const dx = x2 - x1 , dy = y2 - y1 ; let len = dx * dx + dy * dy , n1 = 0 , n2 = 0 ; if ( len ) { len = 1 / Math . sqrt ( len ) ; n1 = - dy * len * thickness ; n2 = dx * len * thickness ; } let i = POINTS * ATTRIBUTES * offset ; const array = this . array ; array [ i ++ ] = x1 ; array [ i ++ ] = y1 ; array [ i ++ ] = n1 ; array [ i ++ ] = n2 ; array [ i ++ ] = color ; array [ i ++ ] = 0 ; array [ i ++ ] = x1 ; array [ i ++ ] = y1 ; array [ i ++ ] = - n1 ; array [ i ++ ] = - n2 ; array [ i ++ ] = color ; array [ i ++ ] = 0 ; array [ i ++ ] = x2 ; array [ i ++ ] = y2 ; array [ i ++ ] = n1 ; array [ i ++ ] = n2 ; array [ i ++ ] = color ; array [ i ++ ] = radius ; array [ i ++ ] = x2 ; array [ i ++ ] = y2 ; array [ i ++ ] = - n1 ; array [ i ++ ] = - n2 ; array [ i ++ ] = color ; array [ i ] = - radius ; } computeIndices ( ) { const l = this . array . length / ATTRIBUTES ; const size = l + l / 2 ; const indices = new this . IndicesArray ( size ) ; for ( let i = 0 , c = 0 ; i < l ; i += 4 ) { indices [ c ++ ] = i ; indices [ c ++ ] = i + 1 ; indices [ c ++ ] = i + 2 ; indices [ c ++ ] = i + 2 ; indices [ c ++ ] = i + 1 ; indices [ c ++ ] = i + 3 ; } this . indicesArray = indices ; } bufferData ( ) { super . bufferData ( ) ; const gl = this . gl ; gl . bufferData ( gl . ELEMENT_ARRAY_BUFFER , this . indicesArray , gl . STATIC_DRAW ) ; } render ( params ) { if ( this . hasNothingToRender ( ) ) return ; const gl = this . gl ; const program = this . program ; gl . useProgram ( program ) ; gl . uniformMatrix3fv ( this . matrixLocation , false , params . matrix ) ; gl . uniform1f ( this . sqrtZoomRatioLocation , Math . sqrt ( params . ratio ) ) ; gl . uniform1f ( this . correctionRatioLocation , params . correctionRatio ) ; gl . drawElements ( gl . TRIANGLES , this . indicesArray . length , this . indicesType , 0 ) ; } }