diff --git a/Makefile b/Makefile index 00327a3..ab8dc4c 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,8 @@ IMGUI = imgui.o imgui_demo.o imgui_draw.o DEMO = \ main.o \ imgui_impl_sdl.o \ - utilities.o + utilities.o \ + texture.o DEMO_DEPS = $(DEMO:%.o=.%.d) diff --git a/main.cc b/main.cc index 0c3022d..acfc06c 100644 --- a/main.cc +++ b/main.cc @@ -2,6 +2,7 @@ #include "imgui_impl_sdl.h" #include "utilities.hh" +#include "texture.hh" /*= T_Main ===================================================================*/ @@ -59,6 +60,8 @@ T_Main::T_Main( ) ImGui_ImplSdl_Init( window ); initProgram( ); + + //T_Texture textureTest( 512 , 512 , E_TexType::R8 ); } void T_Main::mainLoop( ) diff --git a/texture.cc b/texture.cc new file mode 100644 index 0000000..7487ebd --- /dev/null +++ b/texture.cc @@ -0,0 +1,94 @@ +#include "externals.hh" +#include "texture.hh" + + +T_Texture::T_Texture( + __rd__ const uint32_t width , + __rd__ const uint32_t height , + __rd__ const E_TexType type , + __rd__ const uint32_t levels ) + : width_( width ) , height_( height ) +{ + assert( levels > 0 ); + + glGenTextures( 1 , &id_ ); + glBindTexture( GL_TEXTURE_2D , id_ ); + + GLenum ifmt , fmt , dt; + switch ( type ) { + case E_TexType::RGBA8: + ifmt = GL_RGBA8; + fmt = GL_RGBA; + dt = GL_UNSIGNED_BYTE; + break; + + case E_TexType::RGBA16F: + ifmt = GL_RGBA16F; + fmt = GL_RGBA; + dt = GL_FLOAT; + break; + + case E_TexType::R8: + ifmt = GL_R8; + fmt = GL_RED; + dt = GL_UNSIGNED_BYTE; + break; + + case E_TexType::R16F: + ifmt = GL_R16F; + fmt = GL_RED; + dt = GL_FLOAT; + break; + } + + glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MIN_LOD , 0 ); + glTexParameteri( GL_TEXTURE_2D , GL_TEXTURE_MAX_LOD , levels - 1 ); + + uint32_t w = width , h = height; + for ( auto i = 0u ; i < levels ; i ++ ) { + glTexImage2D( GL_TEXTURE_2D , i , ifmt , w , h , 0 , fmt , dt , nullptr ); + w >>= 2; + h >>= 2; + assert( w && h ); + } + + assert( glGetError( ) == GL_NO_ERROR ); + + glBindTexture( GL_TEXTURE_2D , 0 ); +} + +T_Texture::~T_Texture( ) +{ + glDeleteTextures( 1 , &id_ ); +} + + +/*============================================================================*/ + + +T_TextureBinding::T_TextureBinding( + __rd__ const uint32_t binding ) + : binding_( binding ) , uniform_( 0 ) , texture_( nullptr ) +{ } + +void T_TextureBinding::clear( ) +{ + uniform_ = 0; + texture_ = nullptr; +} + +void T_TextureBinding::set( + __rd__ const uint32_t uniform , + __rd__ T_Texture const& texture ) +{ + uniform_ = uniform; + texture_ = &texture; +} + +void T_TextureBinding::bind( ) const +{ + glActiveTexture( GL_TEXTURE0 + binding_ ); + glBindTexture( GL_TEXTURE_2D , texture_ ? texture_->id( ) : 0 ); + glUniform1i( uniform_ , binding_ ); + assert( glGetError( ) == GL_NO_ERROR ); +} diff --git a/texture.hh b/texture.hh new file mode 100644 index 0000000..3fcf4a3 --- /dev/null +++ b/texture.hh @@ -0,0 +1,56 @@ +#pragma once +#ifndef REAL_BUILD +# include "externals.hh" +#endif + + +enum class E_TexType +{ + RGBA8 , + RGBA16F , + R8 , + R16F , +}; + +struct T_Texture +{ + T_Texture( ) = delete; + T_Texture( T_Texture const& ) = delete; + T_Texture( T_Texture&& ) = delete; + + T_Texture( + __rd__ const uint32_t width , + __rd__ const uint32_t height , + __rd__ const E_TexType type , + __rd__ const uint32_t levels = 1 ); + ~T_Texture( ); + + GLuint id( ) const noexcept { return id_; } + uint32_t width( ) const noexcept { return width_; } + uint32_t height( ) const noexcept { return height_; } + + private: + GLuint id_; + uint32_t width_ , height_; +}; + +struct T_TextureBinding +{ + T_TextureBinding( ) = delete; + T_TextureBinding( T_TextureBinding const& ) = delete; + T_TextureBinding( T_TextureBinding&& ) = delete; + + explicit T_TextureBinding( + __rd__ const uint32_t binding ); + + void clear( ); + void set( __rd__ const uint32_t uniform , + __rd__ T_Texture const& texture ); + + void bind( ) const; + + private: + const uint32_t binding_; + uint32_t uniform_; + T_Texture const* texture_; +};