WebGLAttributes.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. function WebGLAttributes( gl ) {
  2. const buffers = new WeakMap();
  3. function createBuffer( attribute, bufferType ) {
  4. const array = attribute.array;
  5. const usage = attribute.usage;
  6. const size = array.byteLength;
  7. const buffer = gl.createBuffer();
  8. gl.bindBuffer( bufferType, buffer );
  9. gl.bufferData( bufferType, array, usage );
  10. attribute.onUploadCallback();
  11. let type;
  12. if ( array instanceof Float32Array ) {
  13. type = gl.FLOAT;
  14. } else if ( array instanceof Uint16Array ) {
  15. if ( attribute.isFloat16BufferAttribute ) {
  16. type = gl.HALF_FLOAT;
  17. } else {
  18. type = gl.UNSIGNED_SHORT;
  19. }
  20. } else if ( array instanceof Int16Array ) {
  21. type = gl.SHORT;
  22. } else if ( array instanceof Uint32Array ) {
  23. type = gl.UNSIGNED_INT;
  24. } else if ( array instanceof Int32Array ) {
  25. type = gl.INT;
  26. } else if ( array instanceof Int8Array ) {
  27. type = gl.BYTE;
  28. } else if ( array instanceof Uint8Array ) {
  29. type = gl.UNSIGNED_BYTE;
  30. } else if ( array instanceof Uint8ClampedArray ) {
  31. type = gl.UNSIGNED_BYTE;
  32. } else {
  33. throw new Error( 'THREE.WebGLAttributes: Unsupported buffer data format: ' + array );
  34. }
  35. return {
  36. buffer: buffer,
  37. type: type,
  38. bytesPerElement: array.BYTES_PER_ELEMENT,
  39. version: attribute.version,
  40. size: size
  41. };
  42. }
  43. function updateBuffer( buffer, attribute, bufferType ) {
  44. const array = attribute.array;
  45. const updateRange = attribute._updateRange; // @deprecated, r159
  46. const updateRanges = attribute.updateRanges;
  47. gl.bindBuffer( bufferType, buffer );
  48. if ( updateRange.count === - 1 && updateRanges.length === 0 ) {
  49. // Not using update ranges
  50. gl.bufferSubData( bufferType, 0, array );
  51. }
  52. if ( updateRanges.length !== 0 ) {
  53. for ( let i = 0, l = updateRanges.length; i < l; i ++ ) {
  54. const range = updateRanges[ i ];
  55. gl.bufferSubData( bufferType, range.start * array.BYTES_PER_ELEMENT,
  56. array, range.start, range.count );
  57. }
  58. attribute.clearUpdateRanges();
  59. }
  60. // @deprecated, r159
  61. if ( updateRange.count !== - 1 ) {
  62. gl.bufferSubData( bufferType, updateRange.offset * array.BYTES_PER_ELEMENT,
  63. array, updateRange.offset, updateRange.count );
  64. updateRange.count = - 1; // reset range
  65. }
  66. attribute.onUploadCallback();
  67. }
  68. //
  69. function get( attribute ) {
  70. if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
  71. return buffers.get( attribute );
  72. }
  73. function remove( attribute ) {
  74. if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
  75. const data = buffers.get( attribute );
  76. if ( data ) {
  77. gl.deleteBuffer( data.buffer );
  78. buffers.delete( attribute );
  79. }
  80. }
  81. function update( attribute, bufferType ) {
  82. if ( attribute.isGLBufferAttribute ) {
  83. const cached = buffers.get( attribute );
  84. if ( ! cached || cached.version < attribute.version ) {
  85. buffers.set( attribute, {
  86. buffer: attribute.buffer,
  87. type: attribute.type,
  88. bytesPerElement: attribute.elementSize,
  89. version: attribute.version
  90. } );
  91. }
  92. return;
  93. }
  94. if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data;
  95. const data = buffers.get( attribute );
  96. if ( data === undefined ) {
  97. buffers.set( attribute, createBuffer( attribute, bufferType ) );
  98. } else if ( data.version < attribute.version ) {
  99. if ( data.size !== attribute.array.byteLength ) {
  100. throw new Error( 'THREE.WebGLAttributes: The size of the buffer attribute\'s array buffer does not match the original size. Resizing buffer attributes is not supported.' );
  101. }
  102. updateBuffer( data.buffer, attribute, bufferType );
  103. data.version = attribute.version;
  104. }
  105. }
  106. return {
  107. get: get,
  108. remove: remove,
  109. update: update
  110. };
  111. }
  112. export { WebGLAttributes };