buffer.align.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. import { Buffer, VertexBuffer } from "./buffer.js";
  2. const isLittleEndian = (() => {
  3. const array = new Uint8Array(4);
  4. const view = new Uint32Array(array.buffer);
  5. return !!((view[0] = 1) & array[0]);
  6. })();
  7. Object.defineProperty(VertexBuffer.prototype, "effectiveByteStride", {
  8. get: function () {
  9. return (this._alignedBuffer && this._alignedBuffer.byteStride) || this.byteStride;
  10. },
  11. enumerable: true,
  12. configurable: true,
  13. });
  14. Object.defineProperty(VertexBuffer.prototype, "effectiveByteOffset", {
  15. get: function () {
  16. return this._alignedBuffer ? 0 : this.byteOffset;
  17. },
  18. enumerable: true,
  19. configurable: true,
  20. });
  21. Object.defineProperty(VertexBuffer.prototype, "effectiveBuffer", {
  22. get: function () {
  23. return (this._alignedBuffer && this._alignedBuffer.getBuffer()) || this._buffer.getBuffer();
  24. },
  25. enumerable: true,
  26. configurable: true,
  27. });
  28. VertexBuffer.prototype._rebuild = function () {
  29. this._buffer?._rebuild();
  30. this._alignedBuffer?._rebuild();
  31. };
  32. VertexBuffer.prototype.dispose = function () {
  33. if (this._ownsBuffer) {
  34. this._buffer.dispose();
  35. }
  36. this._alignedBuffer?.dispose();
  37. this._alignedBuffer = undefined;
  38. this._isDisposed = true;
  39. };
  40. VertexBuffer.prototype.getWrapperBuffer = function () {
  41. return this._alignedBuffer || this._buffer;
  42. };
  43. VertexBuffer.prototype._alignBuffer = function () {
  44. const data = this._buffer.getData();
  45. if (!this.engine._features.forceVertexBufferStrideAndOffsetMultiple4Bytes || (this.byteStride % 4 === 0 && this.byteOffset % 4 === 0) || !data) {
  46. return;
  47. }
  48. const typeByteLength = VertexBuffer.GetTypeByteLength(this.type);
  49. const alignedByteStride = (this.byteStride + 3) & ~3;
  50. const alignedSize = alignedByteStride / typeByteLength;
  51. const totalVertices = this._maxVerticesCount;
  52. const totalByteLength = totalVertices * alignedByteStride;
  53. const totalLength = totalByteLength / typeByteLength;
  54. let sourceData;
  55. if (Array.isArray(data)) {
  56. const sourceDataAsFloat = new Float32Array(data);
  57. sourceData = new DataView(sourceDataAsFloat.buffer, sourceDataAsFloat.byteOffset, sourceDataAsFloat.byteLength);
  58. }
  59. else if (data instanceof ArrayBuffer) {
  60. sourceData = new DataView(data, 0, data.byteLength);
  61. }
  62. else {
  63. sourceData = new DataView(data.buffer, data.byteOffset, data.byteLength);
  64. }
  65. let alignedData;
  66. if (this.type === VertexBuffer.BYTE) {
  67. alignedData = new Int8Array(totalLength);
  68. }
  69. else if (this.type === VertexBuffer.UNSIGNED_BYTE) {
  70. alignedData = new Uint8Array(totalLength);
  71. }
  72. else if (this.type === VertexBuffer.SHORT) {
  73. alignedData = new Int16Array(totalLength);
  74. }
  75. else if (this.type === VertexBuffer.UNSIGNED_SHORT) {
  76. alignedData = new Uint16Array(totalLength);
  77. }
  78. else if (this.type === VertexBuffer.INT) {
  79. alignedData = new Int32Array(totalLength);
  80. }
  81. else if (this.type === VertexBuffer.UNSIGNED_INT) {
  82. alignedData = new Uint32Array(totalLength);
  83. }
  84. else {
  85. alignedData = new Float32Array(totalLength);
  86. }
  87. const numComponents = this.getSize();
  88. let sourceOffset = this.byteOffset;
  89. for (let i = 0; i < totalVertices; ++i) {
  90. for (let j = 0; j < numComponents; ++j) {
  91. switch (this.type) {
  92. case VertexBuffer.BYTE:
  93. alignedData[i * alignedSize + j] = sourceData.getInt8(sourceOffset + j);
  94. break;
  95. case VertexBuffer.UNSIGNED_BYTE:
  96. alignedData[i * alignedSize + j] = sourceData.getUint8(sourceOffset + j);
  97. break;
  98. case VertexBuffer.SHORT:
  99. alignedData[i * alignedSize + j] = sourceData.getInt16(sourceOffset + j * 2, isLittleEndian);
  100. break;
  101. case VertexBuffer.UNSIGNED_SHORT:
  102. alignedData[i * alignedSize + j] = sourceData.getUint16(sourceOffset + j * 2, isLittleEndian);
  103. break;
  104. case VertexBuffer.INT:
  105. alignedData[i * alignedSize + j] = sourceData.getInt32(sourceOffset + j * 4, isLittleEndian);
  106. break;
  107. case VertexBuffer.UNSIGNED_INT:
  108. alignedData[i * alignedSize + j] = sourceData.getUint32(sourceOffset + j * 4, isLittleEndian);
  109. break;
  110. case VertexBuffer.FLOAT:
  111. alignedData[i * alignedSize + j] = sourceData.getFloat32(sourceOffset + j * 4, isLittleEndian);
  112. break;
  113. }
  114. }
  115. sourceOffset += this.byteStride;
  116. }
  117. this._alignedBuffer?.dispose();
  118. this._alignedBuffer = new Buffer(this.engine, alignedData, false, alignedByteStride, false, this.getIsInstanced(), true, this.instanceDivisor, (this._label ?? "VertexBuffer") + "_aligned");
  119. };
  120. //# sourceMappingURL=buffer.align.js.map