From 2f7c97f25acca00a5f744e332fd6a96efd98a5f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Thu, 20 Nov 2014 13:40:23 +0100 Subject: [PATCH] Use OES_element_index_uint when available --- src/ol/has.js | 22 +++++++++++++++++----- src/ol/render/webgl/webglreplay.js | 22 +++++++++++++++++----- src/ol/webgl/context.js | 14 ++++++++++++++ 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/ol/has.js b/src/ol/has.js index 63745b48ac..ed05a84f85 100644 --- a/src/ol/has.js +++ b/src/ol/has.js @@ -113,6 +113,15 @@ ol.has.POINTER = 'PointerEvent' in goog.global; ol.has.MSPOINTER = !!(goog.global.navigator.msPointerEnabled); +/** + * True if browser supports WebGL. + * @const + * @type {boolean} + * @api stable + */ +ol.has.WEBGL; + + /** * The maximum supported WebGL texture size in pixels. If WebGL is not * supported, the value is set to `-1`. @@ -123,17 +132,18 @@ ol.has.WEBGL_MAX_TEXTURE_SIZE; /** - * True if browser supports WebGL. + * List of supported WebGL extensions. * @const - * @type {boolean} - * @api stable + * @type {Array.} */ -ol.has.WEBGL; +ol.has.WEBGL_EXTENSIONS; (function() { if (ol.ENABLE_WEBGL) { - var hasWebGL = false, textureSize = -1; + var hasWebGL = false; + var textureSize = -1; + var /** @type {Array.} */ extensions = []; if ('WebGLRenderingContext' in goog.global) { try { var canvas = /** @type {HTMLCanvasElement} */ @@ -145,10 +155,12 @@ ol.has.WEBGL; hasWebGL = true; textureSize = /** @type {number} */ (gl.getParameter(gl.MAX_TEXTURE_SIZE)); + extensions = gl.getSupportedExtensions(); } } catch (e) {} } ol.has.WEBGL = hasWebGL; ol.has.WEBGL_MAX_TEXTURE_SIZE = textureSize; + ol.has.WEBGL_EXTENSIONS = extensions; } })(); diff --git a/src/ol/render/webgl/webglreplay.js b/src/ol/render/webgl/webglreplay.js index da5c234f4f..1c1335b5c9 100644 --- a/src/ol/render/webgl/webglreplay.js +++ b/src/ol/render/webgl/webglreplay.js @@ -434,8 +434,19 @@ ol.render.webgl.ImageReplay.prototype.finish = function(context) { this.indicesBuffer_ = gl.createBuffer(); gl.bindBuffer(goog.webgl.ELEMENT_ARRAY_BUFFER, this.indicesBuffer_); - gl.bufferData(goog.webgl.ELEMENT_ARRAY_BUFFER, - new Uint16Array(this.indices_), goog.webgl.STATIC_DRAW); + var /** @type {ArrayBufferView} */ arrayBuffer, bits; + if (context.hasOESElementIndexUint) { + bits = 32; + arrayBuffer = new Uint32Array(this.indices_); + } else { + bits = 16; + arrayBuffer = new Uint16Array(this.indices_); + } + goog.asserts.assert(this.indices_[this.indices_.length - 1] < (1 << bits), + 'Too large element index detected, and OES_element_index_uint ' + + 'extension not available.'); + gl.bufferData(goog.webgl.ELEMENT_ARRAY_BUFFER, arrayBuffer, + goog.webgl.STATIC_DRAW); goog.asserts.assert(this.textures_.length === 0); @@ -611,9 +622,10 @@ ol.render.webgl.ImageReplay.prototype.replay = function(context, gl.bindTexture(goog.webgl.TEXTURE_2D, this.textures_[i]); var end = this.groupIndices_[i]; var numItems = end - start; - var offsetInBytes = start * 2; // 2 Bytes for UNSIGNED_SHORT - gl.drawElements(goog.webgl.TRIANGLES, numItems, - goog.webgl.UNSIGNED_SHORT, offsetInBytes); + var offsetInBytes = start * (context.hasOESElementIndexUint ? 4 : 2); + var elementType = context.hasOESElementIndexUint ? + goog.webgl.UNSIGNED_INT : goog.webgl.UNSIGNED_SHORT; + gl.drawElements(goog.webgl.TRIANGLES, numItems, elementType, offsetInBytes); start = end; } }; diff --git a/src/ol/webgl/context.js b/src/ol/webgl/context.js index 307837dc66..674526eac4 100644 --- a/src/ol/webgl/context.js +++ b/src/ol/webgl/context.js @@ -1,9 +1,11 @@ goog.provide('ol.webgl.Context'); +goog.require('goog.array'); goog.require('goog.asserts'); goog.require('goog.events'); goog.require('goog.log'); goog.require('goog.object'); +goog.require('ol.has'); goog.require('ol.structs.Buffer'); goog.require('ol.structs.IntegerSet'); goog.require('ol.webgl.WebGLContextEventType'); @@ -66,6 +68,18 @@ ol.webgl.Context = function(canvas, gl) { */ this.currentProgram_ = null; + /** + * @type {boolean} + */ + this.hasOESElementIndexUint = goog.array.contains( + ol.has.WEBGL_EXTENSIONS, 'OES_element_index_uint'); + + // use the OES_element_index_uint extension if available + if (this.hasOESElementIndexUint) { + var ext = gl.getExtension('OES_element_index_uint'); + goog.asserts.assert(!goog.isNull(ext)); + } + goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.LOST, this.handleWebGLContextLost, false, this); goog.events.listen(this.canvas_, ol.webgl.WebGLContextEventType.RESTORED,