Skip to content

Instantly share code, notes, and snippets.

@Sumbera
Last active January 6, 2017 22:16
Show Gist options
  • Save Sumbera/2a6e5d7e12c263fc3be1 to your computer and use it in GitHub Desktop.
Save Sumbera/2a6e5d7e12c263fc3be1 to your computer and use it in GitHub Desktop.

Revisions

  1. Sumbera revised this gist Aug 16, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    Test of pixi.js capabilities to tessellate polyline comming form geojson
    Test of pixi.js capabilities to tessellate polyline comming form geojson, blogged [here](http://blog.sumbera.com/2014/10/23/webgl-polyline-tessellation-with-pixi-js/)
  2. Sumbera revised this gist Oct 27, 2014. 2 changed files with 2 additions and 2 deletions.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@
    <!doctype html>
    <html>
    <head>
    <title>Many Points with leaflet WebGL</title>
    <title>Polyline tessellation test with Pixi.js</title>
    <meta charset="utf-8">

    <style>
    2 changes: 1 addition & 1 deletion readme.md
    Original file line number Diff line number Diff line change
    @@ -1 +1 @@
    Test of pixi.js capabilities to tesselate polyline comming form geojson
    Test of pixi.js capabilities to tessellate polyline comming form geojson
  3. Sumbera created this gist Oct 23, 2014.
    314 changes: 314 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,314 @@
    <!doctype html>
    <html>
    <head>
    <title>Many Points with leaflet WebGL</title>
    <meta charset="utf-8">

    <style>
    html, body {
    height: 100%;
    padding: 0;
    margin: 0;
    background: rgb(14, 21, 30);
    height: 100%;
    }

    #map {
    position: absolute;
    height: 100%;
    width: 100%;
    background-color: #333;
    }
    </style>
    <!-- vertex shader -->
    <script id="vshader" type="x-shader/x-vertex">
    uniform mat4 u_matrix;
    attribute vec4 a_vertex;
    attribute float a_pointSize;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main() {
    // Set the size of the point
    gl_PointSize = a_pointSize;

    // multiply each vertex by a matrix.
    gl_Position = u_matrix * a_vertex;


    // pass the color to the fragment shader
    v_color = a_color;
    }
    </script>
    <!-- fragment shader -->



    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;

    void main() {

    // -- squares
    gl_FragColor = v_color;
    gl_FragColor =vec4(0.8, 0.1,0.1, 0.9); // v_color;


    }

    </script>

    </head>
    <body>
    <div id="map"></div>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
    <script src="http://www.sumbera.com/gist/js/leaflet/canvas/L.CanvasOverlay.js"></script>
    <script src="http://www.sumbera.com/gist/js/pixi/Pixi.js"></script>
    <script src="http://www.sumbera.com/gist/js/pixi/Point.js"></script>
    <script src="http://www.sumbera.com/gist/js/pixi/WebGLGraphics.js"></script>
    <script src="http://www.sumbera.com/gist/data/route.js" charset="utf-8"></script>


    <script>

    var leafletMap = L.map('map').setView([38.911, -77.0521], 16);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-background,$fff[difference],$fff[@23],$fff[hsl-saturation@20],toner-lines[destination-in])/{z}/{x}/{y}.png")
    //L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    .addTo(leafletMap);


    var glLayer = L.canvasOverlay()
    .drawing(drawingOnCanvas)
    .addTo(leafletMap);
    var canvas = glLayer.canvas();

    glLayer.canvas.width = canvas.clientWidth;
    glLayer.canvas.height = canvas.clientHeight;


    var gl = canvas.getContext('experimental-webgl', { antialias: true });

    var pixelsToWebGLMatrix = new Float32Array(16);
    var mapMatrix = new Float32Array(16);

    // -- WebGl setup
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, document.getElementById('vshader').text);
    gl.compileShader(vertexShader);

    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, document.getElementById('fshader').text);
    gl.compileShader(fragmentShader);

    // link shaders to create our program
    var program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);



    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.BLEND);
    // gl.disable(gl.DEPTH_TEST);
    // ----------------------------
    // look up the locations for the inputs to our shaders.
    var u_matLoc = gl.getUniformLocation(program, "u_matrix");
    gl.aPointSize = gl.getAttribLocation(program, "a_pointSize");
    // Set the matrix to some that makes 1 unit 1 pixel.

    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);

    gl.uniformMatrix4fv(u_matLoc, false, pixelsToWebGLMatrix);










    // -- data

    var verts = [];
    var rawVerts = [];
    //-- verts only


    for (var i = 0 ; i < data.geometry.coordinates.length ; i++) {
    var d = data.geometry.coordinates[i];
    pixel = LatLongToPixelXY(d[1], d[0]);
    verts.push(pixel.x, pixel.y);

    }


    var graphicsData = {
    points: verts,
    lineWidth: 0.00015,
    lineColor: 0x33FF00,
    lineAlpha: 0.8
    };
    var webGLData = {
    points: [],
    indices: []
    };
    // -- from pixi/utils
    PIXI.hex2rgb = function (hex) {
    return [(hex >> 16 & 0xFF) / 255, (hex >> 8 & 0xFF) / 255, (hex & 0xFF) / 255];
    };
    PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);





    // -- buffer (vertex + color interleaved)
    webGLData.buffer = gl.createBuffer();
    gl.bindBuffer(gl.ARRAY_BUFFER, webGLData.buffer);

    var vertArray = new Float32Array(webGLData.points); // -- points includes color too
    var fsize = vertArray.BYTES_PER_ELEMENT;
    // -- set up vertext offset
    gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW);
    var vertLoc = gl.getAttribLocation(program, "a_vertex");
    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, fsize * 6, 0);
    gl.enableVertexAttribArray(vertLoc);

    // -- offset for color buffer
    var colorLoc = gl.getAttribLocation(program, "a_color");
    gl.vertexAttribPointer(colorLoc, 4, gl.FLOAT, false, fsize * 6, fsize * 2);
    gl.enableVertexAttribArray(colorLoc);

    var numPoints = webGLData.points.length / 6;







    // tirangles or point count
    //var numPoints = verts.length / 2;






    glLayer.redraw();


    function drawingOnCanvas(canvasOverlay, params) {
    if (gl == null) return;

    gl.clear(gl.COLOR_BUFFER_BIT);


    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);



    var pointSize = Math.max(leafletMap.getZoom() - 4.0, 1.0);
    gl.vertexAttrib1f(gl.aPointSize, pointSize);

    // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
    mapMatrix.set(pixelsToWebGLMatrix);

    var bounds = leafletMap.getBounds();
    var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());
    var offset = LatLongToPixelXY(topLeft.lat, topLeft.lng);

    // -- Scale to current zoom
    var scale = Math.pow(2, leafletMap.getZoom());
    scaleMatrix(mapMatrix, scale, scale);

    translateMatrix(mapMatrix, -offset.x, -offset.y);

    // -- attach matrix value to 'mapMatrix' uniform in shader
    gl.uniformMatrix4fv(u_matLoc, false, mapMatrix);



    gl.drawArrays(gl.TRIANGLE_STRIP, 0, numPoints);



    }

    // Returns a random integer from 0 to range - 1.
    function randomInt(range) {
    return Math.floor(Math.random() * range);
    }

    /*
    function latlonToPixels(lat, lon) {
    initialResolution = 2 * Math.PI * 6378137 / 256, // at zoomlevel 0
    originShift = 2 * Math.PI * 6378137 / 2;
    // -- to meters
    var mx = lon * originShift / 180;
    var my = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
    my = my * originShift / 180;
    // -- to pixels at zoom level 0
    var res = initialResolution;
    x = (mx + originShift) / res,
    y = (my + originShift) / res;
    return { x: x, y: 256- y };
    }
    */
    // -- converts latlon to pixels at zoom level 0 (for 256x256 tile size) , inverts y coord )
    // -- source : http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html

    function LatLongToPixelXY(latitude, longitude) {
    var pi_180 = Math.PI / 180.0;
    var pi_4 = Math.PI * 4;
    var sinLatitude = Math.sin(latitude * pi_180);
    var pixelY = (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (pi_4)) * 256;
    var pixelX = ((longitude + 180) / 360) * 256;

    var pixel = { x: pixelX, y: pixelY };

    return pixel;
    }

    function translateMatrix(matrix, tx, ty) {
    // translation is in last column of matrix
    matrix[12] += matrix[0] * tx + matrix[4] * ty;
    matrix[13] += matrix[1] * tx + matrix[5] * ty;
    matrix[14] += matrix[2] * tx + matrix[6] * ty;
    matrix[15] += matrix[3] * tx + matrix[7] * ty;
    }

    function scaleMatrix(matrix, scaleX, scaleY) {
    // scaling x and y, which is just scaling first two columns of matrix
    matrix[0] *= scaleX;
    matrix[1] *= scaleX;
    matrix[2] *= scaleX;
    matrix[3] *= scaleX;

    matrix[4] *= scaleY;
    matrix[5] *= scaleY;
    matrix[6] *= scaleY;
    matrix[7] *= scaleY;
    }


    </script>
    </body>



    </html>
    1 change: 1 addition & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Test of pixi.js capabilities to tesselate polyline comming form geojson