diff --git a/src/RenderWebGL.js b/src/RenderWebGL.js index 87f99c5a3..800d31ecc 100644 --- a/src/RenderWebGL.js +++ b/src/RenderWebGL.js @@ -188,23 +188,9 @@ class RenderWebGL extends EventEmitter { /** @type {function} */ this._exitRegion = null; - /** @type {object} */ - this._backgroundDrawRegionId = { - enter: () => this._enterDrawBackground(), - exit: () => this._exitDrawBackground() - }; - /** @type {Array.} */ this._snapshotCallbacks = []; - /** @type {Array} */ - // Don't set this directly-- use setBackgroundColor so it stays in sync with _backgroundColor3b - this._backgroundColor4f = [0, 0, 0, 1]; - - /** @type {Uint8ClampedArray} */ - // Don't set this directly-- use setBackgroundColor so it stays in sync with _backgroundColor4f - this._backgroundColor3b = new Uint8ClampedArray(3); - this._createGeometry(); this.on(RenderConstants.Events.NativeSizeChanged, this.onNativeSizeChanged); @@ -264,14 +250,7 @@ class RenderWebGL extends EventEmitter { * @param {number} blue The blue component for the background. */ setBackgroundColor (red, green, blue) { - this._backgroundColor4f[0] = red; - this._backgroundColor4f[1] = green; - this._backgroundColor4f[2] = blue; - - this._backgroundColor3b[0] = red * 255; - this._backgroundColor3b[1] = green * 255; - this._backgroundColor3b[2] = blue * 255; - + this._backgroundColor = [red, green, blue, 1]; } /** @@ -650,7 +629,7 @@ class RenderWebGL extends EventEmitter { twgl.bindFramebufferInfo(gl, null); gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); - gl.clearColor.apply(gl, this._backgroundColor4f); + gl.clearColor.apply(gl, this._backgroundColor); gl.clear(gl.COLOR_BUFFER_BIT); this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, this._projection); @@ -766,20 +745,12 @@ class RenderWebGL extends EventEmitter { */ isTouchingColor (drawableID, color3b, mask3b) { const candidates = this._candidatesTouching(drawableID, this._visibleDrawList); - - let bounds; - if (colorMatches(color3b, this._backgroundColor3b, 0)) { - // If the color we're checking for is the background color, don't confine the check to - // candidate drawables' bounds--since the background spans the entire stage, we must check - // everything that lies inside the drawable. - bounds = this._touchingBounds(drawableID); - } else if (candidates.length === 0) { - // If not checking for the background color, we can return early if there are no candidate drawables. + if (candidates.length === 0) { return false; - } else { - bounds = this._candidatesBounds(candidates); } + const bounds = this._candidatesBounds(candidates); + const maxPixelsForCPU = this._getMaxPixelsForCPU(); const debugCanvasContext = this._debugCanvas && this._debugCanvas.getContext('2d'); @@ -840,19 +811,6 @@ class RenderWebGL extends EventEmitter { } } - _enterDrawBackground () { - const gl = this.gl; - const currentShader = this._shaderManager.getShader(ShaderManager.DRAW_MODE.background, 0); - gl.disable(gl.BLEND); - gl.useProgram(currentShader.program); - twgl.setBuffersAndAttributes(gl, currentShader, this._bufferInfo); - } - - _exitDrawBackground () { - const gl = this.gl; - gl.enable(gl.BLEND); - } - _isTouchingColorGpuStart (drawableID, candidateIDs, bounds, color3b, mask3b) { this._doExitDrawRegion(); @@ -864,8 +822,15 @@ class RenderWebGL extends EventEmitter { gl.viewport(0, 0, bounds.width, bounds.height); const projection = twgl.m4.ortho(bounds.left, bounds.right, bounds.top, bounds.bottom, -1, 1); - // Clear the query buffer to fully transparent. This will be the color of pixels that fail the stencil test. - gl.clearColor(0, 0, 0, 0); + let fillBackgroundColor = this._backgroundColor; + + // When using masking such that the background fill color will showing through, ensure we don't + // fill using the same color that we are trying to detect! + if (color3b[0] > 196 && color3b[1] > 196 && color3b[2] > 196) { + fillBackgroundColor = [0, 0, 0, 255]; + } + + gl.clearColor.apply(gl, fillBackgroundColor); gl.clear(gl.COLOR_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); let extraUniforms; @@ -877,9 +842,6 @@ class RenderWebGL extends EventEmitter { } try { - // Using the stencil buffer, mask out the drawing to either the drawable's alpha channel - // or pixels of the drawable which match the mask color, depending on whether a mask color is given. - // Masked-out pixels will not be checked. gl.enable(gl.STENCIL_TEST); gl.stencilFunc(gl.ALWAYS, 1, 1); gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE); @@ -900,25 +862,12 @@ class RenderWebGL extends EventEmitter { gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP); gl.colorMask(true, true, true, true); - // Draw the background as a quad. Drawing a background with gl.clear will not mask to the stenciled area. - this.enterDrawRegion(this._backgroundDrawRegionId); - - const uniforms = { - u_backgroundColor: this._backgroundColor4f - }; - - const currentShader = this._shaderManager.getShader(ShaderManager.DRAW_MODE.background, 0); - twgl.setUniforms(currentShader, uniforms); - twgl.drawBufferInfo(gl, this._bufferInfo, gl.TRIANGLES); - - // Draw the candidate drawables on top of the background. this._drawThese(candidateIDs, ShaderManager.DRAW_MODE.default, projection, {idFilterFunc: testID => testID !== drawableID} ); } finally { gl.colorMask(true, true, true, true); gl.disable(gl.STENCIL_TEST); - this._doExitDrawRegion(); } } @@ -937,8 +886,7 @@ class RenderWebGL extends EventEmitter { } for (let pixelBase = 0; pixelBase < pixels.length; pixelBase += 4) { - // Transparent pixels are masked (either by the drawable's alpha channel or color mask). - if (pixels[pixelBase + 3] !== 0 && colorMatches(color3b, pixels, pixelBase)) { + if (colorMatches(color3b, pixels, pixelBase)) { return true; } } @@ -1373,7 +1321,7 @@ class RenderWebGL extends EventEmitter { gl.viewport(0, 0, bounds.width, bounds.height); const projection = twgl.m4.ortho(bounds.left, bounds.right, bounds.top, bounds.bottom, -1, 1); - gl.clearColor.apply(gl, this._backgroundColor4f); + gl.clearColor.apply(gl, this._backgroundColor); gl.clear(gl.COLOR_BUFFER_BIT); this._drawThese(this._drawList, ShaderManager.DRAW_MODE.default, projection); @@ -1461,13 +1409,6 @@ class RenderWebGL extends EventEmitter { // Update the CPU position data drawable.updateCPURenderAttributes(); const candidateBounds = drawable.getFastBounds(); - - // Push bounds out to integers. If a drawable extends out into half a pixel, that half-pixel still - // needs to be tested. Plus, in some areas we construct another rectangle from the union of these, - // and iterate over its pixels (width * height). Turns out that doesn't work so well when the - // width/height aren't integers. - candidateBounds.snapToInt(); - if (bounds.intersects(candidateBounds)) { result.push({ id, diff --git a/src/ShaderManager.js b/src/ShaderManager.js index 37c24346d..8c59d3b7d 100644 --- a/src/ShaderManager.js +++ b/src/ShaderManager.js @@ -176,12 +176,7 @@ ShaderManager.DRAW_MODE = { /** * Draw a line with caps. */ - line: 'line', - - /** - * Draw the background in a certain color. Must sometimes be used instead of gl.clear. - */ - background: 'background' + line: 'line' }; module.exports = ShaderManager; diff --git a/src/shaders/sprite.frag b/src/shaders/sprite.frag index da286883d..f13005901 100644 --- a/src/shaders/sprite.frag +++ b/src/shaders/sprite.frag @@ -39,15 +39,9 @@ uniform float u_lineThickness; uniform float u_lineLength; #endif // DRAW_MODE_line -#ifdef DRAW_MODE_background -uniform vec4 u_backgroundColor; -#endif // DRAW_MODE_background - uniform sampler2D u_skin; -#ifndef DRAW_MODE_background varying vec2 v_texCoord; -#endif // Add this to divisors to prevent division by 0, which results in NaNs propagating through calculations. // Smaller values can cause problems on some mobile devices. @@ -115,7 +109,7 @@ const vec2 kCenter = vec2(0.5, 0.5); void main() { - #if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) + #ifndef DRAW_MODE_line vec2 texcoord0 = v_texCoord; #ifdef ENABLE_mosaic @@ -221,9 +215,7 @@ void main() gl_FragColor.rgb /= gl_FragColor.a + epsilon; #endif - #endif // !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) - - #ifdef DRAW_MODE_line + #else // DRAW_MODE_line // Maaaaagic antialiased-line-with-round-caps shader. // "along-the-lineness". This increases parallel to the line. @@ -242,8 +234,4 @@ void main() // the closer we are to the line, invert it. gl_FragColor = u_lineColor * clamp(1.0 - line, 0.0, 1.0); #endif // DRAW_MODE_line - - #ifdef DRAW_MODE_background - gl_FragColor = u_backgroundColor; - #endif } diff --git a/src/shaders/sprite.vert b/src/shaders/sprite.vert index 24437c3fc..ffc5150f0 100644 --- a/src/shaders/sprite.vert +++ b/src/shaders/sprite.vert @@ -14,7 +14,7 @@ uniform vec4 u_penPoints; const float epsilon = 1e-3; #endif -#if !(defined(DRAW_MODE_line) || defined(DRAW_MODE_background)) +#ifndef DRAW_MODE_line uniform mat4 u_projectionMatrix; uniform mat4 u_modelMatrix; attribute vec2 a_texCoord; @@ -66,8 +66,6 @@ void main() { // 4. Apply view transform position *= 2.0 / u_stageSize; gl_Position = vec4(position, 0, 1); - #elif defined(DRAW_MODE_background) - gl_Position = vec4(a_position * 2.0, 0, 1); #else gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1); v_texCoord = a_texCoord; diff --git a/test/integration/scratch-tests/clear-color.sb3 b/test/integration/scratch-tests/clear-color.sb3 deleted file mode 100644 index 42b6d8516..000000000 Binary files a/test/integration/scratch-tests/clear-color.sb3 and /dev/null differ