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