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

298 lines
5.9 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/image-view.hpp>
  20. #include <engine/gl/opengl/gl-format-lut.hpp>
  21. #include <stdexcept>
  22. #include <glad/gl.h>
  23. namespace gl {
  24. image_view::image_view
  25. (
  26. std::shared_ptr<gl::image> image,
  27. std::uint8_t dimensionality,
  28. gl::format format,
  29. std::uint32_t first_mip_level,
  30. std::uint32_t mip_level_count,
  31. std::uint32_t first_array_layer,
  32. std::uint32_t array_layer_count,
  33. std::uint8_t flags
  34. )
  35. {
  36. if (!image)
  37. {
  38. throw std::invalid_argument("Image view has null image.");
  39. }
  40. if (format == gl::format::undefined)
  41. {
  42. format = image->get_format();
  43. }
  44. const auto format_index = std::to_underlying(format);
  45. const auto gl_internal_format = gl_format_lut[format_index][0];
  46. if (!gl_internal_format)
  47. {
  48. throw std::invalid_argument("Image view has unsupported format.");
  49. }
  50. if (!mip_level_count)
  51. {
  52. throw std::invalid_argument("Image view has zero mip levels.");
  53. }
  54. if (first_mip_level + mip_level_count > image->get_mip_levels())
  55. {
  56. throw std::out_of_range("Image view mip range out of image mip range.");
  57. }
  58. if (!array_layer_count)
  59. {
  60. throw std::invalid_argument("Image view has zero array layers.");
  61. }
  62. if (first_array_layer + array_layer_count > image->get_array_layers())
  63. {
  64. throw std::out_of_range("Image view array layer range out of image array layer range.");
  65. }
  66. if (dimensionality != image->get_dimensionality())
  67. {
  68. throw std::invalid_argument("Image view dimensionality must match image dimensionality.");
  69. }
  70. if (flags & std::to_underlying(image_view_flag::cube))
  71. {
  72. if (!image->is_cube_compatible())
  73. {
  74. throw std::invalid_argument("Cube image views must be constructed from cube-compatible images.");
  75. }
  76. if (array_layer_count % 6 != 0)
  77. {
  78. throw std::invalid_argument("Cube image views array layer count must be a multiple of 6.");
  79. }
  80. }
  81. m_image = image;
  82. m_dimensionality = dimensionality;
  83. m_format = format;
  84. m_first_mip_level = first_mip_level;
  85. m_mip_level_count = mip_level_count;
  86. m_first_array_layer = first_array_layer;
  87. m_array_layer_count = array_layer_count;
  88. m_flags = flags;
  89. unsigned int gl_target = 0;
  90. switch (dimensionality)
  91. {
  92. case 1:
  93. gl_target = is_array() ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D;
  94. break;
  95. case 2:
  96. if (is_cube())
  97. {
  98. gl_target = is_array() ? GL_TEXTURE_CUBE_MAP_ARRAY : GL_TEXTURE_CUBE_MAP;
  99. }
  100. else
  101. {
  102. gl_target = is_array() ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
  103. }
  104. break;
  105. case 3:
  106. gl_target = GL_TEXTURE_3D;
  107. break;
  108. default:
  109. break;
  110. }
  111. glGenTextures(1, &m_gl_texture_name);
  112. glTextureView
  113. (
  114. m_gl_texture_name,
  115. gl_target,
  116. m_image->m_gl_texture_name,
  117. gl_internal_format,
  118. m_first_mip_level,
  119. m_mip_level_count,
  120. m_first_array_layer,
  121. m_array_layer_count
  122. );
  123. }
  124. image_view::~image_view()
  125. {
  126. glDeleteTextures(1, &m_gl_texture_name);
  127. }
  128. image_view_1d::image_view_1d
  129. (
  130. std::shared_ptr<gl::image> image,
  131. gl::format format,
  132. std::uint32_t first_mip_level,
  133. std::uint32_t mip_level_count,
  134. std::uint32_t first_array_layer
  135. ):
  136. image_view
  137. (
  138. image,
  139. 1,
  140. format,
  141. first_mip_level,
  142. mip_level_count,
  143. first_array_layer,
  144. 1,
  145. 0
  146. )
  147. {}
  148. image_view_1d_array::image_view_1d_array
  149. (
  150. std::shared_ptr<gl::image> image,
  151. gl::format format,
  152. std::uint32_t first_mip_level,
  153. std::uint32_t mip_level_count,
  154. std::uint32_t first_array_layer,
  155. std::uint32_t array_layer_count
  156. ):
  157. image_view
  158. (
  159. image,
  160. 1,
  161. format,
  162. first_mip_level,
  163. mip_level_count,
  164. first_array_layer,
  165. array_layer_count,
  166. std::to_underlying(image_view_flag::array)
  167. )
  168. {}
  169. image_view_2d::image_view_2d
  170. (
  171. std::shared_ptr<gl::image> image,
  172. gl::format format,
  173. std::uint32_t first_mip_level,
  174. std::uint32_t mip_level_count,
  175. std::uint32_t first_array_layer
  176. ):
  177. image_view
  178. (
  179. image,
  180. 2,
  181. format,
  182. first_mip_level,
  183. mip_level_count,
  184. first_array_layer,
  185. 1,
  186. 0
  187. )
  188. {}
  189. image_view_2d_array::image_view_2d_array
  190. (
  191. std::shared_ptr<gl::image> image,
  192. gl::format format,
  193. std::uint32_t first_mip_level,
  194. std::uint32_t mip_level_count,
  195. std::uint32_t first_array_layer,
  196. std::uint32_t array_layer_count
  197. ):
  198. image_view
  199. (
  200. image,
  201. 2,
  202. format,
  203. first_mip_level,
  204. mip_level_count,
  205. first_array_layer,
  206. array_layer_count,
  207. std::to_underlying(image_view_flag::array)
  208. )
  209. {}
  210. image_view_3d::image_view_3d
  211. (
  212. std::shared_ptr<gl::image> image,
  213. gl::format format,
  214. std::uint32_t first_mip_level,
  215. std::uint32_t mip_level_count
  216. ):
  217. image_view
  218. (
  219. image,
  220. 3,
  221. format,
  222. first_mip_level,
  223. mip_level_count,
  224. 0,
  225. 1,
  226. 0
  227. )
  228. {}
  229. image_view_cube::image_view_cube
  230. (
  231. std::shared_ptr<gl::image> image,
  232. gl::format format,
  233. std::uint32_t first_mip_level,
  234. std::uint32_t mip_level_count,
  235. std::uint32_t first_array_layer
  236. ):
  237. image_view
  238. (
  239. image,
  240. 2,
  241. format,
  242. first_mip_level,
  243. mip_level_count,
  244. first_array_layer,
  245. 6,
  246. std::to_underlying(image_view_flag::cube)
  247. )
  248. {}
  249. image_view_cube_array::image_view_cube_array
  250. (
  251. std::shared_ptr<gl::image> image,
  252. gl::format format,
  253. std::uint32_t first_mip_level,
  254. std::uint32_t mip_level_count,
  255. std::uint32_t first_array_layer,
  256. std::uint32_t array_layer_count
  257. ):
  258. image_view
  259. (
  260. image,
  261. 2,
  262. format,
  263. first_mip_level,
  264. mip_level_count,
  265. first_array_layer,
  266. array_layer_count,
  267. std::to_underlying(image_view_flag::array) | std::to_underlying(image_view_flag::cube)
  268. )
  269. {}
  270. } // namespace gl