Home Reference Source

cables_dev/cables/src/core/cgl/cgl_shader_uniform.js

  1.  
  2. import CgUniform from "../cg/cg_uniform.js";
  3. import { Port } from "../core_port.js";
  4.  
  5. /**
  6. * Shader uniforms
  7. *
  8. * types:
  9. * <pre>
  10. * f - float
  11. * 2f - vec2
  12. * 3f - vec3
  13. * 4f - vec4
  14. * i - integer
  15. * t - texture
  16. * m4 - mat4, 4x4 float matrix
  17. * f[] - array of floats
  18. * 2f[] - array of float vec2
  19. * 3f[] - array of float vec3
  20. * 4f[] - array of float vec4
  21. * </pre>
  22. *
  23. * @namespace external:CGL
  24. * @class
  25. * @param {Shader} shader
  26. * @param {String} [type=f]
  27. * @param {String} name
  28. * @param {Number|Port} value can be a Number,Matrix or Port
  29. * @example
  30. * // bind float uniform called myfloat and initialize with value 1.0
  31. * const unir=new CGL.Uniform(shader,'f','myfloat',1.0);
  32. * unir.setValue(1.0);
  33. *
  34. * // bind float uniform called myfloat and automatically set it to input port value
  35. * const myPort=op.inFloat("input");
  36. * const pv=new CGL.Uniform(shader,'f','myfloat',myPort);
  37. *
  38. */
  39.  
  40.  
  41. // export const Uniform(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName)
  42.  
  43. class Uniform extends CgUniform
  44. {
  45. constructor(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName)
  46. {
  47. super(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName);
  48. this._loc = -1;
  49. this._cgl = __shader._cgl;
  50. }
  51.  
  52. get name()
  53. {
  54. return this._name;
  55. }
  56.  
  57. copy(newShader)
  58. {
  59. const uni = new Uniform(newShader, this._type, this._name, this._value, this._port2, this._port3, this._port4, this._structUniformName, this._structName, this._propertyName);
  60. uni.shaderType = this.shaderType;
  61. return uni;
  62. }
  63.  
  64. /**
  65. * returns type as glsl type string. e.g. 'f' returns 'float'
  66. * @function getGlslTypeString
  67. * @memberof Uniform
  68. * @instance
  69. * @return {string} type as string
  70. */
  71. getGlslTypeString()
  72. {
  73. return Uniform.glslTypeString(this._type);
  74. }
  75.  
  76. _isValidLoc()
  77. {
  78. return this._loc != -1;// && this._loc != null;
  79. }
  80.  
  81. resetLoc()
  82. {
  83. this._loc = -1;
  84. this.needsUpdate = true;
  85. }
  86.  
  87. bindTextures() {}
  88.  
  89. getLoc()
  90. {
  91. return this._loc;
  92. }
  93.  
  94. updateFromPort4f()
  95. {
  96. this._value[0] = this._port.get();
  97. this._value[1] = this._port2.get();
  98. this._value[2] = this._port3.get();
  99. this._value[3] = this._port4.get();
  100. this.setValue(this._value);
  101. }
  102.  
  103. updateFromPort3f()
  104. {
  105. this._value[0] = this._port.get();
  106. this._value[1] = this._port2.get();
  107. this._value[2] = this._port3.get();
  108. this.setValue(this._value);
  109. }
  110.  
  111. updateFromPort2f()
  112. {
  113. this._value[0] = this._port.get();
  114. this._value[1] = this._port2.get();
  115. this.setValue(this._value);
  116. }
  117.  
  118. updateFromPort()
  119. {
  120. this.setValue(this._port.get());
  121. }
  122.  
  123. updateValueF()
  124. {
  125. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  126. else this.needsUpdate = false;
  127.  
  128. this._shader.getCgl().gl.uniform1f(this._loc, this._value);
  129. this._cgl.profileData.profileUniformCount++;
  130. }
  131.  
  132. setValueF(v)
  133. {
  134. if (v != this._value)
  135. {
  136. this.needsUpdate = true;
  137. this._value = v;
  138. }
  139. }
  140.  
  141. updateValueI()
  142. {
  143. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  144. else this.needsUpdate = false;
  145.  
  146. this._shader.getCgl().gl.uniform1i(this._loc, this._value);
  147. this._cgl.profileData.profileUniformCount++;
  148. }
  149.  
  150. updateValue2I()
  151. {
  152. if (!this._value) return;
  153.  
  154. if (!this._isValidLoc())
  155. {
  156. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  157. this._cgl.profileData.profileShaderGetUniform++;
  158. this._cgl.profileData.profileShaderGetUniformName = this._name;
  159. }
  160.  
  161. this._shader.getCgl().gl.uniform2i(this._loc, this._value[0], this._value[1]);
  162.  
  163. this.needsUpdate = false;
  164. this._cgl.profileData.profileUniformCount++;
  165. }
  166.  
  167. updateValue3I()
  168. {
  169. if (!this._value) return;
  170. if (!this._isValidLoc())
  171. {
  172. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  173. this._cgl.profileData.profileShaderGetUniform++;
  174. this._cgl.profileData.profileShaderGetUniformName = this._name;
  175. }
  176.  
  177. this._shader.getCgl().gl.uniform3i(this._loc, this._value[0], this._value[1], this._value[2]);
  178. this.needsUpdate = false;
  179. this._cgl.profileData.profileUniformCount++;
  180. }
  181.  
  182. updateValue4I()
  183. {
  184. if (!this._isValidLoc())
  185. {
  186. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  187. this._cgl.profileData.profileShaderGetUniform++;
  188. this._cgl.profileData.profileShaderGetUniformName = this._name;
  189. }
  190. this._shader.getCgl().gl.uniform4i(this._loc, this._value[0], this._value[1], this._value[2], this._value[3]);
  191. this._cgl.profileData.profileUniformCount++;
  192. }
  193.  
  194. setValueI(v)
  195. {
  196. if (v != this._value)
  197. {
  198. this.needsUpdate = true;
  199. this._value = v;
  200. }
  201. }
  202.  
  203. setValue2I(v)
  204. {
  205. if (!v) return;
  206. if (!this._oldValue)
  207. {
  208. this._oldValue = [v[0] - 1, 1];
  209. this.needsUpdate = true;
  210. }
  211. else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1])
  212. {
  213. this._oldValue[0] = v[0];
  214. this._oldValue[1] = v[1];
  215. this.needsUpdate = true;
  216. }
  217.  
  218. this._value = v;
  219. }
  220.  
  221. setValue3I(v)
  222. {
  223. if (!v) return;
  224. if (!this._oldValue)
  225. {
  226. this._oldValue = [v[0] - 1, 1, 2];
  227. this.needsUpdate = true;
  228. }
  229. else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2])
  230. {
  231. this._oldValue[0] = v[0];
  232. this._oldValue[1] = v[1];
  233. this._oldValue[2] = v[2];
  234. this.needsUpdate = true;
  235. }
  236.  
  237. this._value = v;
  238. }
  239.  
  240. setValue4I(v)
  241. {
  242. this.needsUpdate = true;
  243. this._value = v || vec4.create();
  244. }
  245.  
  246. updateValueBool()
  247. {
  248. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  249. else this.needsUpdate = false;
  250. this._shader.getCgl().gl.uniform1i(this._loc, this._value ? 1 : 0);
  251.  
  252. this._cgl.profileData.profileUniformCount++;
  253. }
  254.  
  255. setValueBool(v)
  256. {
  257. if (v != this._value)
  258. {
  259. this.needsUpdate = true;
  260. this._value = v;
  261. }
  262. }
  263.  
  264. setValueArray4F(v)
  265. {
  266. this.needsUpdate = true;
  267. this._value = v;
  268. }
  269.  
  270. updateValueArray4F()
  271. {
  272. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  273. else this.needsUpdate = false;
  274.  
  275. if (!this._value) return;
  276. this._shader.getCgl().gl.uniform4fv(this._loc, this._value);
  277. this._cgl.profileData.profileUniformCount++;
  278. }
  279.  
  280. setValueArray3F(v)
  281. {
  282. this.needsUpdate = true;
  283. this._value = v;
  284. }
  285.  
  286. updateValueArray3F()
  287. {
  288. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  289. else this.needsUpdate = false;
  290.  
  291. if (!this._value) return;
  292. this._shader.getCgl().gl.uniform3fv(this._loc, this._value);
  293. this._cgl.profileData.profileUniformCount++;
  294. }
  295.  
  296. setValueArray2F(v)
  297. {
  298. this.needsUpdate = true;
  299. this._value = v;
  300. }
  301.  
  302. updateValueArray2F()
  303. {
  304. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  305. else this.needsUpdate = false;
  306.  
  307. if (!this._value) return;
  308. this._shader.getCgl().gl.uniform2fv(this._loc, this._value);
  309. this._cgl.profileData.profileUniformCount++;
  310. }
  311.  
  312. setValueArrayF(v)
  313. {
  314. this.needsUpdate = true;
  315. this._value = v;
  316. }
  317.  
  318. updateValueArrayF()
  319. {
  320. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  321. else this.needsUpdate = false;
  322.  
  323. if (!this._value) return;
  324. this._shader.getCgl().gl.uniform1fv(this._loc, this._value);
  325. this._cgl.profileData.profileUniformCount++;
  326. }
  327.  
  328. setValueArrayT(v)
  329. {
  330. this.needsUpdate = true;
  331. this._value = v;
  332. }
  333.  
  334.  
  335. updateValue3F()
  336. {
  337. if (!this._value) return;
  338. if (!this._isValidLoc())
  339. {
  340. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  341. this._cgl.profileData.profileShaderGetUniform++;
  342. this._cgl.profileData.profileShaderGetUniformName = this._name;
  343. }
  344.  
  345. this._shader.getCgl().gl.uniform3f(this._loc, this._value[0], this._value[1], this._value[2]);
  346. this.needsUpdate = false;
  347. this._cgl.profileData.profileUniformCount++;
  348. }
  349.  
  350. setValue3F(v)
  351. {
  352. if (!v) return;
  353. if (!this._oldValue)
  354. {
  355. this._oldValue = [v[0] - 1, 1, 2];
  356. this.needsUpdate = true;
  357. }
  358. else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2])
  359. {
  360. this._oldValue[0] = v[0];
  361. this._oldValue[1] = v[1];
  362. this._oldValue[2] = v[2];
  363. this.needsUpdate = true;
  364. }
  365.  
  366. this._value = v;
  367. }
  368.  
  369. updateValue2F()
  370. {
  371. if (!this._value) return;
  372.  
  373. if (!this._isValidLoc())
  374. {
  375. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  376. this._cgl.profileData.profileShaderGetUniform++;
  377. this._cgl.profileData.profileShaderGetUniformName = this._name;
  378. }
  379.  
  380. this._shader.getCgl().gl.uniform2f(this._loc, this._value[0], this._value[1]);
  381. this.needsUpdate = false;
  382. this._cgl.profileData.profileUniformCount++;
  383. }
  384.  
  385. setValue2F(v)
  386. {
  387. if (!v) return;
  388. if (!this._oldValue)
  389. {
  390. this._oldValue = [v[0] - 1, 1];
  391. this.needsUpdate = true;
  392. }
  393. else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1])
  394. {
  395. this._oldValue[0] = v[0];
  396. this._oldValue[1] = v[1];
  397. this.needsUpdate = true;
  398. }
  399. this._value = v;
  400. }
  401.  
  402. updateValue4F()
  403. {
  404. if (!this._isValidLoc())
  405. {
  406. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  407. this._cgl.profileData.profileShaderGetUniform++;
  408. this._cgl.profileData.profileShaderGetUniformName = this._name;
  409. }
  410.  
  411. if (!this._value)
  412. {
  413. this._log.warn("no value for uniform", this._name, this);
  414. this._value = [0, 0, 0, 0];
  415. }
  416.  
  417. this.needsUpdate = false;
  418. this._shader.getCgl().gl.uniform4f(this._loc, this._value[0], this._value[1], this._value[2], this._value[3]);
  419. this._cgl.profileData.profileUniformCount++;
  420. }
  421.  
  422. setValue4F(v)
  423. {
  424. if (typeof this.value == "number") this.value = vec4.create(); // this should not be needed, but somehow it crashes with some shadermods
  425.  
  426. if (!v) return;
  427. if (!this._oldValue)
  428. {
  429. this._oldValue = [v[0] - 1, 1, 2, 3];
  430. this.needsUpdate = true;
  431. }
  432. else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2] || v[3] != this._oldValue[3])
  433. {
  434. this._oldValue[0] = v[0];
  435. this._oldValue[1] = v[1];
  436. this._oldValue[2] = v[2];
  437. this.needsUpdate = true;
  438. }
  439.  
  440. this._value = v;
  441. }
  442.  
  443. updateValueM4()
  444. {
  445. if (!this._isValidLoc())
  446. {
  447. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  448. this._cgl.profileData.profileShaderGetUniform++;
  449. this._cgl.profileData.profileShaderGetUniformName = this._name;
  450. }
  451. if (!this._value || this._value.length % 16 != 0) return console.log("this.name", this._name, this._value);
  452.  
  453. this._shader.getCgl().gl.uniformMatrix4fv(this._loc, false, this._value);
  454. this._cgl.profileData.profileUniformCount++;
  455. }
  456.  
  457. setValueM4(v)
  458. {
  459. this.needsUpdate = true;
  460. this._value = v || mat4.create();
  461. }
  462.  
  463. updateValueArrayT()
  464. {
  465. if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  466. else this.needsUpdate = false;
  467.  
  468. if (!this._value) return;
  469. this._shader.getCgl().gl.uniform1iv(this._loc, this._value);
  470. this._cgl.profileData.profileUniformCount++;
  471. }
  472.  
  473. updateValueT()
  474. {
  475. if (!this._isValidLoc())
  476. {
  477. this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
  478. this._cgl.profileData.profileShaderGetUniform++;
  479. this._cgl.profileData.profileShaderGetUniformName = this._name;
  480. }
  481.  
  482. this._cgl.profileData.profileUniformCount++;
  483. this._shader.getCgl().gl.uniform1i(this._loc, this._value);
  484. this.needsUpdate = false;
  485. }
  486.  
  487. setValueT(v)
  488. {
  489. this.needsUpdate = true;
  490. this._value = v;
  491. }
  492. }
  493.  
  494.  
  495. Uniform.glslTypeString = (t) =>
  496. {
  497. if (t == "f") return "float";
  498. if (t == "b") return "bool";
  499. if (t == "i") return "int";
  500. if (t == "2i") return "ivec2";
  501. if (t == "2f") return "vec2";
  502. if (t == "3f") return "vec3";
  503. if (t == "4f") return "vec4";
  504. if (t == "m4") return "mat4";
  505.  
  506. if (t == "t") return "sampler2D";
  507. if (t == "tc") return "samplerCube";
  508.  
  509. if (t == "3f[]") return null; // ignore this for now...
  510. if (t == "m4[]") return null; // ignore this for now...
  511. if (t == "f[]") return null; // ignore this for now...
  512.  
  513. console.warn("[CGL UNIFORM] unknown glsl type string ", t);
  514. };
  515.  
  516.  
  517. /**
  518. * @function setValue
  519. * @memberof Uniform
  520. * @instance
  521. * @param {Number|Array|Matrix|Texture} value
  522. */
  523.  
  524. export { Uniform };