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 "utilities.hh"
|
||||
#include "uniforms.hh"
|
||||
|
||||
|
||||
|
@ -203,3 +204,144 @@ uint32_t T_UniformSet::position(
|
|||
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_ );
|
||||
}
|
||||
}
|
||||
|
|
56
uniforms.hh
56
uniforms.hh
|
@ -43,6 +43,8 @@ struct T_UniformDeclaration
|
|||
using T_UniformDeclarations = std::unordered_map< std::string , T_UniformDeclaration >;
|
||||
|
||||
|
||||
/*============================================================================*/
|
||||
|
||||
// Packed uniforms
|
||||
struct T_PackedUniforms
|
||||
{
|
||||
|
@ -94,3 +96,57 @@ struct T_UniformSet
|
|||
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_;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue