Antkeeper  0.0.1
sampler.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/sampler.hpp>
21 #include <glad/gl.h>
22 
23 namespace gl {
24 
25 namespace
26 {
27  static constexpr GLenum mag_filter_lut[] =
28  {
29  GL_NEAREST, // sampler_filter::nearest
30  GL_LINEAR // sampler_filter::linear
31  };
32 
33  static constexpr GLenum min_filter_lut[][2] =
34  {
35  {
36  GL_NEAREST_MIPMAP_NEAREST, // sampler_filter::nearest, sampler_mipmap_mode::nearest
37  GL_NEAREST_MIPMAP_LINEAR // sampler_filter::nearest, sampler_mipmap_mode::linear
38  },
39  {
40  GL_LINEAR_MIPMAP_NEAREST, // sampler_filter::linear, sampler_mipmap_mode::nearest
41  GL_LINEAR_MIPMAP_LINEAR // sampler_filter::linear, sampler_mipmap_mode::linear
42  },
43  };
44 
45  static constexpr GLenum wrap_lut[] =
46  {
47  GL_REPEAT, // sampler_address_mode::repeat
48  GL_MIRRORED_REPEAT, // sampler_address_mode::mirrored_repeat
49  GL_CLAMP_TO_EDGE, // sampler_address_mode::clamp_to_edge
50  GL_CLAMP_TO_BORDER, // sampler_address_mode::clamp_to_border
51  GL_MIRROR_CLAMP_TO_EDGE // sampler_address_mode::mirror_clamp_to_edge
52  };
53 
54  static constexpr GLenum compare_func_lut[] =
55  {
56  GL_NEVER, // compare_op::never
57  GL_LESS, // compare_op::less
58  GL_EQUAL, // compare_op::equal
59  GL_LEQUAL, // compare_op::less_or_equal
60  GL_GREATER, // compare_op::greater
61  GL_NOTEQUAL, // compare_op::not_equal
62  GL_GEQUAL, // compare_op::greater_or_equal
63  GL_ALWAYS // compare_op::always
64  };
65 }
66 
68 (
69  sampler_filter mag_filter,
70  sampler_filter min_filter,
71  sampler_mipmap_mode mipmap_mode,
72  sampler_address_mode address_mode_u,
73  sampler_address_mode address_mode_v,
74  sampler_address_mode address_mode_w,
75  float mip_lod_bias,
76  float max_anisotropy,
77  bool compare_enabled,
79  float min_lod,
80  float max_lod,
81  const std::array<float, 4>& border_color
82 )
83 {
84  glCreateSamplers(1, &m_gl_named_sampler);
85 
86  set_mag_filter(mag_filter);
87  set_min_filter(min_filter);
88  set_mipmap_mode(mipmap_mode);
89  set_address_mode_u(address_mode_u);
90  set_address_mode_v(address_mode_v);
91  set_address_mode_w(address_mode_w);
92  set_mip_lod_bias(mip_lod_bias);
93  set_max_anisotropy(max_anisotropy);
94  set_compare_enabled(compare_enabled);
96  set_min_lod(min_lod);
97  set_max_lod(max_lod);
98  set_border_color(border_color);
99 }
100 
102 {
103  glDeleteSamplers(1, &m_gl_named_sampler);
104 }
105 
107 {
108  if (m_mag_filter != filter)
109  {
110  m_mag_filter = filter;
111  const auto gl_mag_filter = mag_filter_lut[std::to_underlying(m_mag_filter)];
112  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MAG_FILTER, gl_mag_filter);
113  }
114 }
115 
117 {
118  if (m_min_filter != filter)
119  {
120  m_min_filter = filter;
121  const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
122  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
123  }
124 }
125 
127 {
128  if (m_mipmap_mode != mode)
129  {
130  m_mipmap_mode = mode;
131  const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
132  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
133  }
134 }
135 
137 {
138  if (m_address_mode_u != mode)
139  {
140  m_address_mode_u = mode;
141  const auto gl_wrap_s = wrap_lut[std::to_underlying(m_address_mode_u)];
142  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_S, gl_wrap_s);
143  }
144 }
145 
147 {
148  if (m_address_mode_v != mode)
149  {
150  m_address_mode_v = mode;
151  const auto gl_wrap_t = wrap_lut[std::to_underlying(m_address_mode_v)];
152  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_T, gl_wrap_t);
153  }
154 }
155 
157 {
158  if (m_address_mode_w != mode)
159  {
160  m_address_mode_w = mode;
161  const auto gl_wrap_r = wrap_lut[std::to_underlying(m_address_mode_w)];
162  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_R, gl_wrap_r);
163  }
164 }
165 
167 {
168  if (m_mip_lod_bias != bias)
169  {
170  m_mip_lod_bias = bias;
171  glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_LOD_BIAS, m_mip_lod_bias);
172  }
173 }
174 
175 void sampler::set_max_anisotropy(float anisotropy)
176 {
177  if (m_max_anisotropy != anisotropy)
178  {
179  m_max_anisotropy = anisotropy;
180  glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_max_anisotropy);
181  }
182 }
183 
185 {
186  if (m_compare_enabled != enabled)
187  {
188  m_compare_enabled = enabled;
189  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_MODE, (m_compare_enabled) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE);
190  }
191 }
192 
194 {
195  if (m_compare_op != op)
196  {
197  m_compare_op = op;
198  const auto gl_compare_func = compare_func_lut[std::to_underlying(m_compare_op)];
199  glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_FUNC, gl_compare_func);
200  }
201 }
202 
203 void sampler::set_min_lod(float lod)
204 {
205  if (m_min_lod != lod)
206  {
207  m_min_lod = lod;
208  glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MIN_LOD, m_min_lod);
209  }
210 }
211 
212 void sampler::set_max_lod(float lod)
213 {
214  if (m_max_lod != lod)
215  {
216  m_max_lod = lod;
217  glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_LOD, m_max_lod);
218  }
219 }
220 
221 void sampler::set_border_color(const std::array<float, 4>& color)
222 {
223  if (m_border_color != color)
224  {
225  m_border_color = color;
226  glSamplerParameterfv(m_gl_named_sampler, GL_TEXTURE_BORDER_COLOR, m_border_color.data());
227  }
228 }
229 
230 } // namespace gl
void set_min_lod(float lod)
Sets the minimum clamp value of the computed LOD.
Definition: sampler.cpp:203
void set_max_anisotropy(float anisotropy)
Sets the anisotropy clamp value.
Definition: sampler.cpp:175
void set_address_mode_w(sampler_address_mode mode)
Sets the addressing mode for W-coordinates outside [0, 1).
Definition: sampler.cpp:156
void set_mipmap_mode(sampler_mipmap_mode mode)
Sets the mipmap filter to apply to lookups.
Definition: sampler.cpp:126
void set_compare_op(gl::compare_op op)
Sets the comparison operator to apply to fetched data, if compare is enabled.
Definition: sampler.cpp:193
void set_address_mode_v(sampler_address_mode mode)
Sets the addressing mode for V-coordinates outside [0, 1).
Definition: sampler.cpp:146
void set_min_filter(sampler_filter filter)
Sets the minification filter to apply to lookups.
Definition: sampler.cpp:116
void set_mip_lod_bias(float bias)
Sets the bias to be added to mipmap LOD calculation.
Definition: sampler.cpp:166
void set_compare_enabled(bool enabled)
Enables or disables a comparison against a reference value during lookups.
Definition: sampler.cpp:184
sampler(sampler_filter mag_filter=sampler_filter::linear, sampler_filter min_filter=sampler_filter::nearest, sampler_mipmap_mode mipmap_mode=sampler_mipmap_mode::linear, sampler_address_mode address_mode_u=sampler_address_mode::repeat, sampler_address_mode address_mode_v=sampler_address_mode::repeat, sampler_address_mode address_mode_w=sampler_address_mode::repeat, float mip_lod_bias=0.0f, float max_anisotropy=0.0f, bool compare_enabled=false, gl::compare_op compare_op=gl::compare_op::less, float min_lod=-1000.0f, float max_lod=1000.0f, const std::array< float, 4 > &border_color={0.0f, 0.0f, 0.0f, 0.0f})
Constructs a sampler object.
Definition: sampler.cpp:68
void set_max_lod(float lod)
Sets the maximum clamp value of the computed LOD.
Definition: sampler.cpp:212
void set_border_color(const std::array< float, 4 > &color)
Sets the border color used for texture lookups.
Definition: sampler.cpp:221
void set_mag_filter(sampler_filter filter)
Sets the magnification filter to apply to lookups.
Definition: sampler.cpp:106
~sampler()
Destroys a sampler object.
Definition: sampler.cpp:101
void set_address_mode_u(sampler_address_mode mode)
Sets the addressing mode for U-coordinates outside [0, 1).
Definition: sampler.cpp:136
Color science.
Definition: aces.hpp:27
Graphics library interface.
Definition: window.hpp:28
sampler_address_mode
Behaviors of sampling with texture coordinates outside an image.
sampler_mipmap_mode
Mipmap modes used for texture lookups.
sampler_filter
Filters used for texture lookups.
compare_op
Comparison operators.
Definition: compare-op.hpp:29