@@ -706,7 +706,10 @@ class RenderWebGL extends EventEmitter {
706
706
gl . clearColor ( ...this . _backgroundColor4f ) ;
707
707
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
708
708
709
- this . _drawThese ( this . _drawList , ShaderManager . DRAW_MODE . default , this . _projection ) ;
709
+ this . _drawThese ( this . _drawList , ShaderManager . DRAW_MODE . default , this . _projection , {
710
+ framebufferWidth : gl . canvas . width ,
711
+ framebufferHeight : gl . canvas . height
712
+ } ) ;
710
713
if ( this . _snapshotCallbacks . length > 0 ) {
711
714
const snapshot = gl . canvas . toDataURL ( ) ;
712
715
this . _snapshotCallbacks . forEach ( cb => cb ( snapshot ) ) ;
@@ -1186,114 +1189,6 @@ class RenderWebGL extends EventEmitter {
1186
1189
return Number ( hit ) ;
1187
1190
}
1188
1191
1189
- /**
1190
- * @typedef DrawableExtractionOld
1191
- * @property {Uint8Array } data Raw pixel data for the drawable
1192
- * @property {int } width Drawable bounding box width
1193
- * @property {int } height Drawable bounding box height
1194
- * @property {Array<number> } scratchOffset [x, y] offset in Scratch coordinates
1195
- * from the drawable position to the client x, y coordinate
1196
- * @property {int } x The x coordinate relative to drawable bounding box
1197
- * @property {int } y The y coordinate relative to drawable bounding box
1198
- */
1199
-
1200
- /**
1201
- * Return drawable pixel data and picking coordinates relative to the drawable bounds
1202
- * @param {int } drawableID The ID of the drawable to get pixel data for
1203
- * @param {int } x The client x coordinate of the picking location.
1204
- * @param {int } y The client y coordinate of the picking location.
1205
- * @return {?DrawableExtractionOld } Data about the picked drawable
1206
- * @deprecated Use {@link extractDrawableScreenSpace} instead.
1207
- */
1208
- extractDrawable ( drawableID , x , y ) {
1209
- this . _doExitDrawRegion ( ) ;
1210
-
1211
- const drawable = this . _allDrawables [ drawableID ] ;
1212
- if ( ! drawable ) return null ;
1213
-
1214
- // Convert client coordinates into absolute scratch units
1215
- const scratchX = this . _nativeSize [ 0 ] * ( ( x / this . _gl . canvas . clientWidth ) - 0.5 ) ;
1216
- const scratchY = this . _nativeSize [ 1 ] * ( ( y / this . _gl . canvas . clientHeight ) - 0.5 ) ;
1217
-
1218
- const gl = this . _gl ;
1219
-
1220
- const bounds = drawable . getFastBounds ( ) ;
1221
- bounds . snapToInt ( ) ;
1222
-
1223
- // Set a reasonable max limit width and height for the bufferInfo bounds
1224
- const maxTextureSize = gl . getParameter ( gl . MAX_TEXTURE_SIZE ) ;
1225
- const clampedWidth = Math . min ( 2048 , bounds . width , maxTextureSize ) ;
1226
- const clampedHeight = Math . min ( 2048 , bounds . height , maxTextureSize ) ;
1227
-
1228
- // Make a new bufferInfo since this._queryBufferInfo is limited to 480x360
1229
- const attachments = [
1230
- { format : gl . RGBA } ,
1231
- { format : gl . DEPTH_STENCIL }
1232
- ] ;
1233
- const bufferInfo = twgl . createFramebufferInfo ( gl , attachments , clampedWidth , clampedHeight ) ;
1234
-
1235
- try {
1236
- // If the new bufferInfo is invalid, fall back to using the smaller _queryBufferInfo
1237
- twgl . bindFramebufferInfo ( gl , bufferInfo ) ;
1238
- if ( gl . checkFramebufferStatus ( gl . FRAMEBUFFER ) !== gl . FRAMEBUFFER_COMPLETE ) {
1239
- twgl . bindFramebufferInfo ( gl , this . _queryBufferInfo ) ;
1240
- }
1241
-
1242
- // Translate to scratch units relative to the drawable
1243
- const pickX = scratchX - bounds . left ;
1244
- const pickY = scratchY + bounds . top ;
1245
-
1246
- // Limit size of viewport to the bounds around the target Drawable,
1247
- // and create the projection matrix for the draw.
1248
- gl . viewport ( 0 , 0 , bounds . width , bounds . height ) ;
1249
- const projection = twgl . m4 . ortho ( bounds . left , bounds . right , bounds . top , bounds . bottom , - 1 , 1 ) ;
1250
-
1251
- gl . clearColor ( 0 , 0 , 0 , 0 ) ;
1252
- gl . clear ( gl . COLOR_BUFFER_BIT ) ;
1253
- try {
1254
- gl . disable ( gl . BLEND ) ;
1255
- // ImageData objects store alpha un-premultiplied, so draw with the `straightAlpha` draw mode.
1256
- this . _drawThese ( [ drawableID ] , ShaderManager . DRAW_MODE . straightAlpha , projection ,
1257
- { effectMask : ~ ShaderManager . EFFECT_INFO . ghost . mask } ) ;
1258
- } finally {
1259
- gl . enable ( gl . BLEND ) ;
1260
- }
1261
-
1262
- const data = new Uint8Array ( Math . floor ( bounds . width * bounds . height * 4 ) ) ;
1263
- gl . readPixels ( 0 , 0 , bounds . width , bounds . height , gl . RGBA , gl . UNSIGNED_BYTE , data ) ;
1264
-
1265
- if ( this . _debugCanvas ) {
1266
- this . _debugCanvas . width = bounds . width ;
1267
- this . _debugCanvas . height = bounds . height ;
1268
- const ctx = this . _debugCanvas . getContext ( '2d' ) ;
1269
- const imageData = ctx . createImageData ( bounds . width , bounds . height ) ;
1270
- imageData . data . set ( data ) ;
1271
- ctx . putImageData ( imageData , 0 , 0 ) ;
1272
- ctx . beginPath ( ) ;
1273
- ctx . arc ( pickX , pickY , 3 , 0 , 2 * Math . PI , false ) ;
1274
- ctx . fillStyle = 'white' ;
1275
- ctx . fill ( ) ;
1276
- ctx . lineWidth = 1 ;
1277
- ctx . strokeStyle = 'black' ;
1278
- ctx . stroke ( ) ;
1279
- }
1280
-
1281
- return {
1282
- data : data ,
1283
- width : bounds . width ,
1284
- height : bounds . height ,
1285
- scratchOffset : [
1286
- - scratchX + drawable . _position [ 0 ] ,
1287
- - scratchY - drawable . _position [ 1 ]
1288
- ] ,
1289
- x : pickX ,
1290
- y : pickY
1291
- } ;
1292
- } finally {
1293
- gl . deleteFramebuffer ( bufferInfo . framebuffer ) ;
1294
- }
1295
- }
1296
-
1297
1192
/**
1298
1193
* @typedef DrawableExtraction
1299
1194
* @property {ImageData } data Raw pixel data for the drawable
@@ -1371,9 +1266,15 @@ class RenderWebGL extends EventEmitter {
1371
1266
1372
1267
gl . clearColor ( 0 , 0 , 0 , 0 ) ;
1373
1268
gl . clear ( gl . COLOR_BUFFER_BIT ) ;
1374
- // Don't apply the ghost effect. TODO: is this an intentional design decision?
1375
1269
this . _drawThese ( [ drawableID ] , ShaderManager . DRAW_MODE . straightAlpha , projection ,
1376
- { effectMask : ~ ShaderManager . EFFECT_INFO . ghost . mask } ) ;
1270
+ {
1271
+ // Don't apply the ghost effect. TODO: is this an intentional design decision?
1272
+ effectMask : ~ ShaderManager . EFFECT_INFO . ghost . mask ,
1273
+ // We're doing this in screen-space, so the framebuffer dimensions should be those of the canvas in
1274
+ // screen-space. This is used to ensure SVG skins are rendered at the proper resolution.
1275
+ framebufferWidth : canvas . width ,
1276
+ framebufferHeight : canvas . height
1277
+ } ) ;
1377
1278
1378
1279
const data = new Uint8Array ( Math . floor ( clampedWidth * clampedHeight * 4 ) ) ;
1379
1280
gl . readPixels ( 0 , 0 , clampedWidth , clampedHeight , gl . RGBA , gl . UNSIGNED_BYTE , data ) ;
@@ -1902,18 +1803,6 @@ class RenderWebGL extends EventEmitter {
1902
1803
this . _regionId = null ;
1903
1804
}
1904
1805
1905
- /**
1906
- * Get the screen-space scale of a drawable, as percentages of the drawable's "normal" size.
1907
- * @param {Drawable } drawable The drawable whose screen-space scale we're fetching.
1908
- * @returns {Array<number> } The screen-space X and Y dimensions of the drawable's scale, as percentages.
1909
- */
1910
- _getDrawableScreenSpaceScale ( drawable ) {
1911
- return [
1912
- drawable . scale [ 0 ] * this . _gl . canvas . width / this . _nativeSize [ 0 ] ,
1913
- drawable . scale [ 1 ] * this . _gl . canvas . height / this . _nativeSize [ 1 ]
1914
- ] ;
1915
- }
1916
-
1917
1806
/**
1918
1807
* Draw a set of Drawables, by drawable ID
1919
1808
* @param {Array<int> } drawables The Drawable IDs to draw, possibly this._drawList.
@@ -1924,13 +1813,20 @@ class RenderWebGL extends EventEmitter {
1924
1813
* @param {object.<string,*> } opts.extraUniforms Extra uniforms for the shaders.
1925
1814
* @param {int } opts.effectMask Bitmask for effects to allow
1926
1815
* @param {boolean } opts.ignoreVisibility Draw all, despite visibility (e.g. stamping, touching color)
1816
+ * @param {int } opts.framebufferWidth The width of the framebuffer being drawn onto. Defaults to "native" width
1817
+ * @param {int } opts.framebufferHeight The height of the framebuffer being drawn onto. Defaults to "native" height
1927
1818
* @private
1928
1819
*/
1929
1820
_drawThese ( drawables , drawMode , projection , opts = { } ) {
1930
1821
1931
1822
const gl = this . _gl ;
1932
1823
let currentShader = null ;
1933
1824
1825
+ const framebufferSpaceScaleDiffers = (
1826
+ 'framebufferWidth' in opts && 'framebufferHeight' in opts &&
1827
+ opts . framebufferWidth !== this . _nativeSize [ 0 ] && opts . framebufferHeight !== this . _nativeSize [ 1 ]
1828
+ ) ;
1829
+
1934
1830
const numDrawables = drawables . length ;
1935
1831
for ( let drawableIndex = 0 ; drawableIndex < numDrawables ; ++ drawableIndex ) {
1936
1832
const drawableID = drawables [ drawableIndex ] ;
@@ -1945,8 +1841,13 @@ class RenderWebGL extends EventEmitter {
1945
1841
// the ignoreVisibility flag is used (e.g. for stamping or touchingColor).
1946
1842
if ( ! drawable . getVisible ( ) && ! opts . ignoreVisibility ) continue ;
1947
1843
1948
- // Combine drawable scale with the native vs. backing pixel ratio
1949
- const drawableScale = this . _getDrawableScreenSpaceScale ( drawable ) ;
1844
+ // drawableScale is the "framebuffer-pixel-space" scale of the drawable, as percentages of the drawable's
1845
+ // "native size" (so 100 = same as skin's "native size", 200 = twice "native size").
1846
+ // If the framebuffer dimensions are the same as the stage's "native" size, there's no need to calculate it.
1847
+ const drawableScale = framebufferSpaceScaleDiffers ? [
1848
+ drawable . scale [ 0 ] * opts . framebufferWidth / this . _nativeSize [ 0 ] ,
1849
+ drawable . scale [ 1 ] * opts . framebufferHeight / this . _nativeSize [ 1 ]
1850
+ ] : drawable . scale ;
1950
1851
1951
1852
// If the skin or texture isn't ready yet, skip it.
1952
1853
if ( ! drawable . skin || ! drawable . skin . getTexture ( drawableScale ) ) continue ;
@@ -2179,7 +2080,7 @@ class RenderWebGL extends EventEmitter {
2179
2080
}
2180
2081
2181
2082
// :3
2182
- RenderWebGL . prototype . canHazPixels = RenderWebGL . prototype . extractDrawable ;
2083
+ RenderWebGL . prototype . canHazPixels = RenderWebGL . prototype . extractDrawableScreenSpace ;
2183
2084
2184
2085
/**
2185
2086
* Values for setUseGPU()
0 commit comments