babylon.layer.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. module BABYLON {
  2. export class Layer {
  3. public texture: Texture;
  4. public isBackground: boolean;
  5. public color: Color4;
  6. public scale = new Vector2(1, 1);
  7. public offset = new Vector2(0, 0);
  8. public alphaBlendingMode = Engine.ALPHA_COMBINE;
  9. public alphaTest: boolean;
  10. private _scene: Scene;
  11. private _vertexBuffers: { [key: string]: VertexBuffer } = {};
  12. private _indexBuffer: WebGLBuffer;
  13. private _effect: Effect;
  14. private _alphaTestEffect: Effect;
  15. // Events
  16. /**
  17. * An event triggered when the layer is disposed.
  18. * @type {BABYLON.Observable}
  19. */
  20. public onDisposeObservable = new Observable<Layer>();
  21. private _onDisposeObserver: Observer<Layer>;
  22. public set onDispose(callback: () => void) {
  23. if (this._onDisposeObserver) {
  24. this.onDisposeObservable.remove(this._onDisposeObserver);
  25. }
  26. this._onDisposeObserver = this.onDisposeObservable.add(callback);
  27. }
  28. /**
  29. * An event triggered before rendering the scene
  30. * @type {BABYLON.Observable}
  31. */
  32. public onBeforeRenderObservable = new Observable<Layer>();
  33. private _onBeforeRenderObserver: Observer<Layer>;
  34. public set onBeforeRender(callback: () => void) {
  35. if (this._onBeforeRenderObserver) {
  36. this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
  37. }
  38. this._onBeforeRenderObserver = this.onBeforeRenderObservable.add(callback);
  39. }
  40. /**
  41. * An event triggered after rendering the scene
  42. * @type {BABYLON.Observable}
  43. */
  44. public onAfterRenderObservable = new Observable<Layer>();
  45. private _onAfterRenderObserver: Observer<Layer>;
  46. public set onAfterRender(callback: () => void) {
  47. if (this._onAfterRenderObserver) {
  48. this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
  49. }
  50. this._onAfterRenderObserver = this.onAfterRenderObservable.add(callback);
  51. }
  52. constructor(public name: string, imgUrl: string, scene: Scene, isBackground?: boolean, color?: Color4) {
  53. this.texture = imgUrl ? new Texture(imgUrl, scene, true) : null;
  54. this.isBackground = isBackground === undefined ? true : isBackground;
  55. this.color = color === undefined ? new Color4(1, 1, 1, 1) : color;
  56. this._scene = scene;
  57. this._scene.layers.push(this);
  58. var engine = scene.getEngine();
  59. // VBO
  60. var vertices = [];
  61. vertices.push(1, 1);
  62. vertices.push(-1, 1);
  63. vertices.push(-1, -1);
  64. vertices.push(1, -1);
  65. var vertexBuffer = new VertexBuffer(engine, vertices, VertexBuffer.PositionKind, false, false, 2);
  66. this._vertexBuffers[VertexBuffer.PositionKind] = vertexBuffer;
  67. // Indices
  68. var indices = [];
  69. indices.push(0);
  70. indices.push(1);
  71. indices.push(2);
  72. indices.push(0);
  73. indices.push(2);
  74. indices.push(3);
  75. this._indexBuffer = engine.createIndexBuffer(indices);
  76. // Effects
  77. this._effect = engine.createEffect("layer",
  78. [VertexBuffer.PositionKind],
  79. ["textureMatrix", "color", "scale", "offset"],
  80. ["textureSampler"], "");
  81. this._alphaTestEffect = engine.createEffect("layer",
  82. [VertexBuffer.PositionKind],
  83. ["textureMatrix", "color", "scale", "offset"],
  84. ["textureSampler"], "#define ALPHATEST");
  85. }
  86. public render(): void {
  87. var currentEffect = this.alphaTest ? this._alphaTestEffect : this._effect;
  88. // Check
  89. if (!currentEffect.isReady() || !this.texture || !this.texture.isReady())
  90. return;
  91. var engine = this._scene.getEngine();
  92. this.onBeforeRenderObservable.notifyObservers(this);
  93. // Render
  94. engine.enableEffect(currentEffect);
  95. engine.setState(false);
  96. // Texture
  97. currentEffect.setTexture("textureSampler", this.texture);
  98. currentEffect.setMatrix("textureMatrix", this.texture.getTextureMatrix());
  99. // Color
  100. currentEffect.setFloat4("color", this.color.r, this.color.g, this.color.b, this.color.a);
  101. // Scale / offset
  102. currentEffect.setVector2("offset", this.offset);
  103. currentEffect.setVector2("scale", this.scale);
  104. // VBOs
  105. engine.bindBuffers(this._vertexBuffers, this._indexBuffer, currentEffect);
  106. // Draw order
  107. if (!this.alphaTest) {
  108. engine.setAlphaMode(this.alphaBlendingMode);
  109. engine.draw(true, 0, 6);
  110. engine.setAlphaMode(Engine.ALPHA_DISABLE);
  111. }
  112. else {
  113. engine.draw(true, 0, 6);
  114. }
  115. this.onAfterRenderObservable.notifyObservers(this);
  116. }
  117. public dispose(): void {
  118. var vertexBuffer = this._vertexBuffers[VertexBuffer.PositionKind];
  119. if (vertexBuffer) {
  120. vertexBuffer.dispose();
  121. this._vertexBuffers[VertexBuffer.PositionKind] = null;
  122. }
  123. if (this._indexBuffer) {
  124. this._scene.getEngine()._releaseBuffer(this._indexBuffer);
  125. this._indexBuffer = null;
  126. }
  127. if (this.texture) {
  128. this.texture.dispose();
  129. this.texture = null;
  130. }
  131. // Remove from scene
  132. var index = this._scene.layers.indexOf(this);
  133. this._scene.layers.splice(index, 1);
  134. // Callback
  135. this.onDisposeObservable.notifyObservers(this);
  136. this.onDisposeObservable.clear();
  137. this.onAfterRenderObservable.clear();
  138. this.onBeforeRenderObservable.clear();
  139. }
  140. }
  141. }