From bd87ec7c832c7e636c25d80bdcfac2826341aa7f Mon Sep 17 00:00:00 2001 From: GaborFarkas Date: Wed, 7 Jun 2017 12:57:03 +0200 Subject: [PATCH] Conform ImageReplay to the new structure --- src/ol/render/webgl/imagereplay.js | 524 ++---------------- test/spec/ol/render/webgl/imagereplay.test.js | 120 ++-- 2 files changed, 85 insertions(+), 559 deletions(-) diff --git a/src/ol/render/webgl/imagereplay.js b/src/ol/render/webgl/imagereplay.js index 16fb0be045..47f22045ef 100644 --- a/src/ol/render/webgl/imagereplay.js +++ b/src/ol/render/webgl/imagereplay.js @@ -1,123 +1,34 @@ goog.provide('ol.render.webgl.ImageReplay'); goog.require('ol'); -goog.require('ol.extent'); -goog.require('ol.obj'); -goog.require('ol.render.webgl.imagereplay.defaultshader'); -goog.require('ol.render.webgl.Replay'); -goog.require('ol.webgl'); +goog.require('ol.render.webgl.TextureReplay'); goog.require('ol.webgl.Buffer'); -goog.require('ol.webgl.Context'); if (ol.ENABLE_WEBGL) { /** * @constructor - * @extends {ol.render.webgl.Replay} + * @extends {ol.render.webgl.TextureReplay} * @param {number} tolerance Tolerance. * @param {ol.Extent} maxExtent Max extent. * @struct */ ol.render.webgl.ImageReplay = function(tolerance, maxExtent) { - ol.render.webgl.Replay.call(this, tolerance, maxExtent); - - /** - * @type {number|undefined} - * @private - */ - this.anchorX_ = undefined; - - /** - * @type {number|undefined} - * @private - */ - this.anchorY_ = undefined; - - /** - * @type {Array.} - * @private - */ - this.groupIndices_ = []; - - /** - * @type {Array.} - * @private - */ - this.hitDetectionGroupIndices_ = []; - - /** - * @type {number|undefined} - * @private - */ - this.height_ = undefined; + ol.render.webgl.TextureReplay.call(this, tolerance, maxExtent); /** * @type {Array.} - * @private + * @protected */ this.images_ = []; /** * @type {Array.} - * @private + * @protected */ this.hitDetectionImages_ = []; - /** - * @type {number|undefined} - * @private - */ - this.imageHeight_ = undefined; - - /** - * @type {number|undefined} - * @private - */ - this.imageWidth_ = undefined; - - /** - * @private - * @type {ol.render.webgl.imagereplay.defaultshader.Locations} - */ - this.defaultLocations_ = null; - - /** - * @private - * @type {number|undefined} - */ - this.opacity_ = undefined; - - /** - * @type {number|undefined} - * @private - */ - this.originX_ = undefined; - - /** - * @type {number|undefined} - * @private - */ - this.originY_ = undefined; - - /** - * @private - * @type {boolean|undefined} - */ - this.rotateWithView_ = undefined; - - /** - * @private - * @type {number|undefined} - */ - this.rotation_ = undefined; - - /** - * @private - * @type {number|undefined} - */ - this.scale_ = undefined; - /** * @type {Array.} * @private @@ -130,141 +41,8 @@ if (ol.ENABLE_WEBGL) { */ this.hitDetectionTextures_ = []; - /** - * @type {number|undefined} - * @private - */ - this.width_ = undefined; - }; - ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.Replay); - - - /** - * @inheritDoc - */ - ol.render.webgl.ImageReplay.prototype.getDeleteResourcesFunction = function(context) { - var verticesBuffer = this.verticesBuffer; - var indicesBuffer = this.indicesBuffer; - var textures = this.textures_; - var hitDetectionTextures = this.hitDetectionTextures_; - var gl = context.getGL(); - return function() { - if (!gl.isContextLost()) { - var i, ii; - for (i = 0, ii = textures.length; i < ii; ++i) { - gl.deleteTexture(textures[i]); - } - for (i = 0, ii = hitDetectionTextures.length; i < ii; ++i) { - gl.deleteTexture(hitDetectionTextures[i]); - } - } - context.deleteBuffer(verticesBuffer); - context.deleteBuffer(indicesBuffer); - }; - }; - - - /** - * @param {Array.} flatCoordinates Flat coordinates. - * @param {number} offset Offset. - * @param {number} end End. - * @param {number} stride Stride. - * @return {number} My end. - * @private - */ - ol.render.webgl.ImageReplay.prototype.drawCoordinates_ = function(flatCoordinates, offset, end, stride) { - var anchorX = /** @type {number} */ (this.anchorX_); - var anchorY = /** @type {number} */ (this.anchorY_); - var height = /** @type {number} */ (this.height_); - var imageHeight = /** @type {number} */ (this.imageHeight_); - var imageWidth = /** @type {number} */ (this.imageWidth_); - var opacity = /** @type {number} */ (this.opacity_); - var originX = /** @type {number} */ (this.originX_); - var originY = /** @type {number} */ (this.originY_); - var rotateWithView = this.rotateWithView_ ? 1.0 : 0.0; - // this.rotation_ is anti-clockwise, but rotation is clockwise - var rotation = /** @type {number} */ (-this.rotation_); - var scale = /** @type {number} */ (this.scale_); - var width = /** @type {number} */ (this.width_); - var cos = Math.cos(rotation); - var sin = Math.sin(rotation); - var numIndices = this.indices.length; - var numVertices = this.vertices.length; - var i, n, offsetX, offsetY, x, y; - for (i = offset; i < end; i += stride) { - x = flatCoordinates[i] - this.origin[0]; - y = flatCoordinates[i + 1] - this.origin[1]; - - // There are 4 vertices per [x, y] point, one for each corner of the - // rectangle we're going to draw. We'd use 1 vertex per [x, y] point if - // WebGL supported Geometry Shaders (which can emit new vertices), but that - // is not currently the case. - // - // And each vertex includes 8 values: the x and y coordinates, the x and - // y offsets used to calculate the position of the corner, the u and - // v texture coordinates for the corner, the opacity, and whether the - // the image should be rotated with the view (rotateWithView). - - n = numVertices / 8; - - // bottom-left corner - offsetX = -scale * anchorX; - offsetY = -scale * (height - anchorY); - this.vertices[numVertices++] = x; - this.vertices[numVertices++] = y; - this.vertices[numVertices++] = offsetX * cos - offsetY * sin; - this.vertices[numVertices++] = offsetX * sin + offsetY * cos; - this.vertices[numVertices++] = originX / imageWidth; - this.vertices[numVertices++] = (originY + height) / imageHeight; - this.vertices[numVertices++] = opacity; - this.vertices[numVertices++] = rotateWithView; - - // bottom-right corner - offsetX = scale * (width - anchorX); - offsetY = -scale * (height - anchorY); - this.vertices[numVertices++] = x; - this.vertices[numVertices++] = y; - this.vertices[numVertices++] = offsetX * cos - offsetY * sin; - this.vertices[numVertices++] = offsetX * sin + offsetY * cos; - this.vertices[numVertices++] = (originX + width) / imageWidth; - this.vertices[numVertices++] = (originY + height) / imageHeight; - this.vertices[numVertices++] = opacity; - this.vertices[numVertices++] = rotateWithView; - - // top-right corner - offsetX = scale * (width - anchorX); - offsetY = scale * anchorY; - this.vertices[numVertices++] = x; - this.vertices[numVertices++] = y; - this.vertices[numVertices++] = offsetX * cos - offsetY * sin; - this.vertices[numVertices++] = offsetX * sin + offsetY * cos; - this.vertices[numVertices++] = (originX + width) / imageWidth; - this.vertices[numVertices++] = originY / imageHeight; - this.vertices[numVertices++] = opacity; - this.vertices[numVertices++] = rotateWithView; - - // top-left corner - offsetX = -scale * anchorX; - offsetY = scale * anchorY; - this.vertices[numVertices++] = x; - this.vertices[numVertices++] = y; - this.vertices[numVertices++] = offsetX * cos - offsetY * sin; - this.vertices[numVertices++] = offsetX * sin + offsetY * cos; - this.vertices[numVertices++] = originX / imageWidth; - this.vertices[numVertices++] = originY / imageHeight; - this.vertices[numVertices++] = opacity; - this.vertices[numVertices++] = rotateWithView; - - this.indices[numIndices++] = n; - this.indices[numIndices++] = n + 1; - this.indices[numIndices++] = n + 2; - this.indices[numIndices++] = n; - this.indices[numIndices++] = n + 2; - this.indices[numIndices++] = n + 3; - } - - return numVertices; }; + ol.inherits(ol.render.webgl.ImageReplay, ol.render.webgl.TextureReplay); /** @@ -275,7 +53,7 @@ if (ol.ENABLE_WEBGL) { this.startIndicesFeature.push(feature); var flatCoordinates = multiPointGeometry.getFlatCoordinates(); var stride = multiPointGeometry.getStride(); - this.drawCoordinates_( + this.drawCoordinates( flatCoordinates, 0, flatCoordinates.length, stride); }; @@ -288,7 +66,7 @@ if (ol.ENABLE_WEBGL) { this.startIndicesFeature.push(feature); var flatCoordinates = pointGeometry.getFlatCoordinates(); var stride = pointGeometry.getStride(); - this.drawCoordinates_( + this.drawCoordinates( flatCoordinates, 0, flatCoordinates.length, stride); }; @@ -299,8 +77,8 @@ if (ol.ENABLE_WEBGL) { ol.render.webgl.ImageReplay.prototype.finish = function(context) { var gl = context.getGL(); - this.groupIndices_.push(this.indices.length); - this.hitDetectionGroupIndices_.push(this.indices.length); + this.groupIndices.push(this.indices.length); + this.hitDetectionGroupIndices.push(this.indices.length); // create, bind, and populate the vertices buffer this.verticesBuffer = new ol.webgl.Buffer(this.vertices); @@ -314,246 +92,14 @@ if (ol.ENABLE_WEBGL) { /** @type {Object.} */ var texturePerImage = {}; - this.createTextures_(this.textures_, this.images_, texturePerImage, gl); + this.createTextures(this.textures_, this.images_, texturePerImage, gl); - this.createTextures_(this.hitDetectionTextures_, this.hitDetectionImages_, + this.createTextures(this.hitDetectionTextures_, this.hitDetectionImages_, texturePerImage, gl); - this.anchorX_ = undefined; - this.anchorY_ = undefined; - this.height_ = undefined; this.images_ = null; this.hitDetectionImages_ = null; - this.imageHeight_ = undefined; - this.imageWidth_ = undefined; - this.indices = null; - this.opacity_ = undefined; - this.originX_ = undefined; - this.originY_ = undefined; - this.rotateWithView_ = undefined; - this.rotation_ = undefined; - this.scale_ = undefined; - this.vertices = null; - this.width_ = undefined; - }; - - - /** - * @private - * @param {Array.} textures Textures. - * @param {Array.} images - * Images. - * @param {Object.} texturePerImage Texture cache. - * @param {WebGLRenderingContext} gl Gl. - */ - ol.render.webgl.ImageReplay.prototype.createTextures_ = function(textures, images, texturePerImage, gl) { - var texture, image, uid, i; - var ii = images.length; - for (i = 0; i < ii; ++i) { - image = images[i]; - - uid = ol.getUid(image).toString(); - if (uid in texturePerImage) { - texture = texturePerImage[uid]; - } else { - texture = ol.webgl.Context.createTexture( - gl, image, ol.webgl.CLAMP_TO_EDGE, ol.webgl.CLAMP_TO_EDGE); - texturePerImage[uid] = texture; - } - textures[i] = texture; - } - }; - - - /** - * @inheritDoc - */ - ol.render.webgl.ImageReplay.prototype.setUpProgram = function(gl, context, size, pixelRatio) { - // get the program - var fragmentShader = ol.render.webgl.imagereplay.defaultshader.fragment; - var vertexShader = ol.render.webgl.imagereplay.defaultshader.vertex; - var program = context.getProgram(fragmentShader, vertexShader); - - // get the locations - var locations; - if (!this.defaultLocations_) { - // eslint-disable-next-line openlayers-internal/no-missing-requires - locations = new ol.render.webgl.imagereplay.defaultshader.Locations(gl, program); - this.defaultLocations_ = locations; - } else { - locations = this.defaultLocations_; - } - - // use the program (FIXME: use the return value) - context.useProgram(program); - - // enable the vertex attrib arrays - gl.enableVertexAttribArray(locations.a_position); - gl.vertexAttribPointer(locations.a_position, 2, ol.webgl.FLOAT, - false, 32, 0); - - gl.enableVertexAttribArray(locations.a_offsets); - gl.vertexAttribPointer(locations.a_offsets, 2, ol.webgl.FLOAT, - false, 32, 8); - - gl.enableVertexAttribArray(locations.a_texCoord); - gl.vertexAttribPointer(locations.a_texCoord, 2, ol.webgl.FLOAT, - false, 32, 16); - - gl.enableVertexAttribArray(locations.a_opacity); - gl.vertexAttribPointer(locations.a_opacity, 1, ol.webgl.FLOAT, - false, 32, 24); - - gl.enableVertexAttribArray(locations.a_rotateWithView); - gl.vertexAttribPointer(locations.a_rotateWithView, 1, ol.webgl.FLOAT, - false, 32, 28); - - return locations; - }; - - - /** - * @inheritDoc - */ - ol.render.webgl.ImageReplay.prototype.shutDownProgram = function(gl, locations) { - gl.disableVertexAttribArray(locations.a_position); - gl.disableVertexAttribArray(locations.a_offsets); - gl.disableVertexAttribArray(locations.a_texCoord); - gl.disableVertexAttribArray(locations.a_opacity); - gl.disableVertexAttribArray(locations.a_rotateWithView); - }; - - - /** - * @inheritDoc - */ - ol.render.webgl.ImageReplay.prototype.drawReplay = function(gl, context, skippedFeaturesHash, hitDetection) { - var textures = hitDetection ? this.hitDetectionTextures_ : this.textures_; - var groupIndices = hitDetection ? this.hitDetectionGroupIndices_ : this.groupIndices_; - - if (!ol.obj.isEmpty(skippedFeaturesHash)) { - this.drawReplaySkipping_( - gl, context, skippedFeaturesHash, textures, groupIndices); - } else { - var i, ii, start; - for (i = 0, ii = textures.length, start = 0; i < ii; ++i) { - gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]); - var end = groupIndices[i]; - this.drawElements(gl, context, start, end); - start = end; - } - } - }; - - - /** - * Draw the replay while paying attention to skipped features. - * - * This functions creates groups of features that can be drawn to together, - * so that the number of `drawElements` calls is minimized. - * - * For example given the following texture groups: - * - * Group 1: A B C - * Group 2: D [E] F G - * - * If feature E should be skipped, the following `drawElements` calls will be - * made: - * - * drawElements with feature A, B and C - * drawElements with feature D - * drawElements with feature F and G - * - * @private - * @param {WebGLRenderingContext} gl gl. - * @param {ol.webgl.Context} context Context. - * @param {Object.} skippedFeaturesHash Ids of features - * to skip. - * @param {Array.} textures Textures. - * @param {Array.} groupIndices Texture group indices. - */ - ol.render.webgl.ImageReplay.prototype.drawReplaySkipping_ = function(gl, context, skippedFeaturesHash, textures, - groupIndices) { - var featureIndex = 0; - - var i, ii; - for (i = 0, ii = textures.length; i < ii; ++i) { - gl.bindTexture(ol.webgl.TEXTURE_2D, textures[i]); - var groupStart = (i > 0) ? groupIndices[i - 1] : 0; - var groupEnd = groupIndices[i]; - - var start = groupStart; - var end = groupStart; - while (featureIndex < this.startIndices.length && - this.startIndices[featureIndex] <= groupEnd) { - var feature = this.startIndicesFeature[featureIndex]; - - var featureUid = ol.getUid(feature).toString(); - if (skippedFeaturesHash[featureUid] !== undefined) { - // feature should be skipped - if (start !== end) { - // draw the features so far - this.drawElements(gl, context, start, end); - } - // continue with the next feature - start = (featureIndex === this.startIndices.length - 1) ? - groupEnd : this.startIndices[featureIndex + 1]; - end = start; - } else { - // the feature is not skipped, augment the end index - end = (featureIndex === this.startIndices.length - 1) ? - groupEnd : this.startIndices[featureIndex + 1]; - } - featureIndex++; - } - - if (start !== end) { - // draw the remaining features (in case there was no skipped feature - // in this texture group, all features of a group are drawn together) - this.drawElements(gl, context, start, end); - } - } - }; - - - /** - * @inheritDoc - */ - ol.render.webgl.ImageReplay.prototype.drawHitDetectionReplayOneByOne = function(gl, context, skippedFeaturesHash, - featureCallback, opt_hitExtent) { - var i, groupStart, start, end, feature, featureUid; - var featureIndex = this.startIndices.length - 1; - for (i = this.hitDetectionTextures_.length - 1; i >= 0; --i) { - gl.bindTexture(ol.webgl.TEXTURE_2D, this.hitDetectionTextures_[i]); - groupStart = (i > 0) ? this.hitDetectionGroupIndices_[i - 1] : 0; - end = this.hitDetectionGroupIndices_[i]; - - // draw all features for this texture group - while (featureIndex >= 0 && - this.startIndices[featureIndex] >= groupStart) { - start = this.startIndices[featureIndex]; - feature = this.startIndicesFeature[featureIndex]; - featureUid = ol.getUid(feature).toString(); - - if (skippedFeaturesHash[featureUid] === undefined && - feature.getGeometry() && - (opt_hitExtent === undefined || ol.extent.intersects( - /** @type {Array} */ (opt_hitExtent), - feature.getGeometry().getExtent()))) { - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); - this.drawElements(gl, context, start, end); - - var result = featureCallback(feature); - if (result) { - return result; - } - } - - end = start; - featureIndex--; - } - } - return undefined; + ol.render.webgl.TextureReplay.prototype.finish.call(this, context); }; @@ -578,7 +124,7 @@ if (ol.ENABLE_WEBGL) { } else { currentImage = this.images_[this.images_.length - 1]; if (ol.getUid(currentImage) != ol.getUid(image)) { - this.groupIndices_.push(this.indices.length); + this.groupIndices.push(this.indices.length); this.images_.push(image); } } @@ -589,23 +135,39 @@ if (ol.ENABLE_WEBGL) { currentImage = this.hitDetectionImages_[this.hitDetectionImages_.length - 1]; if (ol.getUid(currentImage) != ol.getUid(hitDetectionImage)) { - this.hitDetectionGroupIndices_.push(this.indices.length); + this.hitDetectionGroupIndices.push(this.indices.length); this.hitDetectionImages_.push(hitDetectionImage); } } - this.anchorX_ = anchor[0]; - this.anchorY_ = anchor[1]; - this.height_ = size[1]; - this.imageHeight_ = imageSize[1]; - this.imageWidth_ = imageSize[0]; - this.opacity_ = opacity; - this.originX_ = origin[0]; - this.originY_ = origin[1]; - this.rotation_ = rotation; - this.rotateWithView_ = rotateWithView; - this.scale_ = scale; - this.width_ = size[0]; + this.anchorX = anchor[0]; + this.anchorY = anchor[1]; + this.height = size[1]; + this.imageHeight = imageSize[1]; + this.imageWidth = imageSize[0]; + this.opacity = opacity; + this.originX = origin[0]; + this.originY = origin[1]; + this.rotation = rotation; + this.rotateWithView = rotateWithView; + this.scale = scale; + this.width = size[0]; + }; + + + /** + * @inheritDoc + */ + ol.render.webgl.ImageReplay.prototype.getTextures = function(opt_all) { + return opt_all ? this.textures_.concat(this.hitDetectionTextures_) : this.textures_; + }; + + + /** + * @inheritDoc + */ + ol.render.webgl.ImageReplay.prototype.getHitDetectionTextures = function() { + return this.hitDetectionTextures_; }; } diff --git a/test/spec/ol/render/webgl/imagereplay.test.js b/test/spec/ol/render/webgl/imagereplay.test.js index 7e5b1ce621..05e1571d78 100644 --- a/test/spec/ol/render/webgl/imagereplay.test.js +++ b/test/spec/ol/render/webgl/imagereplay.test.js @@ -2,7 +2,6 @@ goog.provide('ol.test.render.webgl.ImageReplay'); goog.require('ol.geom.MultiPoint'); goog.require('ol.geom.Point'); -goog.require('ol.render.webgl.imagereplay.defaultshader'); goog.require('ol.render.webgl.ImageReplay'); goog.require('ol.style.Image'); @@ -57,34 +56,34 @@ describe('ol.render.webgl.ImageReplay', function() { it('set expected states', function() { replay.setImageStyle(imageStyle1); - expect(replay.anchorX_).to.be(0.5); - expect(replay.anchorY_).to.be(1); - expect(replay.height_).to.be(256); - expect(replay.imageHeight_).to.be(512); - expect(replay.imageWidth_).to.be(512); - expect(replay.opacity_).to.be(0.1); - expect(replay.originX_).to.be(200); - expect(replay.originY_).to.be(200); - expect(replay.rotation_).to.be(1.5); - expect(replay.rotateWithView_).to.be(true); - expect(replay.scale_).to.be(2.0); - expect(replay.width_).to.be(256); + expect(replay.anchorX).to.be(0.5); + expect(replay.anchorY).to.be(1); + expect(replay.height).to.be(256); + expect(replay.imageHeight).to.be(512); + expect(replay.imageWidth).to.be(512); + expect(replay.opacity).to.be(0.1); + expect(replay.originX).to.be(200); + expect(replay.originY).to.be(200); + expect(replay.rotation).to.be(1.5); + expect(replay.rotateWithView).to.be(true); + expect(replay.scale).to.be(2.0); + expect(replay.width).to.be(256); expect(replay.images_).to.have.length(1); - expect(replay.groupIndices_).to.have.length(0); + expect(replay.groupIndices).to.have.length(0); expect(replay.hitDetectionImages_).to.have.length(1); - expect(replay.hitDetectionGroupIndices_).to.have.length(0); + expect(replay.hitDetectionGroupIndices).to.have.length(0); replay.setImageStyle(imageStyle1); expect(replay.images_).to.have.length(1); - expect(replay.groupIndices_).to.have.length(0); + expect(replay.groupIndices).to.have.length(0); expect(replay.hitDetectionImages_).to.have.length(1); - expect(replay.hitDetectionGroupIndices_).to.have.length(0); + expect(replay.hitDetectionGroupIndices).to.have.length(0); replay.setImageStyle(imageStyle2); expect(replay.images_).to.have.length(2); - expect(replay.groupIndices_).to.have.length(1); + expect(replay.groupIndices).to.have.length(1); expect(replay.hitDetectionImages_).to.have.length(2); - expect(replay.hitDetectionGroupIndices_).to.have.length(1); + expect(replay.hitDetectionGroupIndices).to.have.length(1); }); }); @@ -168,78 +167,43 @@ describe('ol.render.webgl.ImageReplay', function() { }); }); - describe('#setUpProgram', function() { - var context, gl; + describe('#getTextures', function() { beforeEach(function() { - context = { - getProgram: function() {}, - useProgram: function() {} - }; - gl = { - enableVertexAttribArray: function() {}, - vertexAttribPointer: function() {}, - uniform1f: function() {}, - uniform2fv: function() {}, - getUniformLocation: function() {}, - getAttribLocation: function() {} - }; + replay.textures_ = [1, 2]; + replay.hitDetectionTextures_ = [3, 4]; }); - it('returns the locations used by the shaders', function() { - var locations = replay.setUpProgram(gl, context, [2, 2], 1); - expect(locations).to.be.a( - ol.render.webgl.imagereplay.defaultshader.Locations); + it('returns the textures', function() { + var textures = replay.getTextures(); + + expect(textures).to.have.length(2); + expect(textures[0]).to.be(1); + expect(textures[1]).to.be(2); }); - it('gets and compiles the shaders', function() { - sinon.spy(context, 'getProgram'); - sinon.spy(context, 'useProgram'); + it('can additionally return the hit detection textures', function() { + var textures = replay.getTextures(true); - replay.setUpProgram(gl, context, [2, 2], 1); - expect(context.getProgram.calledWithExactly( - ol.render.webgl.imagereplay.defaultshader.fragment, - ol.render.webgl.imagereplay.defaultshader.vertex)).to.be(true); - expect(context.useProgram.calledOnce).to.be(true); - }); - - it('initializes the attrib pointers', function() { - sinon.spy(gl, 'getAttribLocation'); - sinon.spy(gl, 'vertexAttribPointer'); - sinon.spy(gl, 'enableVertexAttribArray'); - - replay.setUpProgram(gl, context, [2, 2], 1); - expect(gl.vertexAttribPointer.callCount).to.be(gl.getAttribLocation.callCount); - expect(gl.enableVertexAttribArray.callCount).to.be( - gl.getAttribLocation.callCount); + expect(textures).to.have.length(4); + expect(textures[0]).to.be(1); + expect(textures[1]).to.be(2); + expect(textures[2]).to.be(3); + expect(textures[3]).to.be(4); }); }); - describe('#shutDownProgram', function() { - var context, gl; + describe('#getHitDetectionTextures', function() { beforeEach(function() { - context = { - getProgram: function() {}, - useProgram: function() {} - }; - gl = { - enableVertexAttribArray: function() {}, - disableVertexAttribArray: function() {}, - vertexAttribPointer: function() {}, - uniform1f: function() {}, - uniform2fv: function() {}, - getUniformLocation: function() {}, - getAttribLocation: function() {} - }; + replay.textures_ = [1, 2]; + replay.hitDetectionTextures_ = [3, 4]; }); - it('disables the attrib pointers', function() { - sinon.spy(gl, 'getAttribLocation'); - sinon.spy(gl, 'disableVertexAttribArray'); + it('returns the hit detection textures', function() { + var textures = replay.getHitDetectionTextures(); - var locations = replay.setUpProgram(gl, context, [2, 2], 1); - replay.shutDownProgram(gl, locations); - expect(gl.disableVertexAttribArray.callCount).to.be( - gl.getAttribLocation.callCount); + expect(textures).to.have.length(2); + expect(textures[0]).to.be(3); + expect(textures[1]).to.be(4); }); }); });