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

230 lines
6.2 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/sampler.hpp>
  20. #include <glad/gl.h>
  21. namespace gl {
  22. namespace
  23. {
  24. static constexpr GLenum mag_filter_lut[] =
  25. {
  26. GL_NEAREST, // sampler_filter::nearest
  27. GL_LINEAR // sampler_filter::linear
  28. };
  29. static constexpr GLenum min_filter_lut[][2] =
  30. {
  31. {
  32. GL_NEAREST_MIPMAP_NEAREST, // sampler_filter::nearest, sampler_mipmap_mode::nearest
  33. GL_NEAREST_MIPMAP_LINEAR // sampler_filter::nearest, sampler_mipmap_mode::linear
  34. },
  35. {
  36. GL_LINEAR_MIPMAP_NEAREST, // sampler_filter::linear, sampler_mipmap_mode::nearest
  37. GL_LINEAR_MIPMAP_LINEAR // sampler_filter::linear, sampler_mipmap_mode::linear
  38. },
  39. };
  40. static constexpr GLenum wrap_lut[] =
  41. {
  42. GL_REPEAT, // sampler_address_mode::repeat
  43. GL_MIRRORED_REPEAT, // sampler_address_mode::mirrored_repeat
  44. GL_CLAMP_TO_EDGE, // sampler_address_mode::clamp_to_edge
  45. GL_CLAMP_TO_BORDER, // sampler_address_mode::clamp_to_border
  46. GL_MIRROR_CLAMP_TO_EDGE // sampler_address_mode::mirror_clamp_to_edge
  47. };
  48. static constexpr GLenum compare_func_lut[] =
  49. {
  50. GL_NEVER, // compare_op::never
  51. GL_LESS, // compare_op::less
  52. GL_EQUAL, // compare_op::equal
  53. GL_LEQUAL, // compare_op::less_or_equal
  54. GL_GREATER, // compare_op::greater
  55. GL_NOTEQUAL, // compare_op::not_equal
  56. GL_GEQUAL, // compare_op::greater_or_equal
  57. GL_ALWAYS // compare_op::always
  58. };
  59. }
  60. sampler::sampler
  61. (
  62. sampler_filter mag_filter,
  63. sampler_filter min_filter,
  64. sampler_mipmap_mode mipmap_mode,
  65. sampler_address_mode address_mode_u,
  66. sampler_address_mode address_mode_v,
  67. sampler_address_mode address_mode_w,
  68. float mip_lod_bias,
  69. float max_anisotropy,
  70. bool compare_enabled,
  71. gl::compare_op compare_op,
  72. float min_lod,
  73. float max_lod,
  74. const std::array<float, 4>& border_color
  75. )
  76. {
  77. glCreateSamplers(1, &m_gl_named_sampler);
  78. set_mag_filter(mag_filter);
  79. set_min_filter(min_filter);
  80. set_mipmap_mode(mipmap_mode);
  81. set_address_mode_u(address_mode_u);
  82. set_address_mode_v(address_mode_v);
  83. set_address_mode_w(address_mode_w);
  84. set_mip_lod_bias(mip_lod_bias);
  85. set_max_anisotropy(max_anisotropy);
  86. set_compare_enabled(compare_enabled);
  87. set_compare_op(compare_op);
  88. set_min_lod(min_lod);
  89. set_max_lod(max_lod);
  90. set_border_color(border_color);
  91. }
  92. sampler::~sampler()
  93. {
  94. glDeleteSamplers(1, &m_gl_named_sampler);
  95. }
  96. void sampler::set_mag_filter(sampler_filter filter)
  97. {
  98. if (m_mag_filter != filter)
  99. {
  100. m_mag_filter = filter;
  101. const auto gl_mag_filter = mag_filter_lut[std::to_underlying(m_mag_filter)];
  102. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MAG_FILTER, gl_mag_filter);
  103. }
  104. }
  105. void sampler::set_min_filter(sampler_filter filter)
  106. {
  107. if (m_min_filter != filter)
  108. {
  109. m_min_filter = filter;
  110. const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
  111. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
  112. }
  113. }
  114. void sampler::set_mipmap_mode(sampler_mipmap_mode mode)
  115. {
  116. if (m_mipmap_mode != mode)
  117. {
  118. m_mipmap_mode = mode;
  119. const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
  120. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
  121. }
  122. }
  123. void sampler::set_address_mode_u(sampler_address_mode mode)
  124. {
  125. if (m_address_mode_u != mode)
  126. {
  127. m_address_mode_u = mode;
  128. const auto gl_wrap_s = wrap_lut[std::to_underlying(m_address_mode_u)];
  129. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_S, gl_wrap_s);
  130. }
  131. }
  132. void sampler::set_address_mode_v(sampler_address_mode mode)
  133. {
  134. if (m_address_mode_v != mode)
  135. {
  136. m_address_mode_v = mode;
  137. const auto gl_wrap_t = wrap_lut[std::to_underlying(m_address_mode_v)];
  138. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_T, gl_wrap_t);
  139. }
  140. }
  141. void sampler::set_address_mode_w(sampler_address_mode mode)
  142. {
  143. if (m_address_mode_w != mode)
  144. {
  145. m_address_mode_w = mode;
  146. const auto gl_wrap_r = wrap_lut[std::to_underlying(m_address_mode_w)];
  147. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_R, gl_wrap_r);
  148. }
  149. }
  150. void sampler::set_mip_lod_bias(float bias)
  151. {
  152. if (m_mip_lod_bias != bias)
  153. {
  154. m_mip_lod_bias = bias;
  155. glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_LOD_BIAS, m_mip_lod_bias);
  156. }
  157. }
  158. void sampler::set_max_anisotropy(float anisotropy)
  159. {
  160. if (m_max_anisotropy != anisotropy)
  161. {
  162. m_max_anisotropy = anisotropy;
  163. glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_max_anisotropy);
  164. }
  165. }
  166. void sampler::set_compare_enabled(bool enabled)
  167. {
  168. if (m_compare_enabled != enabled)
  169. {
  170. m_compare_enabled = enabled;
  171. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_MODE, (m_compare_enabled) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE);
  172. }
  173. }
  174. void sampler::set_compare_op(gl::compare_op op)
  175. {
  176. if (m_compare_op != op)
  177. {
  178. m_compare_op = op;
  179. const auto gl_compare_func = compare_func_lut[std::to_underlying(m_compare_op)];
  180. glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_FUNC, gl_compare_func);
  181. }
  182. }
  183. void sampler::set_min_lod(float lod)
  184. {
  185. if (m_min_lod != lod)
  186. {
  187. m_min_lod = lod;
  188. glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MIN_LOD, m_min_lod);
  189. }
  190. }
  191. void sampler::set_max_lod(float lod)
  192. {
  193. if (m_max_lod != lod)
  194. {
  195. m_max_lod = lod;
  196. glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_LOD, m_max_lod);
  197. }
  198. }
  199. void sampler::set_border_color(const std::array<float, 4>& color)
  200. {
  201. if (m_border_color != color)
  202. {
  203. m_border_color = color;
  204. glSamplerParameterfv(m_gl_named_sampler, GL_TEXTURE_BORDER_COLOR, m_border_color.data());
  205. }
  206. }
  207. } // namespace gl