💿🐜 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.

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