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

374 lines
9.5 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. #ifndef ANTKEEPER_RENDER_MATERIAL_VARIABLE_HPP
  20. #define ANTKEEPER_RENDER_MATERIAL_VARIABLE_HPP
  21. #include <engine/math/vector.hpp>
  22. #include <engine/math/matrix.hpp>
  23. #include <engine/gl/texture-1d.hpp>
  24. #include <engine/gl/texture-2d.hpp>
  25. #include <engine/gl/texture-3d.hpp>
  26. #include <engine/gl/texture-cube.hpp>
  27. #include <engine/render/material-variable-type.hpp>
  28. #include <memory>
  29. #include <vector>
  30. namespace render {
  31. /**
  32. * Abstract base class for material variables.
  33. */
  34. class material_variable_base
  35. {
  36. public:
  37. /**
  38. * Destructs a material variable base.
  39. */
  40. virtual ~material_variable_base() = default;
  41. /**
  42. * Returns the material variable data type.
  43. */
  44. [[nodiscard]] virtual constexpr material_variable_type type() const noexcept = 0;
  45. /**
  46. * Returns the number of elements in an array variable, or `1` if the variable is not an array.
  47. */
  48. [[nodiscard]] virtual std::size_t size() const noexcept = 0;
  49. /**
  50. * Creates a copy of this material property.
  51. */
  52. [[nodiscard]] virtual std::unique_ptr<material_variable_base> clone() const = 0;
  53. };
  54. /**
  55. * Material variable.
  56. *
  57. * @tparam T Material variable value type.
  58. */
  59. template <class T>
  60. class material_variable: public material_variable_base
  61. {
  62. public:
  63. /// Material variable element type.
  64. using element_type = T;
  65. /**
  66. * Constructs a material variable.
  67. *
  68. * @param size Number of elements in the array, or `1` if the variable is not an array.
  69. * @param value Value with which to initialize the elements.
  70. */
  71. inline explicit material_variable(std::size_t size, const element_type& value = element_type()):
  72. elements(size, value)
  73. {}
  74. /**
  75. * Constructs a material variable with a single element.
  76. */
  77. inline material_variable():
  78. material_variable(1)
  79. {}
  80. /**
  81. * Constructs a material variable from a list of element values.
  82. *
  83. * @param list List of element values.
  84. */
  85. inline explicit material_variable(std::initializer_list<element_type> list):
  86. elements(list)
  87. {}
  88. [[nodiscard]] virtual constexpr material_variable_type type() const noexcept override;
  89. [[nodiscard]] inline std::size_t size() const noexcept override
  90. {
  91. return elements.size();
  92. }
  93. [[nodiscard]] inline std::unique_ptr<material_variable_base> clone() const override
  94. {
  95. return std::make_unique<material_variable<T>>(*this);
  96. }
  97. /**
  98. * Sets the value of the the variable, or the value of the first element if the variable is an array.
  99. *
  100. * @param value Value to set.
  101. */
  102. inline void set(const element_type& value)
  103. {
  104. elements.front() = value;
  105. }
  106. /**
  107. * Sets the value of a single element in an array variable.
  108. *
  109. * @param index Index of an element.
  110. * @param value Value to set.
  111. */
  112. inline void set(std::size_t index, const element_type& value)
  113. {
  114. elements[index] = value;
  115. }
  116. /**
  117. * Returns a reference to the first element in the array.
  118. */
  119. [[nodiscard]] inline const element_type& get() const
  120. {
  121. return elements.front();
  122. }
  123. /**
  124. * Returns a reference to the element at a given index.
  125. *
  126. * @param index Index of an element.
  127. *
  128. * @return Reference to the element at @p index.
  129. */
  130. [[nodiscard]] inline const element_type& get(std::size_t index) const
  131. {
  132. return elements[index];
  133. }
  134. /**
  135. * Returns a pointer to the element array.
  136. */
  137. [[nodiscard]] inline const element_type* data() const noexcept
  138. {
  139. return elements.data();
  140. }
  141. private:
  142. std::vector<element_type> elements;
  143. };
  144. /// Boolean material variable.
  145. using matvar_bool = material_variable<bool>;
  146. /// 2-dimensional boolean vector material variable.
  147. using matvar_bvec2 = material_variable<math::bvec2>;
  148. /// 3-dimensional boolean vector material variable.
  149. using matvar_bvec3 = material_variable<math::bvec3>;
  150. /// 4-dimensional boolean vector material variable.
  151. using matvar_bvec4 = material_variable<math::bvec4>;
  152. /// Integer material variable.
  153. using matvar_int = material_variable<int>;
  154. /// 2-dimensional integer vector material variable.
  155. using matvar_ivec2 = material_variable<math::ivec2>;
  156. /// 3-dimensional integer vector material variable.
  157. using matvar_ivec3 = material_variable<math::ivec3>;
  158. /// 4-dimensional integer vector material variable.
  159. using matvar_ivec4 = material_variable<math::ivec4>;
  160. /// Unsigned integer material variable.
  161. using matvar_uint = material_variable<unsigned int>;
  162. /// 2-dimensional unsigned integer vector material variable.
  163. using matvar_uvec2 = material_variable<math::uvec2>;
  164. /// 3-dimensional unsigned integer vector material variable.
  165. using matvar_uvec3 = material_variable<math::uvec3>;
  166. /// 4-dimensional unsigned integer vector material variable.
  167. using matvar_uvec4 = material_variable<math::uvec4>;
  168. /// Floating-point material variable.
  169. using matvar_float = material_variable<float>;
  170. /// 2-dimensional floating-point vector material variable.
  171. using matvar_fvec2 = material_variable<math::fvec2>;
  172. /// 3-dimensional floating-point vector material variable.
  173. using matvar_fvec3 = material_variable<math::fvec3>;
  174. /// 4-dimensional floating-point vector material variable.
  175. using matvar_fvec4 = material_variable<math::fvec4>;
  176. /// 2x2 floating-point matrix material variable.
  177. using matvar_fmat2 = material_variable<math::fmat2>;
  178. /// 3x3 floating-point matrix material variable.
  179. using matvar_fmat3 = material_variable<math::fmat3>;
  180. /// 4x4 floating-point matrix material variable.
  181. using matvar_fmat4 = material_variable<math::fmat4>;
  182. /// 1-dimensional texture material variable.
  183. using matvar_texture_1d = material_variable<std::shared_ptr<gl::texture_1d>>;
  184. /// 2-dimensional texture material variable.
  185. using matvar_texture_2d = material_variable<std::shared_ptr<gl::texture_2d>>;
  186. /// 3-dimensional texture material variable.
  187. using matvar_texture_3d = material_variable<std::shared_ptr<gl::texture_3d>>;
  188. /// Cube texture material variable.
  189. using matvar_texture_cube = material_variable<std::shared_ptr<gl::texture_cube>>;
  190. template <>
  191. inline constexpr material_variable_type matvar_bool::type() const noexcept
  192. {
  193. return material_variable_type::bvec1;
  194. }
  195. template <>
  196. inline constexpr material_variable_type matvar_bvec2::type() const noexcept
  197. {
  198. return material_variable_type::bvec2;
  199. }
  200. template <>
  201. inline constexpr material_variable_type matvar_bvec3::type() const noexcept
  202. {
  203. return material_variable_type::bvec3;
  204. }
  205. template <>
  206. inline constexpr material_variable_type matvar_bvec4::type() const noexcept
  207. {
  208. return material_variable_type::bvec4;
  209. }
  210. template <>
  211. inline constexpr material_variable_type matvar_int::type() const noexcept
  212. {
  213. return material_variable_type::ivec1;
  214. }
  215. template <>
  216. inline constexpr material_variable_type matvar_ivec2::type() const noexcept
  217. {
  218. return material_variable_type::ivec2;
  219. }
  220. template <>
  221. inline constexpr material_variable_type matvar_ivec3::type() const noexcept
  222. {
  223. return material_variable_type::ivec3;
  224. }
  225. template <>
  226. inline constexpr material_variable_type matvar_ivec4::type() const noexcept
  227. {
  228. return material_variable_type::ivec4;
  229. }
  230. template <>
  231. inline constexpr material_variable_type matvar_uint::type() const noexcept
  232. {
  233. return material_variable_type::uvec1;
  234. }
  235. template <>
  236. inline constexpr material_variable_type matvar_uvec2::type() const noexcept
  237. {
  238. return material_variable_type::uvec2;
  239. }
  240. template <>
  241. inline constexpr material_variable_type matvar_uvec3::type() const noexcept
  242. {
  243. return material_variable_type::uvec3;
  244. }
  245. template <>
  246. inline constexpr material_variable_type matvar_uvec4::type() const noexcept
  247. {
  248. return material_variable_type::uvec4;
  249. }
  250. template <>
  251. inline constexpr material_variable_type matvar_float::type() const noexcept
  252. {
  253. return material_variable_type::fvec1;
  254. }
  255. template <>
  256. inline constexpr material_variable_type matvar_fvec2::type() const noexcept
  257. {
  258. return material_variable_type::fvec2;
  259. }
  260. template <>
  261. inline constexpr material_variable_type matvar_fvec3::type() const noexcept
  262. {
  263. return material_variable_type::fvec3;
  264. }
  265. template <>
  266. inline constexpr material_variable_type matvar_fvec4::type() const noexcept
  267. {
  268. return material_variable_type::fvec4;
  269. }
  270. template <>
  271. inline constexpr material_variable_type matvar_fmat2::type() const noexcept
  272. {
  273. return material_variable_type::fmat2;
  274. }
  275. template <>
  276. inline constexpr material_variable_type matvar_fmat3::type() const noexcept
  277. {
  278. return material_variable_type::fmat3;
  279. }
  280. template <>
  281. inline constexpr material_variable_type matvar_fmat4::type() const noexcept
  282. {
  283. return material_variable_type::fmat4;
  284. }
  285. template <>
  286. inline constexpr material_variable_type matvar_texture_1d::type() const noexcept
  287. {
  288. return material_variable_type::texture_1d;
  289. }
  290. template <>
  291. inline constexpr material_variable_type matvar_texture_2d::type() const noexcept
  292. {
  293. return material_variable_type::texture_2d;
  294. }
  295. template <>
  296. inline constexpr material_variable_type matvar_texture_3d::type() const noexcept
  297. {
  298. return material_variable_type::texture_3d;
  299. }
  300. template <>
  301. inline constexpr material_variable_type matvar_texture_cube::type() const noexcept
  302. {
  303. return material_variable_type::texture_cube;
  304. }
  305. } // namespace render
  306. #endif // ANTKEEPER_RENDER_MATERIAL_VARIABLE_HPP