Better abstraction for shader programs

This commit is contained in:
Emmanuel BENOîT 2017-09-30 12:08:18 +02:00
parent 4ff19bffa6
commit 7d16b704b5
5 changed files with 115 additions and 37 deletions

View file

@ -1,4 +1,4 @@
#!/bin/bash
if make -j 8; then
./editor tests/test.json
optirun ./demo
fi

46
main.cc
View file

@ -26,23 +26,19 @@ struct T_Main
T_Camera camera;
T_FilesWatcher watcher;
T_WatchedFiles shaderFiles;
GLuint prog;
std::unique_ptr< T_ShaderProgram > program;
void startIteration( );
void handleCapture( );
void makeUI( );
void render( );
void loadProgram( );
void initProgram( );
};
/*----------------------------------------------------------------------------*/
T_Main::T_Main( )
: shaderFiles( watcher , [this] {
this->loadProgram( );
} )
{
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
@ -62,7 +58,7 @@ T_Main::T_Main( )
glewInit();
ImGui_ImplSdl_Init( window );
loadProgram( );
initProgram( );
}
void T_Main::mainLoop( )
@ -157,9 +153,7 @@ void T_Main::render( )
// FIXME draw the fuck
//project->render( );
if ( prog != 0 ) {
glUseProgram( prog );
if ( program->activate( ) ) {
enum {
U_TIME = 0 ,
U_RESOLUTION = 1 ,
@ -192,32 +186,14 @@ void T_Main::render( )
}
void T_Main::loadProgram( )
void T_Main::initProgram( )
{
std::vector< std::string > errors;
if ( prog != 0 ) {
glDeleteProgram( prog );
prog = 0;
}
shaderFiles.clear( );
shaderFiles.watch( "raymarch-header.glsl" );
shaderFiles.watch( "map.glsl" );
shaderFiles.watch( "raymarcher.glsl" );
T_ShaderCode shader( 3 );
shader.loadPart( 0 , "raymarch-header.glsl" , errors );
shader.loadPart( 1 , "map.glsl" , errors );
shader.loadPart( 2 , "raymarcher.glsl" , errors );
prog = shader.createProgram( GL_FRAGMENT_SHADER , errors );
if ( errors.size( ) != 0 ) {
for ( auto const& str : errors ) {
printf( "ERR: %s\n" , str.c_str( ) );
}
}
program = std::make_unique< T_ShaderProgram >(
GL_FRAGMENT_SHADER , watcher );
program->addFile( "raymarch-header.glsl" );
program->addFile( "map.glsl" );
program->addFile( "raymarcher.glsl" );
program->load( );
}

View file

@ -1,4 +1,6 @@
vec2 map( vec3 pos )
{
return vec2( length( pos ) - 1. , 0. );
vec3 q = pos;
q.xy = mod( q.xy + 2. , 4. ) - 2.;
return vec2( length( q ) - 2.1 , 0. );
}

View file

@ -297,6 +297,77 @@ GLuint T_ShaderCode::createProgram(
}
/*= T_ShaderProgram ==========================================================*/
T_ShaderProgram::T_ShaderProgram(
__rd__ const GLenum programType ,
__rw__ T_FilesWatcher& watcher )
: files_( watcher , [this] { load( ); } ) ,
programType_( programType ) , program_( 0 )
{
}
T_ShaderProgram::~T_ShaderProgram( )
{
if ( program_ != 0 ) {
glDeleteProgram( program_ );
}
}
void T_ShaderProgram::addChunk(
__rd__ std::string const& string )
{
chunksOrFiles_.push_back( true );
parts_.push_back( string );
}
void T_ShaderProgram::addFile(
__rd__ std::string const& source )
{
chunksOrFiles_.push_back( false );
parts_.push_back( source );
}
void T_ShaderProgram::load( )
{
const auto n( parts_.size( ) );
errors_.clear( );
files_.clear( );
if ( program_ != 0 ) {
glDeleteProgram( program_ );
program_ = 0;
}
T_ShaderCode sc( n );
for ( auto i = 0u ; i < n ; i ++ ) {
if ( chunksOrFiles_[ i ] ) {
sc.setPart( i , parts_[ i ].c_str( ) );
} else if ( sc.loadPart( i , parts_[ i ].c_str( ) , errors_ ) ) {
files_.watch( parts_[ i ] );
}
}
if ( errors_.size( ) == 0 ) {
program_ = sc.createProgram( programType_ , errors_ );
}
if ( errors_.size( ) ) {
printf( "\n--------------------------------------------------------------------------------\n\n" );
for ( auto const& str : errors_ ) {
printf( "ERR: %s\n" , str.c_str( ) );
}
}
}
bool T_ShaderProgram::activate( ) const
{
if ( program_ != 0 ) {
glUseProgram( program_ );
}
return program_ != 0;
}
/*= T_Camera =================================================================*/
void T_Camera::handleDND(

View file

@ -126,6 +126,35 @@ struct T_ShaderCode
std::vector< char* > code;
};
struct T_ShaderProgram
{
T_ShaderProgram( ) = delete;
T_ShaderProgram( T_ShaderProgram const& ) = delete;
T_ShaderProgram( T_ShaderProgram&& ) = delete;
T_ShaderProgram(
__rd__ GLenum programType ,
__rw__ T_FilesWatcher& watcher );
~T_ShaderProgram( );
void addChunk( __rd__ std::string const& string );
void addFile( __rd__ std::string const& source );
void load( );
bool activate( ) const;
private:
T_WatchedFiles files_;
std::vector< bool > chunksOrFiles_;
std::vector< std::string > parts_;
std::vector< std::string > errors_;
GLenum programType_;
GLuint program_;
};
/*= T_Camera =================================================================*/