Skip to content

Revert "Merge pull request #489 from adroitwhiz/touching-white-fixes" #660

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 16, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 16 additions & 75 deletions src/RenderWebGL.js
Original file line number Diff line number Diff line change
@@ -182,23 +182,9 @@ class RenderWebGL extends EventEmitter {
/** @type {function} */
this._exitRegion = null;

/** @type {object} */
this._backgroundDrawRegionId = {
enter: () => this._enterDrawBackground(),
exit: () => this._exitDrawBackground()
};

/** @type {Array.<snapshotCallback>} */
this._snapshotCallbacks = [];

/** @type {Array<number>} */
// 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);
@@ -258,14 +244,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];
}

/**
@@ -644,7 +623,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);
@@ -760,20 +739,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');
@@ -834,19 +805,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();

@@ -858,8 +816,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;
@@ -871,9 +836,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);
@@ -894,25 +856,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();
}
}

@@ -931,8 +880,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;
}
}
@@ -1260,7 +1208,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);

@@ -1348,13 +1296,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,
7 changes: 1 addition & 6 deletions src/ShaderManager.js
Original file line number Diff line number Diff line change
@@ -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;
16 changes: 2 additions & 14 deletions src/shaders/sprite.frag
Original file line number Diff line number Diff line change
@@ -40,15 +40,9 @@ uniform float u_lineLength;
uniform vec4 u_penPoints;
#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.
@@ -116,7 +110,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
@@ -222,9 +216,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.
@@ -243,8 +235,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
}
4 changes: 1 addition & 3 deletions src/shaders/sprite.vert
Original file line number Diff line number Diff line change
@@ -11,7 +11,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;
@@ -60,8 +60,6 @@ void main() {
// 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;
Binary file removed test/integration/scratch-tests/clear-color.sb3
Binary file not shown.