From 4489ce9cedbc1c1a2cd5f5aea0e0e01582b5b430 Mon Sep 17 00:00:00 2001 From: aardgoose Date: Fri, 3 Nov 2023 16:37:24 +0000 Subject: [PATCH] first pass --- examples/jsm/renderers/webgl/WebGLBackend.js | 6 ++ .../webgl/utils/WebGLAttributeUtils.js | 72 +++++++++++++++++++ 2 files changed, 78 insertions(+) diff --git a/examples/jsm/renderers/webgl/WebGLBackend.js b/examples/jsm/renderers/webgl/WebGLBackend.js index 1f72606d4f0371..3dcf31ce399a5c 100644 --- a/examples/jsm/renderers/webgl/WebGLBackend.js +++ b/examples/jsm/renderers/webgl/WebGLBackend.js @@ -51,6 +51,12 @@ class WebGLBackend extends Backend { } + async getArrayBufferAsync( attribute ) { + + return await this.attributeUtils.getArrayBufferAsync( attribute ); + + } + beginRender( renderContext ) { const { gl } = this; diff --git a/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js b/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js index 7372b3dfe7b20d..9f925ba7438080 100644 --- a/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js +++ b/examples/jsm/renderers/webgl/utils/WebGLAttributeUtils.js @@ -1,3 +1,5 @@ +import { arrayBuffer } from "../../../nodes/Nodes"; + class WebGLAttributeUtils { constructor( backend ) { @@ -114,6 +116,76 @@ class WebGLAttributeUtils { } + async getArrayBufferAsync( attribute ) { + + const bufferAttribute = attribute.isInterleavedBufferAttribute ? attribute.data : attribute; + const { bufferType, bufferGPU, bytesPerElement } = backend.get( bufferAttribute ); + + const length = attribute.array.length * bytesPerElement; + + gl.bindBuffer( bufferType, bufferGPU ); + + const writeBuffer = gl.createBuffer(); + + gl.bindBuffer(gl.COPY_WRITE_BUFFER, writeBuffer ); + gl.bufferData(gl.COPY_WRITE_BUFFER, dest.byteLength, gl.STREAM_READ); + + gl.copyBufferSubData( bufferType, gl.COPY_WRITE_BUFFER, 0, 0, length ); + + await this._clientWaitAsync(); + + const dstBuffer = new attribute.array.constructor( length ); + + gl.getBufferSubData( gl.COPY_WRITE_BUFFER, 0, dstBuffer ); + + gl.deleteBuffer( writeBuffer ); + + return dstBuffer; + + } + + _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 WebGLAttributeUtils;