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

663 lines
25 KiB

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