WebGLState.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. THREE.WebGLState = function ( gl, paramThreeToGL ) {
  5. var _this = this;
  6. var newAttributes = new Uint8Array( 16 );
  7. var enabledAttributes = new Uint8Array( 16 );
  8. var capabilities = {};
  9. var currentBlending = null;
  10. var currentBlendEquation = null;
  11. var currentBlendSrc = null;
  12. var currentBlendDst = null;
  13. var currentBlendEquationAlpha = null;
  14. var currentBlendSrcAlpha = null;
  15. var currentBlendDstAlpha = null;
  16. var currentDepthFunc = null;
  17. var currentDepthWrite = null;
  18. var currentColorWrite = null;
  19. var currentFlipSided = null;
  20. var currentLineWidth = null;
  21. var currentPolygonOffsetFactor = null;
  22. var currentPolygonOffsetUnits = null;
  23. var maxTextures = gl.getParameter( gl.MAX_TEXTURE_IMAGE_UNITS );
  24. var currentTextureSlot = undefined;
  25. var currentBoundTextures = {};
  26. this.init = function () {
  27. gl.clearColor( 0, 0, 0, 1 );
  28. gl.clearDepth( 1 );
  29. gl.clearStencil( 0 );
  30. this.enable( gl.DEPTH_TEST );
  31. gl.depthFunc( gl.LEQUAL );
  32. gl.frontFace( gl.CCW );
  33. gl.cullFace( gl.BACK );
  34. this.enable( gl.CULL_FACE );
  35. this.enable( gl.BLEND );
  36. gl.blendEquation( gl.FUNC_ADD );
  37. gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA );
  38. };
  39. this.initAttributes = function () {
  40. for ( var i = 0, l = newAttributes.length; i < l; i ++ ) {
  41. newAttributes[ i ] = 0;
  42. }
  43. };
  44. this.enableAttribute = function ( attribute ) {
  45. newAttributes[ attribute ] = 1;
  46. if ( enabledAttributes[ attribute ] === 0 ) {
  47. gl.enableVertexAttribArray( attribute );
  48. enabledAttributes[ attribute ] = 1;
  49. }
  50. };
  51. this.disableUnusedAttributes = function () {
  52. for ( var i = 0, l = enabledAttributes.length; i < l; i ++ ) {
  53. if ( enabledAttributes[ i ] !== newAttributes[ i ] ) {
  54. gl.disableVertexAttribArray( i );
  55. enabledAttributes[ i ] = 0;
  56. }
  57. }
  58. };
  59. this.enable = function ( id ) {
  60. if ( capabilities[ id ] !== true ) {
  61. gl.enable( id );
  62. capabilities[ id ] = true;
  63. }
  64. };
  65. this.disable = function ( id ) {
  66. if ( capabilities[ id ] !== false ) {
  67. gl.disable( id );
  68. capabilities[ id ] = false;
  69. }
  70. };
  71. this.setBlending = function ( blending, blendEquation, blendSrc, blendDst, blendEquationAlpha, blendSrcAlpha, blendDstAlpha ) {
  72. if ( blending !== currentBlending ) {
  73. if ( blending === THREE.NoBlending ) {
  74. this.disable( gl.BLEND );
  75. } else if ( blending === THREE.AdditiveBlending ) {
  76. this.enable( gl.BLEND );
  77. gl.blendEquation( gl.FUNC_ADD );
  78. gl.blendFunc( gl.SRC_ALPHA, gl.ONE );
  79. } else if ( blending === THREE.SubtractiveBlending ) {
  80. // TODO: Find blendFuncSeparate() combination
  81. this.enable( gl.BLEND );
  82. gl.blendEquation( gl.FUNC_ADD );
  83. gl.blendFunc( gl.ZERO, gl.ONE_MINUS_SRC_COLOR );
  84. } else if ( blending === THREE.MultiplyBlending ) {
  85. // TODO: Find blendFuncSeparate() combination
  86. this.enable( gl.BLEND );
  87. gl.blendEquation( gl.FUNC_ADD );
  88. gl.blendFunc( gl.ZERO, gl.SRC_COLOR );
  89. } else if ( blending === THREE.CustomBlending ) {
  90. this.enable( gl.BLEND );
  91. } else {
  92. this.enable( gl.BLEND );
  93. gl.blendEquationSeparate( gl.FUNC_ADD, gl.FUNC_ADD );
  94. gl.blendFuncSeparate( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA );
  95. }
  96. currentBlending = blending;
  97. }
  98. if ( blending === THREE.CustomBlending ) {
  99. blendEquationAlpha = blendEquationAlpha || blendEquation;
  100. blendSrcAlpha = blendSrcAlpha || blendSrc;
  101. blendDstAlpha = blendDstAlpha || blendDst;
  102. if ( blendEquation !== currentBlendEquation || blendEquationAlpha !== currentBlendEquationAlpha ) {
  103. gl.blendEquationSeparate( paramThreeToGL( blendEquation ), paramThreeToGL( blendEquationAlpha ) );
  104. currentBlendEquation = blendEquation;
  105. currentBlendEquationAlpha = blendEquationAlpha;
  106. }
  107. if ( blendSrc !== currentBlendSrc || blendDst !== currentBlendDst || blendSrcAlpha !== currentBlendSrcAlpha || blendDstAlpha !== currentBlendDstAlpha ) {
  108. gl.blendFuncSeparate( paramThreeToGL( blendSrc ), paramThreeToGL( blendDst ), paramThreeToGL( blendSrcAlpha ), paramThreeToGL( blendDstAlpha ) );
  109. currentBlendSrc = blendSrc;
  110. currentBlendDst = blendDst;
  111. currentBlendSrcAlpha = blendSrcAlpha;
  112. currentBlendDstAlpha = blendDstAlpha;
  113. }
  114. } else {
  115. currentBlendEquation = null;
  116. currentBlendSrc = null;
  117. currentBlendDst = null;
  118. currentBlendEquationAlpha = null;
  119. currentBlendSrcAlpha = null;
  120. currentBlendDstAlpha = null;
  121. }
  122. };
  123. this.setDepthFunc = function ( depthFunc ) {
  124. if ( currentDepthFunc !== depthFunc ) {
  125. if ( depthFunc ) {
  126. switch ( depthFunc ) {
  127. case THREE.NeverDepth:
  128. gl.depthFunc( gl.NEVER );
  129. break;
  130. case THREE.AlwaysDepth:
  131. gl.depthFunc( gl.ALWAYS );
  132. break;
  133. case THREE.LessDepth:
  134. gl.depthFunc( gl.LESS );
  135. break;
  136. case THREE.LessEqualDepth:
  137. gl.depthFunc( gl.LEQUAL );
  138. break;
  139. case THREE.EqualDepth:
  140. gl.depthFunc( gl.EQUAL );
  141. break;
  142. case THREE.GreaterEqualDepth:
  143. gl.depthFunc( gl.GEQUAL );
  144. break;
  145. case THREE.GreaterDepth:
  146. gl.depthFunc( gl.GREATER );
  147. break;
  148. case THREE.NotEqualDepth:
  149. gl.depthFunc( gl.NOTEQUAL );
  150. break;
  151. default:
  152. gl.depthFunc( gl.LEQUAL );
  153. }
  154. } else {
  155. gl.depthFunc( gl.LEQUAL );
  156. }
  157. currentDepthFunc = depthFunc;
  158. }
  159. };
  160. this.setDepthTest = function ( depthTest ) {
  161. if ( depthTest ) {
  162. this.enable( gl.DEPTH_TEST );
  163. } else {
  164. this.disable( gl.DEPTH_TEST );
  165. }
  166. };
  167. this.setDepthWrite = function ( depthWrite ) {
  168. if ( currentDepthWrite !== depthWrite ) {
  169. gl.depthMask( depthWrite );
  170. currentDepthWrite = depthWrite;
  171. }
  172. };
  173. this.setColorWrite = function ( colorWrite ) {
  174. if ( currentColorWrite !== colorWrite ) {
  175. gl.colorMask( colorWrite, colorWrite, colorWrite, colorWrite );
  176. currentColorWrite = colorWrite;
  177. }
  178. };
  179. this.setFlipSided = function ( flipSided ) {
  180. if ( currentFlipSided !== flipSided ) {
  181. if ( flipSided ) {
  182. gl.frontFace( gl.CW );
  183. } else {
  184. gl.frontFace( gl.CCW );
  185. }
  186. currentFlipSided = flipSided;
  187. }
  188. };
  189. this.setLineWidth = function ( width ) {
  190. if ( width !== currentLineWidth ) {
  191. gl.lineWidth( width );
  192. currentLineWidth = width;
  193. }
  194. };
  195. this.setPolygonOffset = function ( polygonOffset, factor, units ) {
  196. if ( polygonOffset ) {
  197. this.enable( gl.POLYGON_OFFSET_FILL );
  198. } else {
  199. this.disable( gl.POLYGON_OFFSET_FILL );
  200. }
  201. if ( polygonOffset && ( currentPolygonOffsetFactor !== factor || currentPolygonOffsetUnits !== units ) ) {
  202. gl.polygonOffset( factor, units );
  203. currentPolygonOffsetFactor = factor;
  204. currentPolygonOffsetUnits = units;
  205. }
  206. };
  207. this.setScissorTest = function ( scissorTest ) {
  208. if ( scissorTest ) {
  209. this.enable( gl.SCISSOR_TEST );
  210. } else {
  211. this.disable( gl.SCISSOR_TEST );
  212. }
  213. };
  214. // texture
  215. this.activeTexture = function ( webglSlot ) {
  216. if ( webglSlot === undefined ) webglSlot = gl.TEXTURE0 + maxTextures - 1;
  217. if ( currentTextureSlot !== webglSlot ) {
  218. gl.activeTexture( webglSlot );
  219. currentTextureSlot = webglSlot;
  220. }
  221. }
  222. this.bindTexture = function ( webglType, webglTexture ) {
  223. if ( currentTextureSlot === undefined ) {
  224. _this.activeTexture();
  225. }
  226. var boundTexture = currentBoundTextures[ currentTextureSlot ];
  227. if ( boundTexture === undefined ) {
  228. boundTexture = { type: undefined, texture: undefined };
  229. currentBoundTextures[ currentTextureSlot ] = boundTexture;
  230. }
  231. if ( boundTexture.type !== webglType || boundTexture.texture !== webglTexture ) {
  232. gl.bindTexture( webglType, webglTexture );
  233. boundTexture.type = webglType;
  234. boundTexture.texture = webglTexture;
  235. }
  236. };
  237. this.compressedTexImage2D = function () {
  238. try {
  239. gl.compressedTexImage2D.apply( gl, arguments );
  240. } catch ( error ) {
  241. console.error( error );
  242. }
  243. };
  244. this.texImage2D = function () {
  245. try {
  246. gl.texImage2D.apply( gl, arguments );
  247. } catch ( error ) {
  248. console.error( error );
  249. }
  250. };
  251. //
  252. this.reset = function () {
  253. for ( var i = 0; i < enabledAttributes.length; i ++ ) {
  254. if ( enabledAttributes[ i ] === 1 ) {
  255. gl.disableVertexAttribArray( i );
  256. enabledAttributes[ i ] = 0;
  257. }
  258. }
  259. capabilities = {};
  260. currentBlending = null;
  261. currentDepthWrite = null;
  262. currentColorWrite = null;
  263. currentFlipSided = null;
  264. };
  265. };
粤ICP备19079148号