From 198e456ae2891dfdd4c9fa259544b9c59bc47e09 Mon Sep 17 00:00:00 2001 From: Perminder Singh Date: Thu, 16 Nov 2023 16:32:28 +0530 Subject: [PATCH 01/27] Adding framebuffer support in filter --- src/webgl/p5.RendererGL.js | 199 +++++++++++++++++-------------------- 1 file changed, 93 insertions(+), 106 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 171b4aa622..d2fb9c492e 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -997,74 +997,13 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.curStrokeJoin = join; } - getFilterGraphicsLayer() { - // Lazily initialize the filter graphics layer. We only do this on demand - // because the graphics layer itself has a p5.RendererGL, which would then - // try to make its own filter layer, infinitely looping. + filter(...args) { + if (!this.filterGraphicsLayer) { - // the real _pInst is buried when this is a secondary p5.Graphics - - const pInst = - this._pInst instanceof p5.Graphics ? this._pInst._pInst : this._pInst; - - // create secondary layer - this.filterGraphicsLayer = - new p5.Graphics( - this.width, - this.height, - constants.WEBGL, - pInst - ); - // geometries/borders on this layer should always be invisible - this.filterGraphicsLayer.noStroke(); - } - if ( - this.filterGraphicsLayer.width !== this.width || - this.filterGraphicsLayer.height !== this.height - ) { - // Resize the graphics layer - this.filterGraphicsLayer.resizeCanvas(this.width, this.height); + this.filterGraphicsLayer = this._pInst.createFramebuffer(); } - if ( - this.filterGraphicsLayer.pixelDensity() !== this._pInst.pixelDensity() - ) { - this.filterGraphicsLayer.pixelDensity(this._pInst.pixelDensity()); - } - return this.filterGraphicsLayer; - } - - getFilterGraphicsLayerTemp() { - // two-pass blur filter needs another graphics layer - if (!this.filterGraphicsLayerTemp) { - const pInst = this._pInst instanceof p5.Graphics ? - this._pInst._pInst : this._pInst; - // create secondary layer - this.filterGraphicsLayerTemp = - new p5.Graphics( - this.width, - this.height, - constants.WEBGL, - pInst - ); - this.filterGraphicsLayerTemp.noStroke(); - } - if ( - this.filterGraphicsLayerTemp.width !== this.width || - this.filterGraphicsLayerTemp.height !== this.height - ) { - // Resize the graphics layer - this.filterGraphicsLayerTemp.resizeCanvas(this.width, this.height); - } - if ( - this.filterGraphicsLayerTemp.pixelDensity() !== this._pInst.pixelDensity() - ) { - this.filterGraphicsLayerTemp.pixelDensity(this._pInst.pixelDensity()); - } - return this.filterGraphicsLayerTemp; - } - - filter(...args) { - let pg = this.getFilterGraphicsLayer(); + // Treating 'pg' as a framebuffer. + let pg = this.filterGraphicsLayer; // use internal shader for filter constants BLUR, INVERT, etc let filterParameter = undefined; @@ -1097,65 +1036,103 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.filterShader = args[0]; } - pg.clear(); // prevent undesirable feedback effects accumulating secretly + // Setting the target to the framebuffer when applying a filter to a framebuffer. + + const target = this.activeFramebuffer() || this; + + // Resize the framebuffer 'pg' and adjust its pixel density if it doesn't match the target. + + if ( + pg.width !== this.width || + pg.height !== this.height + ) { + // Resize pg + pg.resizeCanvas(this.width, this.height); + } + if ( + pg.pixelDensity() !== this._pInst.pixelDensity() + ) { + pg.pixelDensity(this._pInst.pixelDensity()); + } + + // Set the yScale of the filterCamera for framebuffers. + if (target !== this) { + this.filterCamera.yScale = this._curCamera.yScale; + } + pg.draw(() => this._pInst.clear()); // prevent undesirable feedback effects accumulating secretly - let pd = this._pInst.pixelDensity(); - let texelSize = [1 / (this.width * pd), 1 / (this.height * pd)]; + let texelSize = [ + 1 / (target.width * target.pixelDensity()), + 1 / (target.height * target.pixelDensity()) + ]; // apply blur shader with multiple passes if (operation === constants.BLUR) { - - const tmp = this.getFilterGraphicsLayerTemp(); - tmp.clear(); // prevent feedback effects here too + if (!this.filterGraphicsLayerTemp) { + this.filterGraphicsLayerTemp = this._pInst.createFramebuffer(); + } + // Treating 'tmp' as a framebuffer. + const tmp = this.filterGraphicsLayerTemp; + tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too // setup this._pInst.push(); this._pInst.noStroke(); // draw main to temp buffer - tmp.image(this, -this.width / 2, -this.height / 2); - - pg.shader(this.filterShader); - this.filterShader.setUniform('texelSize', texelSize); - this.filterShader.setUniform('canvasSize', [this.width, this.height]); - this.filterShader.setUniform('radius', Math.max(1, filterParameter)); - - // horiz pass - this.filterShader.setUniform('direction', [1, 0]); - this.filterShader.setUniform('tex0', tmp); - pg.clear(); - pg.rect(-this.width / 2, -this.height / 2, this.width, this.height); - - // read back to temp buffer - tmp.clear(); - tmp.image(pg, -this.width / 2, -this.height / 2); - - // vert pass - this.filterShader.setUniform('direction', [0, 1]); - this.filterShader.setUniform('tex0', tmp); - pg.clear(); - pg.rect(-this.width / 2, -this.height / 2, this.width, this.height); + tmp.draw(() => + this._pInst.image(target, -target.width / 2, -target.height / 2)); + + pg.draw(() => { + this._pInst.shader(this.filterShader); + this.filterShader.setUniform('texelSize', texelSize); + this.filterShader.setUniform('canvasSize', [target.width, target.height]); + this.filterShader.setUniform('radius', Math.max(1, filterParameter)); + + // horiz pass + tmp.draw(() => { + this.filterShader.setUniform('direction', [1, 0]); + this.filterShader.setUniform('tex0', tmp); + this._pInst.clear(); + this._pInst.rect(-target.width / 2, + -target.height / 2, target.width, target.height); + + // read back to temp buffer + this._pInst.image(pg, -this.width / 2, -this.height / 2); + + // vert pass + this.filterShader.setUniform('direction', [0, 1]); + this.filterShader.setUniform('tex0', tmp); + }); + this._pInst.clear(); + this._pInst.rect(-target.width / 2, + -target.height / 2, target.width, target.height); + }); this._pInst.pop(); } // every other non-blur shader uses single pass else { - pg.shader(this.filterShader); - this.filterShader.setUniform('tex0', this); - this.filterShader.setUniform('texelSize', texelSize); - this.filterShader.setUniform('canvasSize', [this.width, this.height]); - // filterParameter uniform only used for POSTERIZE, and THRESHOLD - // but shouldn't hurt to always set - this.filterShader.setUniform('filterParameter', filterParameter); - pg.rect(-this.width / 2, -this.height / 2, this.width, this.height); + pg.draw(() => { + this._pInst.noStroke(); + this._pInst.shader(this.filterShader); + this.filterShader.setUniform('tex0', target); + this.filterShader.setUniform('texelSize', texelSize); + this.filterShader.setUniform('canvasSize', [target.width, target.height]); + // filterParameter uniform only used for POSTERIZE, and THRESHOLD + // but shouldn't hurt to always set + this.filterShader.setUniform('filterParameter', filterParameter); + this._pInst.rect(-target.width / 2, -target.height / 2, + target.width, target.height); + }); } // draw pg contents onto main renderer this._pInst.push(); - pg._pInst.resetMatrix(); + pg.draw(() => resetMatrix()); this._pInst.noStroke(); - pg._pInst.imageMode(constants.CORNER); - pg._pInst.blendMode(constants.BLEND); + pg.draw(() => imageMode(constants.CORNER)); + pg.draw(() => blendMode(constants.BLEND)); this.clear(); this._pInst.push(); this.filterCamera._resize(); @@ -1167,6 +1144,16 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this._pInst.pop(); } + // Pass this off to the host instance so that we can treat a renderer and a + // framebuffer the same in filter() + + pixelDensity(newDensity) { + if (newDensity) { + return this._pInst.pixelDensity(newDensity); + } + return this._pInst.pixelDensity(); + } + blendMode(mode) { if ( mode === constants.DARKEST || @@ -2380,4 +2367,4 @@ p5.prototype._assert3d = function (name) { p5.RendererGL.prototype.tessyVertexSize = 12; -export default p5.RendererGL; +export default p5.RendererGL; \ No newline at end of file From 8b71469daf8f9e49384e079adc1f7906a71a59c7 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:45:25 +0530 Subject: [PATCH 02/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index d2fb9c492e..ca110f27f7 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1059,7 +1059,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { if (target !== this) { this.filterCamera.yScale = this._curCamera.yScale; } - pg.draw(() => this._pInst.clear()); // prevent undesirable feedback effects accumulating secretly + pg.draw(() => this._pInst.clear()); // prevent undesirable feedback effects accumulating secretly. let texelSize = [ 1 / (target.width * target.pixelDensity()), @@ -2367,4 +2367,4 @@ p5.prototype._assert3d = function (name) { p5.RendererGL.prototype.tessyVertexSize = 12; -export default p5.RendererGL; \ No newline at end of file +export default p5.RendererGL; From 0ec719ec1bbec71fec8359c67eebb32f7854e2d7 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Sat, 18 Nov 2023 01:54:09 +0530 Subject: [PATCH 03/27] Update material.js --- src/webgl/material.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index 849e901a63..e232ff4d8f 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -278,6 +278,12 @@ p5.prototype.createShader = function(vertSrc, fragSrc) { * */ p5.prototype.createFilterShader = function(fragSrc) { + let iswebgl; + if(this._renderer.GL){ + iswebgl = true; + }else{ + iswebgl = false; + } this._assert3d('createFilterShader'); p5._validateParameters('createFilterShader', arguments); let defaultVertV1 = ` @@ -322,7 +328,13 @@ p5.prototype.createFilterShader = function(fragSrc) { `; let vertSrc = fragSrc.includes('#version 300 es') ? defaultVertV2 : defaultVertV1; const shader = new p5.Shader(this._renderer, vertSrc, fragSrc); - shader.ensureCompiledOnContext(this._renderer.getFilterGraphicsLayer()); + let target; + if(!iswebgl){ + target = this._renderer.getFilterGraphicsLayer(); + }else{ + target = this; + } + shader.ensureCompiledOnContext(target); return shader; }; From 96bc262be84d3a09ad5935753b3a0ac64f733658 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Sat, 18 Nov 2023 01:59:00 +0530 Subject: [PATCH 04/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index ca110f27f7..5b2793b0cd 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -996,14 +996,22 @@ p5.RendererGL = class RendererGL extends p5.Renderer { strokeJoin(join) { this.curStrokeJoin = join; } - - filter(...args) { - + getFilterGraphicsLayer() { if (!this.filterGraphicsLayer) { this.filterGraphicsLayer = this._pInst.createFramebuffer(); } + return this.filterGraphicsLayer; + } + getFilterGraphicsLayerTemp() { + if (!this.filterGraphicsLayerTemp) { + this.filterGraphicsLayerTemp = this._pInst.createFramebuffer(); + } + return this.filterGraphicsLayerTemp; + } + filter(...args) { + // Treating 'pg' as a framebuffer. - let pg = this.filterGraphicsLayer; + let pg = this.getFilterGraphicsLayer(); // use internal shader for filter constants BLUR, INVERT, etc let filterParameter = undefined; @@ -1068,11 +1076,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // apply blur shader with multiple passes if (operation === constants.BLUR) { - if (!this.filterGraphicsLayerTemp) { - this.filterGraphicsLayerTemp = this._pInst.createFramebuffer(); - } // Treating 'tmp' as a framebuffer. - const tmp = this.filterGraphicsLayerTemp; + const tmp = this.getFilterGraphicsLayerTemp(); tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too // setup @@ -1129,10 +1134,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } // draw pg contents onto main renderer this._pInst.push(); - pg.draw(() => resetMatrix()); this._pInst.noStroke(); - pg.draw(() => imageMode(constants.CORNER)); - pg.draw(() => blendMode(constants.BLEND)); this.clear(); this._pInst.push(); this.filterCamera._resize(); From 72cd97b6df6705429b31979c99de73ade347e72e Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Sat, 18 Nov 2023 14:57:39 +0530 Subject: [PATCH 05/27] Reset matrix.js --- src/image/pixels.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/image/pixels.js b/src/image/pixels.js index eef7fb5171..39f8435932 100644 --- a/src/image/pixels.js +++ b/src/image/pixels.js @@ -616,6 +616,8 @@ p5.prototype.filter = function(...args) { ); //clearing the main canvas this._renderer.clear(); + // Resetting the matrix of the canvas + this._renderer.resetMatrix(); // filter it with shaders this.filterGraphicsLayer.filter(operation, value); From 6f0b7151cb89f84b58f48b0efb7ee19ddf73e11b Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Sat, 18 Nov 2023 21:01:43 +0530 Subject: [PATCH 06/27] Added test for filterCamera.js --- test/unit/webgl/p5.RendererGL.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index 216a89cd5e..4d2cfe75af 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -212,6 +212,30 @@ suite('p5.RendererGL', function() { assert.deepEqual(p1, p2); }); + test('Applying filter when a camera is applied', function () { + myp5.createCanvas(50, 50, myp5.WEBGL); + let s1 = myp5.createShader(vert, frag); + myp5.push(); + myp5.background('RED'); + myp5.camera(0, 0, 800); + myp5.fill('blue'); + myp5.square(-120, -120, -50); + myp5.filter(s1); + myp5.loadPixels(); + let p1 = myp5.pixels.slice(); + myp5.pop(); + myp5.clear(); + myp5.push(); + myp5.background('RED'); + myp5.fill('blue'); + myp5.square(-120, -120, -50); + myp5.filter(s1); + myp5.loadPixels(); + let p2 = myp5.pixels.slice(); + myp5.pop(); + assert.deepEqual(p1, p2); + }); + test('stroke and other settings are unaffected after filter', function() { let c = myp5.createCanvas(5, 5, myp5.WEBGL); let getShapeAttributes = () => [ From 2789e2aa9b642abc8a6fb41fdb0c70aacfd065e6 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Tue, 21 Nov 2023 00:21:38 +0530 Subject: [PATCH 07/27] Checking if pixelDensity is defined.js --- src/core/p5.Renderer.js | 72 +++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js index c869f3e6b4..53cbdd53dc 100644 --- a/src/core/p5.Renderer.js +++ b/src/core/p5.Renderer.js @@ -67,7 +67,7 @@ class Renderer extends p5.Element { // the renderer should return a 'style' object that it wishes to // store on the push stack. - push () { + push() { this._pushPopDepth++; return { properties: { @@ -94,10 +94,10 @@ class Renderer extends p5.Element { // a pop() operation is in progress // the renderer is passed the 'style' object that it returned // from its push() method. - pop (style) { + pop(style) { this._pushPopDepth--; if (style.properties) { - // copy the style properties back into the renderer + // copy the style properties back into the renderer Object.assign(this, style.properties); } } @@ -120,26 +120,28 @@ class Renderer extends p5.Element { /** * Resize our canvas element. */ - resize (w, h) { - this.width = w; - this.height = h; - this.elt.width = w * this._pInst._pixelDensity; - this.elt.height = h * this._pInst._pixelDensity; - this.elt.style.width = `${w}px`; - this.elt.style.height = `${h}px`; - if (this._isMainCanvas) { - this._pInst._setProperty('width', this.width); - this._pInst._setProperty('height', this.height); + resize(w, h) { + if (this._pInst && this._pInst._pixelDensity) { + this.width = w; + this.height = h; + this.elt.width = w * this._pInst._pixelDensity; + this.elt.height = h * this._pInst._pixelDensity; + this.elt.style.width = `${w}px`; + this.elt.style.height = `${h}px`; + if (this._isMainCanvas) { + this._pInst._setProperty('width', this.width); + this._pInst._setProperty('height', this.height); + } } } - get (x, y, w, h) { + get(x, y, w, h) { const pixelsState = this._pixelsState; const pd = pixelsState._pixelDensity; const canvas = this.canvas; if (typeof x === 'undefined' && typeof y === 'undefined') { - // get() + // get() x = y = 0; w = pixelsState.width; h = pixelsState.height; @@ -148,26 +150,26 @@ class Renderer extends p5.Element { y *= pd; if (typeof w === 'undefined' && typeof h === 'undefined') { - // get(x,y) + // get(x,y) if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) { return [0, 0, 0, 0]; } return this._getPixel(x, y); } - // get(x,y,w,h) + // get(x,y,w,h) } - const region = new p5.Image(w*pd, h*pd); + const region = new p5.Image(w * pd, h * pd); region._pixelDensity = pd; region.canvas .getContext('2d') - .drawImage(canvas, x, y, w * pd, h * pd, 0, 0, w*pd, h*pd); + .drawImage(canvas, x, y, w * pd, h * pd, 0, 0, w * pd, h * pd); return region; } - textLeading (l) { + textLeading(l) { if (typeof l === 'number') { this._setProperty('_leadingSet', true); this._setProperty('_textLeading', l); @@ -177,13 +179,13 @@ class Renderer extends p5.Element { return this._textLeading; } - textStyle (s) { + textStyle(s) { if (s) { if ( s === constants.NORMAL || - s === constants.ITALIC || - s === constants.BOLD || - s === constants.BOLDITALIC + s === constants.ITALIC || + s === constants.BOLD || + s === constants.BOLDITALIC ) { this._setProperty('_textStyle', s); } @@ -194,21 +196,21 @@ class Renderer extends p5.Element { return this._textStyle; } - textAscent () { + textAscent() { if (this._textAscent === null) { this._updateTextMetrics(); } return this._textAscent; } - textDescent () { + textDescent() { if (this._textDescent === null) { this._updateTextMetrics(); } return this._textDescent; } - textAlign (h, v) { + textAlign(h, v) { if (typeof h !== 'undefined') { this._setProperty('_textAlign', h); @@ -225,7 +227,7 @@ class Renderer extends p5.Element { } } - textWrap (wrapStyle) { + textWrap(wrapStyle) { this._setProperty('_textWrap', wrapStyle); return this._textWrap; } @@ -306,10 +308,10 @@ class Renderer extends p5.Element { finalMaxHeight = originalY + maxHeight - ascent / 2; } } else { - // no text-height specified, show warning for BOTTOM / CENTER + // no text-height specified, show warning for BOTTOM / CENTER if (this._textBaseline === constants.BOTTOM || - this._textBaseline === constants.CENTER) { - // use rectHeight as an approximation for text height + this._textBaseline === constants.CENTER) { + // use rectHeight as an approximation for text height let rectHeight = p.textSize() * this._textLeading; finalMinHeight = y - rectHeight / 2; finalMaxHeight = y + rectHeight / 2; @@ -435,8 +437,8 @@ class Renderer extends p5.Element { y += p.textLeading(); } } else { - // Offset to account for vertically centering multiple lines of text - no - // need to adjust anything for vertical align top or baseline + // Offset to account for vertically centering multiple lines of text - no + // need to adjust anything for vertical align top or baseline let offset = 0; if (this._textBaseline === constants.CENTER) { offset = (lines.length - 1) * p.textLeading() / 2; @@ -536,11 +538,11 @@ function calculateOffset(object) { return [currentLeft, currentTop]; } // This caused the test to failed. -Renderer.prototype.textSize = function(s) { +Renderer.prototype.textSize = function (s) { if (typeof s === 'number') { this._setProperty('_textSize', s); if (!this._leadingSet) { - // only use a default value if not previously set (#5181) + // only use a default value if not previously set (#5181) this._setProperty('_textLeading', s * constants._DEFAULT_LEADMULT); } return this._applyTextProperties(); From 2df0b03aa7c684e84ddeead98e9dda5d6982b1e3 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:47:49 +0530 Subject: [PATCH 08/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 75 +++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 38 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 5b2793b0cd..a019eb2298 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -996,13 +996,13 @@ p5.RendererGL = class RendererGL extends p5.Renderer { strokeJoin(join) { this.curStrokeJoin = join; } - getFilterGraphicsLayer() { + getFilterLayer() { if (!this.filterGraphicsLayer) { this.filterGraphicsLayer = this._pInst.createFramebuffer(); } return this.filterGraphicsLayer; } - getFilterGraphicsLayerTemp() { + getFilterLayerTemp() { if (!this.filterGraphicsLayerTemp) { this.filterGraphicsLayerTemp = this._pInst.createFramebuffer(); } @@ -1010,8 +1010,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } filter(...args) { - // Treating 'pg' as a framebuffer. - let pg = this.getFilterGraphicsLayer(); + let fbo = this.getFilterLayer(); // use internal shader for filter constants BLUR, INVERT, etc let filterParameter = undefined; @@ -1031,7 +1030,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // eg. filter(BLUR) then filter(GRAY) if (!(operation in this.defaultFilterShaders)) { this.defaultFilterShaders[operation] = new p5.Shader( - pg._renderer, + fbo._renderer, filterShaderVert, filterShaderFrags[operation] ); @@ -1048,26 +1047,26 @@ p5.RendererGL = class RendererGL extends p5.Renderer { const target = this.activeFramebuffer() || this; - // Resize the framebuffer 'pg' and adjust its pixel density if it doesn't match the target. + // Resize the framebuffer 'fbo' and adjust its pixel density if it doesn't match the target. if ( - pg.width !== this.width || - pg.height !== this.height + fbo.width !== this.width || + fbo.height !== this.height ) { - // Resize pg - pg.resizeCanvas(this.width, this.height); + // Resize fbo + fbo.resizeCanvas(this.width, this.height); } if ( - pg.pixelDensity() !== this._pInst.pixelDensity() + fbo.pixelDensity() !== this._pInst.pixelDensity() ) { - pg.pixelDensity(this._pInst.pixelDensity()); + fbo.pixelDensity(this._pInst.pixelDensity()); } // Set the yScale of the filterCamera for framebuffers. if (target !== this) { - this.filterCamera.yScale = this._curCamera.yScale; + this.filterCamera = this.getFilterLayer().createCamera(); } - pg.draw(() => this._pInst.clear()); // prevent undesirable feedback effects accumulating secretly. + fbo.draw(() => this._pInst.clear()); // prevent undesirable feedback effects accumulating secretly. let texelSize = [ 1 / (target.width * target.pixelDensity()), @@ -1077,7 +1076,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // apply blur shader with multiple passes if (operation === constants.BLUR) { // Treating 'tmp' as a framebuffer. - const tmp = this.getFilterGraphicsLayerTemp(); + const tmp = this.getFilterLayerTemp(); tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too // setup @@ -1088,28 +1087,28 @@ p5.RendererGL = class RendererGL extends p5.Renderer { tmp.draw(() => this._pInst.image(target, -target.width / 2, -target.height / 2)); - pg.draw(() => { + // fbo.draw(() => { + this._pInst.shader(this.filterShader); + this.filterShader.setUniform('texelSize', texelSize); + this.filterShader.setUniform('canvasSize', [target.width, target.height]); + this.filterShader.setUniform('radius', Math.max(1, filterParameter)); + + // Horiz pass: draw `target` to `tmp` + tmp.draw(() => { + this.filterShader.setUniform('direction', [1, 0]); + this.filterShader.setUniform('tex0', target); + this._pInst.clear(); this._pInst.shader(this.filterShader); - this.filterShader.setUniform('texelSize', texelSize); - this.filterShader.setUniform('canvasSize', [target.width, target.height]); - this.filterShader.setUniform('radius', Math.max(1, filterParameter)); - - // horiz pass - tmp.draw(() => { - this.filterShader.setUniform('direction', [1, 0]); - this.filterShader.setUniform('tex0', tmp); - this._pInst.clear(); - this._pInst.rect(-target.width / 2, - -target.height / 2, target.width, target.height); - - // read back to temp buffer - this._pInst.image(pg, -this.width / 2, -this.height / 2); - - // vert pass - this.filterShader.setUniform('direction', [0, 1]); - this.filterShader.setUniform('tex0', tmp); - }); + this._pInst.rect(-target.width / 2, + -target.height / 2, target.width, target.height); + }); + + // Vert pass: draw `tmp` to `fbo` + fbo.draw(() => { + this.filterShader.setUniform('direction', [0, 1]); + this.filterShader.setUniform('tex0', tmp); this._pInst.clear(); + this._pInst.shader(this.filterShader); this._pInst.rect(-target.width / 2, -target.height / 2, target.width, target.height); }); @@ -1118,7 +1117,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } // every other non-blur shader uses single pass else { - pg.draw(() => { + fbo.draw(() => { this._pInst.noStroke(); this._pInst.shader(this.filterShader); this.filterShader.setUniform('tex0', target); @@ -1132,7 +1131,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { }); } - // draw pg contents onto main renderer + // draw fbo contents onto main renderer this._pInst.push(); this._pInst.noStroke(); this.clear(); @@ -1140,7 +1139,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.filterCamera._resize(); this._pInst.setCamera(this.filterCamera); this._pInst.resetMatrix(); - this._pInst.image(pg, -this.width / 2, -this.height / 2, + this._pInst.image(fbo, -this.width / 2, -this.height / 2, this.width, this.height); this._pInst.pop(); this._pInst.pop(); From f42da5757451746195997a09eb79b4942bf88a01 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Tue, 21 Nov 2023 20:49:29 +0530 Subject: [PATCH 09/27] Update material.js --- src/webgl/material.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index e232ff4d8f..53f1e1ec1f 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -330,7 +330,7 @@ p5.prototype.createFilterShader = function(fragSrc) { const shader = new p5.Shader(this._renderer, vertSrc, fragSrc); let target; if(!iswebgl){ - target = this._renderer.getFilterGraphicsLayer(); + target = this._renderer.getFilterLayer(); }else{ target = this; } From cefc285026d318c79437c6de86d46eefae6c9806 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 01:49:50 +0530 Subject: [PATCH 10/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index a019eb2298..b0fbe560bd 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1087,7 +1087,6 @@ p5.RendererGL = class RendererGL extends p5.Renderer { tmp.draw(() => this._pInst.image(target, -target.width / 2, -target.height / 2)); - // fbo.draw(() => { this._pInst.shader(this.filterShader); this.filterShader.setUniform('texelSize', texelSize); this.filterShader.setUniform('canvasSize', [target.width, target.height]); From 9a86b199ce216bfee5fde09c6849721112801d36 Mon Sep 17 00:00:00 2001 From: Perminder Singh Date: Wed, 22 Nov 2023 04:24:13 +0530 Subject: [PATCH 11/27] merging --- lib/empty-example/sketch.js | 14 ++++++--- src/core/p5.Renderer2D.js | 22 +++++++++++++ src/image/pixels.js | 42 ++++++++++--------------- src/webgl/material.js | 54 +++++++++++++------------------- src/webgl/p5.Shader.js | 12 +++++++ test/unit/core/rendering.js | 2 +- test/unit/webgl/p5.RendererGL.js | 46 ++++++++++++++++++++++++--- 7 files changed, 125 insertions(+), 67 deletions(-) diff --git a/lib/empty-example/sketch.js b/lib/empty-example/sketch.js index 69b202ee71..b2c33213c2 100644 --- a/lib/empty-example/sketch.js +++ b/lib/empty-example/sketch.js @@ -1,7 +1,11 @@ function setup() { - // put setup code here -} + let fragSrc = `precision highp float; + void main() { + gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); + }`; -function draw() { - // put drawing code here -} + createCanvas(100, 100); + let s = createFilterShader(fragSrc); + filter(s); + describe('a yellow canvas'); +} \ No newline at end of file diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index 7935255b49..cd3daf823f 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -18,6 +18,28 @@ class Renderer2D extends p5.Renderer{ this._pInst._setProperty('drawingContext', this.drawingContext); } + getFilterGraphicsLayer() { + // create hidden webgl renderer if it doesn't exist + if (!this.filterGraphicsLayer) { + // the real _pInst is buried when this is a secondary p5.Graphics + const pInst = + this._pInst instanceof p5.Graphics ? + this._pInst._pInst : + this._pInst; + + // create secondary layer + this.filterGraphicsLayer = + new p5.Graphics( + this.width, + this.height, + constants.WEBGL, + pInst + ); + } + + return this.filterGraphicsLayer; + } + _applyDefaults() { this._cachedFillStyle = this._cachedStrokeStyle = undefined; this._cachedBlendMode = constants.BLEND; diff --git a/src/image/pixels.js b/src/image/pixels.js index 39f8435932..c609ec334f 100644 --- a/src/image/pixels.js +++ b/src/image/pixels.js @@ -8,7 +8,6 @@ import p5 from '../core/main'; import Filters from './filters'; import '../color/p5.Color'; -import * as constants from '../core/constants'; /** * An array containing the color of each pixel on the canvas. Colors are @@ -544,6 +543,15 @@ p5.prototype._copyHelper = ( * */ +/** + * @method getFilterGraphicsLayer + * @private + * @returns {p5.Graphics} + */ +p5.prototype.getFilterGraphicsLayer = function() { + return this._renderer.getFilterGraphicsLayer(); +}; + /** * @method filter * @param {Constant} filterType @@ -560,7 +568,7 @@ p5.prototype.filter = function(...args) { let { shader, operation, value, useWebGL } = parseFilterArgs(...args); // when passed a shader, use it directly - if (shader) { + if (this._renderer.isP3D && shader) { p5.RendererGL.prototype.filter.call(this._renderer, shader); return; } @@ -586,27 +594,11 @@ p5.prototype.filter = function(...args) { // when this is P2D renderer, create/use hidden webgl renderer else { - // create hidden webgl renderer if it doesn't exist - if (!this.filterGraphicsLayer) { - // the real _pInst is buried when this is a secondary p5.Graphics - const pInst = - this._renderer._pInst instanceof p5.Graphics ? - this._renderer._pInst._pInst : - this._renderer._pInst; - - // create secondary layer - this.filterGraphicsLayer = - new p5.Graphics( - this.width, - this.height, - constants.WEBGL, - pInst - ); - } + const filterGraphicsLayer = this.getFilterGraphicsLayer(); // copy p2d canvas contents to secondary webgl renderer // dest - this.filterGraphicsLayer.copy( + filterGraphicsLayer.copy( // src this._renderer, // src coods @@ -616,14 +608,14 @@ p5.prototype.filter = function(...args) { ); //clearing the main canvas this._renderer.clear(); - // Resetting the matrix of the canvas + this._renderer.resetMatrix(); // filter it with shaders - this.filterGraphicsLayer.filter(operation, value); + filterGraphicsLayer.filter(...args); // copy secondary webgl renderer back to original p2d canvas - this._renderer._pInst.image(this.filterGraphicsLayer, 0, 0); - this.filterGraphicsLayer.clear(); // prevent feedback effects on p2d canvas + this._renderer._pInst.image(filterGraphicsLayer, 0, 0); + filterGraphicsLayer.clear(); // prevent feedback effects on p2d canvas } }; @@ -927,4 +919,4 @@ p5.prototype.updatePixels = function(x, y, w, h) { this._renderer.updatePixels(x, y, w, h); }; -export default p5; +export default p5; \ No newline at end of file diff --git a/src/webgl/material.js b/src/webgl/material.js index 53f1e1ec1f..26ba269186 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -61,7 +61,7 @@ import './p5.Texture'; * @alt * zooming Mandelbrot set. a colorful, infinitely detailed fractal. */ -p5.prototype.loadShader = function( +p5.prototype.loadShader = function ( vertFilename, fragFilename, callback, @@ -194,8 +194,7 @@ p5.prototype.loadShader = function( * @alt * zooming Mandelbrot set. a colorful, infinitely detailed fractal. */ -p5.prototype.createShader = function(vertSrc, fragSrc) { - this._assert3d('createShader'); +p5.prototype.createShader = function (vertSrc, fragSrc) { p5._validateParameters('createShader', arguments); return new p5.Shader(this._renderer, vertSrc, fragSrc); }; @@ -204,13 +203,13 @@ p5.prototype.createShader = function(vertSrc, fragSrc) { * Creates a new p5.Shader using only a fragment shader, as a convenience method for creating image effects. * It's like createShader() but with a default vertex shader included. * - * createFilterShader() is intended to be used along with filter() for filtering the contents of a canvas in WebGL mode. + * createFilterShader() is intended to be used along with filter() for filtering the contents of a canvas. * A filter shader will not be applied to any geometries. * * The fragment shader receives some uniforms: * - `sampler2D tex0`, which contains the canvas contents as a texture - * - `vec2 canvasSize`, which is the width and height of the canvas - * - `vec2 texelSize`, which is the size of a pixel (`1.0/width`, `1.0/height`) +* - `vec2 canvasSize`, which is the p5 width and height of the canvas (not including pixel density) + * - `vec2 texelSize`, which is the size of a physical pixel including pixel density (`1.0/(width*density)`, `1.0/(height*density)`) * * For more info about filters and shaders, see Adam Ferriss' repo of shader examples * or the introduction to shaders page. @@ -277,14 +276,7 @@ p5.prototype.createShader = function(vertSrc, fragSrc) { * * */ -p5.prototype.createFilterShader = function(fragSrc) { - let iswebgl; - if(this._renderer.GL){ - iswebgl = true; - }else{ - iswebgl = false; - } - this._assert3d('createFilterShader'); +p5.prototype.createFilterShader = function (fragSrc) { p5._validateParameters('createFilterShader', arguments); let defaultVertV1 = ` uniform mat4 uModelViewMatrix; @@ -328,13 +320,11 @@ p5.prototype.createFilterShader = function(fragSrc) { `; let vertSrc = fragSrc.includes('#version 300 es') ? defaultVertV2 : defaultVertV1; const shader = new p5.Shader(this._renderer, vertSrc, fragSrc); - let target; - if(!iswebgl){ - target = this._renderer.getFilterLayer(); - }else{ - target = this; + if (this._renderer.GL) { + shader.ensureCompiledOnContext(this); + } else { + shader.ensureCompiledOnContext(this._renderer.getFilterGraphicsLayer()); } - shader.ensureCompiledOnContext(target); return shader; }; @@ -423,7 +413,7 @@ p5.prototype.createFilterShader = function(fragSrc) { * @alt * canvas toggles between a circular gradient of orange and blue vertically. and a circular gradient of red and green moving horizontally when mouse is clicked/pressed. */ -p5.prototype.shader = function(s) { +p5.prototype.shader = function (s) { this._assert3d('shader'); p5._validateParameters('shader', arguments); @@ -523,7 +513,7 @@ p5.prototype.shader = function(s) { * Two rotating cubes. The left one is painted using a custom (user-defined) shader, * while the right one is painted using the default fill shader. */ -p5.prototype.resetShader = function() { +p5.prototype.resetShader = function () { this._renderer.userFillShader = this._renderer.userStrokeShader = null; return this; }; @@ -658,7 +648,7 @@ p5.prototype.resetShader = function() { * @alt * quad with a texture, mapped using normalized coordinates */ -p5.prototype.texture = function(tex) { +p5.prototype.texture = function (tex) { this._assert3d('texture'); p5._validateParameters('texture', arguments); if (tex.gifProperties) { @@ -741,7 +731,7 @@ p5.prototype.texture = function(tex) { * @alt * quad with a texture, mapped using image coordinates */ -p5.prototype.textureMode = function(mode) { +p5.prototype.textureMode = function (mode) { if (mode !== constants.IMAGE && mode !== constants.NORMAL) { console.warn( `You tried to set ${mode} textureMode only supports IMAGE & NORMAL ` @@ -814,7 +804,7 @@ p5.prototype.textureMode = function(mode) { * @alt * an image of the rocky mountains repeated in mirrored tiles */ -p5.prototype.textureWrap = function(wrapX, wrapY = wrapX) { +p5.prototype.textureWrap = function (wrapX, wrapY = wrapX) { this._renderer.textureWrapX = wrapX; this._renderer.textureWrapY = wrapY; @@ -855,7 +845,7 @@ p5.prototype.textureWrap = function(wrapX, wrapY = wrapX) { * @alt * Sphere with normal material */ -p5.prototype.normalMaterial = function(...args) { +p5.prototype.normalMaterial = function (...args) { this._assert3d('normalMaterial'); p5._validateParameters('normalMaterial', args); this._renderer.drawMode = constants.FILL; @@ -968,7 +958,7 @@ p5.prototype.normalMaterial = function(...args) { * as an array, or as a CSS string * @chainable */ -p5.prototype.ambientMaterial = function(v1, v2, v3) { +p5.prototype.ambientMaterial = function (v1, v2, v3) { this._assert3d('ambientMaterial'); p5._validateParameters('ambientMaterial', arguments); @@ -1039,7 +1029,7 @@ p5.prototype.ambientMaterial = function(v1, v2, v3) { * as an array, or as a CSS string * @chainable */ -p5.prototype.emissiveMaterial = function(v1, v2, v3, a) { +p5.prototype.emissiveMaterial = function (v1, v2, v3, a) { this._assert3d('emissiveMaterial'); p5._validateParameters('emissiveMaterial', arguments); @@ -1125,7 +1115,7 @@ p5.prototype.emissiveMaterial = function(v1, v2, v3, a) { * as an array, or as a CSS string * @chainable */ -p5.prototype.specularMaterial = function(v1, v2, v3, alpha) { +p5.prototype.specularMaterial = function (v1, v2, v3, alpha) { this._assert3d('specularMaterial'); p5._validateParameters('specularMaterial', arguments); @@ -1174,7 +1164,7 @@ p5.prototype.specularMaterial = function(v1, v2, v3, alpha) { * @alt * two spheres, one more shiny than the other */ -p5.prototype.shininess = function(shine) { +p5.prototype.shininess = function (shine) { this._assert3d('shininess'); p5._validateParameters('shininess', arguments); @@ -1192,7 +1182,7 @@ p5.prototype.shininess = function(shine) { * @param {Number[]} color [description] * @return {Number[]]} Normalized numbers array */ -p5.RendererGL.prototype._applyColorBlend = function(colors) { +p5.RendererGL.prototype._applyColorBlend = function (colors) { const gl = this.GL; const isTexture = this.drawMode === constants.TEXTURE; @@ -1227,7 +1217,7 @@ p5.RendererGL.prototype._applyColorBlend = function(colors) { * @param {Number[]} color [description] * @return {Number[]]} Normalized numbers array */ -p5.RendererGL.prototype._applyBlendMode = function() { +p5.RendererGL.prototype._applyBlendMode = function () { if (this._cachedBlendMode === this.curBlendMode) { return; } diff --git a/src/webgl/p5.Shader.js b/src/webgl/p5.Shader.js index 587247cd1f..0366df75e4 100644 --- a/src/webgl/p5.Shader.js +++ b/src/webgl/p5.Shader.js @@ -114,6 +114,18 @@ p5.Shader = class { * @param {p5|p5.Graphics} context The graphic or instance to copy this shader to. * Pass `window` if you need to copy to the main canvas. * @returns {p5.Shader} A new shader on the target context. + * + * @example + *
+ * + * let graphic = createGraphics(200, 200, WEBGL); + * let graphicShader = graphic.createShader(vert, frag); + * graphic.shader(graphicShader); // Use graphicShader on the graphic + * + * let mainShader = graphicShader.copyToContext(window); + * shader(mainShader); // Use `mainShader` on the main canvas + * + *
*/ copyToContext(context) { const shader = new p5.Shader( diff --git a/test/unit/core/rendering.js b/test/unit/core/rendering.js index 8b256507f9..0772f77350 100644 --- a/test/unit/core/rendering.js +++ b/test/unit/core/rendering.js @@ -133,7 +133,7 @@ suite('Rendering', function() { 'camera', 'perspective', 'ortho', 'frustum', 'orbitControl', 'ambientLight', 'directionalLight', 'pointLight', 'lights', 'specularColor', 'spotLight', 'model', - 'createShader', 'shader', + 'shader', 'normalMaterial', 'texture', 'ambientMaterial', 'emissiveMaterial', 'specularMaterial', 'shininess', 'lightFalloff', 'plane', 'box', 'sphere', 'cylinder', 'cone', 'ellipsoid', 'torus' diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index 4d2cfe75af..f1a1df83d7 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -13,7 +13,7 @@ suite('p5.RendererGL', function() { }); teardown(function() { - //myp5.remove(); + myp5.remove(); }); suite('createCanvas(w, h, WEBGL)', function() { @@ -163,6 +163,44 @@ suite('p5.RendererGL', function() { }; }); + suite('custom shaders', function() { + function testFilterShader(target) { + const fragSrc = `precision highp float; + void main() { + gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); + }`; + const s = target.createFilterShader(fragSrc); + target.filter(s); + target.loadPixels(); + assert.deepEqual( + target.get(target.width/2, target.height/2), + [255, 255, 0, 255] + ); + } + + test('work with a 2D main canvas', function() { + myp5.createCanvas(10, 10); + testFilterShader(myp5); + }); + + test('work with a WebGL main canvas', function() { + myp5.createCanvas(10, 10, myp5.WEBGL); + testFilterShader(myp5); + }); + + test('work with a 2D graphic', function() { + myp5.createCanvas(10, 10); + const graphic = myp5.createGraphics(10, 10); + testFilterShader(graphic); + }); + + test('work with a WebGL graphic', function() { + myp5.createCanvas(10, 10); + const graphic = myp5.createGraphics(10, 10, myp5.WEBGL); + testFilterShader(graphic); + }); + }); + test('filter accepts correct params', function() { myp5.createCanvas(5, 5, myp5.WEBGL); let s = myp5.createShader(vert, frag); @@ -317,13 +355,13 @@ suite('p5.RendererGL', function() { test('filter() uses WEBGL implementation behind main P2D canvas', function() { let renderer = myp5.createCanvas(3,3); myp5.filter(myp5.BLUR); - assert.isDefined(renderer._pInst.filterGraphicsLayer); + assert.isDefined(renderer.filterGraphicsLayer); }); test('filter() can opt out of WEBGL implementation', function() { let renderer = myp5.createCanvas(3,3); myp5.filter(myp5.BLUR, useWebGL=false); - assert.isUndefined(renderer._pInst.filterGraphicsLayer); + assert.isUndefined(renderer.filterGraphicsLayer); }); test('filters make changes to canvas', function() { @@ -2342,4 +2380,4 @@ suite('p5.RendererGL', function() { } ); }); -}); +}); \ No newline at end of file From 75b00421e360bf7655d7694c05803c1f92c1fb8f Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 04:29:30 +0530 Subject: [PATCH 12/27] Delete lib/empty-example/sketch.js --- lib/empty-example/sketch.js | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 lib/empty-example/sketch.js diff --git a/lib/empty-example/sketch.js b/lib/empty-example/sketch.js deleted file mode 100644 index b2c33213c2..0000000000 --- a/lib/empty-example/sketch.js +++ /dev/null @@ -1,11 +0,0 @@ -function setup() { - let fragSrc = `precision highp float; - void main() { - gl_FragColor = vec4(1.0, 1.0, 0.0, 1.0); - }`; - - createCanvas(100, 100); - let s = createFilterShader(fragSrc); - filter(s); - describe('a yellow canvas'); -} \ No newline at end of file From ae3730464f5dd5d2691f42b1ed86a6bab7637140 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 04:55:44 +0530 Subject: [PATCH 13/27] function matchsize().js --- src/webgl/p5.RendererGL.js | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index b0fbe560bd..9e72a479bd 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1008,6 +1008,18 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } return this.filterGraphicsLayerTemp; } + matchSize(fboToMatch, target) { + if ( + fboToMatch.width !== target.width || + fboToMatch.height !== target.height + ) { + fboToMatch.resizeCanvas(target.width, target.height); + } + + if (fboToMatch.pixelDensity() !== target._pInst.pixelDensity()) { + fboToMatch.pixelDensity(target._pInst.pixelDensity()); + } + } filter(...args) { let fbo = this.getFilterLayer(); @@ -1048,19 +1060,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { const target = this.activeFramebuffer() || this; // Resize the framebuffer 'fbo' and adjust its pixel density if it doesn't match the target. - - if ( - fbo.width !== this.width || - fbo.height !== this.height - ) { - // Resize fbo - fbo.resizeCanvas(this.width, this.height); - } - if ( - fbo.pixelDensity() !== this._pInst.pixelDensity() - ) { - fbo.pixelDensity(this._pInst.pixelDensity()); - } + this.matchSize(fbo, target); // Set the yScale of the filterCamera for framebuffers. if (target !== this) { @@ -1077,6 +1077,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { if (operation === constants.BLUR) { // Treating 'tmp' as a framebuffer. const tmp = this.getFilterLayerTemp(); + // Resize the framebuffer 'fbo' and adjust its pixel density if it doesn't match the target. + this.matchSize(tmp, target); tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too // setup From e807740de0632e3af311057ca3d6feb50b93c6f1 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:17:14 +0530 Subject: [PATCH 14/27] fixed typo.js --- src/webgl/p5.RendererGL.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 9e72a479bd..39395d6a44 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1062,7 +1062,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // Resize the framebuffer 'fbo' and adjust its pixel density if it doesn't match the target. this.matchSize(fbo, target); - // Set the yScale of the filterCamera for framebuffers. + // Set filterCamera for framebuffers. if (target !== this) { this.filterCamera = this.getFilterLayer().createCamera(); } @@ -1073,11 +1073,11 @@ p5.RendererGL = class RendererGL extends p5.Renderer { 1 / (target.height * target.pixelDensity()) ]; - // apply blur shader with multiple passes + // apply blur shader with multiple passes. if (operation === constants.BLUR) { // Treating 'tmp' as a framebuffer. const tmp = this.getFilterLayerTemp(); - // Resize the framebuffer 'fbo' and adjust its pixel density if it doesn't match the target. + // Resize the framebuffer 'tmp' and adjust its pixel density if it doesn't match the target. this.matchSize(tmp, target); tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too @@ -1132,7 +1132,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { }); } - // draw fbo contents onto main renderer + // draw fbo contents onto main renderer. this._pInst.push(); this._pInst.noStroke(); this.clear(); From 1af2155f3ff8265af2a0a0a9465dabbdd6bd6331 Mon Sep 17 00:00:00 2001 From: Perminder Singh Date: Wed, 22 Nov 2023 19:51:02 +0530 Subject: [PATCH 15/27] some fixes --- src/webgl/p5.RendererGL.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 39395d6a44..bd5d6434dc 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1137,6 +1137,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this._pInst.noStroke(); this.clear(); this._pInst.push(); + this._pInst.imageMode(constants.CORNER); + this._pInst.blendMode(constants.BLEND); this.filterCamera._resize(); this._pInst.setCamera(this.filterCamera); this._pInst.resetMatrix(); From 7fa39f6f4b3c38510fe143811f15a0129aea4e3b Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 19:57:51 +0530 Subject: [PATCH 16/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index bd5d6434dc..6ee0cc8fa5 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1079,16 +1079,11 @@ p5.RendererGL = class RendererGL extends p5.Renderer { const tmp = this.getFilterLayerTemp(); // Resize the framebuffer 'tmp' and adjust its pixel density if it doesn't match the target. this.matchSize(tmp, target); - tmp.draw(() => this._pInst.clear()); // prevent feedback effects here too - // setup this._pInst.push(); this._pInst.noStroke(); // draw main to temp buffer - tmp.draw(() => - this._pInst.image(target, -target.width / 2, -target.height / 2)); - this._pInst.shader(this.filterShader); this.filterShader.setUniform('texelSize', texelSize); this.filterShader.setUniform('canvasSize', [target.width, target.height]); From 683ed18cccb055973d097df274ca2632dcd67558 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 20:03:13 +0530 Subject: [PATCH 17/27] restore.js --- lib/empty-example/sketch.js | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 lib/empty-example/sketch.js diff --git a/lib/empty-example/sketch.js b/lib/empty-example/sketch.js new file mode 100644 index 0000000000..c614f47b93 --- /dev/null +++ b/lib/empty-example/sketch.js @@ -0,0 +1,7 @@ +function setup() { + // put setup code here +} + +function draw() { + // put drawing code here +} From c25053150449916e156a495cd25ea98547811e76 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Wed, 22 Nov 2023 20:43:44 +0530 Subject: [PATCH 18/27] Update p5.RendererGL.js --- src/webgl/p5.RendererGL.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 6ee0cc8fa5..b1a7ad7633 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1016,8 +1016,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { fboToMatch.resizeCanvas(target.width, target.height); } - if (fboToMatch.pixelDensity() !== target._pInst.pixelDensity()) { - fboToMatch.pixelDensity(target._pInst.pixelDensity()); + if (fboToMatch.pixelDensity() !== target.pixelDensity()) { + fboToMatch.pixelDensity(target.pixelDensity()); } } filter(...args) { From e4291cd4d08b4ec1f2f4145e257501207625e173 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 23 Nov 2023 02:16:58 +0530 Subject: [PATCH 19/27] resizeCanvas to resize.js --- src/webgl/p5.RendererGL.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index b1a7ad7633..a9d99abc3d 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1013,7 +1013,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { fboToMatch.width !== target.width || fboToMatch.height !== target.height ) { - fboToMatch.resizeCanvas(target.width, target.height); + fboToMatch.resize(target.width, target.height); } if (fboToMatch.pixelDensity() !== target.pixelDensity()) { From b073664170a5a6bcd6160f1fbb06a72fd67893c8 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 23 Nov 2023 21:35:42 +0530 Subject: [PATCH 20/27] fixes.js --- src/webgl/p5.RendererGL.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index a9d99abc3d..3c4aa212fc 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -633,8 +633,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // for post processing step this.filterShader = undefined; - this.filterGraphicsLayer = undefined; - this.filterGraphicsLayerTemp = undefined; + this.filterLayer = undefined; + this.filterLayerTemp = undefined; this.defaultFilterShaders = {}; this.textureMode = constants.IMAGE; @@ -997,16 +997,16 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.curStrokeJoin = join; } getFilterLayer() { - if (!this.filterGraphicsLayer) { - this.filterGraphicsLayer = this._pInst.createFramebuffer(); + if (!this.filterLayer) { + this.filterLayer = this._pInst.createFramebuffer(); } - return this.filterGraphicsLayer; + return this.filterLayer; } getFilterLayerTemp() { - if (!this.filterGraphicsLayerTemp) { - this.filterGraphicsLayerTemp = this._pInst.createFramebuffer(); + if (!this.filterLayerTemp) { + this.filterLayerTemp = this._pInst.createFramebuffer(); } - return this.filterGraphicsLayerTemp; + return this.filterLayerTemp; } matchSize(fboToMatch, target) { if ( @@ -1451,11 +1451,6 @@ p5.RendererGL = class RendererGL extends p5.Renderer { // can also update their size framebuffer._canvasSizeChanged(); } - - // resize filter graphics layer - if (this.filterGraphicsLayer) { - p5.Renderer.prototype.resize.call(this.filterGraphicsLayer, w, h); - } } /** From a353711f70766dcff27486563fa2c7c29e14c09e Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 23 Nov 2023 21:37:15 +0530 Subject: [PATCH 21/27] fixes.js --- src/core/p5.Renderer.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js index 53cbdd53dc..55964c973d 100644 --- a/src/core/p5.Renderer.js +++ b/src/core/p5.Renderer.js @@ -121,7 +121,6 @@ class Renderer extends p5.Element { * Resize our canvas element. */ resize(w, h) { - if (this._pInst && this._pInst._pixelDensity) { this.width = w; this.height = h; this.elt.width = w * this._pInst._pixelDensity; @@ -132,7 +131,6 @@ class Renderer extends p5.Element { this._pInst._setProperty('width', this.width); this._pInst._setProperty('height', this.height); } - } } get(x, y, w, h) { From 4a9bef962cdc99d855ad32295c8b88045350096f Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 23 Nov 2023 21:41:15 +0530 Subject: [PATCH 22/27] lint fix.js --- src/core/p5.Renderer.js | 72 ++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/src/core/p5.Renderer.js b/src/core/p5.Renderer.js index 55964c973d..c869f3e6b4 100644 --- a/src/core/p5.Renderer.js +++ b/src/core/p5.Renderer.js @@ -67,7 +67,7 @@ class Renderer extends p5.Element { // the renderer should return a 'style' object that it wishes to // store on the push stack. - push() { + push () { this._pushPopDepth++; return { properties: { @@ -94,10 +94,10 @@ class Renderer extends p5.Element { // a pop() operation is in progress // the renderer is passed the 'style' object that it returned // from its push() method. - pop(style) { + pop (style) { this._pushPopDepth--; if (style.properties) { - // copy the style properties back into the renderer + // copy the style properties back into the renderer Object.assign(this, style.properties); } } @@ -120,26 +120,26 @@ class Renderer extends p5.Element { /** * Resize our canvas element. */ - resize(w, h) { - this.width = w; - this.height = h; - this.elt.width = w * this._pInst._pixelDensity; - this.elt.height = h * this._pInst._pixelDensity; - this.elt.style.width = `${w}px`; - this.elt.style.height = `${h}px`; - if (this._isMainCanvas) { - this._pInst._setProperty('width', this.width); - this._pInst._setProperty('height', this.height); - } + resize (w, h) { + this.width = w; + this.height = h; + this.elt.width = w * this._pInst._pixelDensity; + this.elt.height = h * this._pInst._pixelDensity; + this.elt.style.width = `${w}px`; + this.elt.style.height = `${h}px`; + if (this._isMainCanvas) { + this._pInst._setProperty('width', this.width); + this._pInst._setProperty('height', this.height); + } } - get(x, y, w, h) { + get (x, y, w, h) { const pixelsState = this._pixelsState; const pd = pixelsState._pixelDensity; const canvas = this.canvas; if (typeof x === 'undefined' && typeof y === 'undefined') { - // get() + // get() x = y = 0; w = pixelsState.width; h = pixelsState.height; @@ -148,26 +148,26 @@ class Renderer extends p5.Element { y *= pd; if (typeof w === 'undefined' && typeof h === 'undefined') { - // get(x,y) + // get(x,y) if (x < 0 || y < 0 || x >= canvas.width || y >= canvas.height) { return [0, 0, 0, 0]; } return this._getPixel(x, y); } - // get(x,y,w,h) + // get(x,y,w,h) } - const region = new p5.Image(w * pd, h * pd); + const region = new p5.Image(w*pd, h*pd); region._pixelDensity = pd; region.canvas .getContext('2d') - .drawImage(canvas, x, y, w * pd, h * pd, 0, 0, w * pd, h * pd); + .drawImage(canvas, x, y, w * pd, h * pd, 0, 0, w*pd, h*pd); return region; } - textLeading(l) { + textLeading (l) { if (typeof l === 'number') { this._setProperty('_leadingSet', true); this._setProperty('_textLeading', l); @@ -177,13 +177,13 @@ class Renderer extends p5.Element { return this._textLeading; } - textStyle(s) { + textStyle (s) { if (s) { if ( s === constants.NORMAL || - s === constants.ITALIC || - s === constants.BOLD || - s === constants.BOLDITALIC + s === constants.ITALIC || + s === constants.BOLD || + s === constants.BOLDITALIC ) { this._setProperty('_textStyle', s); } @@ -194,21 +194,21 @@ class Renderer extends p5.Element { return this._textStyle; } - textAscent() { + textAscent () { if (this._textAscent === null) { this._updateTextMetrics(); } return this._textAscent; } - textDescent() { + textDescent () { if (this._textDescent === null) { this._updateTextMetrics(); } return this._textDescent; } - textAlign(h, v) { + textAlign (h, v) { if (typeof h !== 'undefined') { this._setProperty('_textAlign', h); @@ -225,7 +225,7 @@ class Renderer extends p5.Element { } } - textWrap(wrapStyle) { + textWrap (wrapStyle) { this._setProperty('_textWrap', wrapStyle); return this._textWrap; } @@ -306,10 +306,10 @@ class Renderer extends p5.Element { finalMaxHeight = originalY + maxHeight - ascent / 2; } } else { - // no text-height specified, show warning for BOTTOM / CENTER + // no text-height specified, show warning for BOTTOM / CENTER if (this._textBaseline === constants.BOTTOM || - this._textBaseline === constants.CENTER) { - // use rectHeight as an approximation for text height + this._textBaseline === constants.CENTER) { + // use rectHeight as an approximation for text height let rectHeight = p.textSize() * this._textLeading; finalMinHeight = y - rectHeight / 2; finalMaxHeight = y + rectHeight / 2; @@ -435,8 +435,8 @@ class Renderer extends p5.Element { y += p.textLeading(); } } else { - // Offset to account for vertically centering multiple lines of text - no - // need to adjust anything for vertical align top or baseline + // Offset to account for vertically centering multiple lines of text - no + // need to adjust anything for vertical align top or baseline let offset = 0; if (this._textBaseline === constants.CENTER) { offset = (lines.length - 1) * p.textLeading() / 2; @@ -536,11 +536,11 @@ function calculateOffset(object) { return [currentLeft, currentTop]; } // This caused the test to failed. -Renderer.prototype.textSize = function (s) { +Renderer.prototype.textSize = function(s) { if (typeof s === 'number') { this._setProperty('_textSize', s); if (!this._leadingSet) { - // only use a default value if not previously set (#5181) + // only use a default value if not previously set (#5181) this._setProperty('_textLeading', s * constants._DEFAULT_LEADMULT); } return this._applyTextProperties(); From 2a330bfd975cf4024a9b035e76edb57252480f06 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Thu, 23 Nov 2023 22:32:08 +0530 Subject: [PATCH 23/27] Rename tests.js --- test/unit/webgl/p5.RendererGL.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index f1a1df83d7..01aeb14326 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -212,7 +212,7 @@ suite('p5.RendererGL', function() { let renderer = myp5.createCanvas(5, 5, myp5.WEBGL); let s = myp5.createShader(vert, frag); myp5.filter(s); - assert.notStrictEqual(renderer.filterGraphicsLayer, undefined); + assert.notStrictEqual(renderer.filterLayer, undefined); }); test('custom shader makes changes to main canvas', function() { @@ -231,7 +231,7 @@ suite('p5.RendererGL', function() { let g1 = myp5.createCanvas(5, 5, myp5.WEBGL); let s = myp5.createShader(vert, frag); myp5.filter(s); - let g2 = g1.filterGraphicsLayer; + let g2 = g1.filterLayer; assert.deepEqual([g1.width, g1.height], [g2.width, g2.height]); myp5.resizeCanvas(4, 4); assert.deepEqual([g1.width, g1.height], [g2.width, g2.height]); @@ -2380,4 +2380,4 @@ suite('p5.RendererGL', function() { } ); }); -}); \ No newline at end of file +}); From 6d04ec65693abbf9303d27ec95dd6a39ca7c67cc Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:35:20 +0530 Subject: [PATCH 24/27] fixes.js --- src/core/p5.Renderer2D.js | 233 ++++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 111 deletions(-) diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index cd3daf823f..fcb582ddb6 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -11,8 +11,8 @@ import './p5.Renderer'; const styleEmpty = 'rgba(0,0,0,0)'; // const alphaThreshold = 0.00125; // minimum visible -class Renderer2D extends p5.Renderer{ - constructor (elt, pInst, isMainCanvas) { +class Renderer2D extends p5.Renderer { + constructor(elt, pInst, isMainCanvas) { super(elt, pInst, isMainCanvas); this.drawingContext = this.canvas.getContext('2d'); this._pInst._setProperty('drawingContext', this.drawingContext); @@ -36,7 +36,18 @@ class Renderer2D extends p5.Renderer{ pInst ); } - + if ( + this.filterGraphicsLayer.width !== this.width || + this.filterGraphicsLayer.height !== this.height + ) { + // Resize the graphics layer + this.filterGraphicsLayer.resize(this.width, this.height); + } + if ( + this.filterGraphicsLayer.pixelDensity() !== this._pInst.pixelDensity() + ) { + this.filterGraphicsLayer.pixelDensity(this._pInst.pixelDensity()); + } return this.filterGraphicsLayer; } @@ -67,7 +78,7 @@ class Renderer2D extends p5.Renderer{ if (args[0] instanceof p5.Image) { if (args[1] >= 0) { - // set transparency of background + // set transparency of background const img = args[0]; this.drawingContext.globalAlpha = args[1] / 255; this._pInst.image(img, 0, 0, this.width, this.height); @@ -275,15 +286,15 @@ class Renderer2D extends p5.Renderer{ } } - _getTintedImageCanvas (img) { + _getTintedImageCanvas(img) { if (!img.canvas) { return img; } if (!img.tintCanvas) { - // Once an image has been tinted, keep its tint canvas - // around so we don't need to re-incur the cost of - // creating a new one for each tint + // Once an image has been tinted, keep its tint canvas + // around so we don't need to re-incur the cost of + // creating a new one for each tint img.tintCanvas = document.createElement('canvas'); } @@ -303,11 +314,11 @@ class Renderer2D extends p5.Renderer{ ctx.clearRect(0, 0, img.canvas.width, img.canvas.height); if (this._tint[0] < 255 || this._tint[1] < 255 || this._tint[2] < 255) { - // Color tint: we need to use the multiply blend mode to change the colors. - // However, the canvas implementation of this destroys the alpha channel of - // the image. To accommodate, we first get a version of the image with full - // opacity everywhere, tint using multiply, and then use the destination-in - // blend mode to restore the alpha channel again. + // Color tint: we need to use the multiply blend mode to change the colors. + // However, the canvas implementation of this destroys the alpha channel of + // the image. To accommodate, we first get a version of the image with full + // opacity everywhere, tint using multiply, and then use the destination-in + // blend mode to restore the alpha channel again. // Start with the original image ctx.drawImage(img.canvas, 0, 0); @@ -332,7 +343,7 @@ class Renderer2D extends p5.Renderer{ ctx.globalAlpha = this._tint[3] / 255; ctx.drawImage(img.canvas, 0, 0); } else { - // If we only need to change the alpha, we can skip all the extra work! + // If we only need to change the alpha, we can skip all the extra work! ctx.globalAlpha = this._tint[3] / 255; ctx.drawImage(img.canvas, 0, 0); } @@ -345,25 +356,25 @@ class Renderer2D extends p5.Renderer{ // IMAGE | Pixels ////////////////////////////////////////////// - blendMode (mode) { + blendMode(mode) { if (mode === constants.SUBTRACT) { console.warn('blendMode(SUBTRACT) only works in WEBGL mode.'); } else if ( mode === constants.BLEND || - mode === constants.REMOVE || - mode === constants.DARKEST || - mode === constants.LIGHTEST || - mode === constants.DIFFERENCE || - mode === constants.MULTIPLY || - mode === constants.EXCLUSION || - mode === constants.SCREEN || - mode === constants.REPLACE || - mode === constants.OVERLAY || - mode === constants.HARD_LIGHT || - mode === constants.SOFT_LIGHT || - mode === constants.DODGE || - mode === constants.BURN || - mode === constants.ADD + mode === constants.REMOVE || + mode === constants.DARKEST || + mode === constants.LIGHTEST || + mode === constants.DIFFERENCE || + mode === constants.MULTIPLY || + mode === constants.EXCLUSION || + mode === constants.SCREEN || + mode === constants.REPLACE || + mode === constants.OVERLAY || + mode === constants.HARD_LIGHT || + mode === constants.SOFT_LIGHT || + mode === constants.DODGE || + mode === constants.BURN || + mode === constants.ADD ) { this._cachedBlendMode = mode; this.drawingContext.globalCompositeOperation = mode; @@ -372,7 +383,7 @@ class Renderer2D extends p5.Renderer{ } } - blend (...args) { + blend(...args) { const currBlend = this.drawingContext.globalCompositeOperation; const blendMode = args[args.length - 1]; @@ -389,7 +400,7 @@ class Renderer2D extends p5.Renderer{ // .get() is not overridden // x,y are canvas-relative (pre-scaled by _pixelDensity) - _getPixel (x, y) { + _getPixel(x, y) { let imageData, index; imageData = this.drawingContext.getImageData(x, y, 1, 1).data; index = 0; @@ -401,7 +412,7 @@ class Renderer2D extends p5.Renderer{ ]; } - loadPixels () { + loadPixels() { const pixelsState = this._pixelsState; // if called by p5.Image const pd = pixelsState._pixelDensity; @@ -414,8 +425,8 @@ class Renderer2D extends p5.Renderer{ pixelsState._setProperty('pixels', imageData.data); } - set (x, y, imgOrCol) { - // round down to get integer numbers + set(x, y, imgOrCol) { + // round down to get integer numbers x = Math.floor(x); y = Math.floor(y); const pixelsState = this._pixelsState; @@ -435,11 +446,11 @@ class Renderer2D extends p5.Renderer{ b = 0, a = 0; let idx = - 4 * - (y * - pixelsState._pixelDensity * - (this.width * pixelsState._pixelDensity) + - x * pixelsState._pixelDensity); + 4 * + (y * + pixelsState._pixelDensity * + (this.width * pixelsState._pixelDensity) + + x * pixelsState._pixelDensity); if (!pixelsState.imageData) { pixelsState.loadPixels.call(pixelsState); } @@ -449,7 +460,7 @@ class Renderer2D extends p5.Renderer{ g = imgOrCol; b = imgOrCol; a = 255; - //this.updatePixels.call(this); + //this.updatePixels.call(this); } } else if (imgOrCol instanceof Array) { if (imgOrCol.length < 4) { @@ -460,7 +471,7 @@ class Renderer2D extends p5.Renderer{ g = imgOrCol[1]; b = imgOrCol[2]; a = imgOrCol[3]; - //this.updatePixels.call(this); + //this.updatePixels.call(this); } } else if (imgOrCol instanceof p5.Color) { if (idx < pixelsState.pixels.length) { @@ -468,19 +479,19 @@ class Renderer2D extends p5.Renderer{ g = imgOrCol.levels[1]; b = imgOrCol.levels[2]; a = imgOrCol.levels[3]; - //this.updatePixels.call(this); + //this.updatePixels.call(this); } } // loop over pixelDensity * pixelDensity for (let i = 0; i < pixelsState._pixelDensity; i++) { for (let j = 0; j < pixelsState._pixelDensity; j++) { - // loop over + // loop over idx = - 4 * - ((y * pixelsState._pixelDensity + j) * - this.width * - pixelsState._pixelDensity + - (x * pixelsState._pixelDensity + i)); + 4 * + ((y * pixelsState._pixelDensity + j) * + this.width * + pixelsState._pixelDensity + + (x * pixelsState._pixelDensity + i)); pixelsState.pixels[idx] = r; pixelsState.pixels[idx + 1] = g; pixelsState.pixels[idx + 2] = b; @@ -490,14 +501,14 @@ class Renderer2D extends p5.Renderer{ } } - updatePixels (x, y, w, h) { + updatePixels(x, y, w, h) { const pixelsState = this._pixelsState; const pd = pixelsState._pixelDensity; if ( x === undefined && - y === undefined && - w === undefined && - h === undefined + y === undefined && + w === undefined && + h === undefined ) { x = 0; y = 0; @@ -511,7 +522,7 @@ class Renderer2D extends p5.Renderer{ if (this.gifProperties) { this.gifProperties.frames[this.gifProperties.displayIndex].image = - pixelsState.imageData; + pixelsState.imageData; } this.drawingContext.putImageData(pixelsState.imageData, x, y, 0, 0, w, h); @@ -532,7 +543,7 @@ class Renderer2D extends p5.Renderer{ start, size ) { - // Evaluate constants. + // Evaluate constants. const alpha = size / 2.0, cos_alpha = Math.cos(alpha), sin_alpha = Math.sin(alpha), @@ -564,7 +575,7 @@ class Renderer2D extends p5.Renderer{ * * start <= stop < start + TWO_PI */ - arc (x, y, w, h, start, stop, mode) { + arc(x, y, w, h, start, stop, mode) { const ctx = this.drawingContext; const rx = w / 2.0; const ry = h / 2.0; @@ -590,10 +601,10 @@ class Renderer2D extends p5.Renderer{ ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry); } /* eslint-disable indent */ - ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry, - x + curve.cx * rx, y + curve.cy * ry, - x + curve.dx * rx, y + curve.dy * ry); - /* eslint-enable indent */ + ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry, + x + curve.cx * rx, y + curve.cy * ry, + x + curve.dx * rx, y + curve.dy * ry); + /* eslint-enable indent */ }); if (mode === constants.PIE || mode == null) { ctx.lineTo(x, y); @@ -610,10 +621,10 @@ class Renderer2D extends p5.Renderer{ ctx.moveTo(x + curve.ax * rx, y + curve.ay * ry); } /* eslint-disable indent */ - ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry, - x + curve.cx * rx, y + curve.cy * ry, - x + curve.dx * rx, y + curve.dy * ry); - /* eslint-enable indent */ + ctx.bezierCurveTo(x + curve.bx * rx, y + curve.by * ry, + x + curve.cx * rx, y + curve.cy * ry, + x + curve.dx * rx, y + curve.dy * ry); + /* eslint-enable indent */ }); if (mode === constants.PIE) { ctx.lineTo(x, y); @@ -626,7 +637,7 @@ class Renderer2D extends p5.Renderer{ return this; } - ellipse (args) { + ellipse(args) { const ctx = this.drawingContext; const doFill = this._doFill, doStroke = this._doStroke; @@ -669,7 +680,7 @@ class Renderer2D extends p5.Renderer{ } } - line (x1, y1, x2, y2) { + line(x1, y1, x2, y2) { const ctx = this.drawingContext; if (!this._doStroke) { return this; @@ -683,7 +694,7 @@ class Renderer2D extends p5.Renderer{ return this; } - point (x, y) { + point(x, y) { const ctx = this.drawingContext; if (!this._doStroke) { return this; @@ -704,7 +715,7 @@ class Renderer2D extends p5.Renderer{ } } - quad (x1, y1, x2, y2, x3, y3, x4, y4) { + quad(x1, y1, x2, y2, x3, y3, x4, y4) { const ctx = this.drawingContext; const doFill = this._doFill, doStroke = this._doStroke; @@ -732,7 +743,7 @@ class Renderer2D extends p5.Renderer{ return this; } - rect (args) { + rect(args) { const x = args[0]; const y = args[1]; const w = args[2]; @@ -756,11 +767,11 @@ class Renderer2D extends p5.Renderer{ if (!this._clipping) ctx.beginPath(); if (typeof tl === 'undefined') { - // No rounded corners + // No rounded corners ctx.rect(x, y, w, h); } else { - // At least one rounded corner - // Set defaults when not specified + // At least one rounded corner + // Set defaults when not specified if (typeof tr === 'undefined') { tr = tl; } @@ -822,7 +833,7 @@ class Renderer2D extends p5.Renderer{ } - triangle (args) { + triangle(args) { const ctx = this.drawingContext; const doFill = this._doFill, doStroke = this._doStroke; @@ -854,7 +865,7 @@ class Renderer2D extends p5.Renderer{ } } - endShape ( + endShape( mode, vertices, isCurve, @@ -891,9 +902,9 @@ class Renderer2D extends p5.Renderer{ ]; b[2] = [ vertices[i + 1][0] + - (s * vertices[i][0] - s * vertices[i + 2][0]) / 6, + (s * vertices[i][0] - s * vertices[i + 2][0]) / 6, vertices[i + 1][1] + - (s * vertices[i][1] - s * vertices[i + 2][1]) / 6 + (s * vertices[i][1] - s * vertices[i + 2][1]) / 6 ]; b[3] = [vertices[i + 1][0], vertices[i + 1][1]]; this.drawingContext.bezierCurveTo( @@ -912,7 +923,7 @@ class Renderer2D extends p5.Renderer{ } } else if ( isBezier && - (shapeKind === constants.POLYGON || shapeKind === null) + (shapeKind === constants.POLYGON || shapeKind === null) ) { if (!this._clipping) this.drawingContext.beginPath(); for (i = 0; i < numVerts; i++) { @@ -936,7 +947,7 @@ class Renderer2D extends p5.Renderer{ this._doFillStrokeClose(closeShape); } else if ( isQuadratic && - (shapeKind === constants.POLYGON || shapeKind === null) + (shapeKind === constants.POLYGON || shapeKind === null) ) { if (!this._clipping) this.drawingContext.beginPath(); for (i = 0; i < numVerts; i++) { @@ -1015,8 +1026,8 @@ class Renderer2D extends p5.Renderer{ } } else if (shapeKind === constants.TRIANGLE_FAN) { if (numVerts > 2) { - // For performance reasons, try to batch as many of the - // fill and stroke calls as possible. + // For performance reasons, try to batch as many of the + // fill and stroke calls as possible. if (!this._clipping) this.drawingContext.beginPath(); for (i = 2; i < numVerts; i++) { v = vertices[i]; @@ -1028,7 +1039,7 @@ class Renderer2D extends p5.Renderer{ if (i < numVerts - 1) { if ( (this._doFill && v[5] !== vertices[i + 1][5]) || - (this._doStroke && v[6] !== vertices[i + 1][6]) + (this._doStroke && v[6] !== vertices[i + 1][6]) ) { if (!this._clipping && this._doFill) { this._pInst.fill(v[5]); @@ -1122,31 +1133,31 @@ class Renderer2D extends p5.Renderer{ // SHAPE | Attributes ////////////////////////////////////////////// - strokeCap (cap) { + strokeCap(cap) { if ( cap === constants.ROUND || - cap === constants.SQUARE || - cap === constants.PROJECT + cap === constants.SQUARE || + cap === constants.PROJECT ) { this.drawingContext.lineCap = cap; } return this; } - strokeJoin (join) { + strokeJoin(join) { if ( join === constants.ROUND || - join === constants.BEVEL || - join === constants.MITER + join === constants.BEVEL || + join === constants.MITER ) { this.drawingContext.lineJoin = join; } return this; } - strokeWeight (w) { + strokeWeight(w) { if (typeof w === 'undefined' || w === 0) { - // hack because lineWidth 0 doesn't work + // hack because lineWidth 0 doesn't work this.drawingContext.lineWidth = 0.0001; } else { this.drawingContext.lineWidth = w; @@ -1154,28 +1165,28 @@ class Renderer2D extends p5.Renderer{ return this; } - _getFill () { + _getFill() { if (!this._cachedFillStyle) { this._cachedFillStyle = this.drawingContext.fillStyle; } return this._cachedFillStyle; } - _setFill (fillStyle) { + _setFill(fillStyle) { if (fillStyle !== this._cachedFillStyle) { this.drawingContext.fillStyle = fillStyle; this._cachedFillStyle = fillStyle; } } - _getStroke () { + _getStroke() { if (!this._cachedStrokeStyle) { this._cachedStrokeStyle = this.drawingContext.strokeStyle; } return this._cachedStrokeStyle; } - _setStroke (strokeStyle) { + _setStroke(strokeStyle) { if (strokeStyle !== this._cachedStrokeStyle) { this.drawingContext.strokeStyle = strokeStyle; this._cachedStrokeStyle = strokeStyle; @@ -1185,7 +1196,7 @@ class Renderer2D extends p5.Renderer{ ////////////////////////////////////////////// // SHAPE | Curves ////////////////////////////////////////////// - bezier (x1, y1, x2, y2, x3, y3, x4, y4) { + bezier(x1, y1, x2, y2, x3, y3, x4, y4) { this._pInst.beginShape(); this._pInst.vertex(x1, y1); this._pInst.bezierVertex(x2, y2, x3, y3, x4, y4); @@ -1193,7 +1204,7 @@ class Renderer2D extends p5.Renderer{ return this; } - curve (x1, y1, x2, y2, x3, y3, x4, y4) { + curve(x1, y1, x2, y2, x3, y3, x4, y4) { this._pInst.beginShape(); this._pInst.curveVertex(x1, y1); this._pInst.curveVertex(x2, y2); @@ -1207,7 +1218,7 @@ class Renderer2D extends p5.Renderer{ // SHAPE | Vertex ////////////////////////////////////////////// - _doFillStrokeClose (closeShape) { + _doFillStrokeClose(closeShape) { if (closeShape) { this.drawingContext.closePath(); } @@ -1223,11 +1234,11 @@ class Renderer2D extends p5.Renderer{ // TRANSFORM ////////////////////////////////////////////// - applyMatrix (a, b, c, d, e, f) { + applyMatrix(a, b, c, d, e, f) { this.drawingContext.transform(a, b, c, d, e, f); } - resetMatrix () { + resetMatrix() { this.drawingContext.setTransform(1, 0, 0, 1, 0, 0); this.drawingContext.scale( this._pInst._pixelDensity, @@ -1236,17 +1247,17 @@ class Renderer2D extends p5.Renderer{ return this; } - rotate (rad) { + rotate(rad) { this.drawingContext.rotate(rad); } - scale (x, y) { + scale(x, y) { this.drawingContext.scale(x, y); return this; } - translate (x, y) { - // support passing a vector as the 1st parameter + translate(x, y) { + // support passing a vector as the 1st parameter if (x instanceof p5.Vector) { y = x.y; x = x.x; @@ -1262,7 +1273,7 @@ class Renderer2D extends p5.Renderer{ - _renderText (p, line, x, y, maxY, minY) { + _renderText(p, line, x, y, maxY, minY) { if (y < minY || y >= maxY) { return; // don't render lines beyond our minY/maxY bounds (see #5785) } @@ -1270,7 +1281,7 @@ class Renderer2D extends p5.Renderer{ p.push(); // fix to #803 if (!this._isOpenType()) { - // a system/browser font + // a system/browser font // no stroke unless specified by user if (this._doStroke && this._strokeSet) { @@ -1278,7 +1289,7 @@ class Renderer2D extends p5.Renderer{ } if (!this._clipping && this._doFill) { - // if fill hasn't been set by user, use default text fill + // if fill hasn't been set by user, use default text fill if (!this._fillSet) { this._setFill(constants._DEFAULT_TEXT_FILL); } @@ -1286,7 +1297,7 @@ class Renderer2D extends p5.Renderer{ this.drawingContext.fillText(line, x, y); } } else { - // an opentype font, let it handle the rendering + // an opentype font, let it handle the rendering this._textFont._renderPath(line, x, y, { renderer: this }); } @@ -1295,7 +1306,7 @@ class Renderer2D extends p5.Renderer{ return p; } - textWidth (s) { + textWidth(s) { if (this._isOpenType()) { return this._textFont._textWidth(s, this._textSize); } @@ -1303,7 +1314,7 @@ class Renderer2D extends p5.Renderer{ return this.drawingContext.measureText(s).width; } - _applyTextProperties () { + _applyTextProperties() { let font; const p = this._pInst; @@ -1318,7 +1329,7 @@ class Renderer2D extends p5.Renderer{ } this.drawingContext.font = `${this._textStyle || 'normal'} ${this._textSize || - 12}px ${font || 'sans-serif'}`; + 12}px ${font || 'sans-serif'}`; this.drawingContext.textAlign = this._textAlign; if (this._textBaseline === constants.CENTER) { @@ -1339,7 +1350,7 @@ class Renderer2D extends p5.Renderer{ // store on the push stack. // derived renderers should call the base class' push() method // to fetch the base style object. - push () { + push() { this.drawingContext.save(); // get the base renderer style @@ -1351,7 +1362,7 @@ class Renderer2D extends p5.Renderer{ // from its push() method. // derived renderers should pass this object to their base // class' pop method - pop (style) { + pop(style) { this.drawingContext.restore(); // Re-cache the fill / stroke state this._cachedFillStyle = this.drawingContext.fillStyle; @@ -1362,7 +1373,7 @@ class Renderer2D extends p5.Renderer{ } // Fix test -Renderer2D.prototype.text = function(str, x, y, maxWidth, maxHeight) { +Renderer2D.prototype.text = function (str, x, y, maxWidth, maxHeight) { let baselineHacked; // baselineHacked: (HACK) From b1ec4410dbf4bc985a8490215b01d381bb8d6b18 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:38:46 +0530 Subject: [PATCH 25/27] add test.js --- test/unit/webgl/p5.RendererGL.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index 01aeb14326..e9a4a6c897 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -237,6 +237,15 @@ suite('p5.RendererGL', function() { assert.deepEqual([g1.width, g1.height], [g2.width, g2.height]); }); + test('Filter graphics layer get resized in 2D mode', function () { + let g1 = myp5.createCanvas(10, 10); + let s = myp5.createShader(vert, frag); + myp5.filter(s); + myp5.resizeCanvas(5, 15); + assert.equal(g1.width, 5); + assert.equal(g1.height, 15); + }); + test('create graphics is unaffected after filter', function() { myp5.createCanvas(5, 5, myp5.WEBGL); let pg = myp5.createGraphics(5, 5, myp5.WEBGL); From c01235fd6dc766a0d366e7151f24fab63afdbaaf Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:41:18 +0530 Subject: [PATCH 26/27] fixes.js --- src/core/p5.Renderer2D.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/p5.Renderer2D.js b/src/core/p5.Renderer2D.js index fcb582ddb6..02286c7c6c 100644 --- a/src/core/p5.Renderer2D.js +++ b/src/core/p5.Renderer2D.js @@ -41,7 +41,7 @@ class Renderer2D extends p5.Renderer { this.filterGraphicsLayer.height !== this.height ) { // Resize the graphics layer - this.filterGraphicsLayer.resize(this.width, this.height); + this.filterGraphicsLayer.resizeCanvas(this.width, this.height); } if ( this.filterGraphicsLayer.pixelDensity() !== this._pInst.pixelDensity() From 8df743704401abc60df0e68e2002c39d282df258 Mon Sep 17 00:00:00 2001 From: perminder-17 <127239756+perminder-17@users.noreply.github.com> Date: Fri, 24 Nov 2023 03:44:57 +0530 Subject: [PATCH 27/27] fixes.js --- test/unit/webgl/p5.RendererGL.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/unit/webgl/p5.RendererGL.js b/test/unit/webgl/p5.RendererGL.js index e9a4a6c897..09c10be158 100644 --- a/test/unit/webgl/p5.RendererGL.js +++ b/test/unit/webgl/p5.RendererGL.js @@ -242,6 +242,7 @@ suite('p5.RendererGL', function() { let s = myp5.createShader(vert, frag); myp5.filter(s); myp5.resizeCanvas(5, 15); + myp5.filter(s); assert.equal(g1.width, 5); assert.equal(g1.height, 15); });