-function initGL() {
- if (gMapGL) {
- gMapGL.clearColor(0.0, 0.0, 0.0, 0.5); // Set clear color to black, fully opaque.
- gMapGL.clear(gMapGL.COLOR_BUFFER_BIT|gMapGL.DEPTH_BUFFER_BIT); // Clear the color.
-
- // Create and initialize the shaders.
- var vertShader = gMapGL.createShader(gMapGL.VERTEX_SHADER);
- var vertShaderSource =
- 'attribute vec2 aVertexPosition;\n' +
- 'attribute vec2 aTextureCoord;\n\n' +
- 'uniform vec2 uResolution;\n\n' +
- 'varying highp vec2 vTextureCoord;\n\n' +
- 'void main(void) {\n' +
- // convert the rectangle from pixels to -1.0 to +1.0 (clipspace) 0.0 to 1.0
- ' vec2 clipSpace = aVertexPosition * 2.0 / uResolution - 1.0;\n' +
- ' gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n' +
- ' vTextureCoord = aTextureCoord;\n' +
- '}';
- var fragShader = gMapGL.createShader(gMapGL.FRAGMENT_SHADER);
- var fragShaderSource =
- 'varying highp vec2 vTextureCoord;\n\n' +
- 'uniform sampler2D uImage;\n\n' +
- 'void main(void) {\n' +
- ' gl_FragColor = texture2D(uImage, vTextureCoord);\n' +
- '}';
-
- gMapGL.shaderSource(vertShader, vertShaderSource);
- // Compile the shader program.
- gMapGL.compileShader(vertShader);
- // See if it compiled successfully.
- if (!gMapGL.getShaderParameter(vertShader, gMapGL.COMPILE_STATUS)) {
- console.log("An error occurred compiling the vertix shader: " + gMapGL.getShaderInfoLog(vertShader));
- return null;
+var gMap = {
+ gl: null,
+ glShaderProgram: null,
+ glVertexPositionAttr: null,
+ glTextureCoordAttr: null,
+ glResolutionAttr: null,
+ glMapTexture: null,
+ glTextures: {},
+ glTxCleanIntervalID: null,
+ glTexturesPerZoomLevel: 0,
+
+ activeMap: "osm_mapnik",
+ tileSize: 256,
+ maxZoom: 18, // The minimum is 0.
+ zoomFactor: null,
+ pos: {
+ x: 35630000.0, // Current position in the map in pixels at the maximum zoom level (18)
+ y: 23670000.0, // The range is 0-67108864 (2^gMap.maxZoom * gMap.tileSize)
+ z: 5 // This could be fractional if supported being between zoom levels.
+ },
+ baseDim: { // Map width, height and tile size in level 18 pixels.
+ wid: null,
+ ht: null,
+ tsize: null,
+ },
+
+ get width() { return gMap.gl ? gMap.gl.drawingBufferWidth : gGLMapCanvas.width; },
+ get height() { return gMap.gl ? gMap.gl.drawingBufferHeight : gGLMapCanvas.height; },
+
+ getVertShaderSource: function() {
+ return 'attribute vec2 aVertexPosition;\n' +
+ 'attribute vec2 aTextureCoord;\n\n' +
+ 'uniform vec2 uResolution;\n\n' +
+ 'varying highp vec2 vTextureCoord;\n\n' +
+ 'void main(void) {\n' +
+ // convert the rectangle from pixels to -1.0 to +1.0 (clipspace) 0.0 to 1.0
+ ' vec2 clipSpace = aVertexPosition * 2.0 / uResolution - 1.0;\n' +
+ ' gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);\n' +
+ ' vTextureCoord = aTextureCoord;\n' +
+ '}'; },
+ getFragShaderSource:function() {
+ return 'varying highp vec2 vTextureCoord;\n\n' +
+ 'uniform sampler2D uImage;\n\n' +
+ 'void main(void) {\n' +
+ ' gl_FragColor = texture2D(uImage, vTextureCoord);\n' +
+ '}'; },
+
+ initGL: function() {
+ // When called from the event listener, the "this" reference doesn't work, so use the object name.
+ if (gMap.gl) {
+ gMap.gl.viewport(0, 0, gMap.gl.drawingBufferWidth, gMap.gl.drawingBufferHeight);
+ gMap.gl.clearColor(0.0, 0.0, 0.0, 0.5); // Set clear color to black, fully opaque.
+ gMap.gl.clear(gMap.gl.COLOR_BUFFER_BIT|gMap.gl.DEPTH_BUFFER_BIT); // Clear the color.
+
+ // Create and initialize the shaders.
+ var vertShader = gMap.gl.createShader(gMap.gl.VERTEX_SHADER);
+ var fragShader = gMap.gl.createShader(gMap.gl.FRAGMENT_SHADER);
+ gMap.gl.shaderSource(vertShader, gMap.getVertShaderSource());
+ // Compile the shader program.
+ gMap.gl.compileShader(vertShader);
+ // See if it compiled successfully.
+ if (!gMap.gl.getShaderParameter(vertShader, gMap.gl.COMPILE_STATUS)) {
+ console.log("An error occurred compiling the vertex shader: " + gMap.gl.getShaderInfoLog(vertShader));
+ return null;
+ }
+ gMap.gl.shaderSource(fragShader, gMap.getFragShaderSource());
+ // Compile the shader program.
+ gMap.gl.compileShader(fragShader);
+ // See if it compiled successfully.
+ if (!gMap.gl.getShaderParameter(fragShader, gMap.gl.COMPILE_STATUS)) {
+ console.log("An error occurred compiling the fragment shader: " + gMap.gl.getShaderInfoLog(fragShader));
+ return null;
+ }
+
+ gMap.glShaderProgram = gMap.gl.createProgram();
+ gMap.gl.attachShader(gMap.glShaderProgram, vertShader);
+ gMap.gl.attachShader(gMap.glShaderProgram, fragShader);
+ gMap.gl.linkProgram(gMap.glShaderProgram);
+ // If creating the shader program failed, alert
+ if (!gMap.gl.getProgramParameter(gMap.glShaderProgram, gMap.gl.LINK_STATUS)) {
+ alert("Unable to initialize the shader program.");
+ }
+ gMap.gl.useProgram(gMap.glShaderProgram);
+ // Get locations of the attributes.
+ gMap.glVertexPositionAttr = gMap.gl.getAttribLocation(gMap.glShaderProgram, "aVertexPosition");
+ gMap.glTextureCoordAttr = gMap.gl.getAttribLocation(gMap.glShaderProgram, "aTextureCoord");
+ gMap.glResolutionAttr = gMap.gl.getUniformLocation(gMap.glShaderProgram, "uResolution");
+
+ var tileVerticesBuffer = gMap.gl.createBuffer();
+ gMap.gl.bindBuffer(gMap.gl.ARRAY_BUFFER, tileVerticesBuffer);
+ // The vertices are the coordinates of the corner points of the square.
+ var vertices = [
+ 0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ 1.0, 1.0,
+ ];
+ gMap.gl.bufferData(gMap.gl.ARRAY_BUFFER, new Float32Array(vertices), gMap.gl.STATIC_DRAW);
+ gMap.gl.enableVertexAttribArray(gMap.glTextureCoordAttr);
+ gMap.gl.vertexAttribPointer(gMap.glTextureCoordAttr, 2, gMap.gl.FLOAT, false, 0, 0);
+
+ gMap.loadImageToTexture(gLoadingTile, getTileKey("loading", {x: 0, y: 0, z: 0}));
+
+ gMap.gl.uniform2f(gMap.glResolutionAttr, gGLMapCanvas.width, gGLMapCanvas.height);
+
+ // Create a buffer for the position of the rectangle corners.
+ var mapVerticesTextureCoordBuffer = gMap.gl.createBuffer();
+ gMap.gl.bindBuffer(gMap.gl.ARRAY_BUFFER, mapVerticesTextureCoordBuffer);
+ gMap.gl.enableVertexAttribArray(gMap.glVertexPositionAttr);
+ gMap.gl.vertexAttribPointer(gMap.glVertexPositionAttr, 2, gMap.gl.FLOAT, false, 0, 0);
+
+ // Call texture cleaning every 30 seconds, for now (is 60 better?).
+ gMap.glTxCleanIntervalID = window.setInterval(gMap.cleanTextures, 30 * 1000);