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

/*
* 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