diff --git a/Makefile b/Makefile index 6764fed..7271aa1 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,6 @@ COMMON = \ utilities.cc \ texture.cc \ rendertarget.cc \ - uniforms.cc \ camera.cc \ \ filewatcher.cc \ diff --git a/uniforms.cc b/uniforms.cc deleted file mode 100644 index 3d90a00..0000000 --- a/uniforms.cc +++ /dev/null @@ -1,347 +0,0 @@ -#include "externals.hh" -#include "utilities.hh" -#include "uniforms.hh" - - -/*= Uniform types ============================================================*/ - -E_UniformCategory GetUniformCategory( - __rd__ const E_UniformType type ) -{ - switch ( type ) { - case E_UniformType::F1: - case E_UniformType::F2: - case E_UniformType::F3: - case E_UniformType::F4: - return E_UniformCategory::FLOAT; - case E_UniformType::I1: - case E_UniformType::I2: - case E_UniformType::I3: - case E_UniformType::I4: - return E_UniformCategory::INT; - case E_UniformType::SAMPLER2D: - return E_UniformCategory::SAMPLER2D; - } - std::abort( ); -} - - -uint32_t GetElementCount( - __rd__ const E_UniformType type ) -{ - switch ( type ) { - case E_UniformType::F1: - case E_UniformType::I1: - return 1; - case E_UniformType::F2: - case E_UniformType::I2: - return 2; - case E_UniformType::F3: - case E_UniformType::I3: - return 3; - case E_UniformType::F4: - case E_UniformType::I4: - return 4; - - case E_UniformType::SAMPLER2D: - return 0; - } - std::abort( ); -} - -bool IsVectorCategory( - __rd__ const E_UniformCategory category ) -{ - assert( category != E_UniformCategory::__COUNT__ ); - return category == E_UniformCategory::FLOAT - || category == E_UniformCategory::INT; -} - - -/*= PackUniforms =============================================================*/ - -namespace { - -T_PackedUniforms PackVectorUniforms_( - __rd__ T_UniformDeclarations const& declarations , - __rd__ const E_UniformCategory category ) -{ - std::vector< std::string > packOrder; - packOrder.reserve( declarations.size( ) ); - for ( auto entry : declarations ) { - auto const& u( entry.second ); - if ( GetUniformCategory( u.type ) == category ) { - packOrder.push_back( entry.first ); - } - } - std::sort( packOrder.begin( ) , packOrder.end( ) , - [&declarations]( auto const& a , auto const& b ) - { - auto const& ua( declarations.find( a )->second ); - auto const& ub( declarations.find( b )->second ); - return GetElementCount( ub.type ) < GetElementCount( ua.type ); - } ); - - const auto n( packOrder.size( ) ); - auto index = 0u; - T_PackedUniforms pu; - - // Place vec4's - while ( index < n && GetElementCount( declarations.find( packOrder[ index ] )->second.type ) == 4 ) { - pu.positions[ packOrder[ index ] ] = pu.elements; - pu.elements += 4; - index ++; - } - - // Place vec3's - uint32_t s3left( 0 ); - while ( index < n && GetElementCount( declarations.find( packOrder[ index ] )->second.type ) == 3 ) { - pu.positions[ packOrder[ index ] ] = pu.elements; - pu.elements += 4; - s3left ++; - index ++; - } - - // Place vec2's - const uint32_t s2s( pu.elements ); - bool s2spare( false ); - while ( index < n && GetElementCount( declarations.find( packOrder[ index ] )->second.type ) == 2 ) { - if ( !s2spare ) { - pu.elements += 4; - } - const uint32_t pos( pu.elements - ( s2spare ? 2 : 4 ) ); - pu.positions[ packOrder[ index ] ] = pos; - s2spare = !s2spare; - index ++; - } - - // Place single elements - uint32_t s1pos( s2spare ? ( pu.elements - 2 ) : pu.elements ); - while ( index < n ) { - uint32_t pos; - if ( s3left ) { - pos = s2s - s3left * 4 + 3; - s3left --; - } else { - if ( s1pos == pu.elements ) { - pu.elements += 4; - } - pos = s1pos; - s1pos ++; - } - pu.positions[ packOrder[ index ] ] = pos; - index ++; - } - - return pu; -} - -T_PackedUniforms PackOpaqueUniforms_( - __rd__ T_UniformDeclarations const& declarations , - __rd__ const E_UniformCategory category ) -{ - T_PackedUniforms pu; - for ( auto entry : declarations ) { - auto const& u( entry.second ); - if ( GetUniformCategory( u.type ) == category ) { - pu.positions[ entry.first ] = pu.elements; - pu.elements ++; - } - } - return pu; -} - -} // namespace - -/*----------------------------------------------------------------------------*/ - -T_PackedUniforms PackUniforms( - __rd__ T_UniformDeclarations const& declarations , - __rd__ const E_UniformCategory category ) -{ - assert( category != E_UniformCategory::__COUNT__ ); - if ( IsVectorCategory( category ) ) { - return PackVectorUniforms_( declarations , category ); - } - return PackOpaqueUniforms_( declarations , category ); -} - - -/*= T_UniformSet =============================================================*/ - -constexpr uint32_t T_UniformSet::Invalid; - -T_UniformSet::T_UniformSet( ) - : vectorElements_( 0 ) , opaqueElements_( 0 ) -{ } - -T_UniformSet::T_UniformSet( - __rw__ T_UniformDeclarations declarations ) - : declarations_( std::move( declarations ) ) , - vectorElements_( 0 ) , opaqueElements_( 0 ) -{ - for ( auto i = 0 ; i < int( E_UniformCategory::__COUNT__ ) ; i ++ ) { - const auto cat{ E_UniformCategory( i ) }; - packed_[ i ] = PackUniforms( declarations_ , cat ); - if ( IsVectorCategory( cat ) ) { - vectorElements_ += packed_[ i ].elements; - } else { - opaqueElements_ += packed_[ i ].elements; - } - } -} - -uint32_t T_UniformSet::position( - __rd__ std::string const& uniform ) const -{ - const auto pos( declarations_.find( uniform ) ); - if ( pos == declarations_.end( ) ) { - return Invalid; - } - - const int ci( int( GetUniformCategory( pos->second.type ) ) ); - const auto ePos( packed_[ ci ].positions.find( uniform ) ); - assert( ePos != packed_[ ci ].positions.end( ) ); - return ePos->second; -} - - -/*= T_UniformStorage =========================================================*/ - -T_UniformStorage::T_UniformStorage( - __rw__ T_UniformSet&& uniforms ) - : uniforms_( std::move( uniforms ) ) -{ - values_.resize( uniforms_.opaqueElements( ) - + uniforms_.vectorElements( ) , 0 ); - - uint32_t pos = 0; - for ( auto i = 0 ; i < int( E_UniformCategory::__COUNT__ ) ; i ++ ) { - starts_[ i ] = pos; - pos += uniforms_.inCategory( E_UniformCategory( i ) ); - } -} - -float* T_UniformStorage::getf( - __rd__ std::string const& name ) -{ - auto const& dPos( uniforms_.declarations( ).find( name ) ); - if ( dPos == uniforms_.declarations( ).end( ) ) { - return nullptr; - } - auto const& decl( dPos->second ); - - const auto cat( GetUniformCategory( decl.type ) ); - const auto pos( starts_[ int( cat ) ] + uniforms_.position( name ) ); - return reinterpret_cast< float* >( &values_[ pos ] ); -} - -int* T_UniformStorage::geti( - __rd__ std::string const& name ) -{ - auto const& dPos( uniforms_.declarations( ).find( name ) ); - if ( dPos == uniforms_.declarations( ).end( ) ) { - return nullptr; - } - auto const& decl( dPos->second ); - - const auto cat( GetUniformCategory( decl.type ) ); - const auto pos( starts_[ int( cat ) ] + uniforms_.position( name ) ); - return &values_[ pos ]; -} - - -/*= T_ProgramUniforms ========================================================*/ - -T_ProgramUniforms::T_ProgramUniforms( - __rw__ T_UniformSet uniforms ) - : T_UniformStorage( std::move( uniforms ) ) -{ } - -void T_ProgramUniforms::apply( - __rd__ const GLuint id ) -{ - GLuint uLoc( 0 ); - for ( auto i = 0 ; i < int( E_UniformCategory::__COUNT__ ) ; i ++ ) { - const auto cat{ E_UniformCategory( i ) }; - const auto count{ uniforms_.inCategory( cat ) }; - if ( count != 0 ) { - switch ( cat ) { - case E_UniformCategory::FLOAT: - glProgramUniform4fv( id , uLoc , count / 4 , - reinterpret_cast< float* >( &values_[ starts_[ i ] ] ) ); - uLoc += count / 4; - break; - case E_UniformCategory::INT: - glProgramUniform4iv( id , uLoc , count / 4 , - &values_[ starts_[ i ] ] ); - uLoc += count / 4; - break; - case E_UniformCategory::SAMPLER2D: - glProgramUniform1iv( id , uLoc , count , - &values_[ starts_[ i ] ] ); - uLoc += count; - break; - - case E_UniformCategory::__COUNT__: - std::abort( ); - } - } - } -} - - -/*= T_UniformBuffer ==========================================================*/ - -T_UniformBuffer::T_UniformBuffer( - __rw__ T_UniformSet set ) - : T_UniformStorage( std::move( set ) ) , buffer_( 0 ) -{ - assert( uniforms_.opaqueElements( ) == 0 ); - - glGenBuffers( 1 , &buffer_ ); - glBindBuffer( GL_UNIFORM_BUFFER , buffer_ ); - glBufferData( GL_UNIFORM_BUFFER , values_.size( ) * 4 , &values_[ 0 ] , GL_STREAM_DRAW ); - GL_ASSERT( ); -} - -T_UniformBuffer::T_UniformBuffer( - __rw__ T_UniformBuffer&& ori ) noexcept - : T_UniformStorage( std::move( ori ) ) , buffer_( 0 ) -{ - std::swap( buffer_ , ori.buffer_ ); -} - -T_UniformBuffer& T_UniformBuffer::operator=( - __rw__ T_UniformBuffer&& other ) noexcept -{ - if ( buffer_ ) { - glBindBuffer( GL_UNIFORM_BUFFER , 0 ); - glDeleteBuffers( 1 , &buffer_ ); - buffer_ = 0; - } - std::swap( buffer_ , other.buffer_ ); - T_UniformStorage::operator=( std::move( other ) ); - return *this; -} - -void T_UniformBuffer::update( ) -{ - glBindBuffer( GL_UNIFORM_BUFFER , buffer_ ); - glInvalidateBufferData( GL_UNIFORM_BUFFER ); - glBufferData( GL_UNIFORM_BUFFER , values_.size( ) * 4 , &values_[ 0 ] , GL_STREAM_DRAW ); -} - -void T_UniformBuffer::bindTo( - __rd__ const GLuint binding ) -{ - glBindBufferBase( GL_UNIFORM_BUFFER , binding , buffer_ ); -} - -T_UniformBuffer::~T_UniformBuffer( ) -{ - if ( buffer_ ) { - glBindBuffer( GL_UNIFORM_BUFFER , 0 ); - glDeleteBuffers( 1 , &buffer_ ); - } -} diff --git a/uniforms.hh b/uniforms.hh deleted file mode 100644 index 2678bf6..0000000 --- a/uniforms.hh +++ /dev/null @@ -1,152 +0,0 @@ -#pragma once -#ifndef REAL_BUILD -# include "externals.hh" -#endif - - -// Uniform types -enum class E_UniformType { - F1 , F2 , F3 , F4 , - I1 , I2 , I3 , I4 , - SAMPLER2D -}; - -// Categories -enum class E_UniformCategory { - FLOAT , INT , - SAMPLER2D , - __COUNT__ -}; - -// Category from type -E_UniformCategory GetUniformCategory( - __rd__ const E_UniformType type ); -// Element count from type -uint32_t GetElementCount( - __rd__ const E_UniformType type ); -// Is some category a vector type? -bool IsVectorCategory( - __rd__ const E_UniformCategory category ); - - -// Uniform declarations -struct T_UniformDeclaration -{ - std::string name; - bool global; - E_UniformType type; - - std::string source; - uint32_t line; -}; - -using T_UniformDeclarations = std::unordered_map< std::string , T_UniformDeclaration >; - - -/*============================================================================*/ - -// Packed uniforms -struct T_PackedUniforms -{ - uint32_t elements = 0; - std::map< std::string , uint32_t > positions; -}; - -T_PackedUniforms PackUniforms( - __rd__ T_UniformDeclarations const& declarations , - __rd__ const E_UniformCategory category ); - - -// A set of uniforms, meant for use with a buffer or directly -struct T_UniformSet -{ - static constexpr uint32_t Invalid = 0xffffffff; - - T_UniformSet( ); - explicit T_UniformSet( - __rw__ T_UniformDeclarations uniforms ); - - DEF_MOVE( T_UniformSet ); - NO_COPY( T_UniformSet ); - - // --------------------------------------------------------------------- - - T_UniformDeclarations const& declarations( ) const noexcept - { return declarations_; } - - uint32_t vectorElements( ) const noexcept - { return vectorElements_; } - uint32_t opaqueElements( ) const noexcept - { return opaqueElements_; } - - uint32_t inCategory( - __rd__ const E_UniformCategory category ) const noexcept - { - assert( category != E_UniformCategory::__COUNT__ ); - return packed_[ int( category ) ].elements; - } - - // Return the position of the specified uniform in its category. - // If the uniform doesn't exist, this will return Invalid. - uint32_t position( - __rd__ std::string const& uniform ) const; - - private: - T_UniformDeclarations declarations_; - uint32_t vectorElements_ , opaqueElements_; - T_PackedUniforms packed_[ int( E_UniformCategory::__COUNT__ ) ]; -}; - - -/*============================================================================*/ - -struct T_UniformStorage -{ - T_UniformStorage( ) = delete; - NO_COPY( T_UniformStorage ); - DEF_MOVE( T_UniformStorage ); - - explicit T_UniformStorage( - __rw__ T_UniformSet&& uniforms ); - - float* getf( - __rd__ std::string const& name ); - int* geti( - __rd__ std::string const& name ); - - protected: - T_UniformSet uniforms_; - uint32_t starts_[ int( E_UniformCategory::__COUNT__ ) ]; - std::vector< int > values_; -}; - -struct T_ProgramUniforms : public T_UniformStorage -{ - T_ProgramUniforms( ) = delete; - NO_COPY( T_ProgramUniforms ); - DEF_MOVE( T_ProgramUniforms ); - - explicit T_ProgramUniforms( - __rw__ T_UniformSet uniforms ); - - void apply( - __rd__ const GLuint id ); -}; - -struct T_UniformBuffer : public T_UniformStorage -{ - T_UniformBuffer( ) = delete; - NO_COPY( T_UniformBuffer ); - - explicit T_UniformBuffer( - __rw__ T_UniformSet uniforms ); - MOVE( T_UniformBuffer ); - ~T_UniformBuffer( ); - - void update( ); - void bindTo( - __rd__ const GLuint binding ); - - private: - GLuint buffer_; -};