import { BUFFER_FORMAT } from "../constants" ; import { Renderer } from "../Renderer" ; export interface IBufferOptions { name ? : string ; format : BUFFER_FORMAT ; byteLength : number ; } export const BUFFER_DEFAULT_OPTIONS = { name : null , format : BUFFER_FORMAT . NONE , byteLength : 0 , } ; export interface IBufferUpdate { offset : number ; data : ArrayBufferView ; } export class Buffer { private _name : string = null ; private _format : BUFFER_FORMAT = BUFFER_FORMAT . NONE ; private _byteLength : number = 0 ; private _updateQueue : IBufferUpdate [ ] = [ ] ; private _resource : GPUBuffer = null ; param options public constructor ( options ? ) { options = Object . assign ( { } , BUFFER_DEFAULT_OPTIONS , options ) ; this . setName ( options . name ) ; this . _format = options . format ; this . _byteLength = options . byteLength ; } /**
     * The buffer name
     */ public getName ( ) { return this . _name ; } param value public setName ( value ) { this . _name = value ; } /**
     * The buffer format
     */ public getFormat ( ) { return this . _format ; } /**
     * The byte length of the buffer
     */ public getByteLength ( ) { return this . _byteLength ; } /**
     * The GPU buffer resource
     */ public getResource ( ) { return this . _resource ; } param renderer param descriptor public create ( renderer , descriptor ) { if ( this . _resource === null ) { const device = renderer . getDevice ( ) ; const instance = device . createBuffer ( descriptor ) ; this . _resource = instance ; } } param data param startByteOffset public setSubData ( data , startByteOffset = 0x0 ) { if ( ! ( ArrayBuffer . isView ( data ) ) ) { throw new TypeError ( `Parameter 'data' must be an ArrayBufferView` ) ; } if ( startByteOffset < 0 ) { throw new RangeError ( `Parameter 'startByteOffset' must be a positive number` ) ; } if ( startByteOffset + data . byteLength > this . getByteLength ( ) ) { throw new RangeError ( `Data copy overflows the byte length of the buffer` ) ; } this . _updateQueue . push ( { offset : startByteOffset , data } ) ; } /**
     * Update this buffer
     */ public update ( renderer ) { const queue = renderer . getDevice ( ) . defaultQueue ; const updateQueue = this . _updateQueue ; const resource = this . getResource ( ) ; if ( resource !== null ) { for ( let ii = 0 ; ii < updateQueue . length ; ++ ii ) { const { offset , data } = updateQueue [ ii ] ; queue . writeBuffer ( resource , offset , data ) ; updateQueue . splice ( ii -- , 1 ) ; } } } /**
     * Destroy this Object
     */ public destroy ( ) { this . _name = null ; this . _resource = null ; } }