#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_; };