Source: extras/webgl/TilingSpriteRenderer.js

extras/webgl/TilingSpriteRenderer.js

  1. import * as core from '../../core';
  2. import { WRAP_MODES } from '../../core/const';
  3. import { readFileSync } from 'fs';
  4. import { join } from 'path';
  5. const tempMat = new core.Matrix();
  6. /**
  7. * WebGL renderer plugin for tiling sprites
  8. *
  9. * @class
  10. * @memberof PIXI.extras
  11. * @extends PIXI.ObjectRenderer
  12. */
  13. export default class TilingSpriteRenderer extends core.ObjectRenderer
  14. {
  15. /**
  16. * constructor for renderer
  17. *
  18. * @param {WebGLRenderer} renderer The renderer this tiling awesomeness works for.
  19. */
  20. constructor(renderer)
  21. {
  22. super(renderer);
  23. this.shader = null;
  24. this.simpleShader = null;
  25. this.quad = null;
  26. }
  27. /**
  28. * Sets up the renderer context and necessary buffers.
  29. *
  30. * @private
  31. */
  32. onContextChange()
  33. {
  34. const gl = this.renderer.gl;
  35. this.shader = new core.Shader(gl,
  36. readFileSync(join(__dirname, './tilingSprite.vert'), 'utf8'),
  37. readFileSync(join(__dirname, './tilingSprite.frag'), 'utf8'));
  38. this.simpleShader = new core.Shader(gl,
  39. readFileSync(join(__dirname, './tilingSprite.vert'), 'utf8'),
  40. readFileSync(join(__dirname, './tilingSprite_simple.frag'), 'utf8'));
  41. this.renderer.bindVao(null);
  42. this.quad = new core.Quad(gl, this.renderer.state.attribState);
  43. this.quad.initVao(this.shader);
  44. }
  45. /**
  46. *
  47. * @param {PIXI.extras.TilingSprite} ts tilingSprite to be rendered
  48. */
  49. render(ts)
  50. {
  51. const renderer = this.renderer;
  52. const quad = this.quad;
  53. renderer.bindVao(quad.vao);
  54. let vertices = quad.vertices;
  55. vertices[0] = vertices[6] = (ts._width) * -ts.anchor.x;
  56. vertices[1] = vertices[3] = ts._height * -ts.anchor.y;
  57. vertices[2] = vertices[4] = (ts._width) * (1.0 - ts.anchor.x);
  58. vertices[5] = vertices[7] = ts._height * (1.0 - ts.anchor.y);
  59. if (ts.uvRespectAnchor)
  60. {
  61. vertices = quad.uvs;
  62. vertices[0] = vertices[6] = -ts.anchor.x;
  63. vertices[1] = vertices[3] = -ts.anchor.y;
  64. vertices[2] = vertices[4] = 1.0 - ts.anchor.x;
  65. vertices[5] = vertices[7] = 1.0 - ts.anchor.y;
  66. }
  67. quad.upload();
  68. const tex = ts._texture;
  69. const baseTex = tex.baseTexture;
  70. const lt = ts.tileTransform.localTransform;
  71. const uv = ts.uvTransform;
  72. let isSimple = baseTex.isPowerOfTwo
  73. && tex.frame.width === baseTex.width && tex.frame.height === baseTex.height;
  74. // auto, force repeat wrapMode for big tiling textures
  75. if (isSimple)
  76. {
  77. if (!baseTex._glTextures[renderer.CONTEXT_UID])
  78. {
  79. if (baseTex.wrapMode === WRAP_MODES.CLAMP)
  80. {
  81. baseTex.wrapMode = WRAP_MODES.REPEAT;
  82. }
  83. }
  84. else
  85. {
  86. isSimple = baseTex.wrapMode !== WRAP_MODES.CLAMP;
  87. }
  88. }
  89. const shader = isSimple ? this.simpleShader : this.shader;
  90. renderer.bindShader(shader);
  91. const w = tex.width;
  92. const h = tex.height;
  93. const W = ts._width;
  94. const H = ts._height;
  95. tempMat.set(lt.a * w / W,
  96. lt.b * w / H,
  97. lt.c * h / W,
  98. lt.d * h / H,
  99. lt.tx / W,
  100. lt.ty / H);
  101. // that part is the same as above:
  102. // tempMat.identity();
  103. // tempMat.scale(tex.width, tex.height);
  104. // tempMat.prepend(lt);
  105. // tempMat.scale(1.0 / ts._width, 1.0 / ts._height);
  106. tempMat.invert();
  107. if (isSimple)
  108. {
  109. tempMat.prepend(uv.mapCoord);
  110. }
  111. else
  112. {
  113. shader.uniforms.uMapCoord = uv.mapCoord.toArray(true);
  114. shader.uniforms.uClampFrame = uv.uClampFrame;
  115. shader.uniforms.uClampOffset = uv.uClampOffset;
  116. }
  117. shader.uniforms.uTransform = tempMat.toArray(true);
  118. shader.uniforms.uColor = core.utils.premultiplyTintToRgba(ts.tint, ts.worldAlpha,
  119. shader.uniforms.uColor, baseTex.premultipliedAlpha);
  120. shader.uniforms.translationMatrix = ts.transform.worldTransform.toArray(true);
  121. shader.uniforms.uSampler = renderer.bindTexture(tex);
  122. renderer.setBlendMode(core.utils.correctBlendMode(ts.blendMode, baseTex.premultipliedAlpha));
  123. quad.vao.draw(this.renderer.gl.TRIANGLES, 6, 0);
  124. }
  125. }
  126. core.WebGLRenderer.registerPlugin('tilingSprite', TilingSpriteRenderer);