💿🐜 Antkeeper source code https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

672 lines
18 KiB

  1. /*
  2. * Copyright (C) 2021 Christopher J. Howard
  3. *
  4. * This file is part of Antkeeper source code.
  5. *
  6. * Antkeeper source code is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Antkeeper source code is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "rasterizer/shader-input.hpp"
  20. #include "rasterizer/texture-2d.hpp"
  21. #include "rasterizer/texture-cube.hpp"
  22. #include <glad/glad.h>
  23. shader_input::shader_input(shader_program* program, std::size_t input_index, int gl_uniform_location, const std::string& name, shader_variable_type data_type, std::size_t element_count, int texture_unit):
  24. program(program),
  25. input_index(input_index),
  26. gl_uniform_location(gl_uniform_location),
  27. name(name),
  28. data_type(data_type),
  29. element_count(element_count),
  30. texture_unit(texture_unit)
  31. {}
  32. shader_input::~shader_input()
  33. {}
  34. bool shader_input::upload(const bool& value) const
  35. {
  36. if (gl_uniform_location == -1)
  37. return false;
  38. glUniform1i(gl_uniform_location, static_cast<GLint>(value));
  39. return true;
  40. }
  41. bool shader_input::upload(const bool2& value) const
  42. {
  43. if (gl_uniform_location == -1)
  44. return false;
  45. const GLint values[] = {value[0], value[1]};
  46. glUniform2iv(gl_uniform_location, 1, values);
  47. return true;
  48. }
  49. bool shader_input::upload(const bool3& value) const
  50. {
  51. if (gl_uniform_location == -1)
  52. return false;
  53. const GLint values[] = {value[0], value[1], value[2]};
  54. glUniform3iv(gl_uniform_location, 1, values);
  55. return true;
  56. }
  57. bool shader_input::upload(const bool4& value) const
  58. {
  59. if (gl_uniform_location == -1)
  60. return false;
  61. const GLint values[] = {value[0], value[1], value[2], value[3]};
  62. glUniform4iv(gl_uniform_location, 1, values);
  63. return true;
  64. }
  65. bool shader_input::upload(const int& value) const
  66. {
  67. if (gl_uniform_location == -1)
  68. return false;
  69. glUniform1i(gl_uniform_location, value);
  70. return true;
  71. }
  72. bool shader_input::upload(const int2& value) const
  73. {
  74. if (gl_uniform_location == -1)
  75. return false;
  76. glUniform2iv(gl_uniform_location, 1, value.data());
  77. return true;
  78. }
  79. bool shader_input::upload(const int3& value) const
  80. {
  81. if (gl_uniform_location == -1)
  82. return false;
  83. glUniform3iv(gl_uniform_location, 1, value.data());
  84. return true;
  85. }
  86. bool shader_input::upload(const int4& value) const
  87. {
  88. if (gl_uniform_location == -1)
  89. return false;
  90. glUniform4iv(gl_uniform_location, 1, value.data());
  91. return true;
  92. }
  93. bool shader_input::upload(const unsigned int& value) const
  94. {
  95. if (gl_uniform_location == -1)
  96. return false;
  97. glUniform1ui(gl_uniform_location, value);
  98. return true;
  99. }
  100. bool shader_input::upload(const uint2& value) const
  101. {
  102. if (gl_uniform_location == -1)
  103. return false;
  104. glUniform2uiv(gl_uniform_location, 1, value.data());
  105. return true;
  106. }
  107. bool shader_input::upload(const uint3& value) const
  108. {
  109. if (gl_uniform_location == -1)
  110. return false;
  111. glUniform3uiv(gl_uniform_location, 1, value.data());
  112. return true;
  113. }
  114. bool shader_input::upload(const uint4& value) const
  115. {
  116. if (gl_uniform_location == -1)
  117. return false;
  118. glUniform4uiv(gl_uniform_location, 1, value.data());
  119. return true;
  120. }
  121. bool shader_input::upload(const float& value) const
  122. {
  123. if (gl_uniform_location == -1)
  124. return false;
  125. glUniform1f(gl_uniform_location, value);
  126. return true;
  127. }
  128. bool shader_input::upload(const float2& value) const
  129. {
  130. if (gl_uniform_location == -1)
  131. return false;
  132. glUniform2fv(gl_uniform_location, 1, value.data());
  133. return true;
  134. }
  135. bool shader_input::upload(const float3& value) const
  136. {
  137. if (gl_uniform_location == -1)
  138. return false;
  139. glUniform3fv(gl_uniform_location, 1, value.data());
  140. return true;
  141. }
  142. bool shader_input::upload(const float4& value) const
  143. {
  144. if (gl_uniform_location == -1)
  145. return false;
  146. glUniform4fv(gl_uniform_location, 1, value.data());
  147. return true;
  148. }
  149. bool shader_input::upload(const float2x2& value) const
  150. {
  151. if (gl_uniform_location == -1)
  152. return false;
  153. glUniformMatrix2fv(gl_uniform_location, 1, GL_FALSE, value[0].data());
  154. return true;
  155. }
  156. bool shader_input::upload(const float3x3& value) const
  157. {
  158. if (gl_uniform_location == -1)
  159. return false;
  160. glUniformMatrix3fv(gl_uniform_location, 1, GL_FALSE, value[0].data());
  161. return true;
  162. }
  163. bool shader_input::upload(const float4x4& value) const
  164. {
  165. if (gl_uniform_location == -1)
  166. return false;
  167. glUniformMatrix4fv(gl_uniform_location, 1, GL_FALSE, value[0].data());
  168. return true;
  169. }
  170. bool shader_input::upload(const texture_2d* value) const
  171. {
  172. if (gl_uniform_location == -1)
  173. return false;
  174. // Bind texture to a texture unit reserved by this shader input
  175. glActiveTexture(GL_TEXTURE0 + texture_unit);
  176. glBindTexture(GL_TEXTURE_2D, value->gl_texture_id);
  177. // Upload texture unit index to shader
  178. glUniform1i(gl_uniform_location, texture_unit);
  179. return true;
  180. }
  181. bool shader_input::upload(const texture_cube* value) const
  182. {
  183. if (gl_uniform_location == -1)
  184. return false;
  185. // Bind texture to a texture unit reserved by this shader input
  186. glActiveTexture(GL_TEXTURE0 + texture_unit);
  187. glBindTexture(GL_TEXTURE_CUBE_MAP, value->gl_texture_id);
  188. // Upload texture unit index to shader
  189. glUniform1i(gl_uniform_location, texture_unit);
  190. return true;
  191. }
  192. bool shader_input::upload(std::size_t index, const bool& value) const
  193. {
  194. if (gl_uniform_location == -1)
  195. return false;
  196. glUniform1i(gl_uniform_location + static_cast<int>(index), static_cast<GLint>(value));
  197. return true;
  198. }
  199. bool shader_input::upload(std::size_t index, const bool2& value) const
  200. {
  201. if (gl_uniform_location == -1)
  202. return false;
  203. const GLint values[] = {value[0], value[1]};
  204. glUniform2iv(gl_uniform_location + static_cast<int>(index), 1, values);
  205. return true;
  206. }
  207. bool shader_input::upload(std::size_t index, const bool3& value) const
  208. {
  209. if (gl_uniform_location == -1)
  210. return false;
  211. const GLint values[] = {value[0], value[1], value[3]};
  212. glUniform3iv(gl_uniform_location + static_cast<int>(index), 1, values);
  213. return true;
  214. }
  215. bool shader_input::upload(std::size_t index, const bool4& value) const
  216. {
  217. if (gl_uniform_location == -1)
  218. return false;
  219. const GLint values[] = {value[0], value[1], value[3], value[4]};
  220. glUniform4iv(gl_uniform_location + static_cast<int>(index), 1, values);
  221. return true;
  222. }
  223. bool shader_input::upload(std::size_t index, const int& value) const
  224. {
  225. if (gl_uniform_location == -1)
  226. return false;
  227. glUniform1i(gl_uniform_location + static_cast<int>(index), value);
  228. return true;
  229. }
  230. bool shader_input::upload(std::size_t index, const int2& value) const
  231. {
  232. if (gl_uniform_location == -1)
  233. return false;
  234. glUniform2iv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  235. return true;
  236. }
  237. bool shader_input::upload(std::size_t index, const int3& value) const
  238. {
  239. if (gl_uniform_location == -1)
  240. return false;
  241. glUniform3iv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  242. return true;
  243. }
  244. bool shader_input::upload(std::size_t index, const int4& value) const
  245. {
  246. if (gl_uniform_location == -1)
  247. return false;
  248. glUniform4iv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  249. return true;
  250. }
  251. bool shader_input::upload(std::size_t index, const unsigned int& value) const
  252. {
  253. if (gl_uniform_location == -1)
  254. return false;
  255. glUniform1ui(gl_uniform_location + static_cast<int>(index), value);
  256. return true;
  257. }
  258. bool shader_input::upload(std::size_t index, const uint2& value) const
  259. {
  260. if (gl_uniform_location == -1)
  261. return false;
  262. glUniform2uiv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  263. return true;
  264. }
  265. bool shader_input::upload(std::size_t index, const uint3& value) const
  266. {
  267. if (gl_uniform_location == -1)
  268. return false;
  269. glUniform3uiv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  270. return true;
  271. }
  272. bool shader_input::upload(std::size_t index, const uint4& value) const
  273. {
  274. if (gl_uniform_location == -1)
  275. return false;
  276. glUniform4uiv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  277. return true;
  278. }
  279. bool shader_input::upload(std::size_t index, const float& value) const
  280. {
  281. if (gl_uniform_location == -1)
  282. return false;
  283. glUniform1f(gl_uniform_location + static_cast<int>(index), value);
  284. return true;
  285. }
  286. bool shader_input::upload(std::size_t index, const float2& value) const
  287. {
  288. if (gl_uniform_location == -1)
  289. return false;
  290. glUniform2fv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  291. return true;
  292. }
  293. bool shader_input::upload(std::size_t index, const float3& value) const
  294. {
  295. if (gl_uniform_location == -1)
  296. return false;
  297. glUniform3fv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  298. return true;
  299. }
  300. bool shader_input::upload(std::size_t index, const float4& value) const
  301. {
  302. if (gl_uniform_location == -1)
  303. return false;
  304. glUniform4fv(gl_uniform_location + static_cast<int>(index), 1, value.data());
  305. return true;
  306. }
  307. bool shader_input::upload(std::size_t index, const float2x2& value) const
  308. {
  309. if (gl_uniform_location == -1)
  310. return false;
  311. glUniformMatrix2fv(gl_uniform_location + static_cast<int>(index) * 2, 1, GL_FALSE, value[0].data());
  312. return true;
  313. }
  314. bool shader_input::upload(std::size_t index, const float3x3& value) const
  315. {
  316. if (gl_uniform_location == -1)
  317. return false;
  318. glUniformMatrix3fv(gl_uniform_location + static_cast<int>(index) * 3, 1, GL_FALSE, value[0].data());
  319. return true;
  320. }
  321. bool shader_input::upload(std::size_t index, const float4x4& value) const
  322. {
  323. if (gl_uniform_location == -1)
  324. return false;
  325. glUniformMatrix4fv(gl_uniform_location + static_cast<int>(index) * 4, 1, GL_FALSE, value[0].data());
  326. return true;
  327. }
  328. bool shader_input::upload(std::size_t index, const texture_2d* value) const
  329. {
  330. if (gl_uniform_location == -1)
  331. return false;
  332. // Bind texture to a texture unit reserved by this shader input
  333. glActiveTexture(GL_TEXTURE0 + texture_unit + static_cast<int>(index));
  334. glBindTexture(GL_TEXTURE_2D, value->gl_texture_id);
  335. // Upload texture unit index to shader
  336. glUniform1i(gl_uniform_location + static_cast<int>(index), texture_unit + static_cast<int>(index));
  337. return true;
  338. }
  339. bool shader_input::upload(std::size_t index, const texture_cube* value) const
  340. {
  341. if (gl_uniform_location == -1)
  342. return false;
  343. // Bind texture to a texture unit reserved by this shader input
  344. glActiveTexture(GL_TEXTURE0 + texture_unit + static_cast<int>(index));
  345. glBindTexture(GL_TEXTURE_CUBE_MAP, value->gl_texture_id);
  346. // Upload texture unit index to shader
  347. glUniform1i(gl_uniform_location + static_cast<int>(index), texture_unit + static_cast<int>(index));
  348. return true;
  349. }
  350. bool shader_input::upload(std::size_t index, const bool* values, std::size_t count) const
  351. {
  352. if (gl_uniform_location == -1)
  353. return false;
  354. int* int_values = new int[count];
  355. for (std::size_t i = 0; i < count; ++i)
  356. int_values[i] = values[i];
  357. glUniform1iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &(*int_values));
  358. delete[] int_values;
  359. return true;
  360. }
  361. bool shader_input::upload(std::size_t index, const bool2* values, std::size_t count) const
  362. {
  363. if (gl_uniform_location == -1)
  364. return false;
  365. int2* int2_values = new int2[count];
  366. for (std::size_t i = 0; i < count; ++i)
  367. int2_values[i] = {values[i][0], values[i][1]};
  368. glUniform2iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &((*int2_values)[0]));
  369. delete[] int2_values;
  370. return true;
  371. }
  372. bool shader_input::upload(std::size_t index, const bool3* values, std::size_t count) const
  373. {
  374. if (gl_uniform_location == -1)
  375. return false;
  376. int3* int3_values = new int3[count];
  377. for (std::size_t i = 0; i < count; ++i)
  378. int3_values[i] = {values[i][0], values[i][1], values[i][2]};
  379. glUniform3iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &((*int3_values)[0]));
  380. delete[] int3_values;
  381. return true;
  382. }
  383. bool shader_input::upload(std::size_t index, const bool4* values, std::size_t count) const
  384. {
  385. if (gl_uniform_location == -1)
  386. return false;
  387. int4* int4_values = new int4[count];
  388. for (std::size_t i = 0; i < count; ++i)
  389. int4_values[i] = {values[i][0], values[i][1], values[i][2], values[i][3]};
  390. glUniform4iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &((*int4_values)[0]));
  391. delete[] int4_values;
  392. return true;
  393. }
  394. bool shader_input::upload(std::size_t index, const int* values, std::size_t count) const
  395. {
  396. if (gl_uniform_location == -1)
  397. return false;
  398. glUniform1iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &(*values));
  399. return true;
  400. }
  401. bool shader_input::upload(std::size_t index, const int2* values, std::size_t count) const
  402. {
  403. if (gl_uniform_location == -1)
  404. return false;
  405. glUniform2iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  406. return true;
  407. }
  408. bool shader_input::upload(std::size_t index, const int3* values, std::size_t count) const
  409. {
  410. if (gl_uniform_location == -1)
  411. return false;
  412. glUniform3iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  413. return true;
  414. }
  415. bool shader_input::upload(std::size_t index, const int4* values, std::size_t count) const
  416. {
  417. if (gl_uniform_location == -1)
  418. return false;
  419. glUniform4iv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  420. return true;
  421. }
  422. bool shader_input::upload(std::size_t index, const unsigned int* values, std::size_t count) const
  423. {
  424. if (gl_uniform_location == -1)
  425. return false;
  426. glUniform1uiv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &(*values));
  427. return true;
  428. }
  429. bool shader_input::upload(std::size_t index, const uint2* values, std::size_t count) const
  430. {
  431. if (gl_uniform_location == -1)
  432. return false;
  433. glUniform2uiv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  434. return true;
  435. }
  436. bool shader_input::upload(std::size_t index, const uint3* values, std::size_t count) const
  437. {
  438. if (gl_uniform_location == -1)
  439. return false;
  440. glUniform3uiv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  441. return true;
  442. }
  443. bool shader_input::upload(std::size_t index, const uint4* values, std::size_t count) const
  444. {
  445. if (gl_uniform_location == -1)
  446. return false;
  447. glUniform4uiv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  448. return true;
  449. }
  450. bool shader_input::upload(std::size_t index, const float* values, std::size_t count) const
  451. {
  452. if (gl_uniform_location == -1)
  453. return false;
  454. glUniform1fv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), &(*values));
  455. return true;
  456. }
  457. bool shader_input::upload(std::size_t index, const float2* values, std::size_t count) const
  458. {
  459. if (gl_uniform_location == -1)
  460. return false;
  461. glUniform2fv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  462. return true;
  463. }
  464. bool shader_input::upload(std::size_t index, const float3* values, std::size_t count) const
  465. {
  466. if (gl_uniform_location == -1)
  467. return false;
  468. glUniform3fv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  469. return true;
  470. }
  471. bool shader_input::upload(std::size_t index, const float4* values, std::size_t count) const
  472. {
  473. if (gl_uniform_location == -1)
  474. return false;
  475. glUniform4fv(gl_uniform_location + static_cast<int>(index), static_cast<GLsizei>(count), (*values).data());
  476. return true;
  477. }
  478. bool shader_input::upload(std::size_t index, const float2x2* values, std::size_t count) const
  479. {
  480. if (gl_uniform_location == -1)
  481. return false;
  482. glUniformMatrix2fv(gl_uniform_location + static_cast<int>(index) * 2, static_cast<GLsizei>(count), GL_FALSE, (*values)[0].data());
  483. return true;
  484. }
  485. bool shader_input::upload(std::size_t index, const float3x3* values, std::size_t count) const
  486. {
  487. if (gl_uniform_location == -1)
  488. return false;
  489. glUniformMatrix3fv(gl_uniform_location + static_cast<int>(index) * 3, static_cast<GLsizei>(count), GL_FALSE, (*values)[0].data());
  490. return true;
  491. }
  492. bool shader_input::upload(std::size_t index, const float4x4* values, std::size_t count) const
  493. {
  494. if (gl_uniform_location == -1)
  495. return false;
  496. glUniformMatrix4fv(gl_uniform_location + static_cast<int>(index) * 4, static_cast<GLsizei>(count), GL_FALSE, (*values)[0].data());
  497. return true;
  498. }
  499. bool shader_input::upload(std::size_t index, const texture_2d** values, std::size_t count) const
  500. {
  501. if (gl_uniform_location == -1)
  502. return false;
  503. for (std::size_t i = 0; i < count; ++i)
  504. {
  505. // Bind texture to a texture unit reserved by this shader input
  506. glActiveTexture(GL_TEXTURE0 + texture_unit + static_cast<int>(index + i));
  507. glBindTexture(GL_TEXTURE_2D, values[i]->gl_texture_id);
  508. // Upload texture unit index to shader
  509. glUniform1i(gl_uniform_location + static_cast<int>(index + i), texture_unit + static_cast<int>(index + i));
  510. }
  511. return true;
  512. }
  513. bool shader_input::upload(std::size_t index, const texture_cube** values, std::size_t count) const
  514. {
  515. if (gl_uniform_location == -1)
  516. return false;
  517. for (std::size_t i = 0; i < count; ++i)
  518. {
  519. // Bind texture to a texture unit reserved by this shader input
  520. glActiveTexture(GL_TEXTURE0 + texture_unit + static_cast<int>(index + i));
  521. glBindTexture(GL_TEXTURE_CUBE_MAP, values[i]->gl_texture_id);
  522. // Upload texture unit index to shader
  523. glUniform1i(gl_uniform_location + static_cast<int>(index + i), texture_unit + static_cast<int>(index + i));
  524. }
  525. return true;
  526. }