Home Reference Source Repository

js/base/TextureBank.js

  1. 'use strict'
  2.  
  3. /**
  4. * TextureBank class
  5. * @access public
  6. */
  7. export class TextureBank {
  8. /**
  9. * constructor
  10. * @access public
  11. * @constructor
  12. */
  13. constructor() {
  14. /** @type {WebGLContext} */
  15. this._gl = null
  16.  
  17. /** @type {Map} */
  18. this._textures = new Map()
  19. }
  20.  
  21. setContext(gl) {
  22. this._gl = gl
  23. }
  24.  
  25. getTextureID(canvas) {
  26. if(!(canvas instanceof HTMLCanvasElement)){
  27. return ''
  28. }
  29. if(!canvas._textureID){
  30. const radix = 16
  31. const length = 20
  32. let id = '_'
  33.  
  34. for(let i=0; i<length; i++){
  35. const n = Math.floor(Math.random() * radix)
  36. id += n.toString(radix)
  37. }
  38. canvas._textureID = id
  39. }
  40. //return 'CANVAS:' + canvas._textureID
  41. return `CANVAS:${canvas._textureID}`
  42. }
  43.  
  44. getTexture(textureName){
  45. let key = textureName
  46. if(textureName instanceof HTMLCanvasElement){
  47. key = this.getTextureID(textureName)
  48. }
  49.  
  50. let texture = this._textures.get(key)
  51.  
  52. if(texture === undefined){
  53. texture = this._gl.createTexture()
  54. const orgImage = new Image()
  55. let texImage = null
  56. const gl = this._gl
  57. const obj = this
  58.  
  59. const texCallback = () => {
  60. //gl.enable(gl.TEXTURE_2D)
  61. gl.checkGLError('gl.TEXTURE_2D')
  62. gl.bindTexture(gl.TEXTURE_2D, texture)
  63. gl.checkGLError('gl.bindTexture')
  64. gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texImage)
  65. gl.checkGLError('gl.texImage2D')
  66. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR)
  67. gl.checkGLError('gl.texParameteri: MAG_FILTER')
  68. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)
  69. gl.checkGLError('gl.texParameteri: MIN_FILTER')
  70. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
  71. gl.checkGLError('gl.texParameteri: WRAP_S')
  72. gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
  73. gl.checkGLError('gl.texParameteri: WRAP_T')
  74. gl.generateMipmap(gl.TEXTURE_2D)
  75. gl.checkGLError('gl.generateMipmap')
  76. gl.bindTexture(gl.TEXTURE_2D, null)
  77. gl.checkGLError('gl.bindTexture')
  78. //myAlert('error:' + gl.getError())
  79. }
  80.  
  81. if(textureName instanceof HTMLCanvasElement){
  82. texImage = textureName
  83. texCallback()
  84. }else{
  85. orgImage.onload = () => {
  86. gl.checkGLError('before image.onload')
  87. texImage = obj._createTextureImage(orgImage, texCallback)
  88. }
  89. orgImage.src = textureName
  90. }
  91.  
  92. this._textures.set(key, texture)
  93. }
  94. return texture
  95. }
  96.  
  97. _createTextureImage(orgImage, callback){
  98. // adjust image width/height to powers of 2
  99. const texImage = new Image()
  100.  
  101. let orgWidth = (orgImage.width >> 1)
  102. let texWidth = 1
  103. while(orgWidth > 0){
  104. orgWidth >>= 1
  105. texWidth <<= 1
  106. }
  107.  
  108. let orgHeight = (orgImage.height >> 1)
  109. let texHeight = 1
  110. while(orgHeight > 0){
  111. orgHeight >>= 1
  112. texHeight <<= 1
  113. }
  114.  
  115. // create canvas
  116. const texCanvas = document.createElement('canvas')
  117. texCanvas.width = texWidth
  118. texCanvas.height = texHeight
  119. const texContext = texCanvas.getContext('2d')
  120.  
  121. // drawImage
  122. texContext.drawImage(orgImage, 0, 0, orgImage.width, orgImage.height,
  123. 0, 0, texWidth, texHeight)
  124.  
  125. // createImage from canvas data
  126. if(callback){
  127. texImage.onload = callback
  128. }
  129. texImage.src = texCanvas.toDataURL()
  130.  
  131. return texImage
  132. }
  133. }
  134.  
  135. // for singleton
  136. export default new TextureBank()