depthCullingState.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. import { Nullable } from "../types";
  2. /**
  3. * @hidden
  4. **/
  5. export class DepthCullingState {
  6. private _isDepthTestDirty = false;
  7. private _isDepthMaskDirty = false;
  8. private _isDepthFuncDirty = false;
  9. private _isCullFaceDirty = false;
  10. private _isCullDirty = false;
  11. private _isZOffsetDirty = false;
  12. private _isFrontFaceDirty = false;
  13. private _depthTest: boolean;
  14. private _depthMask: boolean;
  15. private _depthFunc: Nullable<number>;
  16. private _cull: Nullable<boolean>;
  17. private _cullFace: Nullable<number>;
  18. private _zOffset: number;
  19. private _frontFace: Nullable<number>;
  20. /**
  21. * Initializes the state.
  22. */
  23. public constructor() {
  24. this.reset();
  25. }
  26. public get isDirty(): boolean {
  27. return this._isDepthFuncDirty || this._isDepthTestDirty || this._isDepthMaskDirty || this._isCullFaceDirty || this._isCullDirty || this._isZOffsetDirty || this._isFrontFaceDirty;
  28. }
  29. public get zOffset(): number {
  30. return this._zOffset;
  31. }
  32. public set zOffset(value: number) {
  33. if (this._zOffset === value) {
  34. return;
  35. }
  36. this._zOffset = value;
  37. this._isZOffsetDirty = true;
  38. }
  39. public get cullFace(): Nullable<number> {
  40. return this._cullFace;
  41. }
  42. public set cullFace(value: Nullable<number>) {
  43. if (this._cullFace === value) {
  44. return;
  45. }
  46. this._cullFace = value;
  47. this._isCullFaceDirty = true;
  48. }
  49. public get cull(): Nullable<boolean> {
  50. return this._cull;
  51. }
  52. public set cull(value: Nullable<boolean>) {
  53. if (this._cull === value) {
  54. return;
  55. }
  56. this._cull = value;
  57. this._isCullDirty = true;
  58. }
  59. public get depthFunc(): Nullable<number> {
  60. return this._depthFunc;
  61. }
  62. public set depthFunc(value: Nullable<number>) {
  63. if (this._depthFunc === value) {
  64. return;
  65. }
  66. this._depthFunc = value;
  67. this._isDepthFuncDirty = true;
  68. }
  69. public get depthMask(): boolean {
  70. return this._depthMask;
  71. }
  72. public set depthMask(value: boolean) {
  73. if (this._depthMask === value) {
  74. return;
  75. }
  76. this._depthMask = value;
  77. this._isDepthMaskDirty = true;
  78. }
  79. public get depthTest(): boolean {
  80. return this._depthTest;
  81. }
  82. public set depthTest(value: boolean) {
  83. if (this._depthTest === value) {
  84. return;
  85. }
  86. this._depthTest = value;
  87. this._isDepthTestDirty = true;
  88. }
  89. public get frontFace(): Nullable<number> {
  90. return this._frontFace;
  91. }
  92. public set frontFace(value: Nullable<number>) {
  93. if (this._frontFace === value) {
  94. return;
  95. }
  96. this._frontFace = value;
  97. this._isFrontFaceDirty = true;
  98. }
  99. public reset() {
  100. this._depthMask = true;
  101. this._depthTest = true;
  102. this._depthFunc = null;
  103. this._cullFace = null;
  104. this._cull = null;
  105. this._zOffset = 0;
  106. this._frontFace = null;
  107. this._isDepthTestDirty = true;
  108. this._isDepthMaskDirty = true;
  109. this._isDepthFuncDirty = false;
  110. this._isCullFaceDirty = false;
  111. this._isCullDirty = false;
  112. this._isZOffsetDirty = false;
  113. this._isFrontFaceDirty = false;
  114. }
  115. public apply(gl: WebGLRenderingContext) {
  116. if (!this.isDirty) {
  117. return;
  118. }
  119. // Cull
  120. if (this._isCullDirty) {
  121. if (this.cull) {
  122. gl.enable(gl.CULL_FACE);
  123. } else {
  124. gl.disable(gl.CULL_FACE);
  125. }
  126. this._isCullDirty = false;
  127. }
  128. // Cull face
  129. if (this._isCullFaceDirty) {
  130. gl.cullFace(<number>this.cullFace);
  131. this._isCullFaceDirty = false;
  132. }
  133. // Depth mask
  134. if (this._isDepthMaskDirty) {
  135. gl.depthMask(this.depthMask);
  136. this._isDepthMaskDirty = false;
  137. }
  138. // Depth test
  139. if (this._isDepthTestDirty) {
  140. if (this.depthTest) {
  141. gl.enable(gl.DEPTH_TEST);
  142. } else {
  143. gl.disable(gl.DEPTH_TEST);
  144. }
  145. this._isDepthTestDirty = false;
  146. }
  147. // Depth func
  148. if (this._isDepthFuncDirty) {
  149. gl.depthFunc(<number>this.depthFunc);
  150. this._isDepthFuncDirty = false;
  151. }
  152. // zOffset
  153. if (this._isZOffsetDirty) {
  154. if (this.zOffset) {
  155. gl.enable(gl.POLYGON_OFFSET_FILL);
  156. gl.polygonOffset(this.zOffset, 0);
  157. } else {
  158. gl.disable(gl.POLYGON_OFFSET_FILL);
  159. }
  160. this._isZOffsetDirty = false;
  161. }
  162. // Front face
  163. if (this._isFrontFaceDirty) {
  164. gl.frontFace(<number>this.frontFace);
  165. this._isFrontFaceDirty = false;
  166. }
  167. }
  168. }