Skip to content

Commit

Permalink
Revert "Put back in "Merge pull request #489 from adroitwhiz/touching…
Browse files Browse the repository at this point in the history
…-white-fixes""
  • Loading branch information
fsih authored Aug 27, 2020
1 parent 5902c4a commit 0ae9cdd
Show file tree
Hide file tree
Showing 8 changed files with 31 additions and 126 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"eslint": "^4.6.1",
"eslint-config-scratch": "^5.0.0",
"gh-pages": "^1.0.0",
"jsdoc": "^3.6.0",
"jsdoc": "^3.5.5",
"json": "^9.0.4",
"playwright-chromium": "^1.0.1",
"scratch-vm": "0.2.0-prerelease.20200622143012",
Expand Down
5 changes: 0 additions & 5 deletions src/Drawable.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,6 @@ const getLocalPosition = (drawable, vec) => {
// localPosition matches that transformation.
localPosition[0] = 0.5 - (((v0 * m[0]) + (v1 * m[4]) + m[12]) / d);
localPosition[1] = (((v0 * m[1]) + (v1 * m[5]) + m[13]) / d) + 0.5;
// Fix floating point issues near 0.
// TODO: Check if this can be removed after render pull 479 is merged
if (Math.abs(localPosition[0] < 1e-8)) localPosition[0] = 0;
if (Math.abs(localPosition[1] < 1e-8)) localPosition[1] = 0;
// Apply texture effect transform if the localPosition is within the drawable's space,
// and any effects are currently active.
if (drawable.enabledEffects !== 0 &&
Expand Down Expand Up @@ -732,7 +728,6 @@ class Drawable {
dst[3] = 0;
return dst;
}

const textColor =
// commenting out to only use nearest for now
// drawable.useNearest() ?
Expand Down
93 changes: 16 additions & 77 deletions src/RenderWebGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.<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);
Expand Down Expand Up @@ -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];
}

/**
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -766,22 +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);
// e.g. empty costume, or off the stage
if (bounds === null) return false;
} 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');
Expand Down Expand Up @@ -842,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();

Expand All @@ -866,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;
Expand All @@ -879,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);
Expand All @@ -902,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();
}
}

Expand All @@ -939,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;
}
}
Expand Down Expand Up @@ -1375,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);

Expand Down Expand Up @@ -1465,13 +1411,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,
Expand Down
7 changes: 1 addition & 6 deletions src/ShaderManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
30 changes: 10 additions & 20 deletions src/Silhouette.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,6 @@
*/
let __SilhouetteUpdateCanvas;

// Optimized Math.min and Math.max for integers;
// taken from https://web.archive.org/web/20190716181049/http://guihaire.com/code/?p=549
const intMin = (i, j) => j ^ ((i ^ j) & ((i - j) >> 31));
const intMax = (i, j) => i ^ ((i ^ j) & ((i - j) >> 31));

/**
* Internal helper function (in hopes that compiler can inline). Get a pixel
* from silhouette data, or 0 if outside it's bounds.
Expand Down Expand Up @@ -45,18 +40,13 @@ const __cornerWork = [
/**
* Get the color from a given silhouette at an x/y local texture position.
* Multiply color values by alpha for proper blending.
* @param {Silhouette} $0 The silhouette to sample.
* @param {number} x X position of texture [0, width).
* @param {number} y Y position of texture [0, height).
* @param {Silhouette} The silhouette to sample.
* @param {number} x X position of texture (0-1).
* @param {number} y Y position of texture (0-1).
* @param {Uint8ClampedArray} dst A color 4b space.
* @return {Uint8ClampedArray} The dst vector.
*/
const getColor4b = ({_width: width, _height: height, _colorData: data}, x, y, dst) => {
// Clamp coords to edge, matching GL_CLAMP_TO_EDGE.
// (See github.com/LLK/scratch-render/blob/954cfff02b08069a082cbedd415c1fecd9b1e4fb/src/BitmapSkin.js#L88)
x = intMax(0, intMin(x, width - 1));
y = intMax(0, intMin(y, height - 1));

// 0 if outside bounds, otherwise read from data.
if (x >= width || y >= height || x < 0 || y < 0) {
return dst.fill(0);
Expand All @@ -74,17 +64,17 @@ const getColor4b = ({_width: width, _height: height, _colorData: data}, x, y, ds
/**
* Get the color from a given silhouette at an x/y local texture position.
* Do not multiply color values by alpha, as it has already been done.
* @param {Silhouette} $0 The silhouette to sample.
* @param {number} x X position of texture [0, width).
* @param {number} y Y position of texture [0, height).
* @param {Silhouette} The silhouette to sample.
* @param {number} x X position of texture (0-1).
* @param {number} y Y position of texture (0-1).
* @param {Uint8ClampedArray} dst A color 4b space.
* @return {Uint8ClampedArray} The dst vector.
*/
const getPremultipliedColor4b = ({_width: width, _height: height, _colorData: data}, x, y, dst) => {
// Clamp coords to edge, matching GL_CLAMP_TO_EDGE.
x = intMax(0, intMin(x, width - 1));
y = intMax(0, intMin(y, height - 1));

// 0 if outside bounds, otherwise read from data.
if (x >= width || y >= height || x < 0 || y < 0) {
return dst.fill(0);
}
const offset = ((y * width) + x) * 4;
dst[0] = data[offset];
dst[1] = data[offset + 1];
Expand Down
16 changes: 2 additions & 14 deletions src/shaders/sprite.frag
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
}
4 changes: 1 addition & 3 deletions src/shaders/sprite.vert
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
Binary file removed test/integration/scratch-tests/clear-color.sb3
Binary file not shown.

0 comments on commit 0ae9cdd

Please sign in to comment.