Uniforms storage
This commit is contained in:
parent
ab4416ed58
commit
84ebc69d54
2 changed files with 198 additions and 0 deletions
142
uniforms.cc
142
uniforms.cc
|
@ -1,4 +1,5 @@
|
||||||
#include "externals.hh"
|
#include "externals.hh"
|
||||||
|
#include "utilities.hh"
|
||||||
#include "uniforms.hh"
|
#include "uniforms.hh"
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,3 +204,144 @@ uint32_t T_UniformSet::position(
|
||||||
assert( ePos != packed_[ ci ].positions.end( ) );
|
assert( ePos != packed_[ ci ].positions.end( ) );
|
||||||
return ePos->second;
|
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_ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
56
uniforms.hh
56
uniforms.hh
|
@ -43,6 +43,8 @@ struct T_UniformDeclaration
|
||||||
using T_UniformDeclarations = std::unordered_map< std::string , T_UniformDeclaration >;
|
using T_UniformDeclarations = std::unordered_map< std::string , T_UniformDeclaration >;
|
||||||
|
|
||||||
|
|
||||||
|
/*============================================================================*/
|
||||||
|
|
||||||
// Packed uniforms
|
// Packed uniforms
|
||||||
struct T_PackedUniforms
|
struct T_PackedUniforms
|
||||||
{
|
{
|
||||||
|
@ -94,3 +96,57 @@ struct T_UniformSet
|
||||||
uint32_t vectorElements_ , opaqueElements_;
|
uint32_t vectorElements_ , opaqueElements_;
|
||||||
T_PackedUniforms packed_[ int( E_UniformCategory::__COUNT__ ) ];
|
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_;
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in a new issue