Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGLTextures: More flexible image dimensions computation. #27810

Merged
merged 2 commits into from
Feb 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
"XRMediaBinding": "readonly",
"CodeMirror": "readonly",
"esprima": "readonly",
"jsonlint": "readonly"
"jsonlint": "readonly",
"VideoFrame": "readonly"
},
"rules": {
"no-throw-literal": [
Expand Down
60 changes: 49 additions & 11 deletions src/renderers/webgl/WebGLTextures.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import * as MathUtils from '../../math/MathUtils.js';
import { ImageUtils } from '../../extras/ImageUtils.js';
import { createElementNS } from '../../utils.js';
import { ColorManagement } from '../../math/ColorManagement.js';
import { Vector2 } from '../../math/Vector2.js';

function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {

const isWebGL2 = capabilities.isWebGL2;
const multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' ) ? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null;
const supportsInvalidateFramebuffer = typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent );

const _imageDimensions = new Vector2();
const _videoTextures = new WeakMap();
let _canvas;

Expand Down Expand Up @@ -47,11 +49,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

let scale = 1;

const dimensions = getDimensions( image );

// handle case if texture exceeds max size

if ( image.width > maxSize || image.height > maxSize ) {
if ( dimensions.width > maxSize || dimensions.height > maxSize ) {

scale = maxSize / Math.max( image.width, image.height );
scale = maxSize / Math.max( dimensions.width, dimensions.height );

}

Expand All @@ -63,12 +67,13 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

if ( ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) ||
( typeof HTMLCanvasElement !== 'undefined' && image instanceof HTMLCanvasElement ) ||
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ) {
( typeof ImageBitmap !== 'undefined' && image instanceof ImageBitmap ) ||
( typeof VideoFrame !== 'undefined' && image instanceof VideoFrame ) ) {

const floor = needsPowerOfTwo ? MathUtils.floorPowerOfTwo : Math.floor;

const width = floor( scale * image.width );
const height = floor( scale * image.height );
const width = floor( scale * dimensions.width );
const height = floor( scale * dimensions.height );

if ( _canvas === undefined ) _canvas = createCanvas( width, height );

Expand All @@ -82,15 +87,15 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
const context = canvas.getContext( '2d' );
context.drawImage( image, 0, 0, width, height );

console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + image.width + 'x' + image.height + ') to (' + width + 'x' + height + ').' );
console.warn( 'THREE.WebGLRenderer: Texture has been resized from (' + dimensions.width + 'x' + dimensions.height + ') to (' + width + 'x' + height + ').' );

return canvas;

} else {

if ( 'data' in image ) {

console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + image.width + 'x' + image.height + ').' );
console.warn( 'THREE.WebGLRenderer: Image in DataTexture is too big (' + dimensions.width + 'x' + dimensions.height + ').' );

}

Expand All @@ -106,7 +111,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

function isPowerOfTwo( image ) {

return MathUtils.isPowerOfTwo( image.width ) && MathUtils.isPowerOfTwo( image.height );
const dimensions = getDimensions( image );

return MathUtils.isPowerOfTwo( dimensions.width ) && MathUtils.isPowerOfTwo( dimensions.height );

}

Expand Down Expand Up @@ -1114,7 +1121,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

if ( useTexStorage && allocateMemory ) {

state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );
const dimensions = getDimensions( mipmaps[ 0 ] );

state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height );

}

Expand Down Expand Up @@ -1146,7 +1155,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

if ( allocateMemory ) {

state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height );
const dimensions = getDimensions( image );

state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, dimensions.width, dimensions.height );

}

Expand Down Expand Up @@ -1316,7 +1327,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

if ( mipmaps.length > 0 ) levels ++;

state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[ 0 ].width, cubeImage[ 0 ].height );
const dimensions = getDimensions( cubeImage[ 0 ] );

state.texStorage2D( _gl.TEXTURE_CUBE_MAP, levels, glInternalFormat, dimensions.width, dimensions.height );

}

Expand Down Expand Up @@ -2153,6 +2166,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,

}

function getDimensions( image ) {

if ( typeof HTMLImageElement !== 'undefined' && image instanceof HTMLImageElement ) {

// if intrinsic data are not available, fallback to width/height

_imageDimensions.width = image.naturalWidth || image.width;
_imageDimensions.height = image.naturalHeight || image.height;

} else if ( typeof VideoFrame !== 'undefined' && image instanceof VideoFrame ) {

_imageDimensions.width = image.displayWidth;
_imageDimensions.height = image.displayHeight;

} else {

_imageDimensions.width = image.width;
_imageDimensions.height = image.height;

}

return _imageDimensions;

}

//

this.allocateTextureUnit = allocateTextureUnit;
Expand Down