You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DDSTexture.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. const NOCOMPRESSED_RGB565 = 0x111
  2. const NOCOMPRESSED_RGBA = 0x1111
  3. const NOCOMPRESSED_LA = 6410
  4. const { Cesium } = DC.Namespace
  5. function DDSTexture(context, id, options) {
  6. let gl = context._gl
  7. this.contextId = context.id
  8. this.textureId = id
  9. this.layerId = options.layerId
  10. this.rootName = options.rootName
  11. this.context = context
  12. this.width = options.width
  13. this.height = options.height
  14. this.compressType = options.compressType
  15. this.internalFormat = options.internalFormat
  16. this.pixelFormat = options.pixelFormat
  17. this.arrayBufferView = options.arrayBufferView
  18. this.wrapS = Cesium.defaultValue(
  19. options.wrapS,
  20. Cesium.TextureWrap.CLAMP_TO_EDGE
  21. )
  22. this.wrapT = Cesium.defaultValue(
  23. options.wrapT,
  24. Cesium.TextureWrap.CLAMP_TO_EDGE
  25. )
  26. this._target = gl.TEXTURE_2D
  27. this._texture = undefined
  28. this.refCount = 1
  29. if (this.arrayBufferView) {
  30. this.init()
  31. }
  32. }
  33. DDSTexture.prototype.init = function() {
  34. let gl = this.context._gl
  35. if (!this._texture) {
  36. this._texture = gl.createTexture()
  37. }
  38. gl.bindTexture(gl.TEXTURE_2D, this._texture)
  39. let internalFormat = this.internalFormat
  40. if (
  41. internalFormat === NOCOMPRESSED_LA ||
  42. internalFormat === NOCOMPRESSED_RGBA
  43. ) {
  44. gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true)
  45. }
  46. let i = 0
  47. let offset = 0
  48. let texWidth = this.width
  49. let texHeight = this.height
  50. let bMipMap = validateMipmap(
  51. this.arrayBufferView,
  52. internalFormat,
  53. texWidth,
  54. texHeight
  55. )
  56. do {
  57. let levelSize = Cesium.PixelFormat.compressedTextureSizeInBytes(
  58. internalFormat,
  59. texWidth,
  60. texHeight
  61. )
  62. let subArrayBuffer = new Uint8Array(
  63. this.arrayBufferView.buffer,
  64. this.arrayBufferView.byteOffset + offset,
  65. levelSize
  66. )
  67. if (internalFormat === NOCOMPRESSED_RGBA) {
  68. gl.texImage2D(
  69. gl.TEXTURE_2D,
  70. i++,
  71. gl.RGBA,
  72. texWidth,
  73. texHeight,
  74. 0,
  75. gl.RGBA,
  76. gl.UNSIGNED_BYTE,
  77. subArrayBuffer
  78. )
  79. } else {
  80. gl.compressedTexImage2D(
  81. gl.TEXTURE_2D,
  82. i++,
  83. internalFormat,
  84. texWidth,
  85. texHeight,
  86. 0,
  87. subArrayBuffer
  88. )
  89. }
  90. texWidth = Math.max(texWidth >> 1, 1)
  91. texHeight = Math.max(texHeight >> 1, 1)
  92. offset += levelSize
  93. } while (offset < this.arrayBufferView.byteLength && bMipMap)
  94. if (i > 1) {
  95. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
  96. gl.texParameteri(
  97. gl.TEXTURE_2D,
  98. gl.TEXTURE_MIN_FILTER,
  99. gl.LINEAR_MIPMAP_LINEAR
  100. )
  101. } else {
  102. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
  103. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  104. }
  105. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, this.wrapS)
  106. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, this.wrapT)
  107. gl.texParameteri(
  108. this._target,
  109. this.context._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,
  110. 1
  111. )
  112. gl.bindTexture(gl.TEXTURE_2D, null)
  113. this.arrayBufferView = undefined
  114. this.ready = true
  115. }
  116. function validateMipmap(buffer, pixelFormat, width, height) {
  117. let len = buffer.length
  118. let w = width,
  119. h = height
  120. let totalBytes = 0
  121. while (1) {
  122. let sizeInBytes = Cesium.PixelFormat.compressedTextureSizeInBytes(
  123. pixelFormat,
  124. w,
  125. h
  126. )
  127. totalBytes += sizeInBytes
  128. w = w >> 1
  129. h = h >> 1
  130. if (w === 0 && h === 0) {
  131. break
  132. }
  133. w = Math.max(w, 1)
  134. h = Math.max(h, 1)
  135. }
  136. return totalBytes === len
  137. }
  138. DDSTexture.prototype.isDestroyed = function() {
  139. return false
  140. }
  141. DDSTexture.prototype.destroy = function() {
  142. let gl = this.context._gl
  143. gl.deleteTexture(this._texture)
  144. this._texture = null
  145. this.id = 0
  146. Cesium.destroyObject(this)
  147. }
  148. export default DDSTexture