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

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