From 456affe7844be742d09063b8ae0b68313e5c39f0 Mon Sep 17 00:00:00 2001 From: Emmanuel Benoit Date: Mon, 2 Oct 2017 10:42:06 +0200 Subject: [PATCH] Texture sampler abstraction --- texture.cc | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++ texture.hh | 48 ++++++++++++++++++++ 2 files changed, 178 insertions(+) diff --git a/texture.cc b/texture.cc index e27efc8..337570e 100644 --- a/texture.cc +++ b/texture.cc @@ -3,6 +3,8 @@ #include "texture.hh" +/*==============================================================================*/ + T_Texture::T_Texture( __rd__ const uint32_t width , __rd__ const uint32_t height , @@ -124,6 +126,134 @@ T_Texture& T_Texture::wrap( return *this; } +/*==============================================================================*/ + +T_TextureSampler::T_TextureSampler( ) +{ + glGenSamplers( 1 , &id_ ); + GL_CHECK( ); +} + +T_TextureSampler::T_TextureSampler( + __rw__ T_TextureSampler&& other ) noexcept +{ + std::swap( id_ , other.id_ ); + std::swap( sampling_ , other.sampling_ ); + std::swap( lodSampling_ , other.lodSampling_ ); + std::swap( hasLOD_ , other.hasLOD_ ); + setSamplingMode( ); +} + +T_TextureSampler& T_TextureSampler::operator =( + __rw__ T_TextureSampler&& other ) noexcept +{ + std::swap( id_ , other.id_ ); + std::swap( sampling_ , other.sampling_ ); + std::swap( lodSampling_ , other.lodSampling_ ); + std::swap( hasLOD_ , other.hasLOD_ ); + return *this; +} + +T_TextureSampler::~T_TextureSampler( ) +{ + if ( id_ != 0 ) { + glDeleteSamplers( 1 , &id_ ); + } +} + +/*----------------------------------------------------------------------------*/ + +T_TextureSampler& T_TextureSampler::sampling( + __rd__ const E_TexSampling mode ) +{ + sampling_ = mode; + setSamplingMode( ); + return *this; +} + +T_TextureSampler& T_TextureSampler::noMipmap( ) +{ + hasLOD_ = false; + setSamplingMode( ); + return *this; +} + +T_TextureSampler& T_TextureSampler::mipmap( + __rd__ const E_TexSampling mode ) +{ + hasLOD_ = true; + lodSampling_ = mode; + setSamplingMode( ); + return *this; +} + +T_TextureSampler& T_TextureSampler::wrap( + __rd__ const E_TexWrap mode ) +{ + GLenum gm; + switch ( mode ) { + case E_TexWrap::REPEAT: + gm = GL_REPEAT; + break; + case E_TexWrap::CLAMP_EDGE: + gm = GL_CLAMP_TO_EDGE; + break; + case E_TexWrap::CLAMP_BORDER: + gm = GL_CLAMP_TO_BORDER; + break; + } + glSamplerParameteri( id_ , GL_TEXTURE_WRAP_S , gm ); + glSamplerParameteri( id_ , GL_TEXTURE_WRAP_T , gm ); + GL_CHECK( ); + return *this; +} + +T_TextureSampler& T_TextureSampler::lod( + __rd__ const float min , + __rd__ const float max ) +{ + glSamplerParameterf( id_ , GL_TEXTURE_MIN_LOD , min ); + glSamplerParameterf( id_ , GL_TEXTURE_MAX_LOD , max ); + GL_CHECK( ); + return *this; +} + +/*----------------------------------------------------------------------------*/ + +void T_TextureSampler::setSamplingMode( ) const +{ + GLenum min , max; + if ( hasLOD_ ) { + switch ( sampling_ ) { + + case E_TexSampling::NEAREST: + min = lodSampling_ == E_TexSampling::LINEAR + ? GL_NEAREST_MIPMAP_LINEAR + : GL_NEAREST_MIPMAP_NEAREST; + max = GL_NEAREST; + break; + + case E_TexSampling::LINEAR: + min = lodSampling_ == E_TexSampling::LINEAR + ? GL_LINEAR_MIPMAP_LINEAR + : GL_LINEAR_MIPMAP_NEAREST; + max = GL_LINEAR; + break; + + } + } else { + min = ( sampling_ == E_TexSampling::LINEAR ) + ? GL_LINEAR + : GL_NEAREST; + max = min; + } + + glSamplerParameteri( id_ , GL_TEXTURE_MIN_FILTER , min ); + glSamplerParameteri( id_ , GL_TEXTURE_MAG_FILTER , max ); + GL_CHECK( ); +} + + /*============================================================================*/ diff --git a/texture.hh b/texture.hh index 03c4e0f..3ef5595 100644 --- a/texture.hh +++ b/texture.hh @@ -52,6 +52,54 @@ struct T_Texture uint32_t levels_ , width_ , height_; }; + +struct T_TextureSampler +{ + T_TextureSampler( T_TextureSampler const& ) = delete; + + // -------------------------------------------------------------------- + // Initialisation, destruction & move + + T_TextureSampler( ); + T_TextureSampler( + __rw__ T_TextureSampler&& other ) noexcept; + T_TextureSampler& operator=( + __rw__ T_TextureSampler&& other ) noexcept; + ~T_TextureSampler( ); + + // -------------------------------------------------------------------- + // Configuration + + T_TextureSampler& sampling( + __rd__ const E_TexSampling mode ); + + T_TextureSampler& noMipmap( ); + T_TextureSampler& mipmap( + __rd__ const E_TexSampling mode ); + + T_TextureSampler& wrap( + __rd__ const E_TexWrap mode ); + + T_TextureSampler& lod( + __rd__ const float min , + __rd__ const float max ); + + // -------------------------------------------------------------------- + // Usage + + void bind( __rd__ const GLuint unit ) + { glBindSampler( unit , id_ ); } + + private: + void setSamplingMode( ) const; + + GLuint id_ = 0; + E_TexSampling sampling_ = E_TexSampling::NEAREST; + E_TexSampling lodSampling_ = E_TexSampling::NEAREST; + bool hasLOD_ = false; +}; + + struct T_TextureBinding { T_TextureBinding( ) = delete;