Spaces:
Running
Running
| function WebGLAttributes(gl, capabilities) { | |
| const isWebGL2 = capabilities.isWebGL2; | |
| const buffers = new WeakMap(); | |
| function createBuffer(attribute, bufferType) { | |
| const array = attribute.array; | |
| const usage = attribute.usage; | |
| const buffer = gl.createBuffer(); | |
| gl.bindBuffer(bufferType, buffer); | |
| gl.bufferData(bufferType, array, usage); | |
| attribute.onUploadCallback(); | |
| let type = gl.FLOAT; | |
| if (array instanceof Float32Array) { | |
| type = gl.FLOAT; | |
| } else if (array instanceof Float64Array) { | |
| console.warn('THREE.WebGLAttributes: Unsupported data buffer format: Float64Array.'); | |
| } else if (array instanceof Uint16Array) { | |
| if (attribute.isFloat16BufferAttribute) { | |
| if (isWebGL2) { | |
| type = gl.HALF_FLOAT; | |
| } else { | |
| console.warn('THREE.WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.'); | |
| } | |
| } else { | |
| type = gl.UNSIGNED_SHORT; | |
| } | |
| } else if (array instanceof Int16Array) { | |
| type = gl.SHORT; | |
| } else if (array instanceof Uint32Array) { | |
| type = gl.UNSIGNED_INT; | |
| } else if (array instanceof Int32Array) { | |
| type = gl.INT; | |
| } else if (array instanceof Int8Array) { | |
| type = gl.BYTE; | |
| } else if (array instanceof Uint8Array) { | |
| type = gl.UNSIGNED_BYTE; | |
| } else if (array instanceof Uint8ClampedArray) { | |
| type = gl.UNSIGNED_BYTE; | |
| } | |
| return { | |
| buffer: buffer, | |
| type: type, | |
| bytesPerElement: array.BYTES_PER_ELEMENT, | |
| version: attribute.version, | |
| }; | |
| } | |
| function updateBuffer(buffer, attribute, bufferType) { | |
| const array = attribute.array; | |
| const updateRange = attribute.updateRange; | |
| gl.bindBuffer(bufferType, buffer); | |
| if (updateRange.count === -1) { | |
| // Not using update ranges | |
| gl.bufferSubData(bufferType, 0, array); | |
| } else { | |
| if (isWebGL2) { | |
| gl.bufferSubData(bufferType, updateRange.offset * array.BYTES_PER_ELEMENT, array, updateRange.offset, updateRange.count); | |
| } else { | |
| gl.bufferSubData( | |
| bufferType, | |
| updateRange.offset * array.BYTES_PER_ELEMENT, | |
| array.subarray(updateRange.offset, updateRange.offset + updateRange.count) | |
| ); | |
| } | |
| updateRange.count = -1; // reset range | |
| } | |
| } | |
| // | |
| function get(attribute) { | |
| if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; | |
| return buffers.get(attribute); | |
| } | |
| function remove(attribute) { | |
| if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; | |
| const data = buffers.get(attribute); | |
| if (data) { | |
| gl.deleteBuffer(data.buffer); | |
| buffers.delete(attribute); | |
| } | |
| } | |
| function update(attribute, bufferType) { | |
| if (attribute.isGLBufferAttribute) { | |
| const cached = buffers.get(attribute); | |
| if (!cached || cached.version < attribute.version) { | |
| buffers.set(attribute, { | |
| buffer: attribute.buffer, | |
| type: attribute.type, | |
| bytesPerElement: attribute.elementSize, | |
| version: attribute.version, | |
| }); | |
| } | |
| return; | |
| } | |
| if (attribute.isInterleavedBufferAttribute) attribute = attribute.data; | |
| const data = buffers.get(attribute); | |
| if (data === undefined) { | |
| buffers.set(attribute, createBuffer(attribute, bufferType)); | |
| } else if (data.version < attribute.version) { | |
| updateBuffer(data.buffer, attribute, bufferType); | |
| data.version = attribute.version; | |
| } | |
| } | |
| return { | |
| get: get, | |
| remove: remove, | |
| update: update, | |
| }; | |
| } | |
| export { WebGLAttributes }; | |