engine.readTexture.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { ThinEngine } from "../../Engines/thinEngine.js";
  2. /**
  3. * Allocate a typed array depending on a texture type. Optionally can copy existing data in the buffer.
  4. * @param type type of the texture
  5. * @param sizeOrDstBuffer size of the array OR an existing buffer that will be used as the destination of the copy (if copyBuffer is provided)
  6. * @param sizeInBytes true if the size of the array is given in bytes, false if it is the number of elements of the array
  7. * @param copyBuffer if provided, buffer to copy into the destination buffer (either a newly allocated buffer if sizeOrDstBuffer is a number or use sizeOrDstBuffer as the destination buffer otherwise)
  8. * @returns the allocated buffer or sizeOrDstBuffer if the latter is an ArrayBuffer
  9. */
  10. export function allocateAndCopyTypedBuffer(type, sizeOrDstBuffer, sizeInBytes = false, copyBuffer) {
  11. switch (type) {
  12. case 3: {
  13. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Int8Array(sizeOrDstBuffer) : new Int8Array(sizeOrDstBuffer);
  14. if (copyBuffer) {
  15. buffer.set(new Int8Array(copyBuffer));
  16. }
  17. return buffer;
  18. }
  19. case 0: {
  20. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Uint8Array(sizeOrDstBuffer) : new Uint8Array(sizeOrDstBuffer);
  21. if (copyBuffer) {
  22. buffer.set(new Uint8Array(copyBuffer));
  23. }
  24. return buffer;
  25. }
  26. case 4: {
  27. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Int16Array(sizeOrDstBuffer) : new Int16Array(sizeInBytes ? sizeOrDstBuffer / 2 : sizeOrDstBuffer);
  28. if (copyBuffer) {
  29. buffer.set(new Int16Array(copyBuffer));
  30. }
  31. return buffer;
  32. }
  33. case 5:
  34. case 8:
  35. case 9:
  36. case 10:
  37. case 2: {
  38. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Uint16Array(sizeOrDstBuffer) : new Uint16Array(sizeInBytes ? sizeOrDstBuffer / 2 : sizeOrDstBuffer);
  39. if (copyBuffer) {
  40. buffer.set(new Uint16Array(copyBuffer));
  41. }
  42. return buffer;
  43. }
  44. case 6: {
  45. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Int32Array(sizeOrDstBuffer) : new Int32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);
  46. if (copyBuffer) {
  47. buffer.set(new Int32Array(copyBuffer));
  48. }
  49. return buffer;
  50. }
  51. case 7:
  52. case 11:
  53. case 12:
  54. case 13:
  55. case 14:
  56. case 15: {
  57. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Uint32Array(sizeOrDstBuffer) : new Uint32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);
  58. if (copyBuffer) {
  59. buffer.set(new Uint32Array(copyBuffer));
  60. }
  61. return buffer;
  62. }
  63. case 1: {
  64. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Float32Array(sizeOrDstBuffer) : new Float32Array(sizeInBytes ? sizeOrDstBuffer / 4 : sizeOrDstBuffer);
  65. if (copyBuffer) {
  66. buffer.set(new Float32Array(copyBuffer));
  67. }
  68. return buffer;
  69. }
  70. }
  71. const buffer = sizeOrDstBuffer instanceof ArrayBuffer ? new Uint8Array(sizeOrDstBuffer) : new Uint8Array(sizeOrDstBuffer);
  72. if (copyBuffer) {
  73. buffer.set(new Uint8Array(copyBuffer));
  74. }
  75. return buffer;
  76. }
  77. ThinEngine.prototype._readTexturePixelsSync = function (texture, width, height, faceIndex = -1, level = 0, buffer = null, flushRenderer = true, noDataConversion = false, x = 0, y = 0) {
  78. const gl = this._gl;
  79. if (!gl) {
  80. throw new Error("Engine does not have gl rendering context.");
  81. }
  82. if (!this._dummyFramebuffer) {
  83. const dummy = gl.createFramebuffer();
  84. if (!dummy) {
  85. throw new Error("Unable to create dummy framebuffer");
  86. }
  87. this._dummyFramebuffer = dummy;
  88. }
  89. gl.bindFramebuffer(gl.FRAMEBUFFER, this._dummyFramebuffer);
  90. if (faceIndex > -1) {
  91. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, texture._hardwareTexture?.underlyingResource, level);
  92. }
  93. else {
  94. gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture._hardwareTexture?.underlyingResource, level);
  95. }
  96. let readType = texture.type !== undefined ? this._getWebGLTextureType(texture.type) : gl.UNSIGNED_BYTE;
  97. if (!noDataConversion) {
  98. switch (readType) {
  99. case gl.UNSIGNED_BYTE:
  100. if (!buffer) {
  101. buffer = new Uint8Array(4 * width * height);
  102. }
  103. readType = gl.UNSIGNED_BYTE;
  104. break;
  105. default:
  106. if (!buffer) {
  107. buffer = new Float32Array(4 * width * height);
  108. }
  109. readType = gl.FLOAT;
  110. break;
  111. }
  112. }
  113. else if (!buffer) {
  114. buffer = allocateAndCopyTypedBuffer(texture.type, 4 * width * height);
  115. }
  116. if (flushRenderer) {
  117. this.flushFramebuffer();
  118. }
  119. gl.readPixels(x, y, width, height, gl.RGBA, readType, buffer);
  120. gl.bindFramebuffer(gl.FRAMEBUFFER, this._currentFramebuffer);
  121. return buffer;
  122. };
  123. ThinEngine.prototype._readTexturePixels = function (texture, width, height, faceIndex = -1, level = 0, buffer = null, flushRenderer = true, noDataConversion = false, x = 0, y = 0) {
  124. return Promise.resolve(this._readTexturePixelsSync(texture, width, height, faceIndex, level, buffer, flushRenderer, noDataConversion, x, y));
  125. };
  126. //# sourceMappingURL=engine.readTexture.js.map