Skip to content

Commit ed26828

Browse files
committed
Minor changes and added tests for the stencil tests
1 parent bc4b5f8 commit ed26828

File tree

2 files changed

+105
-14
lines changed

2 files changed

+105
-14
lines changed

src/webgl/p5.RendererGL.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -429,16 +429,13 @@ class RendererGL extends Renderer {
429429
this.scratchMat3 = new Matrix(3);
430430

431431
this._userEnabledStencil = false;
432-
this.isStencilTestOn = false;
433432
// Store original methods for internal use
434433
this._internalEnable = this.drawingContext.enable;
435434
this._internalDisable = this.drawingContext.disable;
436435

437436
// Override WebGL enable function
438437
this.drawingContext.enable = (key) => {
439-
// When enable is called with STENCIL_TEST
440438
if (key === this.drawingContext.STENCIL_TEST) {
441-
// If not during clip(), mark as user-enabled
442439
if (!this._clipping) {
443440
this._userEnabledStencil = true;
444441
}
@@ -449,14 +446,7 @@ class RendererGL extends Renderer {
449446
// Override WebGL disable function
450447
this.drawingContext.disable = (key) => {
451448
if (key === this.drawingContext.STENCIL_TEST) {
452-
// When pop() disables the stencil test after clip(),
453-
// preserve the user's stencil test setting
454-
if (this._clipDepth === this._pushPopDepth) {
455-
// Don't change user setting here, just use internal disable
456-
} else {
457-
// User explicitly disabled stencil test
458449
this._userEnabledStencil = false;
459-
}
460450
}
461451
return this._internalDisable.call(this.drawingContext, key);
462452
};
@@ -1423,9 +1413,9 @@ class RendererGL extends Renderer {
14231413
this.drawTarget()._isClipApplied = true;
14241414

14251415
const gl = this.GL;
1426-
gl.clearStencil(0);
1416+
gl.clearStencil(0);
14271417
gl.clear(gl.STENCIL_BUFFER_BIT);
1428-
gl.enable(gl.STENCIL_TEST);
1418+
this._internalEnable.call(gl, gl.STENCIL_TEST);
14291419
this._stencilTestOn = true;
14301420
gl.stencilFunc(
14311421
gl.ALWAYS, // the test
@@ -1789,7 +1779,7 @@ class RendererGL extends Renderer {
17891779
const drawTarget = this.drawTarget();
17901780
if (drawTarget._isClipApplied !== this._stencilTestOn) {
17911781
if (drawTarget._isClipApplied) {
1792-
this.GL.enable(this.GL.STENCIL_TEST);
1782+
this._internalEnable.call(this.GL, this.GL.STENCIL_TEST);
17931783
this._stencilTestOn = true;
17941784
} else {
17951785
if (!this._userEnabledStencil) {

test/unit/webgl/p5.RendererGL.js

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { suite } from 'vitest';
12
import p5 from '../../../src/app.js';
23
import '../../js/chai_helpers';
34
const toArray = (typedArray) => Array.from(typedArray);
@@ -2684,5 +2685,105 @@ suite('p5.RendererGL', function() {
26842685
expect(logs.join('\n')).to.match(/One of the geometries has a custom vertex property 'aCustom' with fewer values than vertices./);
26852686
}
26862687
);
2687-
})
2688+
});
2689+
2690+
suite('Stencil Test Tracking', function() {
2691+
test('Stencil test is disabled by default',
2692+
function() {
2693+
myp5.createCanvas(50, 50, myp5.WEBGL);
2694+
const gl = myp5._renderer.GL;
2695+
const isEnabled = gl.isEnabled(gl.STENCIL_TEST);
2696+
2697+
assert.equal(isEnabled, false);
2698+
assert.equal(myp5._renderer._userEnabledStencil, false);
2699+
}
2700+
);
2701+
2702+
test('Tracks when user manually enables stencil test',
2703+
function() {
2704+
myp5.createCanvas(50, 50, myp5.WEBGL);
2705+
const gl = myp5._renderer.GL;
2706+
2707+
gl.enable(gl.STENCIL_TEST);
2708+
assert.equal(myp5._renderer._userEnabledStencil, true);
2709+
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true);
2710+
}
2711+
);
2712+
2713+
test('Tracks when user manually disables stencil test',
2714+
function() {
2715+
myp5.createCanvas(50, 50, myp5.WEBGL);
2716+
const gl = myp5._renderer.GL;
2717+
2718+
gl.enable(gl.STENCIL_TEST);
2719+
gl.disable(gl.STENCIL_TEST);
2720+
2721+
assert.equal(myp5._renderer._userEnabledStencil, false);
2722+
assert.equal(gl.isEnabled(gl.STENCIL_TEST), false);
2723+
}
2724+
);
2725+
2726+
test('Maintains stencil test state across draw cycles when user enabled',
2727+
function() {
2728+
let drawCalled = false;
2729+
2730+
myp5.createCanvas(50, 50, myp5.WEBGL);
2731+
const originalDraw = myp5.draw;
2732+
2733+
myp5.draw = function() {
2734+
drawCalled = true;
2735+
if (originalDraw) originalDraw.call(myp5);
2736+
};
2737+
2738+
const gl = myp5._renderer.GL;
2739+
gl.enable(gl.STENCIL_TEST);
2740+
2741+
myp5.redraw();
2742+
2743+
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true);
2744+
assert.equal(myp5._renderer._userEnabledStencil, true);
2745+
2746+
myp5.draw = originalDraw;
2747+
}
2748+
);
2749+
2750+
test('Internal clip operations preserve user stencil test setting',
2751+
function() {
2752+
myp5.createCanvas(50, 50, myp5.WEBGL);
2753+
const gl = myp5._renderer.GL;
2754+
2755+
gl.enable(gl.STENCIL_TEST);
2756+
2757+
myp5.push();
2758+
myp5.clip(() => {
2759+
myp5.rect(0, 0, 10, 10);
2760+
});
2761+
myp5.pop();
2762+
2763+
assert.equal(myp5._renderer._userEnabledStencil, true);
2764+
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true);
2765+
}
2766+
);
2767+
2768+
test('Internal clip operations do not enable stencil test for future draw cycles',
2769+
function() {
2770+
myp5.createCanvas(50, 50, myp5.WEBGL);
2771+
const gl = myp5._renderer.GL;
2772+
2773+
gl.disable(gl.STENCIL_TEST);
2774+
assert.equal(myp5._renderer._userEnabledStencil, false);
2775+
2776+
myp5.push();
2777+
myp5.clip(() => {
2778+
myp5.rect(0, 0, 10, 10);
2779+
});
2780+
myp5.pop();
2781+
2782+
myp5.redraw();
2783+
2784+
assert.equal(myp5._renderer._userEnabledStencil, false);
2785+
assert.equal(gl.isEnabled(gl.STENCIL_TEST), false);
2786+
}
2787+
);
2788+
});
26882789
});

0 commit comments

Comments
 (0)