Skip to content

Commit cf37090

Browse files
authored
Merge pull request #7668 from processing/fix/texture-binding
Fix binding of texture()
2 parents 8e090ea + 09dbadc commit cf37090

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

src/webgl/p5.RendererGL.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@ class RendererGL extends Renderer {
10361036
if (!this._userEnabledStencil) {
10371037
this._internalDisable.call(this.GL, this.GL.STENCIL_TEST);
10381038
}
1039-
1039+
10401040
}
10411041

10421042
/**
@@ -1781,7 +1781,7 @@ class RendererGL extends Renderer {
17811781
if (!this._userEnabledStencil) {
17821782
this._internalDisable.call(this.GL, this.GL.STENCIL_TEST);
17831783
}
1784-
1784+
17851785
// Reset saved state
17861786
// this._userEnabledStencil = this._savedStencilTestState;
17871787
}
@@ -2349,6 +2349,7 @@ class RendererGL extends Renderer {
23492349

23502350
_setFillUniforms(fillShader) {
23512351
this.mixedSpecularColor = [...this.states.curSpecularColor];
2352+
const empty = this._getEmptyTexture();
23522353

23532354
if (this.states._useMetalness > 0) {
23542355
this.mixedSpecularColor = this.mixedSpecularColor.map(
@@ -2362,9 +2363,12 @@ class RendererGL extends Renderer {
23622363
fillShader.setUniform("uUseVertexColor", this._useVertexColor);
23632364
fillShader.setUniform("uMaterialColor", this.states.curFillColor);
23642365
fillShader.setUniform("isTexture", !!this.states._tex);
2365-
if (this.states._tex) {
2366-
fillShader.setUniform("uSampler", this.states._tex);
2367-
}
2366+
// We need to explicitly set uSampler back to an empty texture here.
2367+
// In general, we record the last set texture so we can re-apply it
2368+
// the next time a shader is used. However, the texture() function
2369+
// works differently and is global p5 state. If the p5 state has
2370+
// been cleared, we also need to clear the value in uSampler to match.
2371+
fillShader.setUniform("uSampler", this.states._tex || empty);
23682372
fillShader.setUniform("uTint", this.states.tint);
23692373

23702374
fillShader.setUniform("uHasSetAmbient", this.states._hasSetAmbient);

test/unit/webgl/p5.RendererGL.js

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ suite('p5.RendererGL', function() {
119119

120120
// It should be red
121121
assert.deepEqual(myp5.get(5, 5), [255, 0, 0, 255]);
122-
})
122+
});
123+
123124
test('textures remain bound after each draw call', function() {
124125
myp5.createCanvas(20, 10, myp5.WEBGL);
125126
myp5.background(255);
@@ -132,7 +133,7 @@ suite('p5.RendererGL', function() {
132133
inputs.color = texture(myTex, inputs.texCoord);
133134
return inputs;
134135
}`
135-
})
136+
});
136137

137138
// Make a red texture
138139
const tex = myp5.createFramebuffer();
@@ -154,7 +155,33 @@ suite('p5.RendererGL', function() {
154155
// Both rectangles should be red
155156
assert.deepEqual(myp5.get(5, 5), [255, 0, 0, 255]);
156157
assert.deepEqual(myp5.get(15, 5), [255, 0, 0, 255]);
157-
})
158+
});
159+
160+
test('texture() does not remain bound', function() {
161+
myp5.createCanvas(20, 10, myp5.WEBGL);
162+
myp5.background(255);
163+
164+
const myShader = myp5.baseMaterialShader().modify({});
165+
166+
// Make a red texture
167+
const tex = myp5.createFramebuffer();
168+
tex.draw(() => myp5.background('red'));
169+
170+
myp5.shader(myShader);
171+
const uSampler = myShader.samplers.find((s) => s.name === 'uSampler');
172+
173+
myp5.push();
174+
myp5.texture(tex);
175+
myp5.circle(0, 0, 20);
176+
expect(uSampler.texture.isFramebufferTexture).toBeTruthy();
177+
myp5.pop();
178+
179+
myp5.push();
180+
// Texture should be unbound now
181+
myp5.circle(0, 0, 20);
182+
expect(uSampler.texture.isFramebufferTexture).toBeFalsy();
183+
myp5.pop();
184+
});
158185
});
159186

160187
suite('default stroke shader', function() {
@@ -2711,48 +2738,48 @@ suite('p5.RendererGL', function() {
27112738
myp5.createCanvas(50, 50, myp5.WEBGL);
27122739
const gl = myp5._renderer.GL;
27132740
const isEnabled = gl.isEnabled(gl.STENCIL_TEST);
2714-
2741+
27152742
assert.equal(isEnabled, false);
27162743
assert.equal(myp5._renderer._userEnabledStencil, false);
27172744
}
27182745
);
2719-
2746+
27202747
test('Tracks when user manually enables stencil test',
27212748
function() {
27222749
myp5.createCanvas(50, 50, myp5.WEBGL);
27232750
const gl = myp5._renderer.GL;
2724-
2751+
27252752
gl.enable(gl.STENCIL_TEST);
27262753
assert.equal(myp5._renderer._userEnabledStencil, true);
27272754
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true);
27282755
}
27292756
);
2730-
2757+
27312758
test('Tracks when user manually disables stencil test',
27322759
function() {
27332760
myp5.createCanvas(50, 50, myp5.WEBGL);
27342761
const gl = myp5._renderer.GL;
27352762

27362763
gl.enable(gl.STENCIL_TEST);
27372764
gl.disable(gl.STENCIL_TEST);
2738-
2765+
27392766
assert.equal(myp5._renderer._userEnabledStencil, false);
27402767
assert.equal(gl.isEnabled(gl.STENCIL_TEST), false);
27412768
}
27422769
);
2743-
2770+
27442771
test('Maintains stencil test state across draw cycles when user enabled',
27452772
function() {
27462773
let drawCalled = false;
27472774

27482775
myp5.createCanvas(50, 50, myp5.WEBGL);
27492776
const originalDraw = myp5.draw;
2750-
2777+
27512778
myp5.draw = function() {
27522779
drawCalled = true;
27532780
if (originalDraw) originalDraw.call(myp5);
27542781
};
2755-
2782+
27562783
const gl = myp5._renderer.GL;
27572784
gl.enable(gl.STENCIL_TEST);
27582785
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true)
@@ -2764,7 +2791,7 @@ suite('p5.RendererGL', function() {
27642791
myp5.draw = originalDraw;
27652792
}
27662793
);
2767-
2794+
27682795
test('Internal clip operations preserve user stencil test setting',
27692796
function() {
27702797
myp5.createCanvas(50, 50, myp5.WEBGL);
@@ -2783,7 +2810,7 @@ suite('p5.RendererGL', function() {
27832810
assert.equal(gl.isEnabled(gl.STENCIL_TEST), true);
27842811
}
27852812
);
2786-
2813+
27872814
test('Internal clip operations do not enable stencil test for future draw cycles',
27882815
function() {
27892816
myp5.createCanvas(50, 50, myp5.WEBGL);

0 commit comments

Comments
 (0)