demotool/shaders.hh

207 lines
4.1 KiB
C++
Raw Normal View History

2017-10-03 13:53:50 +02:00
#pragma once
#include "filewatcher.hh"
2017-10-03 13:53:50 +02:00
#include "utilities.hh"
/*= INPUT FILES ==============================================================*/
// Type of input chunk
enum class E_ShaderInputChunk {
CODE ,
2017-10-08 10:13:11 +02:00
INCLUDE ,
UNIFORMS
2017-10-03 13:53:50 +02:00
};
// 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
2017-10-03 13:53:50 +02:00
};
// Preprocessing errors
struct T_ShaderInputError
{
uint32_t line;
std::string error;
};
2017-10-08 10:13:11 +02:00
// 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;
};
2017-10-03 13:53:50 +02:00
// Source file
struct T_ShaderInput
{
E_ShaderInput type = E_ShaderInput::CHUNK;
std::vector< T_ShaderInputChunk > chunks;
std::vector< T_ShaderInputError > errors;
2017-10-08 10:13:11 +02:00
std::unordered_map< std::string , T_ShaderUniform > uniforms;
2017-10-03 13:53:50 +02:00
bool load( __rd__ std::string const& path );
};
2017-10-03 16:09:12 +02:00
using P_ShaderInput = std::unique_ptr< T_ShaderInput >;
2017-10-03 13:53:50 +02:00
2017-10-03 16:09:12 +02:00
// Type of shader
enum class E_ShaderType {
VERTEX , FRAGMENT , GEOMETRY ,
COMPUTE ,
__COUNT__
2017-10-03 16:09:12 +02:00
};
// 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
2017-10-03 16:09:12 +02:00
{
friend struct T_ShaderManager;
T_ShaderPipeline( );
COPY( T_ShaderPipeline );
MOVE( T_ShaderPipeline );
~T_ShaderPipeline( );
bool valid( ) const noexcept;
void enable( ) const;
GLuint id( ) 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( );
2017-10-06 18:42:51 +02:00
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;
};
2017-10-06 18:42:51 +02:00
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_;
2017-10-03 16:09:12 +02:00
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 );
2017-10-03 16:09:12 +02:00
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 );
};