|
@@ -7,7 +7,6 @@ import { _Math } from '../../math/Math.js';
|
|
|
|
|
|
function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) {
|
|
|
|
|
|
- var _isWebGL2 = ( typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext ); /* global WebGL2RenderingContext */
|
|
|
var _videoTextures = {};
|
|
|
var _canvas;
|
|
|
|
|
@@ -76,6 +75,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
function textureNeedsPowerOfTwo( texture ) {
|
|
|
|
|
|
+ if ( _gl.isWebGL2 ) return false;
|
|
|
+
|
|
|
return ( texture.wrapS !== ClampToEdgeWrapping || texture.wrapT !== ClampToEdgeWrapping ) ||
|
|
|
( texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter );
|
|
|
|
|
@@ -99,6 +100,30 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
}
|
|
|
|
|
|
+ function getInternalFormat( glFormat, glType ) {
|
|
|
+
|
|
|
+ if ( ! _gl.isWebGL2 ) return glFormat;
|
|
|
+
|
|
|
+ if ( glFormat === _gl.RGB ) {
|
|
|
+
|
|
|
+ if ( glType === _gl.FLOAT ) return _gl.RGB32F;
|
|
|
+ if ( glType === _gl.HALF_FLOAT ) return _gl.RGB16F;
|
|
|
+ if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGB8;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( glFormat === _gl.RGBA ) {
|
|
|
+
|
|
|
+ if ( glType === _gl.FLOAT ) return _gl.RGBA32F;
|
|
|
+ if ( glType === _gl.HALF_FLOAT ) return _gl.RGBA16F;
|
|
|
+ if ( glType === _gl.UNSIGNED_BYTE ) return _gl.RGBA8;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ return glFormat;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
// Fallback filters for non-power-of-2 textures
|
|
|
|
|
|
function filterFallback( f ) {
|
|
@@ -293,7 +318,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
var image = cubeImage[ 0 ],
|
|
|
isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
|
glFormat = utils.convert( texture.format ),
|
|
|
- glType = utils.convert( texture.type );
|
|
|
+ glType = utils.convert( texture.type ),
|
|
|
+ glInternalFormat = getInternalFormat( glFormat, glType );
|
|
|
|
|
|
setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
|
|
|
|
|
@@ -303,11 +329,11 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
if ( isDataTexture ) {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
|
|
|
+ state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[ i ].width, cubeImage[ i ].height, 0, glFormat, glType, cubeImage[ i ].data );
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
|
|
|
+ state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[ i ] );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -323,7 +349,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
|
|
- state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
+ state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -333,7 +359,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
+ state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -421,7 +447,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
if ( extension ) {
|
|
|
|
|
|
if ( texture.type === FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
|
|
|
- if ( texture.type === HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
|
|
|
+ if ( texture.type === HalfFloatType && ( _gl.isWebGL2 || extensions.get( 'OES_texture_half_float_linear' ) ) === null ) return;
|
|
|
|
|
|
if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
|
|
|
|
|
@@ -465,7 +491,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
var isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
|
glFormat = utils.convert( texture.format ),
|
|
|
- glType = utils.convert( texture.type );
|
|
|
+ glType = utils.convert( texture.type ),
|
|
|
+ glInternalFormat = getInternalFormat( glFormat, glType );
|
|
|
|
|
|
setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
|
|
|
|
|
@@ -475,21 +502,21 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
// populate depth texture with dummy data
|
|
|
|
|
|
- var internalFormat = _gl.DEPTH_COMPONENT;
|
|
|
+ glInternalFormat = _gl.DEPTH_COMPONENT;
|
|
|
|
|
|
if ( texture.type === FloatType ) {
|
|
|
|
|
|
- if ( ! _isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' );
|
|
|
- internalFormat = _gl.DEPTH_COMPONENT32F;
|
|
|
+ if ( ! _gl.isWebGL2 ) throw new Error( 'Float Depth Texture only supported in WebGL2.0' );
|
|
|
+ glInternalFormat = _gl.DEPTH_COMPONENT32F;
|
|
|
|
|
|
- } else if ( _isWebGL2 ) {
|
|
|
+ } else if ( _gl.isWebGL2 ) {
|
|
|
|
|
|
// WebGL 2.0 requires signed internalformat for glTexImage2D
|
|
|
- internalFormat = _gl.DEPTH_COMPONENT16;
|
|
|
+ glInternalFormat = _gl.DEPTH_COMPONENT16;
|
|
|
|
|
|
}
|
|
|
|
|
|
- if ( texture.format === DepthFormat && internalFormat === _gl.DEPTH_COMPONENT ) {
|
|
|
+ if ( texture.format === DepthFormat && glInternalFormat === _gl.DEPTH_COMPONENT ) {
|
|
|
|
|
|
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
|
|
|
// DEPTH_COMPONENT and type is not UNSIGNED_SHORT or UNSIGNED_INT
|
|
@@ -509,7 +536,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
// (https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/)
|
|
|
if ( texture.format === DepthStencilFormat ) {
|
|
|
|
|
|
- internalFormat = _gl.DEPTH_STENCIL;
|
|
|
+ glInternalFormat = _gl.DEPTH_STENCIL;
|
|
|
|
|
|
// The error INVALID_OPERATION is generated by texImage2D if format and internalformat are
|
|
|
// DEPTH_STENCIL and type is not UNSIGNED_INT_24_8_WEBGL.
|
|
@@ -525,7 +552,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
}
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null );
|
|
|
|
|
|
} else if ( texture.isDataTexture ) {
|
|
|
|
|
@@ -538,7 +565,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
|
|
mipmap = mipmaps[ i ];
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -547,7 +574,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data );
|
|
|
textureProperties.__maxMipLevel = 0;
|
|
|
|
|
|
}
|
|
@@ -562,7 +589,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
|
|
- state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
+ state.compressedTexImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
|
|
} else {
|
|
|
|
|
@@ -572,7 +599,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -593,7 +620,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
|
|
mipmap = mipmaps[ i ];
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap );
|
|
|
|
|
|
}
|
|
|
|
|
@@ -602,7 +629,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
} else {
|
|
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
|
|
|
+ state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image );
|
|
|
textureProperties.__maxMipLevel = 0;
|
|
|
|
|
|
}
|
|
@@ -628,7 +655,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
|
|
|
|
|
|
var glFormat = utils.convert( renderTarget.texture.format );
|
|
|
var glType = utils.convert( renderTarget.texture.type );
|
|
|
- state.texImage2D( textureTarget, 0, glFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
|
+ var glInternalFormat = getInternalFormat( glFormat, glType );
|
|
|
+ state.texImage2D( textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null );
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
|
_gl.framebufferTexture2D( _gl.FRAMEBUFFER, attachment, textureTarget, properties.get( renderTarget.texture ).__webglTexture, 0 );
|
|
|
_gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
|