createUniform.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. import Cartesian2 from '../Core/Cartesian2.js';
  2. import Cartesian3 from '../Core/Cartesian3.js';
  3. import Cartesian4 from '../Core/Cartesian4.js';
  4. import Color from '../Core/Color.js';
  5. import defined from '../Core/defined.js';
  6. import DeveloperError from '../Core/DeveloperError.js';
  7. import Matrix2 from '../Core/Matrix2.js';
  8. import Matrix3 from '../Core/Matrix3.js';
  9. import Matrix4 from '../Core/Matrix4.js';
  10. import RuntimeError from '../Core/RuntimeError.js';
  11. /**
  12. * @private
  13. */
  14. function createUniform(gl, activeUniform, uniformName, location) {
  15. switch (activeUniform.type) {
  16. case gl.FLOAT:
  17. return new UniformFloat(gl, activeUniform, uniformName, location);
  18. case gl.FLOAT_VEC2:
  19. return new UniformFloatVec2(gl, activeUniform, uniformName, location);
  20. case gl.FLOAT_VEC3:
  21. return new UniformFloatVec3(gl, activeUniform, uniformName, location);
  22. case gl.FLOAT_VEC4:
  23. return new UniformFloatVec4(gl, activeUniform, uniformName, location);
  24. case gl.SAMPLER_2D:
  25. case gl.SAMPLER_CUBE:
  26. return new UniformSampler(gl, activeUniform, uniformName, location);
  27. case gl.INT:
  28. case gl.BOOL:
  29. return new UniformInt(gl, activeUniform, uniformName, location);
  30. case gl.INT_VEC2:
  31. case gl.BOOL_VEC2:
  32. return new UniformIntVec2(gl, activeUniform, uniformName, location);
  33. case gl.INT_VEC3:
  34. case gl.BOOL_VEC3:
  35. return new UniformIntVec3(gl, activeUniform, uniformName, location);
  36. case gl.INT_VEC4:
  37. case gl.BOOL_VEC4:
  38. return new UniformIntVec4(gl, activeUniform, uniformName, location);
  39. case gl.FLOAT_MAT2:
  40. return new UniformMat2(gl, activeUniform, uniformName, location);
  41. case gl.FLOAT_MAT3:
  42. return new UniformMat3(gl, activeUniform, uniformName, location);
  43. case gl.FLOAT_MAT4:
  44. return new UniformMat4(gl, activeUniform, uniformName, location);
  45. default:
  46. throw new RuntimeError('Unrecognized uniform type: ' + activeUniform.type + ' for uniform "' + uniformName + '".');
  47. }
  48. }
  49. /**
  50. * @private
  51. */
  52. function UniformFloat(gl, activeUniform, uniformName, location) {
  53. /**
  54. * @type {String}
  55. * @readonly
  56. */
  57. this.name = uniformName;
  58. this.value = undefined;
  59. this._value = 0.0;
  60. this._gl = gl;
  61. this._location = location;
  62. }
  63. UniformFloat.prototype.set = function() {
  64. if (this.value !== this._value) {
  65. this._value = this.value;
  66. this._gl.uniform1f(this._location, this.value);
  67. }
  68. };
  69. ///////////////////////////////////////////////////////////////////////////
  70. /**
  71. * @private
  72. */
  73. function UniformFloatVec2(gl, activeUniform, uniformName, location) {
  74. /**
  75. * @type {String}
  76. * @readonly
  77. */
  78. this.name = uniformName;
  79. this.value = undefined;
  80. this._value = new Cartesian2();
  81. this._gl = gl;
  82. this._location = location;
  83. }
  84. UniformFloatVec2.prototype.set = function() {
  85. var v = this.value;
  86. if (!Cartesian2.equals(v, this._value)) {
  87. Cartesian2.clone(v, this._value);
  88. this._gl.uniform2f(this._location, v.x, v.y);
  89. }
  90. };
  91. ///////////////////////////////////////////////////////////////////////////
  92. /**
  93. * @private
  94. */
  95. function UniformFloatVec3(gl, activeUniform, uniformName, location) {
  96. /**
  97. * @type {String}
  98. * @readonly
  99. */
  100. this.name = uniformName;
  101. this.value = undefined;
  102. this._value = undefined;
  103. this._gl = gl;
  104. this._location = location;
  105. }
  106. UniformFloatVec3.prototype.set = function() {
  107. var v = this.value;
  108. if (defined(v.red)) {
  109. if (!Color.equals(v, this._value)) {
  110. this._value = Color.clone(v, this._value);
  111. this._gl.uniform3f(this._location, v.red, v.green, v.blue);
  112. }
  113. } else if (defined(v.x)) {
  114. if (!Cartesian3.equals(v, this._value)) {
  115. this._value = Cartesian3.clone(v, this._value);
  116. this._gl.uniform3f(this._location, v.x, v.y, v.z);
  117. }
  118. } else {
  119. //>>includeStart('debug', pragmas.debug);
  120. throw new DeveloperError('Invalid vec3 value for uniform "' + this.name + '".');
  121. //>>includeEnd('debug');
  122. }
  123. };
  124. ///////////////////////////////////////////////////////////////////////////
  125. /**
  126. * @private
  127. */
  128. function UniformFloatVec4(gl, activeUniform, uniformName, location) {
  129. /**
  130. * @type {String}
  131. * @readonly
  132. */
  133. this.name = uniformName;
  134. this.value = undefined;
  135. this._value = undefined;
  136. this._gl = gl;
  137. this._location = location;
  138. }
  139. UniformFloatVec4.prototype.set = function() {
  140. var v = this.value;
  141. if (defined(v.red)) {
  142. if (!Color.equals(v, this._value)) {
  143. this._value = Color.clone(v, this._value);
  144. this._gl.uniform4f(this._location, v.red, v.green, v.blue, v.alpha);
  145. }
  146. } else if (defined(v.x)) {
  147. if (!Cartesian4.equals(v, this._value)) {
  148. this._value = Cartesian4.clone(v, this._value);
  149. this._gl.uniform4f(this._location, v.x, v.y, v.z, v.w);
  150. }
  151. } else {
  152. //>>includeStart('debug', pragmas.debug);
  153. throw new DeveloperError('Invalid vec4 value for uniform "' + this.name + '".');
  154. //>>includeEnd('debug');
  155. }
  156. };
  157. ///////////////////////////////////////////////////////////////////////////
  158. /**
  159. * @private
  160. */
  161. function UniformSampler(gl, activeUniform, uniformName, location) {
  162. /**
  163. * @type {String}
  164. * @readonly
  165. */
  166. this.name = uniformName;
  167. this.value = undefined;
  168. this._gl = gl;
  169. this._location = location;
  170. this.textureUnitIndex = undefined;
  171. }
  172. UniformSampler.prototype.set = function() {
  173. var gl = this._gl;
  174. gl.activeTexture(gl.TEXTURE0 + this.textureUnitIndex);
  175. var v = this.value;
  176. gl.bindTexture(v._target, v._texture);
  177. };
  178. UniformSampler.prototype._setSampler = function(textureUnitIndex) {
  179. this.textureUnitIndex = textureUnitIndex;
  180. this._gl.uniform1i(this._location, textureUnitIndex);
  181. return textureUnitIndex + 1;
  182. };
  183. ///////////////////////////////////////////////////////////////////////////
  184. /**
  185. * @private
  186. */
  187. function UniformInt(gl, activeUniform, uniformName, location) {
  188. /**
  189. * @type {String}
  190. * @readonly
  191. */
  192. this.name = uniformName;
  193. this.value = undefined;
  194. this._value = 0.0;
  195. this._gl = gl;
  196. this._location = location;
  197. }
  198. UniformInt.prototype.set = function() {
  199. if (this.value !== this._value) {
  200. this._value = this.value;
  201. this._gl.uniform1i(this._location, this.value);
  202. }
  203. };
  204. ///////////////////////////////////////////////////////////////////////////
  205. /**
  206. * @private
  207. */
  208. function UniformIntVec2(gl, activeUniform, uniformName, location) {
  209. /**
  210. * @type {String}
  211. * @readonly
  212. */
  213. this.name = uniformName;
  214. this.value = undefined;
  215. this._value = new Cartesian2();
  216. this._gl = gl;
  217. this._location = location;
  218. }
  219. UniformIntVec2.prototype.set = function() {
  220. var v = this.value;
  221. if (!Cartesian2.equals(v, this._value)) {
  222. Cartesian2.clone(v, this._value);
  223. this._gl.uniform2i(this._location, v.x, v.y);
  224. }
  225. };
  226. ///////////////////////////////////////////////////////////////////////////
  227. /**
  228. * @private
  229. */
  230. function UniformIntVec3(gl, activeUniform, uniformName, location) {
  231. /**
  232. * @type {String}
  233. * @readonly
  234. */
  235. this.name = uniformName;
  236. this.value = undefined;
  237. this._value = new Cartesian3();
  238. this._gl = gl;
  239. this._location = location;
  240. }
  241. UniformIntVec3.prototype.set = function() {
  242. var v = this.value;
  243. if (!Cartesian3.equals(v, this._value)) {
  244. Cartesian3.clone(v, this._value);
  245. this._gl.uniform3i(this._location, v.x, v.y, v.z);
  246. }
  247. };
  248. ///////////////////////////////////////////////////////////////////////////
  249. /**
  250. * @private
  251. */
  252. function UniformIntVec4(gl, activeUniform, uniformName, location) {
  253. /**
  254. * @type {String}
  255. * @readonly
  256. */
  257. this.name = uniformName;
  258. this.value = undefined;
  259. this._value = new Cartesian4();
  260. this._gl = gl;
  261. this._location = location;
  262. }
  263. UniformIntVec4.prototype.set = function() {
  264. var v = this.value;
  265. if (!Cartesian4.equals(v, this._value)) {
  266. Cartesian4.clone(v, this._value);
  267. this._gl.uniform4i(this._location, v.x, v.y, v.z, v.w);
  268. }
  269. };
  270. ///////////////////////////////////////////////////////////////////////////
  271. var scratchUniformArray = new Float32Array(4);
  272. /**
  273. * @private
  274. */
  275. function UniformMat2(gl, activeUniform, uniformName, location) {
  276. /**
  277. * @type {String}
  278. * @readonly
  279. */
  280. this.name = uniformName;
  281. this.value = undefined;
  282. this._value = new Matrix2();
  283. this._gl = gl;
  284. this._location = location;
  285. }
  286. UniformMat2.prototype.set = function() {
  287. if (!Matrix2.equalsArray(this.value, this._value, 0)) {
  288. Matrix2.clone(this.value, this._value);
  289. var array = Matrix2.toArray(this.value, scratchUniformArray);
  290. this._gl.uniformMatrix2fv(this._location, false, array);
  291. }
  292. };
  293. ///////////////////////////////////////////////////////////////////////////
  294. var scratchMat3Array = new Float32Array(9);
  295. /**
  296. * @private
  297. */
  298. function UniformMat3(gl, activeUniform, uniformName, location) {
  299. /**
  300. * @type {String}
  301. * @readonly
  302. */
  303. this.name = uniformName;
  304. this.value = undefined;
  305. this._value = new Matrix3();
  306. this._gl = gl;
  307. this._location = location;
  308. }
  309. UniformMat3.prototype.set = function() {
  310. if (!Matrix3.equalsArray(this.value, this._value, 0)) {
  311. Matrix3.clone(this.value, this._value);
  312. var array = Matrix3.toArray(this.value, scratchMat3Array);
  313. this._gl.uniformMatrix3fv(this._location, false, array);
  314. }
  315. };
  316. ///////////////////////////////////////////////////////////////////////////
  317. var scratchMat4Array = new Float32Array(16);
  318. /**
  319. * @private
  320. */
  321. function UniformMat4(gl, activeUniform, uniformName, location) {
  322. /**
  323. * @type {String}
  324. * @readonly
  325. */
  326. this.name = uniformName;
  327. this.value = undefined;
  328. this._value = new Matrix4();
  329. this._gl = gl;
  330. this._location = location;
  331. }
  332. UniformMat4.prototype.set = function() {
  333. if (!Matrix4.equalsArray(this.value, this._value, 0)) {
  334. Matrix4.clone(this.value, this._value);
  335. var array = Matrix4.toArray(this.value, scratchMat4Array);
  336. this._gl.uniformMatrix4fv(this._location, false, array);
  337. }
  338. };
  339. export default createUniform;