|
|
- /*
- * Copyright (C) 2023 Christopher J. Howard
- *
- * This file is part of Antkeeper source code.
- *
- * Antkeeper source code is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Antkeeper source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Antkeeper source code. If not, see <http://www.gnu.org/licenses/>.
- */
-
- #include <engine/gl/sampler.hpp>
- #include <glad/gl.h>
-
- namespace gl {
-
- namespace
- {
- static constexpr GLenum mag_filter_lut[] =
- {
- GL_NEAREST, // sampler_filter::nearest
- GL_LINEAR // sampler_filter::linear
- };
-
- static constexpr GLenum min_filter_lut[][2] =
- {
- {
- GL_NEAREST_MIPMAP_NEAREST, // sampler_filter::nearest, sampler_mipmap_mode::nearest
- GL_NEAREST_MIPMAP_LINEAR // sampler_filter::nearest, sampler_mipmap_mode::linear
- },
- {
- GL_LINEAR_MIPMAP_NEAREST, // sampler_filter::linear, sampler_mipmap_mode::nearest
- GL_LINEAR_MIPMAP_LINEAR // sampler_filter::linear, sampler_mipmap_mode::linear
- },
- };
-
- static constexpr GLenum wrap_lut[] =
- {
- GL_REPEAT, // sampler_address_mode::repeat
- GL_MIRRORED_REPEAT, // sampler_address_mode::mirrored_repeat
- GL_CLAMP_TO_EDGE, // sampler_address_mode::clamp_to_edge
- GL_CLAMP_TO_BORDER, // sampler_address_mode::clamp_to_border
- GL_MIRROR_CLAMP_TO_EDGE // sampler_address_mode::mirror_clamp_to_edge
- };
-
- static constexpr GLenum compare_func_lut[] =
- {
- GL_NEVER, // compare_op::never
- GL_LESS, // compare_op::less
- GL_EQUAL, // compare_op::equal
- GL_LEQUAL, // compare_op::less_or_equal
- GL_GREATER, // compare_op::greater
- GL_NOTEQUAL, // compare_op::not_equal
- GL_GEQUAL, // compare_op::greater_or_equal
- GL_ALWAYS // compare_op::always
- };
- }
-
- sampler::sampler
- (
- sampler_filter mag_filter,
- sampler_filter min_filter,
- sampler_mipmap_mode mipmap_mode,
- sampler_address_mode address_mode_u,
- sampler_address_mode address_mode_v,
- sampler_address_mode address_mode_w,
- float mip_lod_bias,
- float max_anisotropy,
- bool compare_enabled,
- gl::compare_op compare_op,
- float min_lod,
- float max_lod,
- const std::array<float, 4>& border_color
- )
- {
- glCreateSamplers(1, &m_gl_named_sampler);
-
- set_mag_filter(mag_filter);
- set_min_filter(min_filter);
- set_mipmap_mode(mipmap_mode);
- set_address_mode_u(address_mode_u);
- set_address_mode_v(address_mode_v);
- set_address_mode_w(address_mode_w);
- set_mip_lod_bias(mip_lod_bias);
- set_max_anisotropy(max_anisotropy);
- set_compare_enabled(compare_enabled);
- set_compare_op(compare_op);
- set_min_lod(min_lod);
- set_max_lod(max_lod);
- set_border_color(border_color);
- }
-
- sampler::~sampler()
- {
- glDeleteSamplers(1, &m_gl_named_sampler);
- }
-
- void sampler::set_mag_filter(sampler_filter filter)
- {
- if (m_mag_filter != filter)
- {
- m_mag_filter = filter;
- const auto gl_mag_filter = mag_filter_lut[std::to_underlying(m_mag_filter)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MAG_FILTER, gl_mag_filter);
- }
- }
-
- void sampler::set_min_filter(sampler_filter filter)
- {
- if (m_min_filter != filter)
- {
- m_min_filter = filter;
- const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
- }
- }
-
- void sampler::set_mipmap_mode(sampler_mipmap_mode mode)
- {
- if (m_mipmap_mode != mode)
- {
- m_mipmap_mode = mode;
- const auto gl_min_filter = min_filter_lut[std::to_underlying(m_min_filter)][std::to_underlying(m_mipmap_mode)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_MIN_FILTER, gl_min_filter);
- }
- }
-
- void sampler::set_address_mode_u(sampler_address_mode mode)
- {
- if (m_address_mode_u != mode)
- {
- m_address_mode_u = mode;
- const auto gl_wrap_s = wrap_lut[std::to_underlying(m_address_mode_u)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_S, gl_wrap_s);
- }
- }
-
- void sampler::set_address_mode_v(sampler_address_mode mode)
- {
- if (m_address_mode_v != mode)
- {
- m_address_mode_v = mode;
- const auto gl_wrap_t = wrap_lut[std::to_underlying(m_address_mode_v)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_T, gl_wrap_t);
- }
- }
-
- void sampler::set_address_mode_w(sampler_address_mode mode)
- {
- if (m_address_mode_w != mode)
- {
- m_address_mode_w = mode;
- const auto gl_wrap_r = wrap_lut[std::to_underlying(m_address_mode_w)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_WRAP_R, gl_wrap_r);
- }
- }
-
- void sampler::set_mip_lod_bias(float bias)
- {
- if (m_mip_lod_bias != bias)
- {
- m_mip_lod_bias = bias;
- glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_LOD_BIAS, m_mip_lod_bias);
- }
- }
-
- void sampler::set_max_anisotropy(float anisotropy)
- {
- if (m_max_anisotropy != anisotropy)
- {
- m_max_anisotropy = anisotropy;
- glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_max_anisotropy);
- }
- }
-
- void sampler::set_compare_enabled(bool enabled)
- {
- if (m_compare_enabled != enabled)
- {
- m_compare_enabled = enabled;
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_MODE, (m_compare_enabled) ? GL_COMPARE_REF_TO_TEXTURE : GL_NONE);
- }
- }
-
- void sampler::set_compare_op(gl::compare_op op)
- {
- if (m_compare_op != op)
- {
- m_compare_op = op;
- const auto gl_compare_func = compare_func_lut[std::to_underlying(m_compare_op)];
- glSamplerParameteri(m_gl_named_sampler, GL_TEXTURE_COMPARE_FUNC, gl_compare_func);
- }
- }
-
- void sampler::set_min_lod(float lod)
- {
- if (m_min_lod != lod)
- {
- m_min_lod = lod;
- glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MIN_LOD, m_min_lod);
- }
- }
-
- void sampler::set_max_lod(float lod)
- {
- if (m_max_lod != lod)
- {
- m_max_lod = lod;
- glSamplerParameterf(m_gl_named_sampler, GL_TEXTURE_MAX_LOD, m_max_lod);
- }
- }
-
- void sampler::set_border_color(const std::array<float, 4>& color)
- {
- if (m_border_color != color)
- {
- m_border_color = color;
- glSamplerParameterfv(m_gl_named_sampler, GL_TEXTURE_BORDER_COLOR, m_border_color.data());
- }
- }
-
- } // namespace gl
|