2
0
Эх сурвалжийг харах

WebGPURenderer: support getArrayBufferAsync() for WebGL backend (#27355)

* read buffer async

* return ArrayBuffer

---------

Co-authored-by: aardgoose <[email protected]>
aardgoose 1 жил өмнө
parent
commit
fff4f00482

+ 6 - 0
examples/jsm/renderers/webgl/WebGLBackend.js

@@ -53,6 +53,12 @@ class WebGLBackend extends Backend {
 
 	}
 
+	async getArrayBufferAsync( attribute ) {
+
+		return await this.attributeUtils.getArrayBufferAsync( attribute );
+
+	}
+
 	beginRender( renderContext ) {
 
 		const { gl } = this;

+ 32 - 0
examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js

@@ -134,6 +134,38 @@ class WebGLAttributeUtils {
 
 	}
 
+	async getArrayBufferAsync( attribute ) {
+
+		const backend = this.backend;
+		const { gl } = backend;
+
+		const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute;
+		const { bufferGPU } = backend.get( bufferAttribute );
+
+		const array = attribute.array;
+		const byteLength = array.byteLength;
+
+		gl.bindBuffer( gl.COPY_READ_BUFFER, bufferGPU );
+
+		const writeBuffer = gl.createBuffer();
+
+		gl.bindBuffer( gl.COPY_WRITE_BUFFER, writeBuffer );
+		gl.bufferData( gl.COPY_WRITE_BUFFER, byteLength, gl.STREAM_READ );
+
+		gl.copyBufferSubData( gl.COPY_READ_BUFFER, gl.COPY_WRITE_BUFFER, 0, 0, byteLength );
+
+		await backend.utils._clientWaitAsync();
+
+		const dstBuffer = new attribute.array.constructor( array.length );
+
+		gl.getBufferSubData( gl.COPY_WRITE_BUFFER, 0, dstBuffer );
+
+		gl.deleteBuffer( writeBuffer );
+
+		return dstBuffer.buffer;
+
+	}
+
 }
 
 export default WebGLAttributeUtils;

+ 2 - 42
examples/jsm/renderers/webgl/utils/WebGLTextureUtils.js

@@ -213,7 +213,7 @@ class WebGLTextureUtils {
 
 	async copyTextureToBuffer( texture, x, y, width, height ) {
 
-		const { gl } = this;
+		const { backend, gl } = this;
 
 		const { textureGPU, glFormat, glType } = this.backend.get( texture );
 
@@ -235,13 +235,7 @@ class WebGLTextureUtils {
 		gl.readPixels( x, y, width, height, glFormat, glType, 0 );
 		gl.bindBuffer( gl.PIXEL_PACK_BUFFER, null );
 
-		const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
-
-		gl.flush();
-
-		await this._clientWaitAsync( sync );
-
-		gl.deleteSync( sync );
+		await backend.utils._clientWaitAsync();
 
 		const dstBuffer = new typedArrayType( elementCount );
 
@@ -280,40 +274,6 @@ class WebGLTextureUtils {
 
 	}
 
-	_clientWaitAsync( sync ) {
-
-		const { gl } = this;
-
-		return new Promise( ( resolve, reject ) => {
-
-			function test() {
-
-				const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );
-
-				if ( res === gl.WAIT_FAILED) {
-
-					reject();
-					return;
-
-				}
-
-				if ( res === gl.TIMEOUT_EXPIRED) {
-
-					requestAnimationFrame( test );
-					return;
-
-				}
-
-				resolve();
-
-			}
-
-			test();
-
-		} );
-
-	}
-
 }
 
 export default WebGLTextureUtils;

+ 42 - 0
examples/jsm/renderers/webgl/utils/WebGLUtils.js

@@ -237,6 +237,48 @@ class WebGLUtils {
 
 	}
 
+	_clientWaitAsync() {
+
+		const { gl } = this;
+
+		const sync = gl.fenceSync( gl.SYNC_GPU_COMMANDS_COMPLETE, 0 );
+
+		gl.flush();
+
+		return new Promise( ( resolve, reject ) => {
+
+			function test() {
+
+				const res = gl.clientWaitSync( sync, gl.SYNC_FLUSH_COMMANDS_BIT, 0 );
+
+				if ( res === gl.WAIT_FAILED) {
+
+					gl.deleteSync( sync );
+
+					reject();
+					return;
+
+				}
+
+				if ( res === gl.TIMEOUT_EXPIRED) {
+
+					requestAnimationFrame( test );
+					return;
+
+				}
+
+				gl.deleteSync( sync );
+
+				resolve();
+
+			}
+
+			test();
+
+		} );
+
+	}
+
 }
 
 export default WebGLUtils;