|
@@ -78,10 +78,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
this.maxMorphTargets = 8;
|
|
this.maxMorphTargets = 8;
|
|
this.maxMorphNormals = 4;
|
|
this.maxMorphNormals = 4;
|
|
|
|
|
|
- // flags
|
|
|
|
-
|
|
|
|
- this.autoScaleCubemaps = true;
|
|
|
|
-
|
|
|
|
// internal properties
|
|
// internal properties
|
|
|
|
|
|
var _this = this,
|
|
var _this = this,
|
|
@@ -161,13 +157,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// info
|
|
// info
|
|
|
|
|
|
- _infoMemory = {
|
|
|
|
-
|
|
|
|
- geometries: 0,
|
|
|
|
- textures: 0
|
|
|
|
-
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
_infoRender = {
|
|
_infoRender = {
|
|
|
|
|
|
calls: 0,
|
|
calls: 0,
|
|
@@ -180,7 +169,12 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
this.info = {
|
|
this.info = {
|
|
|
|
|
|
render: _infoRender,
|
|
render: _infoRender,
|
|
- memory: _infoMemory,
|
|
|
|
|
|
+ memory: {
|
|
|
|
+
|
|
|
|
+ geometries: 0,
|
|
|
|
+ textures: 0
|
|
|
|
+
|
|
|
|
+ },
|
|
programs: null
|
|
programs: null
|
|
|
|
|
|
};
|
|
};
|
|
@@ -237,7 +231,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- var _isWebGL2 = (typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext);
|
|
|
|
var extensions = new THREE.WebGLExtensions( _gl );
|
|
var extensions = new THREE.WebGLExtensions( _gl );
|
|
|
|
|
|
extensions.get( 'WEBGL_depth_texture' );
|
|
extensions.get( 'WEBGL_depth_texture' );
|
|
@@ -258,6 +251,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
|
|
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
|
|
var properties = new THREE.WebGLProperties();
|
|
var properties = new THREE.WebGLProperties();
|
|
|
|
+ var textures = new THREE.WebGLTextures( _gl, extensions, state, properties, capabilities, paramThreeToGL, this.info );
|
|
var objects = new THREE.WebGLObjects( _gl, properties, this.info );
|
|
var objects = new THREE.WebGLObjects( _gl, properties, this.info );
|
|
var programCache = new THREE.WebGLPrograms( this, capabilities );
|
|
var programCache = new THREE.WebGLPrograms( this, capabilities );
|
|
var lightCache = new THREE.WebGLLights();
|
|
var lightCache = new THREE.WebGLLights();
|
|
@@ -350,31 +344,11 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
- this.getMaxAnisotropy = ( function () {
|
|
|
|
-
|
|
|
|
- var value;
|
|
|
|
-
|
|
|
|
- return function getMaxAnisotropy() {
|
|
|
|
-
|
|
|
|
- if ( value !== undefined ) return value;
|
|
|
|
-
|
|
|
|
- var extension = extensions.get( 'EXT_texture_filter_anisotropic' );
|
|
|
|
-
|
|
|
|
- if ( extension !== null ) {
|
|
|
|
-
|
|
|
|
- value = _gl.getParameter( extension.MAX_TEXTURE_MAX_ANISOTROPY_EXT );
|
|
|
|
|
|
+ this.getMaxAnisotropy = function () {
|
|
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- value = 0;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return value;
|
|
|
|
-
|
|
|
|
- };
|
|
|
|
|
|
+ return capabilities.getMaxAnisotropy();
|
|
|
|
|
|
- } )();
|
|
|
|
|
|
+ };
|
|
|
|
|
|
this.getPrecision = function () {
|
|
this.getPrecision = function () {
|
|
|
|
|
|
@@ -541,31 +515,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function onTextureDispose( event ) {
|
|
|
|
-
|
|
|
|
- var texture = event.target;
|
|
|
|
-
|
|
|
|
- texture.removeEventListener( 'dispose', onTextureDispose );
|
|
|
|
-
|
|
|
|
- deallocateTexture( texture );
|
|
|
|
-
|
|
|
|
- _infoMemory.textures --;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function onRenderTargetDispose( event ) {
|
|
|
|
-
|
|
|
|
- var renderTarget = event.target;
|
|
|
|
-
|
|
|
|
- renderTarget.removeEventListener( 'dispose', onRenderTargetDispose );
|
|
|
|
-
|
|
|
|
- deallocateRenderTarget( renderTarget );
|
|
|
|
-
|
|
|
|
- _infoMemory.textures --;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function onMaterialDispose( event ) {
|
|
function onMaterialDispose( event ) {
|
|
|
|
|
|
var material = event.target;
|
|
var material = event.target;
|
|
@@ -578,71 +527,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
// Buffer deallocation
|
|
// Buffer deallocation
|
|
|
|
|
|
- function deallocateTexture( texture ) {
|
|
|
|
-
|
|
|
|
- var textureProperties = properties.get( texture );
|
|
|
|
-
|
|
|
|
- if ( texture.image && textureProperties.__image__webglTextureCube ) {
|
|
|
|
-
|
|
|
|
- // cube texture
|
|
|
|
-
|
|
|
|
- _gl.deleteTexture( textureProperties.__image__webglTextureCube );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- // 2D texture
|
|
|
|
-
|
|
|
|
- if ( textureProperties.__webglInit === undefined ) return;
|
|
|
|
-
|
|
|
|
- _gl.deleteTexture( textureProperties.__webglTexture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // remove all webgl properties
|
|
|
|
- properties.delete( texture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function deallocateRenderTarget( renderTarget ) {
|
|
|
|
-
|
|
|
|
- var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
- var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
-
|
|
|
|
- if ( ! renderTarget ) return;
|
|
|
|
-
|
|
|
|
- if ( textureProperties.__webglTexture !== undefined ) {
|
|
|
|
-
|
|
|
|
- _gl.deleteTexture( textureProperties.__webglTexture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( renderTarget.depthTexture ) {
|
|
|
|
-
|
|
|
|
- renderTarget.depthTexture.dispose();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( renderTarget instanceof THREE.WebGLRenderTargetCube ) {
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer[ i ] );
|
|
|
|
- if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer[ i ] );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- _gl.deleteFramebuffer( renderTargetProperties.__webglFramebuffer );
|
|
|
|
- if ( renderTargetProperties.__webglDepthbuffer ) _gl.deleteRenderbuffer( renderTargetProperties.__webglDepthbuffer );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- properties.delete( renderTarget.texture );
|
|
|
|
- properties.delete( renderTarget );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
function deallocateMaterial( material ) {
|
|
function deallocateMaterial( material ) {
|
|
|
|
|
|
releaseMaterialProgramReference( material );
|
|
releaseMaterialProgramReference( material );
|
|
@@ -1292,15 +1176,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( renderTarget ) {
|
|
if ( renderTarget ) {
|
|
|
|
|
|
- var texture = renderTarget.texture;
|
|
|
|
-
|
|
|
|
- if ( texture.generateMipmaps && isPowerOfTwo( renderTarget ) &&
|
|
|
|
- texture.minFilter !== THREE.NearestFilter &&
|
|
|
|
- texture.minFilter !== THREE.LinearFilter ) {
|
|
|
|
-
|
|
|
|
- updateRenderTargetMipmap( renderTarget );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+ textures.updateRenderTargetMipmap( renderTarget );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -2499,420 +2375,9 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- function setTextureParameters ( textureType, texture, isPowerOfTwoImage ) {
|
|
|
|
-
|
|
|
|
- var extension;
|
|
|
|
-
|
|
|
|
- if ( isPowerOfTwoImage ) {
|
|
|
|
-
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, paramThreeToGL( texture.wrapS ) );
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, paramThreeToGL( texture.wrapT ) );
|
|
|
|
-
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, paramThreeToGL( texture.magFilter ) );
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, paramThreeToGL( texture.minFilter ) );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
|
|
|
|
-
|
|
|
|
- if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) {
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.wrapS and Texture.wrapT should be set to THREE.ClampToEdgeWrapping.', texture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_MAG_FILTER, filterFallback( texture.magFilter ) );
|
|
|
|
- _gl.texParameteri( textureType, _gl.TEXTURE_MIN_FILTER, filterFallback( texture.minFilter ) );
|
|
|
|
-
|
|
|
|
- if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) {
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter should be set to THREE.NearestFilter or THREE.LinearFilter.', texture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- extension = extensions.get( 'EXT_texture_filter_anisotropic' );
|
|
|
|
-
|
|
|
|
- if ( extension ) {
|
|
|
|
-
|
|
|
|
- if ( texture.type === THREE.FloatType && extensions.get( 'OES_texture_float_linear' ) === null ) return;
|
|
|
|
- if ( texture.type === THREE.HalfFloatType && extensions.get( 'OES_texture_half_float_linear' ) === null ) return;
|
|
|
|
-
|
|
|
|
- if ( texture.anisotropy > 1 || properties.get( texture ).__currentAnisotropy ) {
|
|
|
|
-
|
|
|
|
- _gl.texParameterf( textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT, Math.min( texture.anisotropy, _this.getMaxAnisotropy() ) );
|
|
|
|
- properties.get( texture ).__currentAnisotropy = texture.anisotropy;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function uploadTexture( textureProperties, texture, slot ) {
|
|
|
|
-
|
|
|
|
- if ( textureProperties.__webglInit === undefined ) {
|
|
|
|
-
|
|
|
|
- textureProperties.__webglInit = true;
|
|
|
|
-
|
|
|
|
- texture.addEventListener( 'dispose', onTextureDispose );
|
|
|
|
-
|
|
|
|
- textureProperties.__webglTexture = _gl.createTexture();
|
|
|
|
-
|
|
|
|
- _infoMemory.textures ++;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.activeTexture( _gl.TEXTURE0 + slot );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
-
|
|
|
|
- _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
|
|
|
|
- _gl.pixelStorei( _gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha );
|
|
|
|
- _gl.pixelStorei( _gl.UNPACK_ALIGNMENT, texture.unpackAlignment );
|
|
|
|
-
|
|
|
|
- var image = clampToMaxSize( texture.image, capabilities.maxTextureSize );
|
|
|
|
-
|
|
|
|
- if ( textureNeedsPowerOfTwo( texture ) && isPowerOfTwo( image ) === false ) {
|
|
|
|
-
|
|
|
|
- image = makePowerOfTwo( image );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
|
|
- glFormat = paramThreeToGL( texture.format ),
|
|
|
|
- glType = paramThreeToGL( texture.type );
|
|
|
|
-
|
|
|
|
- setTextureParameters( _gl.TEXTURE_2D, texture, isPowerOfTwoImage );
|
|
|
|
-
|
|
|
|
- var mipmap, mipmaps = texture.mipmaps;
|
|
|
|
-
|
|
|
|
- if ( texture instanceof THREE.DepthTexture ) {
|
|
|
|
-
|
|
|
|
- // populate depth texture with dummy data
|
|
|
|
-
|
|
|
|
- var internalFormat = _gl.DEPTH_COMPONENT;
|
|
|
|
-
|
|
|
|
- if ( texture.type === THREE.FloatType ) {
|
|
|
|
-
|
|
|
|
- if ( !_isWebGL2 ) throw new Error('Float Depth Texture only supported in WebGL2.0');
|
|
|
|
- internalFormat = _gl.DEPTH_COMPONENT32F;
|
|
|
|
-
|
|
|
|
- } else if ( _isWebGL2 ) {
|
|
|
|
-
|
|
|
|
- // WebGL 2.0 requires signed internalformat for glTexImage2D
|
|
|
|
- internalFormat = _gl.DEPTH_COMPONENT16;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, internalFormat, image.width, image.height, 0, glFormat, glType, null );
|
|
|
|
-
|
|
|
|
- } else if ( texture instanceof THREE.DataTexture ) {
|
|
|
|
-
|
|
|
|
- // use manually created mipmaps if available
|
|
|
|
- // if there are no manual mipmaps
|
|
|
|
- // set 0 level mipmap and then use GL to generate other mipmap levels
|
|
|
|
-
|
|
|
|
- if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
|
|
|
|
-
|
|
|
|
- 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 );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- texture.generateMipmaps = false;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, image.width, image.height, 0, glFormat, glType, image.data );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else if ( texture instanceof THREE.CompressedTexture ) {
|
|
|
|
-
|
|
|
|
- for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
-
|
|
|
|
- mipmap = mipmaps[ i ];
|
|
|
|
-
|
|
|
|
- if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
|
|
|
|
-
|
|
|
|
- if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
-
|
|
|
|
- state.compressedTexImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()" );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, i, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- // regular Texture (image, video, canvas)
|
|
|
|
-
|
|
|
|
- // use manually created mipmaps if available
|
|
|
|
- // if there are no manual mipmaps
|
|
|
|
- // set 0 level mipmap and then use GL to generate other mipmap levels
|
|
|
|
-
|
|
|
|
- if ( mipmaps.length > 0 && isPowerOfTwoImage ) {
|
|
|
|
-
|
|
|
|
- for ( var i = 0, il = mipmaps.length; i < il; i ++ ) {
|
|
|
|
-
|
|
|
|
- mipmap = mipmaps[ i ];
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, i, glFormat, glFormat, glType, mipmap );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- texture.generateMipmaps = false;
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_2D, 0, glFormat, glFormat, glType, image );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( texture.generateMipmaps && isPowerOfTwoImage ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
-
|
|
|
|
- textureProperties.__version = texture.version;
|
|
|
|
-
|
|
|
|
- if ( texture.onUpdate ) texture.onUpdate( texture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function setTexture2D( texture, slot ) {
|
|
|
|
-
|
|
|
|
- var textureProperties = properties.get( texture );
|
|
|
|
-
|
|
|
|
- if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
|
|
|
|
-
|
|
|
|
- var image = texture.image;
|
|
|
|
-
|
|
|
|
- if ( image === undefined ) {
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is undefined', texture );
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( image.complete === false ) {
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: Texture marked for update but image is incomplete', texture );
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- uploadTexture( textureProperties, texture, slot );
|
|
|
|
-
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.activeTexture( _gl.TEXTURE0 + slot );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function clampToMaxSize ( image, maxSize ) {
|
|
|
|
-
|
|
|
|
- if ( image.width > maxSize || image.height > maxSize ) {
|
|
|
|
-
|
|
|
|
- // Warning: Scaling through the canvas will only work with images that use
|
|
|
|
- // premultiplied alpha.
|
|
|
|
-
|
|
|
|
- var scale = maxSize / Math.max( image.width, image.height );
|
|
|
|
-
|
|
|
|
- var canvas = document.createElement( 'canvas' );
|
|
|
|
- canvas.width = Math.floor( image.width * scale );
|
|
|
|
- canvas.height = Math.floor( image.height * scale );
|
|
|
|
-
|
|
|
|
- var context = canvas.getContext( '2d' );
|
|
|
|
- context.drawImage( image, 0, 0, image.width, image.height, 0, 0, canvas.width, canvas.height );
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: image is too big (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
|
|
|
|
-
|
|
|
|
- return canvas;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return image;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function isPowerOfTwo( image ) {
|
|
|
|
-
|
|
|
|
- return THREE.Math.isPowerOfTwo( image.width ) && THREE.Math.isPowerOfTwo( image.height );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function textureNeedsPowerOfTwo( texture ) {
|
|
|
|
-
|
|
|
|
- if ( texture.wrapS !== THREE.ClampToEdgeWrapping || texture.wrapT !== THREE.ClampToEdgeWrapping ) return true;
|
|
|
|
- if ( texture.minFilter !== THREE.NearestFilter && texture.minFilter !== THREE.LinearFilter ) return true;
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function makePowerOfTwo( image ) {
|
|
|
|
-
|
|
|
|
- if ( image instanceof HTMLImageElement || image instanceof HTMLCanvasElement ) {
|
|
|
|
-
|
|
|
|
- var canvas = document.createElement( 'canvas' );
|
|
|
|
- canvas.width = THREE.Math.nearestPowerOfTwo( image.width );
|
|
|
|
- canvas.height = THREE.Math.nearestPowerOfTwo( image.height );
|
|
|
|
-
|
|
|
|
- var context = canvas.getContext( '2d' );
|
|
|
|
- context.drawImage( image, 0, 0, canvas.width, canvas.height );
|
|
|
|
-
|
|
|
|
- console.warn( 'THREE.WebGLRenderer: image is not power of two (' + image.width + 'x' + image.height + '). Resized to ' + canvas.width + 'x' + canvas.height, image );
|
|
|
|
-
|
|
|
|
- return canvas;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return image;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function setTextureCube ( texture, slot ) {
|
|
|
|
-
|
|
|
|
- var textureProperties = properties.get( texture );
|
|
|
|
-
|
|
|
|
- if ( texture.image.length === 6 ) {
|
|
|
|
-
|
|
|
|
- if ( texture.version > 0 && textureProperties.__version !== texture.version ) {
|
|
|
|
-
|
|
|
|
- if ( ! textureProperties.__image__webglTextureCube ) {
|
|
|
|
-
|
|
|
|
- texture.addEventListener( 'dispose', onTextureDispose );
|
|
|
|
-
|
|
|
|
- textureProperties.__image__webglTextureCube = _gl.createTexture();
|
|
|
|
-
|
|
|
|
- _infoMemory.textures ++;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- state.activeTexture( _gl.TEXTURE0 + slot );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
|
|
|
|
-
|
|
|
|
- _gl.pixelStorei( _gl.UNPACK_FLIP_Y_WEBGL, texture.flipY );
|
|
|
|
-
|
|
|
|
- var isCompressed = texture instanceof THREE.CompressedTexture;
|
|
|
|
- var isDataTexture = texture.image[ 0 ] instanceof THREE.DataTexture;
|
|
|
|
-
|
|
|
|
- var cubeImage = [];
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- if ( _this.autoScaleCubemaps && ! isCompressed && ! isDataTexture ) {
|
|
|
|
-
|
|
|
|
- cubeImage[ i ] = clampToMaxSize( texture.image[ i ], capabilities.maxCubemapSize );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- cubeImage[ i ] = isDataTexture ? texture.image[ i ].image : texture.image[ i ];
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- var image = cubeImage[ 0 ],
|
|
|
|
- isPowerOfTwoImage = isPowerOfTwo( image ),
|
|
|
|
- glFormat = paramThreeToGL( texture.format ),
|
|
|
|
- glType = paramThreeToGL( texture.type );
|
|
|
|
-
|
|
|
|
- setTextureParameters( _gl.TEXTURE_CUBE_MAP, texture, isPowerOfTwoImage );
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- if ( ! isCompressed ) {
|
|
|
|
-
|
|
|
|
- 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 );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glFormat, glFormat, glType, cubeImage[ i ] );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- var mipmap, mipmaps = cubeImage[ i ].mipmaps;
|
|
|
|
-
|
|
|
|
- for ( var j = 0, jl = mipmaps.length; j < jl; j ++ ) {
|
|
|
|
-
|
|
|
|
- mipmap = mipmaps[ j ];
|
|
|
|
-
|
|
|
|
- if ( texture.format !== THREE.RGBAFormat && texture.format !== THREE.RGBFormat ) {
|
|
|
|
-
|
|
|
|
- if ( state.getCompressedTextureFormats().indexOf( glFormat ) > - 1 ) {
|
|
|
|
-
|
|
|
|
- state.compressedTexImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, mipmap.data );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- console.warn( "THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()" );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.texImage2D( _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( texture.generateMipmaps && isPowerOfTwoImage ) {
|
|
|
|
-
|
|
|
|
- _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- textureProperties.__version = texture.version;
|
|
|
|
-
|
|
|
|
- if ( texture.onUpdate ) texture.onUpdate( texture );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.activeTexture( _gl.TEXTURE0 + slot );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__image__webglTextureCube );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- function setTextureCubeDynamic ( texture, slot ) {
|
|
|
|
-
|
|
|
|
- state.activeTexture( _gl.TEXTURE0 + slot );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, properties.get( texture ).__webglTexture );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
this.allocTextureUnit = allocTextureUnit;
|
|
this.allocTextureUnit = allocTextureUnit;
|
|
|
|
|
|
- //this.setTexture2D = setTexture2D;
|
|
|
|
|
|
+ // this.setTexture2D = setTexture2D;
|
|
this.setTexture2D = ( function() {
|
|
this.setTexture2D = ( function() {
|
|
|
|
|
|
var warned = false;
|
|
var warned = false;
|
|
@@ -2933,7 +2398,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- setTexture2D( texture, slot );
|
|
|
|
|
|
+ textures.setTexture2D( texture, slot );
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
@@ -2952,7 +2417,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
- _this.setTexture2D( texture, slot );
|
|
|
|
|
|
+ textures.setTexture2D( texture, slot );
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
@@ -2986,13 +2451,13 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
// CompressedTexture can have Array in image :/
|
|
// CompressedTexture can have Array in image :/
|
|
|
|
|
|
// this function alone should take care of cube textures
|
|
// this function alone should take care of cube textures
|
|
- setTextureCube( texture, slot );
|
|
|
|
|
|
+ textures.setTextureCube( texture, slot );
|
|
|
|
|
|
} else {
|
|
} else {
|
|
|
|
|
|
// assumed: texture property of THREE.WebGLRenderTargetCube
|
|
// assumed: texture property of THREE.WebGLRenderTargetCube
|
|
|
|
|
|
- setTextureCubeDynamic( texture, slot );
|
|
|
|
|
|
+ textures.setTextureCubeDynamic( texture, slot );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3000,187 +2465,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}() );
|
|
}() );
|
|
|
|
|
|
- // Render targets
|
|
|
|
-
|
|
|
|
- // Setup storage for target texture and bind it to correct framebuffer
|
|
|
|
- function setupFrameBufferTexture ( framebuffer, renderTarget, attachment, textureTarget ) {
|
|
|
|
-
|
|
|
|
- var glFormat = paramThreeToGL( renderTarget.texture.format );
|
|
|
|
- var glType = paramThreeToGL( renderTarget.texture.type );
|
|
|
|
- state.texImage2D( textureTarget, 0, glFormat, 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 );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
|
|
|
|
- function setupRenderBufferStorage ( renderbuffer, renderTarget ) {
|
|
|
|
-
|
|
|
|
- _gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
-
|
|
|
|
- if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
|
|
|
|
-
|
|
|
|
- _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_COMPONENT16, renderTarget.width, renderTarget.height );
|
|
|
|
- _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
-
|
|
|
|
- } else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
|
|
|
|
-
|
|
|
|
- _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
|
|
|
|
- _gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- // FIXME: We don't support !depth !stencil
|
|
|
|
- _gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.RGBA4, renderTarget.width, renderTarget.height );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _gl.bindRenderbuffer( _gl.RENDERBUFFER, null );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Setup resources for a Depth Texture for a FBO (needs an extension)
|
|
|
|
- function setupDepthTexture ( framebuffer, renderTarget ) {
|
|
|
|
-
|
|
|
|
- var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
|
|
|
|
- if ( isCube ) throw new Error('Depth Texture with cube render targets is not supported!');
|
|
|
|
-
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, framebuffer );
|
|
|
|
-
|
|
|
|
- if ( !( renderTarget.depthTexture instanceof THREE.DepthTexture ) ) {
|
|
|
|
-
|
|
|
|
- throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // upload an empty depth texture with framebuffer size
|
|
|
|
- if ( !properties.get( renderTarget.depthTexture ).__webglTexture ||
|
|
|
|
- renderTarget.depthTexture.image.width !== renderTarget.width ||
|
|
|
|
- renderTarget.depthTexture.image.height !== renderTarget.height ) {
|
|
|
|
- renderTarget.depthTexture.image.width = renderTarget.width;
|
|
|
|
- renderTarget.depthTexture.image.height = renderTarget.height;
|
|
|
|
- renderTarget.depthTexture.needsUpdate = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _this.setTexture2D( renderTarget.depthTexture, 0 );
|
|
|
|
-
|
|
|
|
- var webglDepthTexture = properties.get( renderTarget.depthTexture ).__webglTexture;
|
|
|
|
- _gl.framebufferTexture2D( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.TEXTURE_2D, webglDepthTexture, 0 );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Setup GL resources for a non-texture depth buffer
|
|
|
|
- function setupDepthRenderbuffer( renderTarget ) {
|
|
|
|
-
|
|
|
|
- var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
-
|
|
|
|
- var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
|
|
|
|
-
|
|
|
|
- if ( renderTarget.depthTexture ) {
|
|
|
|
-
|
|
|
|
- if ( isCube ) throw new Error('target.depthTexture not supported in Cube render targets');
|
|
|
|
-
|
|
|
|
- setupDepthTexture( renderTargetProperties.__webglFramebuffer, renderTarget );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- if ( isCube ) {
|
|
|
|
-
|
|
|
|
- renderTargetProperties.__webglDepthbuffer = [];
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer[ i ] );
|
|
|
|
- renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
|
|
|
|
- setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, renderTargetProperties.__webglFramebuffer );
|
|
|
|
- renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
|
|
|
|
- setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- _gl.bindFramebuffer( _gl.FRAMEBUFFER, null );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Set up GL resources for the render target
|
|
|
|
- function setupRenderTarget( renderTarget ) {
|
|
|
|
-
|
|
|
|
- var renderTargetProperties = properties.get( renderTarget );
|
|
|
|
- var textureProperties = properties.get( renderTarget.texture );
|
|
|
|
-
|
|
|
|
- renderTarget.addEventListener( 'dispose', onRenderTargetDispose );
|
|
|
|
-
|
|
|
|
- textureProperties.__webglTexture = _gl.createTexture();
|
|
|
|
-
|
|
|
|
- _infoMemory.textures ++;
|
|
|
|
-
|
|
|
|
- var isCube = ( renderTarget instanceof THREE.WebGLRenderTargetCube );
|
|
|
|
- var isTargetPowerOfTwo = THREE.Math.isPowerOfTwo( renderTarget.width ) && THREE.Math.isPowerOfTwo( renderTarget.height );
|
|
|
|
-
|
|
|
|
- // Setup framebuffer
|
|
|
|
-
|
|
|
|
- if ( isCube ) {
|
|
|
|
-
|
|
|
|
- renderTargetProperties.__webglFramebuffer = [];
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- renderTargetProperties.__webglFramebuffer[ i ] = _gl.createFramebuffer();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- renderTargetProperties.__webglFramebuffer = _gl.createFramebuffer();
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Setup color buffer
|
|
|
|
-
|
|
|
|
- if ( isCube ) {
|
|
|
|
-
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, textureProperties.__webglTexture );
|
|
|
|
- setTextureParameters( _gl.TEXTURE_CUBE_MAP, renderTarget.texture, isTargetPowerOfTwo );
|
|
|
|
-
|
|
|
|
- for ( var i = 0; i < 6; i ++ ) {
|
|
|
|
-
|
|
|
|
- setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer[ i ], renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_CUBE_MAP );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_CUBE_MAP, null );
|
|
|
|
-
|
|
|
|
- } else {
|
|
|
|
-
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, textureProperties.__webglTexture );
|
|
|
|
- setTextureParameters( _gl.TEXTURE_2D, renderTarget.texture, isTargetPowerOfTwo );
|
|
|
|
- setupFrameBufferTexture( renderTargetProperties.__webglFramebuffer, renderTarget, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_2D );
|
|
|
|
-
|
|
|
|
- if ( renderTarget.texture.generateMipmaps && isTargetPowerOfTwo ) _gl.generateMipmap( _gl.TEXTURE_2D );
|
|
|
|
- state.bindTexture( _gl.TEXTURE_2D, null );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Setup depth and stencil buffers
|
|
|
|
-
|
|
|
|
- if ( renderTarget.depthBuffer ) {
|
|
|
|
-
|
|
|
|
- setupDepthRenderbuffer( renderTarget );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
this.getCurrentRenderTarget = function() {
|
|
this.getCurrentRenderTarget = function() {
|
|
|
|
|
|
return _currentRenderTarget;
|
|
return _currentRenderTarget;
|
|
@@ -3193,7 +2477,7 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
|
|
if ( renderTarget && properties.get( renderTarget ).__webglFramebuffer === undefined ) {
|
|
|
|
|
|
- setupRenderTarget( renderTarget );
|
|
|
|
|
|
+ textures.setupRenderTarget( renderTarget );
|
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3325,31 +2609,6 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
};
|
|
};
|
|
|
|
|
|
- function updateRenderTargetMipmap( renderTarget ) {
|
|
|
|
-
|
|
|
|
- var target = renderTarget instanceof THREE.WebGLRenderTargetCube ? _gl.TEXTURE_CUBE_MAP : _gl.TEXTURE_2D;
|
|
|
|
- var texture = properties.get( renderTarget.texture ).__webglTexture;
|
|
|
|
-
|
|
|
|
- state.bindTexture( target, texture );
|
|
|
|
- _gl.generateMipmap( target );
|
|
|
|
- state.bindTexture( target, null );
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Fallback filters for non-power-of-2 textures
|
|
|
|
-
|
|
|
|
- function filterFallback ( f ) {
|
|
|
|
-
|
|
|
|
- if ( f === THREE.NearestFilter || f === THREE.NearestMipMapNearestFilter || f === THREE.NearestMipMapLinearFilter ) {
|
|
|
|
-
|
|
|
|
- return _gl.NEAREST;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return _gl.LINEAR;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
// Map three.js constants to WebGL constants
|
|
// Map three.js constants to WebGL constants
|
|
|
|
|
|
function paramThreeToGL ( p ) {
|
|
function paramThreeToGL ( p ) {
|