CubeMap.js 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. /*global define*/
  2. define([
  3. '../Core/defaultValue',
  4. '../Core/defined',
  5. '../Core/defineProperties',
  6. '../Core/destroyObject',
  7. '../Core/DeveloperError',
  8. '../Core/Math',
  9. './CubeMapFace',
  10. './MipmapHint',
  11. './PixelDatatype',
  12. './TextureMagnificationFilter',
  13. './TextureMinificationFilter',
  14. './TextureWrap'
  15. ], function(
  16. defaultValue,
  17. defined,
  18. defineProperties,
  19. destroyObject,
  20. DeveloperError,
  21. CesiumMath,
  22. CubeMapFace,
  23. MipmapHint,
  24. PixelDatatype,
  25. TextureMagnificationFilter,
  26. TextureMinificationFilter,
  27. TextureWrap) {
  28. "use strict";
  29. /**
  30. * @private
  31. */
  32. var CubeMap = function(gl, textureFilterAnisotropic, textureTarget, texture, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY) {
  33. this._gl = gl;
  34. this._textureFilterAnisotropic = textureFilterAnisotropic;
  35. this._textureTarget = textureTarget;
  36. this._texture = texture;
  37. this._pixelFormat = pixelFormat;
  38. this._pixelDatatype = pixelDatatype;
  39. this._size = size;
  40. this._preMultiplyAlpha = preMultiplyAlpha;
  41. this._flipY = flipY;
  42. this._sampler = undefined;
  43. this._positiveX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  44. this._negativeX = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  45. this._positiveY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  46. this._negativeY = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  47. this._positiveZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  48. this._negativeZ = new CubeMapFace(gl, texture, textureTarget, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, pixelFormat, pixelDatatype, size, preMultiplyAlpha, flipY);
  49. this.sampler = undefined;
  50. };
  51. defineProperties(CubeMap.prototype, {
  52. positiveX : {
  53. get : function() {
  54. return this._positiveX;
  55. }
  56. },
  57. negativeX : {
  58. get : function() {
  59. return this._negativeX;
  60. }
  61. },
  62. positiveY : {
  63. get : function() {
  64. return this._positiveY;
  65. }
  66. },
  67. negativeY : {
  68. get : function() {
  69. return this._negativeY;
  70. }
  71. },
  72. positiveZ : {
  73. get : function() {
  74. return this._positiveZ;
  75. }
  76. },
  77. negativeZ : {
  78. get : function() {
  79. return this._negativeZ;
  80. }
  81. },
  82. sampler : {
  83. get : function() {
  84. return this._sampler;
  85. },
  86. set : function(sampler) {
  87. var samplerDefined = true;
  88. if (!defined(sampler)) {
  89. samplerDefined = false;
  90. var minFilter = TextureMinificationFilter.LINEAR;
  91. var magFilter = TextureMagnificationFilter.LINEAR;
  92. if (this._pixelDatatype === PixelDatatype.FLOAT) {
  93. minFilter = TextureMinificationFilter.NEAREST;
  94. magFilter = TextureMagnificationFilter.NEAREST;
  95. }
  96. sampler = {
  97. wrapS : TextureWrap.CLAMP_TO_EDGE,
  98. wrapT : TextureWrap.CLAMP_TO_EDGE,
  99. minificationFilter : minFilter,
  100. magnificationFilter : magFilter,
  101. maximumAnisotropy : 1.0
  102. };
  103. }
  104. if (this._pixelDatatype === PixelDatatype.FLOAT) {
  105. if (sampler.minificationFilter !== TextureMinificationFilter.NEAREST &&
  106. sampler.minificationFilter !== TextureMinificationFilter.NEAREST_MIPMAP_NEAREST) {
  107. throw new DeveloperError('Only NEAREST and NEAREST_MIPMAP_NEAREST minification filters are supported for floating point textures.');
  108. }
  109. if (sampler.magnificationFilter !== TextureMagnificationFilter.NEAREST) {
  110. throw new DeveloperError('Only the NEAREST magnification filter is supported for floating point textures.');
  111. }
  112. }
  113. var gl = this._gl;
  114. var target = this._textureTarget;
  115. gl.activeTexture(gl.TEXTURE0);
  116. gl.bindTexture(target, this._texture);
  117. gl.texParameteri(target, gl.TEXTURE_MIN_FILTER, sampler.minificationFilter);
  118. gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, sampler.magnificationFilter);
  119. gl.texParameteri(target, gl.TEXTURE_WRAP_S, sampler.wrapS);
  120. gl.texParameteri(target, gl.TEXTURE_WRAP_T, sampler.wrapT);
  121. if (defined(this._textureFilterAnisotropic)) {
  122. gl.texParameteri(target, this._textureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT, sampler.maximumAnisotropy);
  123. }
  124. gl.bindTexture(target, null);
  125. this._sampler = !samplerDefined ? undefined : {
  126. wrapS : sampler.wrapS,
  127. wrapT : sampler.wrapT,
  128. minificationFilter : sampler.minificationFilter,
  129. magnificationFilter : sampler.magnificationFilter,
  130. maximumAnisotropy : sampler.maximumAnisotropy
  131. };
  132. }
  133. },
  134. pixelFormat: {
  135. get : function() {
  136. return this._pixelFormat;
  137. }
  138. },
  139. pixelDatatype : {
  140. get : function() {
  141. return this._pixelDatatype;
  142. }
  143. },
  144. width : {
  145. get : function() {
  146. return this._size;
  147. }
  148. },
  149. height: {
  150. get : function() {
  151. return this._size;
  152. }
  153. },
  154. preMultiplyAlpha : {
  155. get : function() {
  156. return this._preMultiplyAlpha;
  157. }
  158. },
  159. flipY : {
  160. get : function() {
  161. return this._flipY;
  162. }
  163. },
  164. _target : {
  165. get : function() {
  166. return this._textureTarget;
  167. }
  168. }
  169. });
  170. /**
  171. * Generates a complete mipmap chain for each cubemap face.
  172. *
  173. * @param {MipmapHint} [hint=MipmapHint.DONT_CARE] A performance vs. quality hint.
  174. *
  175. * @exception {DeveloperError} hint is invalid.
  176. * @exception {DeveloperError} This CubeMap's width must be a power of two to call generateMipmap().
  177. * @exception {DeveloperError} This CubeMap's height must be a power of two to call generateMipmap().
  178. * @exception {DeveloperError} This CubeMap was destroyed, i.e., destroy() was called.
  179. *
  180. * @example
  181. * // Generate mipmaps, and then set the sampler so mipmaps are used for
  182. * // minification when the cube map is sampled.
  183. * cubeMap.generateMipmap();
  184. * cubeMap.sampler = context.createSampler({
  185. * minificationFilter : Cesium.TextureMinificationFilter.NEAREST_MIPMAP_LINEAR
  186. * });
  187. */
  188. CubeMap.prototype.generateMipmap = function(hint) {
  189. hint = defaultValue(hint, MipmapHint.DONT_CARE);
  190. //>>includeStart('debug', pragmas.debug);
  191. if ((this._size > 1) && !CesiumMath.isPowerOfTwo(this._size)) {
  192. throw new DeveloperError('width and height must be a power of two to call generateMipmap().');
  193. }
  194. if (!MipmapHint.validate(hint)) {
  195. throw new DeveloperError('hint is invalid.');
  196. }
  197. //>>includeEnd('debug');
  198. var gl = this._gl;
  199. var target = this._textureTarget;
  200. gl.hint(gl.GENERATE_MIPMAP_HINT, hint);
  201. gl.activeTexture(gl.TEXTURE0);
  202. gl.bindTexture(target, this._texture);
  203. gl.generateMipmap(target);
  204. gl.bindTexture(target, null);
  205. };
  206. CubeMap.prototype.isDestroyed = function() {
  207. return false;
  208. };
  209. CubeMap.prototype.destroy = function() {
  210. this._gl.deleteTexture(this._texture);
  211. this._positiveX = destroyObject(this._positiveX);
  212. this._negativeX = destroyObject(this._negativeX);
  213. this._positiveY = destroyObject(this._positiveY);
  214. this._negativeY = destroyObject(this._negativeY);
  215. this._positiveZ = destroyObject(this._positiveZ);
  216. this._negativeZ = destroyObject(this._negativeZ);
  217. return destroyObject(this);
  218. };
  219. return CubeMap;
  220. });