diff --git a/src/ol/webgl/RenderTarget.js b/src/ol/webgl/RenderTarget.js index 4500495dc1..a3933ae414 100644 --- a/src/ol/webgl/RenderTarget.js +++ b/src/ol/webgl/RenderTarget.js @@ -115,12 +115,18 @@ class WebGLRenderTarget { /** * Reads one pixel of the frame buffer as an array of r, g, b, a components * in the 0-255 range (unsigned byte). + * If x and/or y are outside of existing data, an array filled with 0 is returned. * @param {number} x Pixel coordinate * @param {number} y Pixel coordinate * @returns {Uint8Array} Integer array with one color value (4 components) * @api */ readPixel(x, y) { + if (x < 0 || y < 0 || x > this.size_[0] || y >= this.size_[1]) { + tmpArray4[0] = tmpArray4[1] = tmpArray4[2] = tmpArray4[3] = 0; + return tmpArray4; + } + this.readAll(); const index = Math.floor(x) + (this.size_[1] - Math.floor(y) - 1) * this.size_[0]; tmpArray4[0] = this.data_[index * 4]; diff --git a/test/spec/ol/webgl/rendertarget.test.js b/test/spec/ol/webgl/rendertarget.test.js index 3468b16c26..550aae73d0 100644 --- a/test/spec/ol/webgl/rendertarget.test.js +++ b/test/spec/ol/webgl/rendertarget.test.js @@ -123,6 +123,26 @@ describe('ol.webgl.RenderTarget', function() { expect(spy.callCount).to.eql(2); }); + it('returns an array filled with 0 if outside of range', function() { + const rt = new WebGLRenderTarget(helper, [4, 4]); + helper.createTexture([4, 4], testImage_4x4, rt.getTexture()); + + let data = rt.readPixel(-1, 0); + expect(data).to.eql([0, 0, 0, 0]); + + data = rt.readPixel(3, -1); + expect(data).to.eql([0, 0, 0, 0]); + + data = rt.readPixel(6, 2); + expect(data).to.eql([0, 0, 0, 0]); + + data = rt.readPixel(2, 7); + expect(data).to.eql([0, 0, 0, 0]); + + data = rt.readPixel(2, 3); + expect(data).not.to.eql([0, 0, 0, 0]); + }); + }); });