浏览代码

WebGLTexture: Basic support for gl.texStorage2D(). (#22790)

* WebGLTexture: Basic support for gl.texStorage2D().

* WebGLTextures: Fix bugs.

* Texture: Update docs.

* WebGLTextures: Simplify getMipLevels().

* WebGLTextures: Clean up.
Michael Herzog 3 年之前
父节点
当前提交
deb5a9e7dc
共有 3 个文件被更改,包括 98 次插入4 次删除
  1. 8 2
      docs/api/en/textures/Texture.html
  2. 31 0
      src/renderers/webgl/WebGLState.js
  3. 59 2
      src/renderers/webgl/WebGLTextures.js

+ 8 - 2
docs/api/en/textures/Texture.html

@@ -9,7 +9,13 @@
 	<body>
 	<body>
 		<h1>[name]</h1>
 		<h1>[name]</h1>
 
 
-		<p class="desc">Create a texture to apply to a surface or as a reflection or refraction map.</p>
+		<p class="desc">
+			Create a texture to apply to a surface or as a reflection or refraction map.
+		</p>
+
+		<p>
+			Note: After the initial use of a texture, its dimensions, format, and type cannot be changed. Instead, call [page:.dispose]() on the texture and instantiate a new one.
+		</p>
 
 
 		<h2>Code Example</h2>
 		<h2>Code Example</h2>
 
 
@@ -286,7 +292,7 @@
 
 
 		<h3>[method:undefined dispose]()</h3>
 		<h3>[method:undefined dispose]()</h3>
 		<p>
 		<p>
-		Call [page:EventDispatcher EventDispatcher].dispatchEvent with a 'dispose' event type.
+		Frees the GPU related resources allocated by a texture. Call this method whenever a texture is no longer used in your app.
 		</p>
 		</p>
 
 
 		<h3>[method:Vector2 transformUv]( [param:Vector2 uv] )</h3>
 		<h3>[method:Vector2 transformUv]( [param:Vector2 uv] )</h3>

+ 31 - 0
src/renderers/webgl/WebGLState.js

@@ -879,6 +879,34 @@ function WebGLState( gl, extensions, capabilities ) {
 
 
 	}
 	}
 
 
+	function texSubImage2D() {
+
+		try {
+
+			gl.texSubImage2D.apply( gl, arguments );
+
+		} catch ( error ) {
+
+			console.error( 'THREE.WebGLState:', error );
+
+		}
+
+	}
+
+	function texStorage2D() {
+
+		try {
+
+			gl.texStorage2D.apply( gl, arguments );
+
+		} catch ( error ) {
+
+			console.error( 'THREE.WebGLState:', error );
+
+		}
+
+	}
+
 	function texImage2D() {
 	function texImage2D() {
 
 
 		try {
 		try {
@@ -1057,6 +1085,9 @@ function WebGLState( gl, extensions, capabilities ) {
 		texImage2D: texImage2D,
 		texImage2D: texImage2D,
 		texImage3D: texImage3D,
 		texImage3D: texImage3D,
 
 
+		texStorage2D: texStorage2D,
+		texSubImage2D: texSubImage2D,
+
 		scissor: scissor,
 		scissor: scissor,
 		viewport: viewport,
 		viewport: viewport,
 
 

+ 59 - 2
src/renderers/webgl/WebGLTextures.js

@@ -179,6 +179,30 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 	}
 	}
 
 
+	function getMipLevels( texture, image, supportsMips ) {
+
+		if ( textureNeedsGenerateMipmaps( texture, supportsMips ) === true ) {
+
+			// generated mipmaps via gl.generateMipmap()
+
+			return Math.log2( Math.max( image.width, image.height ) ) + 1;
+
+		} else if ( texture.mipmaps.length > 0 ) {
+
+			// user-defined mipmaps
+
+			return texture.mipmaps.length;
+
+		} else {
+
+			// texture without mipmaps (only base level)
+
+			return 1;
+
+		}
+
+	}
+
 	// Fallback filters for non-power-of-2 textures
 	// Fallback filters for non-power-of-2 textures
 
 
 	function filterFallback( f ) {
 	function filterFallback( f ) {
@@ -680,12 +704,31 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 			// if there are no manual mipmaps
 			// if there are no manual mipmaps
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 			// set 0 level mipmap and then use GL to generate other mipmap levels
 
 
+			const levels = getMipLevels( texture, image, supportsMips );
+			const useTexStorage = ( isWebGL2 && texture.isVideoTexture !== true );
+			const allocateMemory = ( texture.version === 1 );
+
 			if ( mipmaps.length > 0 && supportsMips ) {
 			if ( mipmaps.length > 0 && supportsMips ) {
 
 
+				if ( useTexStorage && allocateMemory ) {
+
+					state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height );
+
+				}
+
 				for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
 				for ( let i = 0, il = mipmaps.length; i < il; i ++ ) {
 
 
 					mipmap = mipmaps[ i ];
 					mipmap = mipmaps[ i ];
-					state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap );
+
+					if ( useTexStorage ) {
+
+						state.texSubImage2D( _gl.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap );
+
+					} else {
+
+						state.texImage2D( _gl.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap );
+
+					}
 
 
 				}
 				}
 
 
@@ -693,7 +736,21 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 
 			} else {
 			} else {
 
 
-				state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image );
+				if ( useTexStorage ) {
+
+					if ( allocateMemory ) {
+
+						state.texStorage2D( _gl.TEXTURE_2D, levels, glInternalFormat, image.width, image.height );
+
+					}
+
+					state.texSubImage2D( _gl.TEXTURE_2D, 0, 0, 0, glFormat, glType, image );
+
+				} else {
+
+					state.texImage2D( _gl.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image );
+
+				}
 
 
 			}
 			}