|
2 | 2 | // ID: penP |
3 | 3 | // Description: Advanced rendering capabilities. |
4 | 4 | // By: ObviousAlexC <https://scratch.mit.edu/users/pinksheep2917/> |
| 5 | +// By: Pen-Group |
5 | 6 | // License: MIT |
6 | 7 |
|
7 | 8 | // With permission from Sharkpool-SP to use his pen layer data uri block! |
|
13 | 14 |
|
14 | 15 | //if you are looking for extension settings search up /* EXTENSION SETTINGS */ |
15 | 16 |
|
16 | | -//7.1.8 patch notes |
| 17 | +//7.1.9 patch notes |
17 | 18 |
|
18 | 19 | /* |
19 | 20 | ? -- Changes -- ? |
20 | | - ? Bug Fixes |
21 | | - ? Standardized naming |
| 21 | + ? Bug Fixes (see https://github.com/Pen-Group/extensions/issues/39) |
22 | 22 | */ |
23 | 23 |
|
24 | 24 | (function (Scratch) { |
|
91 | 91 | //?Call it to have it consistant |
92 | 92 | updateCanvasSize(); |
93 | 93 |
|
94 | | - //?Call every frame because I don't know of a way to detect when the stage is resized through window resizing (2/7/24) thought I should clarify |
95 | | - |
| 94 | + vm.renderer.on("UseHighQualityRenderChanged", updateCanvasSize); |
96 | 95 | window.addEventListener("resize", updateCanvasSize); |
97 | 96 | canvas.addEventListener("resize", updateCanvasSize); |
98 | | - vm.runtime.on("STAGE_SIZE_CHANGED", () => { |
99 | | - updateCanvasSize(); |
100 | | - }); |
| 97 | + vm.runtime.on("STAGE_SIZE_CHANGED", updateCanvasSize); |
101 | 98 |
|
102 | 99 | let lastCanvasSize = [canvas.clientWidth, canvas.clientHeight]; |
103 | 100 | vm.runtime.on("BEFORE_EXECUTE", () => { |
|
242 | 239 | void main() |
243 | 240 | { |
244 | 241 | gl_FragColor = texture2D(u_drawTex, v_texCoord); |
245 | | - gl_FragColor.rgb = clamp(gl_FragColor.rgb / (gl_FragColor.a + 1e-3), 0.0, 1.0); |
246 | 242 | } |
247 | 243 | `, |
248 | 244 | }, |
|
431 | 427 | }, |
432 | 428 | }; |
433 | 429 |
|
434 | | - extensionVersion = "7.1.8"; |
| 430 | + extensionVersion = "7.1.9"; |
435 | 431 |
|
436 | 432 | //?Stores our attributes |
437 | 433 | triangleAttributesOfAllSprites = {}; |
|
3375 | 3371 | Scratch.vm.renderer.penPoint( |
3376 | 3372 | Scratch.vm.renderer._penSkinId, |
3377 | 3373 | attrib, |
3378 | | - x, |
3379 | | - y |
| 3374 | + Scratch.Cast.toNumber(x), |
| 3375 | + Scratch.Cast.toNumber(y) |
3380 | 3376 | ); |
3381 | 3377 | } |
3382 | 3378 | drawLine({ x1, y1, x2, y2 }, util) { |
|
3387 | 3383 | Scratch.vm.renderer.penLine( |
3388 | 3384 | Scratch.vm.renderer._penSkinId, |
3389 | 3385 | attrib, |
3390 | | - x1, |
3391 | | - y1, |
3392 | | - x2, |
3393 | | - y2 |
| 3386 | + Scratch.Cast.toNumber(x1), |
| 3387 | + Scratch.Cast.toNumber(y1), |
| 3388 | + Scratch.Cast.toNumber(x2), |
| 3389 | + Scratch.Cast.toNumber(y2) |
3394 | 3390 | ); |
3395 | 3391 | } |
3396 | 3392 | stampSprite({ sprite }) { |
|
4125 | 4121 | x = Math.floor(x - 1); |
4126 | 4122 | y = Math.floor(y - 1); |
4127 | 4123 | const colorIndex = (y * curCostume.width + x) * 4; |
4128 | | - if (textureData[colorIndex] && x < curCostume.width && x >= 0) { |
| 4124 | + if ( |
| 4125 | + textureData[colorIndex] !== undefined && |
| 4126 | + x < curCostume.width && |
| 4127 | + x >= 0 |
| 4128 | + ) { |
4129 | 4129 | return ( |
4130 | 4130 | this.colorLib.rgbtoSColor({ |
4131 | 4131 | R: textureData[colorIndex] / 2.55, |
|
4778 | 4778 | item > this.programs[shader].uniformDec[uniformName].arrayLength |
4779 | 4779 | ) |
4780 | 4780 | return; |
4781 | | - item -= (item - 1) * 2; |
| 4781 | + item = (item - 1) * 2; |
4782 | 4782 | this.programs[shader].uniformDat[uniformName][item] = numberX; |
4783 | 4783 | this.programs[shader].uniformDat[uniformName][item + 1] = numberY; |
4784 | 4784 | } |
|
5712 | 5712 | curCostume.height |
5713 | 5713 | ); |
5714 | 5714 |
|
| 5715 | + // don't assume the image is square |
| 5716 | + const maxDimension = Math.max(curCostume.width, curCostume.height); |
| 5717 | + |
5715 | 5718 | gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.penPlusCubemap[name]); |
5716 | 5719 | gl.texImage2D( |
5717 | | - cubemapSetup[faceID].texture.side, |
| 5720 | + cubemapSetup[faceID].side, |
5718 | 5721 | 0, |
5719 | 5722 | gl.RGBA, |
5720 | | - curCostume.width, |
5721 | | - curCostume.height, |
| 5723 | + maxDimension, |
| 5724 | + maxDimension, |
5722 | 5725 | 0, |
5723 | 5726 | gl.RGBA, |
5724 | 5727 | gl.UNSIGNED_BYTE, |
|
5743 | 5746 | //Only used for images we got permission to fetch before. Don't need this. |
5744 | 5747 | // eslint-disable-next-line |
5745 | 5748 | const image = new Image(); |
| 5749 | + |
5746 | 5750 | image.onload = () => { |
5747 | | - gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.penPlusCubemap[name]); |
5748 | | - gl.texImage2D( |
5749 | | - cubemapSetup[faceID].texture.side, |
5750 | | - 0, |
5751 | | - gl.RGBA, |
5752 | | - gl.RGBA, |
5753 | | - gl.UNSIGNED_BYTE, |
5754 | | - image |
5755 | | - ); |
| 5751 | + const maxDimension = Math.max(image.width, image.height); |
| 5752 | + if (image.width != image.height) { |
| 5753 | + // I don't know if there's a better way to do this. |
| 5754 | + const canvas = document.createElement("canvas"); |
| 5755 | + canvas.width = maxDimension; |
| 5756 | + canvas.height = maxDimension; |
| 5757 | + |
| 5758 | + const ctx = canvas.getContext("2d"); |
| 5759 | + ctx.drawImage( |
| 5760 | + image, |
| 5761 | + (maxDimension - image.width) / 2, |
| 5762 | + (maxDimension - image.height) / 2 |
| 5763 | + ); |
5756 | 5764 |
|
| 5765 | + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.penPlusCubemap[name]); |
| 5766 | + gl.texImage2D( |
| 5767 | + cubemapSetup[faceID].side, |
| 5768 | + 0, |
| 5769 | + gl.RGBA, |
| 5770 | + gl.RGBA, |
| 5771 | + gl.UNSIGNED_BYTE, |
| 5772 | + canvas |
| 5773 | + ); |
| 5774 | + } else { |
| 5775 | + gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.penPlusCubemap[name]); |
| 5776 | + gl.texImage2D( |
| 5777 | + cubemapSetup[faceID].side, |
| 5778 | + 0, |
| 5779 | + gl.RGBA, |
| 5780 | + gl.RGBA, |
| 5781 | + gl.UNSIGNED_BYTE, |
| 5782 | + image |
| 5783 | + ); |
| 5784 | + } |
5757 | 5785 | gl.texParameteri( |
5758 | 5786 | gl.TEXTURE_CUBE_MAP, |
5759 | 5787 | gl.TEXTURE_MIN_FILTER, |
|
6116 | 6144 | //If it is named scratch stage get that stuff out of here |
6117 | 6145 | if (name == "Scratch Stage") return; |
6118 | 6146 |
|
| 6147 | + // preserve GL binding |
| 6148 | + if (!this.inDrawRegion) renderer.enterDrawRegion(this.penPlusDrawRegion); |
| 6149 | + const prevFB = gl.getParameter(gl.FRAMEBUFFER_BINDING); |
| 6150 | + |
6119 | 6151 | //if the render texture exists delete it |
6120 | 6152 | if (this.renderTextures[this.prefixes.renderTextures + name]) { |
6121 | 6153 | this._deleteFramebuffer( |
6122 | 6154 | this.renderTextures[this.prefixes.renderTextures + name] |
6123 | 6155 | ); |
6124 | 6156 | } |
6125 | 6157 |
|
| 6158 | + // restore GL framebuffer binding |
| 6159 | + gl.bindFramebuffer(gl.FRAMEBUFFER, prevFB); |
| 6160 | + |
6126 | 6161 | //Add it |
6127 | 6162 | this.renderTextures[this.prefixes.renderTextures + name] = |
6128 | 6163 | twgl.createFramebufferInfo(gl, triBufferAttachments); |
|
6134 | 6169 | //If it is named scratch stage get that stuff out of here |
6135 | 6170 | if (name == "Scratch Stage") return; |
6136 | 6171 |
|
| 6172 | + // preserve GL binding |
| 6173 | + if (!this.inDrawRegion) renderer.enterDrawRegion(this.penPlusDrawRegion); |
| 6174 | + const prevFB = gl.getParameter(gl.FRAMEBUFFER_BINDING); |
| 6175 | + |
6137 | 6176 | //if the render texture exists delete it |
6138 | 6177 | if (this.renderTextures[this.prefixes.renderTextures + name]) { |
6139 | 6178 | this._deleteFramebuffer( |
6140 | 6179 | this.renderTextures[this.prefixes.renderTextures + name] |
6141 | 6180 | ); |
6142 | 6181 | } |
6143 | 6182 |
|
| 6183 | + // restore GL framebuffer binding |
| 6184 | + gl.bindFramebuffer(gl.FRAMEBUFFER, prevFB); |
| 6185 | + |
6144 | 6186 | //Add it |
6145 | 6187 | this.renderTextures[this.prefixes.renderTextures + name] = |
6146 | 6188 | twgl.createFramebufferInfo(gl, triBufferAttachments); |
|
0 commit comments