Antkeeper  0.0.1
image-view.cpp
Go to the documentation of this file.
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 
20 #include <engine/gl/image-view.hpp>
22 #include <stdexcept>
23 #include <glad/gl.h>
24 
25 namespace gl {
26 
28 (
29  std::shared_ptr<gl::image> image,
30  std::uint8_t dimensionality,
32  std::uint32_t first_mip_level,
33  std::uint32_t mip_level_count,
34  std::uint32_t first_array_layer,
35  std::uint32_t array_layer_count,
36  std::uint8_t flags
37 )
38 {
39  if (!image)
40  {
41  throw std::invalid_argument("Image view has null image.");
42  }
43 
45  {
46  format = image->get_format();
47  }
48 
49  const auto format_index = std::to_underlying(format);
50  const auto gl_internal_format = gl_format_lut[format_index][0];
51 
52  if (!gl_internal_format)
53  {
54  throw std::invalid_argument("Image view has unsupported format.");
55  }
56 
57  if (!mip_level_count)
58  {
59  throw std::invalid_argument("Image view has zero mip levels.");
60  }
61 
62  if (first_mip_level + mip_level_count > image->get_mip_levels())
63  {
64  throw std::out_of_range("Image view mip range out of image mip range.");
65  }
66 
67  if (!array_layer_count)
68  {
69  throw std::invalid_argument("Image view has zero array layers.");
70  }
71 
72  if (first_array_layer + array_layer_count > image->get_array_layers())
73  {
74  throw std::out_of_range("Image view array layer range out of image array layer range.");
75  }
76 
77  if (dimensionality != image->get_dimensionality())
78  {
79  throw std::invalid_argument("Image view dimensionality must match image dimensionality.");
80  }
81 
82  if (flags & std::to_underlying(image_view_flag::cube))
83  {
84  if (!image->is_cube_compatible())
85  {
86  throw std::invalid_argument("Cube image views must be constructed from cube-compatible images.");
87  }
88 
89  if (array_layer_count % 6 != 0)
90  {
91  throw std::invalid_argument("Cube image views array layer count must be a multiple of 6.");
92  }
93  }
94 
95  m_image = image;
96  m_dimensionality = dimensionality;
97  m_format = format;
98  m_first_mip_level = first_mip_level;
99  m_mip_level_count = mip_level_count;
100  m_first_array_layer = first_array_layer;
101  m_array_layer_count = array_layer_count;
102  m_flags = flags;
103 
104  unsigned int gl_target = 0;
105  switch (dimensionality)
106  {
107  case 1:
108  gl_target = is_array() ? GL_TEXTURE_1D_ARRAY : GL_TEXTURE_1D;
109  break;
110 
111  case 2:
112  if (is_cube())
113  {
114  gl_target = is_array() ? GL_TEXTURE_CUBE_MAP_ARRAY : GL_TEXTURE_CUBE_MAP;
115  }
116  else
117  {
118  gl_target = is_array() ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
119  }
120  break;
121 
122  case 3:
123  gl_target = GL_TEXTURE_3D;
124  break;
125 
126  default:
127  break;
128  }
129 
130  glGenTextures(1, &m_gl_texture_name);
131  glTextureView
132  (
133  m_gl_texture_name,
134  gl_target,
135  m_image->m_gl_texture_name,
136  gl_internal_format,
137  m_first_mip_level,
138  m_mip_level_count,
139  m_first_array_layer,
140  m_array_layer_count
141  );
142 }
143 
145 {
146  glDeleteTextures(1, &m_gl_texture_name);
147 }
148 
150 (
151  std::shared_ptr<gl::image> image,
153  std::uint32_t first_mip_level,
154  std::uint32_t mip_level_count,
155  std::uint32_t first_array_layer
156 ):
157  image_view
158  (
159  image,
160  1,
161  format,
162  first_mip_level,
163  mip_level_count,
164  first_array_layer,
165  1,
166  0
167  )
168 {}
169 
171 (
172  std::shared_ptr<gl::image> image,
174  std::uint32_t first_mip_level,
175  std::uint32_t mip_level_count,
176  std::uint32_t first_array_layer,
177  std::uint32_t array_layer_count
178 ):
179  image_view
180  (
181  image,
182  1,
183  format,
184  first_mip_level,
185  mip_level_count,
186  first_array_layer,
187  array_layer_count,
188  std::to_underlying(image_view_flag::array)
189  )
190 {}
191 
193 (
194  std::shared_ptr<gl::image> image,
196  std::uint32_t first_mip_level,
197  std::uint32_t mip_level_count,
198  std::uint32_t first_array_layer
199 ):
200  image_view
201  (
202  image,
203  2,
204  format,
205  first_mip_level,
206  mip_level_count,
207  first_array_layer,
208  1,
209  0
210  )
211 {}
212 
214 (
215  std::shared_ptr<gl::image> image,
217  std::uint32_t first_mip_level,
218  std::uint32_t mip_level_count,
219  std::uint32_t first_array_layer,
220  std::uint32_t array_layer_count
221 ):
222  image_view
223  (
224  image,
225  2,
226  format,
227  first_mip_level,
228  mip_level_count,
229  first_array_layer,
230  array_layer_count,
231  std::to_underlying(image_view_flag::array)
232  )
233 {}
234 
236 (
237  std::shared_ptr<gl::image> image,
239  std::uint32_t first_mip_level,
240  std::uint32_t mip_level_count
241 ):
242  image_view
243  (
244  image,
245  3,
246  format,
247  first_mip_level,
248  mip_level_count,
249  0,
250  1,
251  0
252  )
253 {}
254 
256 (
257  std::shared_ptr<gl::image> image,
259  std::uint32_t first_mip_level,
260  std::uint32_t mip_level_count,
261  std::uint32_t first_array_layer
262 ):
263  image_view
264  (
265  image,
266  2,
267  format,
268  first_mip_level,
269  mip_level_count,
270  first_array_layer,
271  6,
272  std::to_underlying(image_view_flag::cube)
273  )
274 {}
275 
277 (
278  std::shared_ptr<gl::image> image,
280  std::uint32_t first_mip_level,
281  std::uint32_t mip_level_count,
282  std::uint32_t first_array_layer,
283  std::uint32_t array_layer_count
284 ):
285  image_view
286  (
287  image,
288  2,
289  format,
290  first_mip_level,
291  mip_level_count,
292  first_array_layer,
293  array_layer_count,
294  std::to_underlying(image_view_flag::array) | std::to_underlying(image_view_flag::cube)
295  )
296 {}
297 
298 } // namespace gl
image_view_1d_array(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0, std::uint32_t array_layer_count=1)
Definition: image-view.cpp:171
image_view_1d(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0)
Definition: image-view.cpp:150
image_view_2d_array(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0, std::uint32_t array_layer_count=1)
Definition: image-view.cpp:214
image_view_2d(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0)
Definition: image-view.cpp:193
image_view_3d(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1)
Definition: image-view.cpp:236
image_view_cube_array(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0, std::uint32_t array_layer_count=6)
Definition: image-view.cpp:277
image_view_cube(std::shared_ptr< gl::image > image, gl::format format=gl::format::undefined, std::uint32_t first_mip_level=0, std::uint32_t mip_level_count=1, std::uint32_t first_array_layer=0)
Definition: image-view.cpp:256
Image view.
Definition: image-view.hpp:34
constexpr bool is_cube() const noexcept
Returns true if the image view is a cube map view, false otherwise.
Definition: image-view.hpp:111
virtual ~image_view()=0
Destructs an image view.
Definition: image-view.cpp:144
image_view(const image_view &)=delete
constexpr bool is_array() const noexcept
Returns true if the image view is an array view, false otherwise.
Definition: image-view.hpp:105
constexpr bool is_cube_compatible() const noexcept
Returns true if the image is cube map compatible, false otherwise.
Definition: image.hpp:198
constexpr std::uint8_t get_dimensionality() const noexcept
Returns the dimensionality of the image.
Definition: image.hpp:144
constexpr std::uint32_t get_mip_levels() const noexcept
Returns the number of levels of detail available for minified sampling of the image.
Definition: image.hpp:180
constexpr format get_format() const noexcept
Returns the format and type of the texel blocks contained in the image.
Definition: image.hpp:168
constexpr std::uint32_t get_array_layers() const noexcept
Returns the number of layers in the image.
Definition: image.hpp:186
Graphics library interface.
Definition: window.hpp:28
format
Image and vertex formats.
Definition: format.hpp:29
image_view_flag
Image flags.
@ cube
Cube map view.
@ array
Image array view.
constexpr GLenum gl_format_lut[][3]
Maps gl::format to OpenGL internal format, base format, and pixel type.