205 lines
4.1 KiB
C++
205 lines
4.1 KiB
C++
#pragma once
|
|
#include "filewatcher.hh"
|
|
#include "utilities.hh"
|
|
|
|
|
|
/*= INPUT FILES ==============================================================*/
|
|
|
|
// Type of input chunk
|
|
enum class E_ShaderInputChunk {
|
|
CODE ,
|
|
INCLUDE ,
|
|
UNIFORMS
|
|
};
|
|
|
|
// Input chunk data
|
|
struct T_ShaderInputChunk
|
|
{
|
|
E_ShaderInputChunk type;
|
|
std::string text;
|
|
uint32_t lines;
|
|
|
|
T_ShaderInputChunk( ) = default;
|
|
T_ShaderInputChunk(
|
|
__rd__ const E_ShaderInputChunk type ,
|
|
__rd__ std::string text ,
|
|
__rd__ const uint32_t lines )
|
|
: type( type ) , text( std::move( text ) ) , lines( lines )
|
|
{ }
|
|
};
|
|
|
|
// Input file type
|
|
enum class E_ShaderInput {
|
|
CHUNK , // Chunk that may be repeated
|
|
LIBRARY , // Library (will only be loaded once)
|
|
|
|
// "Main" shader source files
|
|
VERTEX , FRAGMENT , GEOMETRY ,
|
|
COMPUTE
|
|
};
|
|
|
|
// Preprocessing errors
|
|
struct T_ShaderInputError
|
|
{
|
|
uint32_t line;
|
|
std::string error;
|
|
};
|
|
|
|
// Uniform types
|
|
enum class E_UniformType {
|
|
F1 , F2 , F3 , F4 ,
|
|
I1 , I2 , I3 , I4 ,
|
|
SAMPLER2D
|
|
};
|
|
|
|
// Uniform declarations
|
|
struct T_ShaderUniform
|
|
{
|
|
std::string name;
|
|
bool global;
|
|
E_UniformType type;
|
|
};
|
|
|
|
// Source file
|
|
struct T_ShaderInput
|
|
{
|
|
E_ShaderInput type = E_ShaderInput::CHUNK;
|
|
std::vector< T_ShaderInputChunk > chunks;
|
|
std::vector< T_ShaderInputError > errors;
|
|
std::unordered_map< std::string , T_ShaderUniform > uniforms;
|
|
|
|
bool load( __rd__ std::string const& path );
|
|
};
|
|
using P_ShaderInput = std::unique_ptr< T_ShaderInput >;
|
|
|
|
|
|
// Type of shader
|
|
enum class E_ShaderType {
|
|
VERTEX , FRAGMENT , GEOMETRY ,
|
|
COMPUTE ,
|
|
__COUNT__
|
|
};
|
|
|
|
|
|
// Errors in shader code - the errors it represents may come from either
|
|
// the input loader, the shader loader or the driver.
|
|
struct T_ShaderError
|
|
{
|
|
std::string source;
|
|
uint32_t line;
|
|
std::string error;
|
|
};
|
|
|
|
|
|
struct T_ShaderManager;
|
|
|
|
struct T_ShaderPipeline
|
|
{
|
|
friend struct T_ShaderManager;
|
|
|
|
T_ShaderPipeline( );
|
|
COPY( T_ShaderPipeline );
|
|
MOVE( T_ShaderPipeline );
|
|
~T_ShaderPipeline( );
|
|
|
|
bool valid( ) const noexcept;
|
|
void enable( ) const;
|
|
|
|
GLuint program( __rd__ const E_ShaderType program ) const;
|
|
|
|
private:
|
|
explicit T_ShaderPipeline(
|
|
__rd__ const int32_t index );
|
|
int32_t smIndex_;
|
|
};
|
|
|
|
|
|
struct T_ShaderManager
|
|
{
|
|
friend struct T_ShaderPipeline;
|
|
|
|
struct T_ShaderCode
|
|
{
|
|
E_ShaderType type;
|
|
std::vector< uint32_t > starts; // Position of chunk in source file
|
|
std::vector< uint32_t > counts; // Chunk lengths
|
|
std::vector< std::string > sources; // Chunk source files
|
|
std::string code;
|
|
std::vector< T_ShaderError > errors;
|
|
std::map< std::string , bool > files;
|
|
};
|
|
|
|
T_ShaderPipeline pipeline(
|
|
__rd__ std::initializer_list< std::string > shaders );
|
|
|
|
void update( );
|
|
|
|
void makeUI( );
|
|
bool& uiEnabled( )
|
|
{ return uiEnabled_; }
|
|
|
|
private:
|
|
struct T_Pipeline_
|
|
{
|
|
uint32_t references;
|
|
std::string idString;
|
|
GLuint id;
|
|
std::vector< std::string > programs;
|
|
};
|
|
|
|
struct T_Program_
|
|
{
|
|
std::string name;
|
|
std::set< uint32_t > references;
|
|
T_ShaderCode code;
|
|
GLuint id;
|
|
std::unique_ptr< T_WatchedFiles > watch;
|
|
};
|
|
|
|
bool uiEnabled_ = false;
|
|
|
|
std::vector< T_Pipeline_ > pipelines_;
|
|
std::map< std::string , uint32_t > pipelineIndex_;
|
|
|
|
std::vector< T_Program_ > programs_;
|
|
std::map< std::string , uint32_t > programIndex_;
|
|
|
|
std::map< std::string , P_ShaderInput > inputs_;
|
|
|
|
std::map< std::string , std::set< std::string > > missing_;
|
|
std::set< std::string > updates_;
|
|
|
|
uint32_t newPipelineRecord( );
|
|
uint32_t newProgramRecord( );
|
|
|
|
void loadProgram(
|
|
__rd__ const uint32_t pipeline ,
|
|
__rd__ std::string const& name );
|
|
bool useExistingProgram(
|
|
__rd__ const uint32_t pipeline ,
|
|
__rd__ std::string const& name );
|
|
|
|
T_ShaderInput const* getInput(
|
|
__rd__ std::string const& name );
|
|
|
|
void dereferencePipeline(
|
|
__rd__ const uint32_t index );
|
|
void dereferenceProgram(
|
|
__rd__ const uint32_t index ,
|
|
__rd__ const uint32_t pipeline );
|
|
|
|
void initPipeline(
|
|
__rw__ T_Pipeline_& pipeline ) const;
|
|
void initProgram(
|
|
__rw__ T_Program_& program );
|
|
|
|
void parseGLSLError(
|
|
__rw__ T_ShaderCode& code ,
|
|
__rd__ char const* errorLine );
|
|
|
|
void programUpdated(
|
|
__rd__ std::string const& name );
|
|
|
|
void resetProgram(
|
|
__rw__ T_Program_& program );
|
|
};
|