Structure overhaul + shader stuff progress

This commit is contained in:
Emmanuel BENOîT 2017-10-04 11:20:27 +02:00
parent 53fbdba979
commit eb122b598e
26 changed files with 513 additions and 309 deletions

View file

@ -13,6 +13,8 @@ DEMO = \
main.cc \ main.cc \
imgui_impl_sdl.cc \ imgui_impl_sdl.cc \
\ \
filewatcher.cc \
window.cc \
utilities.cc \ utilities.cc \
texture.cc \ texture.cc \
rendertarget.cc \ rendertarget.cc \
@ -20,6 +22,7 @@ DEMO = \
shaders.cc \ shaders.cc \
camera.cc \ camera.cc \
demo.cc \ demo.cc \
globals.cc \
\ \
raymarcher.cc \ raymarcher.cc \
\ \

View file

@ -1,6 +1,7 @@
#include "externals.hh" #include "externals.hh"
#include "bloom.hh" #include "bloom.hh"
#include "profiling.hh" #include "profiling.hh"
#include "globals.hh"
namespace { namespace {
static const std::string Name_( "BLOOOOM!" ); static const std::string Name_( "BLOOOOM!" );
@ -11,12 +12,11 @@ namespace {
T_BloomPass::T_BloomPass( T_BloomPass::T_BloomPass(
__rw__ T_FilesWatcher& watcher ,
__rw__ T_Texture& input ) __rw__ T_Texture& input )
: input_( input ) , : input_( input ) ,
spHighpass_( GL_FRAGMENT_SHADER , watcher ) , spHighpass_( GL_FRAGMENT_SHADER ) ,
spDownsample_( GL_FRAGMENT_SHADER , watcher ) , spDownsample_( GL_FRAGMENT_SHADER ) ,
spBlur_( GL_FRAGMENT_SHADER , watcher ) , spBlur_( GL_FRAGMENT_SHADER ) ,
// //
txBlur0_( input.width( ) , input.height( ) , E_TexType::RGB16F , BloomLevels ) , txBlur0_( input.width( ) , input.height( ) , E_TexType::RGB16F , BloomLevels ) ,
txBlur1_( input.width( ) , input.height( ) , E_TexType::RGB16F , BloomLevels ) , txBlur1_( input.width( ) , input.height( ) , E_TexType::RGB16F , BloomLevels ) ,
@ -46,7 +46,7 @@ void T_BloomPass::render( )
{ {
PSTART( ); PSTART( );
auto& tm( T_TextureManagement::TM( ) ); auto& tm( Globals::Textures( ) );
if ( spHighpass_.activate( ) && rtBlur0_[ 0 ].activate( ) ) { if ( spHighpass_.activate( ) && rtBlur0_[ 0 ].activate( ) ) {
enum { enum {
U_TEXTURE = 0 , U_TEXTURE = 0 ,

View file

@ -15,8 +15,7 @@ struct T_BloomPass
T_BloomPass( T_BloomPass const& ) = delete; T_BloomPass( T_BloomPass const& ) = delete;
T_BloomPass( T_BloomPass&& ) = delete; T_BloomPass( T_BloomPass&& ) = delete;
T_BloomPass( __rw__ T_FilesWatcher& watcher , T_BloomPass( __rw__ T_Texture& input );
__rw__ T_Texture& input );
void render( ); void render( );
void makeUI( ); void makeUI( );

View file

@ -2,6 +2,7 @@
#include "combine.hh" #include "combine.hh"
#include "bloom.hh" #include "bloom.hh"
#include "profiling.hh" #include "profiling.hh"
#include "globals.hh"
namespace { namespace {
static const std::string Name_( "Combine" ); static const std::string Name_( "Combine" );
@ -12,11 +13,10 @@ namespace {
T_CombinePass::T_CombinePass( T_CombinePass::T_CombinePass(
__rw__ T_FilesWatcher& watcher ,
__rw__ T_Texture& image , __rw__ T_Texture& image ,
__rw__ T_Texture& bloom ) __rw__ T_Texture& bloom )
: txImage_( image ) , txBloom_( bloom ) , : txImage_( image ) , txBloom_( bloom ) ,
program_( GL_FRAGMENT_SHADER , watcher ) , program_( GL_FRAGMENT_SHADER ) ,
bloomStrength_( 0.45 ) , bloomStrength_( 0.45 ) ,
bloomAttenuation_( 0.3 ) bloomAttenuation_( 0.3 )
{ {
@ -31,7 +31,7 @@ void T_CombinePass::render( )
glClearColor( 1 , 0 , 1 , 1 ); glClearColor( 1 , 0 , 1 , 1 );
glClear( GL_COLOR_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT );
if ( program_.activate( ) ) { if ( program_.activate( ) ) {
auto& tm( T_TextureManagement::TM( ) ); auto& tm( Globals::Textures( ) );
tm.bind( 0 , txImage_ ); tm.bind( 0 , txImage_ );
tm.bind( 1 , txBloom_ ); tm.bind( 1 , txBloom_ );
glUniform1i( 0 , 0 ); glUniform1i( 0 , 0 );

View file

@ -10,8 +10,7 @@ struct T_CombinePass
T_CombinePass( T_CombinePass const& ) = delete; T_CombinePass( T_CombinePass const& ) = delete;
T_CombinePass( T_CombinePass&& ) = delete; T_CombinePass( T_CombinePass&& ) = delete;
T_CombinePass( __rw__ T_FilesWatcher& watcher , T_CombinePass( __rw__ T_Texture& image ,
__rw__ T_Texture& image ,
__rw__ T_Texture& bloom ); __rw__ T_Texture& bloom );
void render( ); void render( );

13
demo.cc
View file

@ -2,22 +2,21 @@
#include "demo.hh" #include "demo.hh"
T_Demo::T_Demo( __rw__ T_FilesWatcher& watcher , T_Demo::T_Demo( __rd__ const uint32_t width ,
__rd__ const uint32_t width ,
__rd__ const uint32_t height ) __rd__ const uint32_t height )
: watcher( watcher ) , width( width ) , height( height ) : width( width ) , height( height )
{ } { }
bool T_Demo::initialise( ) bool T_Demo::initialise( )
{ {
raymarcher = std::make_unique< T_Raymarcher >( raymarcher = std::make_unique< T_Raymarcher >(
watcher , width , height ); width , height );
dof = std::make_unique< T_DoFPass >( watcher , dof = std::make_unique< T_DoFPass >(
raymarcher->output( ) , raymarcher->depth( ) ); raymarcher->output( ) , raymarcher->depth( ) );
bloom = std::make_unique< T_BloomPass >( watcher , bloom = std::make_unique< T_BloomPass >(
raymarcher->output( ) ); raymarcher->output( ) );
combine = std::make_unique< T_CombinePass >( watcher , combine = std::make_unique< T_CombinePass >(
dof->output( ) , bloom->output( ) ); dof->output( ) , bloom->output( ) );
return true; return true;
} }

View file

@ -15,8 +15,7 @@ struct T_Demo
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
T_Demo( __rw__ T_FilesWatcher& watcher , T_Demo( __rd__ const uint32_t width ,
__rd__ const uint32_t width ,
__rd__ const uint32_t height ); __rd__ const uint32_t height );
bool initialise( ); bool initialise( );
@ -37,7 +36,6 @@ struct T_Demo
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
T_FilesWatcher& watcher;
const uint32_t width; const uint32_t width;
const uint32_t height; const uint32_t height;

8
dof.cc
View file

@ -1,6 +1,7 @@
#include "externals.hh" #include "externals.hh"
#include "dof.hh" #include "dof.hh"
#include "profiling.hh" #include "profiling.hh"
#include "globals.hh"
namespace { namespace {
static const std::string Name_( "DoF" ); static const std::string Name_( "DoF" );
@ -11,12 +12,11 @@ namespace {
T_DoFPass::T_DoFPass( T_DoFPass::T_DoFPass(
__rw__ T_FilesWatcher& watcher ,
__rw__ T_Texture& imageInput , __rw__ T_Texture& imageInput ,
__rw__ T_Texture& depthInput ) __rw__ T_Texture& depthInput )
: imageInput_( imageInput ) , depthInput_( depthInput ) , : imageInput_( imageInput ) , depthInput_( depthInput ) ,
spPass1_( GL_FRAGMENT_SHADER , watcher ) , spPass1_( GL_FRAGMENT_SHADER ) ,
spPass2_( GL_FRAGMENT_SHADER , watcher ) , spPass2_( GL_FRAGMENT_SHADER ) ,
txPass1_( imageInput.width( ) , imageInput.height( ) , txPass1_( imageInput.width( ) , imageInput.height( ) ,
E_TexType::RGB16F ) , E_TexType::RGB16F ) ,
txOutput_( imageInput.width( ) , imageInput.height( ) , txOutput_( imageInput.width( ) , imageInput.height( ) ,
@ -48,7 +48,7 @@ void T_DoFPass::render( )
U_RES_TIME = 4 U_RES_TIME = 4
}; };
auto& tm( T_TextureManagement::TM( ) ); auto& tm( Globals::Textures( ) );
if ( spPass1_.activate( ) && rtPass1_.activate( ) ) { if ( spPass1_.activate( ) && rtPass1_.activate( ) ) {
glUniform1i( U_INPUT , 0 ); glUniform1i( U_INPUT , 0 );
glUniform1i( U_DEPTH , 1 ); glUniform1i( U_DEPTH , 1 );

3
dof.hh
View file

@ -9,8 +9,7 @@ struct T_DoFPass
T_DoFPass( T_DoFPass const& ) = delete; T_DoFPass( T_DoFPass const& ) = delete;
T_DoFPass( T_DoFPass&& ) = delete; T_DoFPass( T_DoFPass&& ) = delete;
T_DoFPass( __rw__ T_FilesWatcher& watcher , T_DoFPass( __rw__ T_Texture& imageInput ,
__rw__ T_Texture& imageInput ,
__rw__ T_Texture& depthInput ); __rw__ T_Texture& depthInput );
void render( ); void render( );

120
filewatcher.cc Normal file
View file

@ -0,0 +1,120 @@
#include "externals.hh"
#include "filewatcher.hh"
#include "utilities.hh"
/*= T_FilesWatcher ===========================================================*/
T_FilesWatcher::T_FilesWatcher( )
: fd( inotify_init1( O_NONBLOCK ) )
{ }
T_FilesWatcher::T_FilesWatcher( T_FilesWatcher&& other ) noexcept
: fd( 0 ) , watched( std::move( other.watched ) )
{
std::swap( fd , other.fd );
other.watched.clear( );
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->watcher = this;
}
}
}
T_FilesWatcher::~T_FilesWatcher( )
{
if ( fd ) {
close( fd );
}
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->watcher = nullptr;
}
}
}
void T_FilesWatcher::check( )
{
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->triggered = false;
}
}
inotify_event ie;
while ( read( fd , &ie , sizeof( ie ) ) == sizeof( ie ) ) {
if ( ( ie.mask & ( IN_CLOSE_WRITE | IN_DELETE_SELF ) ) == 0 ) {
continue;
}
for ( T_WatchedFiles* wf : watched ) {
if ( !wf || wf->triggered ) {
continue;
}
auto const& idl( wf->identifiers );
if ( find( idl , ie.wd ) != idl.end( ) ) {
wf->triggered = true;
wf->callback( );
}
}
}
}
/*= T_WatchedFiles ===========================================================*/
T_WatchedFiles::T_WatchedFiles( T_WatchedFiles&& other ) noexcept
: watcher( other.watcher ) , callback( other.callback ) ,
triggered( other.triggered ) ,
identifiers( std::move( other.identifiers ) )
{
if ( watcher ) {
other.watcher = nullptr;
*( find( watcher->watched , &other ) ) = this;
}
}
T_WatchedFiles::T_WatchedFiles(
__rw__ T_FilesWatcher& watcher ,
__rd__ const F_OnFileChanges callback )
: watcher( &watcher ) , callback( callback ) , triggered( false )
{
watcher.watched.push_back( this );
}
T_WatchedFiles::~T_WatchedFiles( )
{
clear( );
if ( watcher ) {
watcher->watched.erase( find( watcher->watched , this ) );
}
}
void T_WatchedFiles::clear( )
{
if ( watcher ) {
const auto fd( watcher->fd );
for ( int wd : identifiers ) {
inotify_rm_watch( fd , wd );
}
}
identifiers.clear( );
}
bool T_WatchedFiles::watch(
__rd__ std::string const& file )
{
static constexpr auto inFlags( IN_CLOSE_WRITE | IN_DELETE_SELF );
if ( watcher ) {
const auto wd( inotify_add_watch( watcher->fd ,
file.c_str( ) , inFlags ) );
if ( wd == -1 ) {
return false;
}
if ( find( identifiers , wd ) == identifiers.end( ) ) {
identifiers.push_back( wd );
}
return true;
}
return false;
}

55
filewatcher.hh Normal file
View file

@ -0,0 +1,55 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
#endif
/*= T_FilesWatcher / T_WatchedFiles ==========================================*/
struct T_FilesWatcher;
struct T_WatchedFiles;
using F_OnFileChanges = std::function< void( void ) >;
struct T_FilesWatcher
{
friend struct T_WatchedFiles;
T_FilesWatcher( T_FilesWatcher const& ) = delete;
T_FilesWatcher( );
T_FilesWatcher( T_FilesWatcher&& ) noexcept;
~T_FilesWatcher( );
void check( );
private:
int fd;
std::vector< T_WatchedFiles* > watched;
};
/*----------------------------------------------------------------------------*/
struct T_WatchedFiles
{
friend struct T_FilesWatcher;
T_WatchedFiles( ) = delete;
T_WatchedFiles( T_WatchedFiles const& ) = delete;
T_WatchedFiles( T_WatchedFiles&& ) noexcept;
T_WatchedFiles(
__rw__ T_FilesWatcher& watcher ,
__rd__ const F_OnFileChanges callback );
~T_WatchedFiles( );
void clear( );
bool watch( __rd__ std::string const& file );
private:
T_FilesWatcher* watcher;
const F_OnFileChanges callback;
bool triggered;
std::vector< int > identifiers;
};

34
globals.cc Normal file
View file

@ -0,0 +1,34 @@
#include "externals.hh"
#include "globals.hh"
#include "filewatcher.hh"
#include "profiling.hh"
#include "texture.hh"
#include "shaders.hh"
#include "window.hh"
std::unique_ptr< T_FilesWatcher > Globals::watcher_;
std::unique_ptr< T_Window > Globals::window_;
std::unique_ptr< T_Profiler > Globals::profiler_;
std::unique_ptr< T_TextureManager > Globals::textures_;
std::unique_ptr< T_ShaderManager > Globals::shaders_;
void Globals::Init( )
{
watcher_ = std::make_unique< T_FilesWatcher >( );
window_ = std::make_unique< T_Window >( );
profiler_ = std::make_unique< T_Profiler >( );
textures_ = std::make_unique< T_TextureManager >( );
shaders_ = std::make_unique< T_ShaderManager >( );
}
void Globals::Shutdown( )
{
shaders_.reset( );
textures_.reset( );
profiler_.reset( );
window_.reset( );
watcher_.reset( );
}

31
globals.hh Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
#endif
struct T_Window;
struct T_FilesWatcher;
struct T_Profiler;
struct T_TextureManager;
struct T_ShaderManager;
struct Globals
{
static void Init( );
static void Shutdown( );
static T_FilesWatcher& Watcher( ) { return *watcher_; }
static T_Window& Window( ) { return *window_; }
static T_Profiler& Profiler( ) { return *profiler_; }
static T_TextureManager& Textures( ) { return *textures_; }
static T_ShaderManager& Shaders( ) { return *shaders_; }
private:
static std::unique_ptr< T_FilesWatcher > watcher_;
static std::unique_ptr< T_Window > window_;
static std::unique_ptr< T_Profiler > profiler_;
static std::unique_ptr< T_ShaderManager > shaders_;
static std::unique_ptr< T_TextureManager > textures_;
};

82
main.cc
View file

@ -2,7 +2,11 @@
#include "imgui_impl_sdl.h" #include "imgui_impl_sdl.h"
#include "demo.hh" #include "demo.hh"
#include "globals.hh"
#include "profiling.hh" #include "profiling.hh"
#include "window.hh"
#include "shaders.hh"
// FIXME ^^
/*= T_Main ===================================================================*/ /*= T_Main ===================================================================*/
@ -15,16 +19,11 @@ struct T_Main
void mainLoop( ); void mainLoop( );
private: private:
const std::string projectFile;
SDL_Window * window;
SDL_GLContext gl;
bool done = false; bool done = false;
bool capture = false; bool capture = false;
ImVec2 mouseInitial; ImVec2 mouseInitial;
ImVec2 mouseMove; ImVec2 mouseMove;
T_FilesWatcher watcher;
std::unique_ptr< T_ShaderProgram > spCopy; std::unique_ptr< T_ShaderProgram > spCopy;
std::unique_ptr< T_Demo > demo; std::unique_ptr< T_Demo > demo;
@ -43,30 +42,13 @@ struct T_Main
T_Main::T_Main( ) T_Main::T_Main( )
{ {
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ); Globals::Init( );
// Setup window
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER , 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE , 24 );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE , 8 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION , 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION , 2 );
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode( 0 , &current );
window = SDL_CreateWindow( "DEMO",
SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,
1280 , 720 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
gl = SDL_GL_CreateContext( window );
glewInit();
ImGui_ImplSdl_Init( window );
initProgram( ); initProgram( );
} }
void T_Main::mainLoop( ) void T_Main::mainLoop( )
{ {
auto& p( T_Profiler::Profiler ); auto& p( Globals::Profiler( ) );
while ( !done ) { while ( !done ) {
if ( demo ) { if ( demo ) {
auto const& dspSize( ImGui::GetIO( ).DisplaySize ); auto const& dspSize( ImGui::GetIO( ).DisplaySize );
@ -80,15 +62,15 @@ void T_Main::mainLoop( )
glFinish( ); glFinish( );
p.startFrame( ); p.startFrame( );
T_Profiler::Profiler.start( "Full frame" ); p.start( "Full frame" );
startIteration( ); startIteration( );
if ( !done ) { if ( !done ) {
handleCapture( ); handleCapture( );
makeUI( ); makeUI( );
watcher.check( );
render( ); render( );
T_Profiler::Profiler.end( "Full frame" ); p.end( "Full frame" );
SDL_GL_SwapWindow( window ); Globals::Window( ).swap( );
Globals::Watcher( ).check( );
p.endFrame( ); p.endFrame( );
} }
} }
@ -97,11 +79,7 @@ void T_Main::mainLoop( )
T_Main::~T_Main( ) T_Main::~T_Main( )
{ {
demo.reset( ); demo.reset( );
T_TextureManagement::Shutdown( ); Globals::Shutdown( );
ImGui_ImplSdl_Shutdown( );
SDL_GL_DeleteContext( gl );
SDL_DestroyWindow( window );
SDL_Quit( );
} }
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
@ -115,9 +93,9 @@ void T_Main::initDemo( )
} }
printf( "init w/ dspsize %dx%d\n" , int( dspSize.x ) , int( dspSize.y ) ); printf( "init w/ dspsize %dx%d\n" , int( dspSize.x ) , int( dspSize.y ) );
demo = std::make_unique< T_Demo >( watcher , dspSize.x , dspSize.y ); demo = std::make_unique< T_Demo >( dspSize.x , dspSize.y );
if ( demo->initialise( ) ) { if ( demo->initialise( ) ) {
T_Profiler::Profiler.clear( ); Globals::Profiler( ).clear( );
} else { } else {
demo.reset( ); demo.reset( );
} }
@ -140,7 +118,7 @@ void T_Main::startIteration( )
} }
} }
ImGui_ImplSdl_NewFrame( window , capture , mouseInitial ); Globals::Window( ).startFrame( capture , mouseInitial );
ImGui::GetIO( ).MouseDrawCursor = true; ImGui::GetIO( ).MouseDrawCursor = true;
} }
@ -159,9 +137,7 @@ void T_Main::handleCapture( )
capture = false; capture = false;
ImGui::CaptureMouseFromApp( false ); ImGui::CaptureMouseFromApp( false );
SDL_SetRelativeMouseMode( SDL_FALSE ); SDL_SetRelativeMouseMode( SDL_FALSE );
SDL_WarpMouseInWindow( window , Globals::Window( ).warpMouse( mouseInitial );
int( mouseInitial.x ) ,
int( mouseInitial.y ) );
ImGui::SetMouseCursor( ImGuiMouseCursor_Arrow ); ImGui::SetMouseCursor( ImGuiMouseCursor_Arrow );
} else if ( capture ) { } else if ( capture ) {
ImGui::SetMouseCursor( ImGuiMouseCursor_Move ); ImGui::SetMouseCursor( ImGuiMouseCursor_Move );
@ -188,31 +164,31 @@ void T_Main::makeUI( )
ImGuiSetCond_Once ); ImGuiSetCond_Once );
ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once ); ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once );
ImGui::Begin( "Yay! Demo!" ); ImGui::Begin( "Yay! Demo!" );
ImGui::Checkbox( "Profiler" , &T_Profiler::Profiler.uiEnabled( ) ); ImGui::Checkbox( "Profiler" , &Globals::Profiler( ).uiEnabled( ) );
if ( demo ) { if ( demo ) {
demo->makeUI( ); demo->makeUI( );
} }
ImGui::End( ); ImGui::End( );
T_Profiler::Profiler.makeUI( ); Globals::Profiler( ).makeUI( );
} }
void T_Main::render( ) void T_Main::render( )
{ {
if ( demo ) { if ( demo ) {
T_Profiler::Profiler.start( "Render" ); Globals::Profiler( ).start( "Render" );
demo->render( ); demo->render( );
glFinish( ); T_Profiler::Profiler.end( "Render" ); glFinish( ); Globals::Profiler( ).end( "Render" );
} }
glUseProgram( 0 ); glUseProgram( 0 );
T_TextureManagement::TM( ).reset( ); Globals::Textures( ).reset( );
ImGui::Render( ); ImGui::Render( );
} }
void T_Main::initProgram( ) void T_Main::initProgram( )
{ {
spCopy = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher ); spCopy = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER );
spCopy->addFile( "copy.glsl" ); spCopy->addFile( "copy.glsl" );
spCopy->load( ); spCopy->load( );
} }
@ -223,20 +199,10 @@ void T_Main::initProgram( )
int main( int , char** ) int main( int , char** )
{ {
T_Main m; T_Main m;
#if 0
testLoadShaderFile( );
#else
m.mainLoop( ); m.mainLoop( );
#if 0
// Frame time history
const int nFrameTimes = 200;
float frameTimes[ nFrameTimes ];
memset( frameTimes , 0 , sizeof( float ) * nFrameTimes );
#endif #endif
#if 0
// Update frame time history
memmove( frameTimes , &frameTimes[ 1 ] ,
( nFrameTimes - 1 ) * sizeof( float ) );
frameTimes[ nFrameTimes - 1 ] = 1000.0f / ImGui::GetIO( ).Framerate;
#endif
return 0; return 0;
} }

View file

@ -1,5 +1,6 @@
#include "externals.hh" #include "externals.hh"
#include "programs.hh" #include "programs.hh"
#include "globals.hh"
/*= T_ShaderCode =============================================================*/ /*= T_ShaderCode =============================================================*/
@ -144,9 +145,8 @@ GLuint T_ShaderCode::createProgram(
/*= T_ShaderProgram ==========================================================*/ /*= T_ShaderProgram ==========================================================*/
T_ShaderProgram::T_ShaderProgram( T_ShaderProgram::T_ShaderProgram(
__rd__ const GLenum programType , __rd__ const GLenum programType )
__rw__ T_FilesWatcher& watcher ) : files_( Globals::Watcher( ) , [this] { load( ); } ) ,
: files_( watcher , [this] { load( ); } ) ,
programType_( programType ) , program_( 0 ) programType_( programType ) , program_( 0 )
{ {
} }
@ -245,12 +245,11 @@ namespace {
std::unique_ptr< T_ShaderProgram > FsQuad_; std::unique_ptr< T_ShaderProgram > FsQuad_;
} }
T_ShaderProgram const& T_ShaderProgram::FullscreenQuad( T_ShaderProgram const& T_ShaderProgram::FullscreenQuad( )
__rw__ T_FilesWatcher& watcher )
{ {
if ( !FsQuad_ ) { if ( !FsQuad_ ) {
FsQuad_ = std::make_unique< T_ShaderProgram >( FsQuad_ = std::make_unique< T_ShaderProgram >(
GL_VERTEX_SHADER , watcher ); GL_VERTEX_SHADER );
FsQuad_->addFile( "fsquad.glsl" ); FsQuad_->addFile( "fsquad.glsl" );
FsQuad_->load( ); FsQuad_->load( );
} }

View file

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "utilities.hh" #include "filewatcher.hh"
/*= T_ShaderCode =============================================================*/ /*= T_ShaderCode =============================================================*/
@ -40,9 +40,7 @@ struct T_ShaderProgram
T_ShaderProgram( T_ShaderProgram const& ) = delete; T_ShaderProgram( T_ShaderProgram const& ) = delete;
T_ShaderProgram( T_ShaderProgram&& ) = delete; T_ShaderProgram( T_ShaderProgram&& ) = delete;
T_ShaderProgram( T_ShaderProgram( __rd__ GLenum programType );
__rd__ GLenum programType ,
__rw__ T_FilesWatcher& watcher );
~T_ShaderProgram( ); ~T_ShaderProgram( );
void addChunk( __rd__ std::string const& string ); void addChunk( __rd__ std::string const& string );
@ -53,8 +51,7 @@ struct T_ShaderProgram
GLuint id( ) const { return program_; } GLuint id( ) const { return program_; }
static T_ShaderProgram const& FullscreenQuad( static T_ShaderProgram const& FullscreenQuad( );
__rw__ T_FilesWatcher& watcher );
private: private:
T_WatchedFiles files_; T_WatchedFiles files_;

View file

@ -12,10 +12,9 @@ namespace {
T_Raymarcher::T_Raymarcher( T_Raymarcher::T_Raymarcher(
__rw__ T_FilesWatcher& watcher ,
__rd__ const uint32_t width , __rd__ const uint32_t width ,
__rd__ const uint32_t height ) __rd__ const uint32_t height )
: camera_( ) , program_( GL_FRAGMENT_SHADER , watcher ) , : camera_( ) , program_( GL_FRAGMENT_SHADER ) ,
txOutput_( width , height , E_TexType::RGB16F ) , txOutput_( width , height , E_TexType::RGB16F ) ,
txDepth_( width , height , E_TexType::R16F ) , txDepth_( width , height , E_TexType::R16F ) ,
rtOutput_( T_RendertargetSetup( ) rtOutput_( T_RendertargetSetup( )

View file

@ -12,8 +12,7 @@ struct T_Raymarcher
T_Raymarcher( T_Raymarcher const& ) = delete; T_Raymarcher( T_Raymarcher const& ) = delete;
T_Raymarcher( T_Raymarcher&& ) = delete; T_Raymarcher( T_Raymarcher&& ) = delete;
T_Raymarcher( __rw__ T_FilesWatcher& watcher , T_Raymarcher( __rd__ const uint32_t width ,
__rd__ const uint32_t width ,
__rd__ const uint32_t height ); __rd__ const uint32_t height );
void render( ); void render( );

View file

@ -1,5 +1,6 @@
#include "externals.hh" #include "externals.hh"
#include "shaders.hh" #include "shaders.hh"
#include "globals.hh"
namespace { namespace {
@ -14,6 +15,8 @@ const std::map< std::string , E_ShaderInput > InputTypes_( ([] {
t.emplace( "vertex" , E_ShaderInput::VERTEX ); t.emplace( "vertex" , E_ShaderInput::VERTEX );
t.emplace( "fragment" , E_ShaderInput::FRAGMENT ); t.emplace( "fragment" , E_ShaderInput::FRAGMENT );
t.emplace( "compute" , E_ShaderInput::COMPUTE ); t.emplace( "compute" , E_ShaderInput::COMPUTE );
t.emplace( "geo" , E_ShaderInput::GEOMETRY );
t.emplace( "geometry" , E_ShaderInput::GEOMETRY );
return t; return t;
})()); })());
@ -313,34 +316,62 @@ void T_CodeBuilder_::next( )
/*============================================================================*/ /*============================================================================*/
T_ShaderCodeLoader::T_ShaderCodeLoader(
__rw__ T_FilesWatcher& watcher )
: watcher_( watcher )
{
}
bool T_ShaderCodeLoader::load( bool T_ShaderCodeLoader::load(
__rd__ std::string const& name , __rd__ std::string const& name ,
__wr__ T_Frankenshader& code ) __wr__ T_Frankenshader& code )
{ {
T_CodeBuilder_ cb( *this , name , code ); T_CodeBuilder_ cb( *this , name , code );
return cb.buildCode( ); const bool rv( cb.buildCode( ) );
// Update dependencies
for ( auto const& dep : code.files ) {
deps_[ name ].insert( dep.first );
}
return rv;
} }
T_ShaderInput const* T_ShaderCodeLoader::getInput( T_ShaderInput const* T_ShaderCodeLoader::getInput(
__rd__ std::string const& name ) __rd__ std::string const& name )
{ {
auto pos( files.find( name ) ); auto pos( inputs_.find( name ) );
if ( pos != files.end( ) ) { if ( pos != inputs_.end( ) ) {
return pos->second.get( ); return pos->second.get( );
} }
T_ShaderInput ni; T_ShaderInput ni;
if ( !ni.load( "shaders/" + name ) ) { if ( !ni.load( "shaders/" + name ) ) {
return nullptr; return nullptr;
} }
files.emplace( name , std::make_unique< T_ShaderInput >( inputs_.emplace( name , std::make_unique< T_ShaderInput >( std::move( ni ) ) );
std::move( ni ) ) ); return inputs_.find( name )->second.get( );
return files.find( name )->second.get( );
} }
void T_ShaderCodeLoader::removeInput( void T_ShaderCodeLoader::removeInput(
__rd__ std::string const& name ) __rd__ std::string const& name )
{ {
files.erase( name ); inputs_.erase( name );
}
void T_ShaderCodeLoader::onFileUpdated(
__rd__ std::string const& name )
{
inputs_.erase( name );
auto& deps( deps_[ name ] );
for ( auto const& dep : deps ) {
pending_.insert( dep );
}
}
bool T_ShaderPipeline::valid( ) const noexcept
{
return Globals::Shaders( ).pipelines_[ smIndex_ ].id != 0;
} }
@ -348,7 +379,7 @@ void T_ShaderCodeLoader::removeInput(
void testLoadShaderFile( ) void testLoadShaderFile( )
{ {
const std::string source( "test-loader.glsl" ); const std::string source( "test-loader.glsl" );
T_ShaderCodeLoader loader; T_ShaderCodeLoader loader( Globals::Watcher( ) );
T_Frankenshader code; T_Frankenshader code;
if ( loader.load( source , code ) ) { if ( loader.load( source , code ) ) {
printf( "SUCCESS! TYPE = %d\n" , int( code.type ) ); printf( "SUCCESS! TYPE = %d\n" , int( code.type ) );

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "filewatcher.hh"
#include "utilities.hh" #include "utilities.hh"
@ -32,7 +33,8 @@ enum class E_ShaderInput {
LIBRARY , // Library (will only be loaded once) LIBRARY , // Library (will only be loaded once)
// "Main" shader source files // "Main" shader source files
VERTEX , FRAGMENT , COMPUTE VERTEX , FRAGMENT , GEOMETRY ,
COMPUTE
}; };
// Preprocessing errors // Preprocessing errors
@ -56,7 +58,8 @@ using P_ShaderInput = std::unique_ptr< T_ShaderInput >;
// Type of shader // Type of shader
enum class E_ShaderType { enum class E_ShaderType {
VERTEX , FRAGMENT , COMPUTE VERTEX , FRAGMENT , COMPUTE ,
__COUNT__
}; };
@ -83,9 +86,42 @@ struct T_Frankenshader
}; };
using P_Frankenshader = std::unique_ptr< T_Frankenshader >; using P_Frankenshader = std::unique_ptr< T_Frankenshader >;
// A shader program
struct T_ShaderProgram2 // FIXME: name
{
~T_ShaderProgram2( ) // XXX pipelines, notify loader
{ if ( valid( ) ) glDeleteProgram( id_ ); }
bool valid( ) const noexcept
{ return id_ != 0; }
std::string const& name( ) const noexcept
{ return name_; }
GLuint id( ) const noexcept
{ return id_; }
bool activate( ) const
{
if ( valid( ) ) {
glUseProgram( id_ );
GL_CHECK( return false );
}
return valid( );
}
private:
std::string name_;
E_ShaderType type_;
GLuint id_;
};
// XXX test for the loader // XXX test for the loader
struct T_ShaderCodeLoader struct T_ShaderCodeLoader
{ {
T_ShaderCodeLoader( ) = delete;
explicit T_ShaderCodeLoader(
__rw__ T_FilesWatcher& watcher );
bool load( __rd__ std::string const& name , bool load( __rd__ std::string const& name ,
__wr__ T_Frankenshader& code ); __wr__ T_Frankenshader& code );
@ -93,7 +129,55 @@ struct T_ShaderCodeLoader
void removeInput( __rd__ std::string const& name ); void removeInput( __rd__ std::string const& name );
private: private:
std::map< std::string , P_ShaderInput > files; T_FilesWatcher& watcher_;
std::set< std::string > pending_;
std::map< std::string , P_ShaderInput > inputs_;
std::map< std::string , P_Frankenshader > code_;
std::map< std::string , std::set< std::string > > deps_;
void onFileUpdated( __rd__ std::string const& name );
};
struct T_ShaderPipeline
{
bool valid( ) const noexcept;
void enable( ) const;
private:
uint32_t smIndex_;
};
struct T_ShaderManager
{
friend struct T_ShaderPipeline;
T_ShaderPipeline pipeline(
__rd__ std::initializer_list< std::string > shaders );
private:
struct T_Pipeline_
{
uint32_t references;
std::string idString;
GLuint id;
int32_t programs[ size_t( E_ShaderType::__COUNT__ ) ];
};
struct T_Program_
{
uint32_t references;
std::string name;
E_ShaderType type;
GLuint id;
};
std::vector< T_Pipeline_ > pipelines_;
std::map< std::string , uint32_t > pipelineIndex_;
std::vector< T_Program_ > program_;
}; };

View file

@ -256,25 +256,10 @@ void T_TextureSampler::setSamplingMode( ) const
/*============================================================================*/ /*============================================================================*/
constexpr uint32_t T_TextureManagement::MaxUnits; constexpr uint32_t T_TextureManager::MaxUnits;
std::unique_ptr< T_TextureManagement > T_TextureManagement::instance_;
T_TextureManagement& T_TextureManagement::TM( ) T_TextureManager::T_TextureManager( )
{
if ( !instance_ ) {
instance_.reset( new T_TextureManagement( ) );
}
return *instance_;
}
void T_TextureManagement::Shutdown( )
{
instance_.reset( );
}
T_TextureManagement::T_TextureManagement( )
{ {
std::shared_ptr< T_TextureSampler > tsam; std::shared_ptr< T_TextureSampler > tsam;
@ -295,7 +280,7 @@ T_TextureManagement::T_TextureManagement( )
samplers_[ "linear-border" ] = tsam; samplers_[ "linear-border" ] = tsam;
} }
T_TextureSampler const* T_TextureManagement::sampler( T_TextureSampler const* T_TextureManager::sampler(
__rd__ std::string const& name ) const __rd__ std::string const& name ) const
{ {
auto pos( samplers_.find( name ) ); auto pos( samplers_.find( name ) );
@ -305,7 +290,7 @@ T_TextureSampler const* T_TextureManagement::sampler(
return (*pos).second.get( ); return (*pos).second.get( );
} }
void T_TextureManagement::bind( void T_TextureManager::bind(
__rd__ const uint32_t unit , __rd__ const uint32_t unit ,
__rd__ T_Texture const& texture ) __rd__ T_Texture const& texture )
{ {
@ -320,7 +305,7 @@ void T_TextureManagement::bind(
glBindSampler( unit , 0 ); glBindSampler( unit , 0 );
} }
void T_TextureManagement::bind( void T_TextureManager::bind(
__rd__ const uint32_t unit , __rd__ const uint32_t unit ,
__rd__ T_Texture const& texture , __rd__ T_Texture const& texture ,
__rd__ T_TextureSampler const& sampler ) __rd__ T_TextureSampler const& sampler )
@ -336,7 +321,7 @@ void T_TextureManagement::bind(
glBindSampler( unit , sampler.id( ) ); glBindSampler( unit , sampler.id( ) );
} }
void T_TextureManagement::reset( ) void T_TextureManager::reset( )
{ {
for ( auto i = 0u ; i < MaxUnits ; i ++ ) { for ( auto i = 0u ; i < MaxUnits ; i ++ ) {
auto& u( bindings_[ i ] ); auto& u( bindings_[ i ] );

View file

@ -103,15 +103,14 @@ struct T_TextureSampler
}; };
struct T_TextureManagement struct T_TextureManager
{ {
static constexpr uint32_t MaxUnits = 8; static constexpr uint32_t MaxUnits = 8;
NO_COPY( T_TextureManagement ); T_TextureManager( );
NO_MOVE( T_TextureManagement );
static T_TextureManagement& TM( ); NO_COPY( T_TextureManager );
static void Shutdown( ); NO_MOVE( T_TextureManager );
void reset( ); void reset( );
T_TextureSampler const* sampler( T_TextureSampler const* sampler(
@ -124,10 +123,6 @@ struct T_TextureManagement
__rd__ T_TextureSampler const& sampler ); __rd__ T_TextureSampler const& sampler );
private: private:
static std::unique_ptr< T_TextureManagement > instance_;
T_TextureManagement( );
struct T_Binding_ struct T_Binding_
{ {
GLuint texture = 0; GLuint texture = 0;

View file

@ -39,119 +39,3 @@ void anglesToMatrix(
matrix[7] = s[0]*c[1]; matrix[7] = s[0]*c[1];
matrix[8] = c[0]*c[1]; matrix[8] = c[0]*c[1];
} }
/*= T_FilesWatcher ===========================================================*/
T_FilesWatcher::T_FilesWatcher( )
: fd( inotify_init1( O_NONBLOCK ) )
{ }
T_FilesWatcher::T_FilesWatcher( T_FilesWatcher&& other ) noexcept
: fd( 0 ) , watched( std::move( other.watched ) )
{
std::swap( fd , other.fd );
other.watched.clear( );
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->watcher = this;
}
}
}
T_FilesWatcher::~T_FilesWatcher( )
{
if ( fd ) {
close( fd );
}
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->watcher = nullptr;
}
}
}
void T_FilesWatcher::check( )
{
for ( T_WatchedFiles* wf : watched ) {
if ( wf ) {
wf->triggered = false;
}
}
inotify_event ie;
while ( read( fd , &ie , sizeof( ie ) ) == sizeof( ie ) ) {
if ( ( ie.mask & ( IN_CLOSE_WRITE | IN_DELETE_SELF ) ) == 0 ) {
continue;
}
for ( T_WatchedFiles* wf : watched ) {
if ( !wf || wf->triggered ) {
continue;
}
auto const& idl( wf->identifiers );
if ( find( idl , ie.wd ) != idl.end( ) ) {
wf->triggered = true;
wf->callback( );
}
}
}
}
/*= T_WatchedFiles ===========================================================*/
T_WatchedFiles::T_WatchedFiles( T_WatchedFiles&& other ) noexcept
: watcher( other.watcher ) , callback( other.callback ) ,
triggered( other.triggered ) ,
identifiers( std::move( other.identifiers ) )
{
if ( watcher ) {
other.watcher = nullptr;
*( find( watcher->watched , &other ) ) = this;
}
}
T_WatchedFiles::T_WatchedFiles(
__rw__ T_FilesWatcher& watcher ,
__rd__ const F_OnFileChanges callback )
: watcher( &watcher ) , callback( callback ) , triggered( false )
{
watcher.watched.push_back( this );
}
T_WatchedFiles::~T_WatchedFiles( )
{
clear( );
if ( watcher ) {
watcher->watched.erase( find( watcher->watched , this ) );
}
}
void T_WatchedFiles::clear( )
{
if ( watcher ) {
const auto fd( watcher->fd );
for ( int wd : identifiers ) {
inotify_rm_watch( fd , wd );
}
}
identifiers.clear( );
}
bool T_WatchedFiles::watch(
__rd__ std::string const& file )
{
static constexpr auto inFlags( IN_CLOSE_WRITE | IN_DELETE_SELF );
if ( watcher ) {
const auto wd( inotify_add_watch( watcher->fd ,
file.c_str( ) , inFlags ) );
if ( wd == -1 ) {
return false;
}
if ( find( identifiers , wd ) == identifiers.end( ) ) {
identifiers.push_back( wd );
}
return true;
}
return false;
}

View file

@ -58,53 +58,3 @@ inline auto find(
{ {
return std::find( collection.begin( ) , collection.end( ) , item ); return std::find( collection.begin( ) , collection.end( ) , item );
} }
/*= T_FilesWatcher / T_WatchedFiles ==========================================*/
struct T_FilesWatcher;
struct T_WatchedFiles;
using F_OnFileChanges = std::function< void( void ) >;
struct T_FilesWatcher
{
friend struct T_WatchedFiles;
T_FilesWatcher( T_FilesWatcher const& ) = delete;
T_FilesWatcher( );
T_FilesWatcher( T_FilesWatcher&& ) noexcept;
~T_FilesWatcher( );
void check( );
private:
int fd;
std::vector< T_WatchedFiles* > watched;
};
/*----------------------------------------------------------------------------*/
struct T_WatchedFiles
{
friend struct T_FilesWatcher;
T_WatchedFiles( ) = delete;
T_WatchedFiles( T_WatchedFiles const& ) = delete;
T_WatchedFiles( T_WatchedFiles&& ) noexcept;
T_WatchedFiles(
__rw__ T_FilesWatcher& watcher ,
__rd__ const F_OnFileChanges callback );
~T_WatchedFiles( );
void clear( );
bool watch( __rd__ std::string const& file );
private:
T_FilesWatcher* watcher;
const F_OnFileChanges callback;
bool triggered;
std::vector< int > identifiers;
};

56
window.cc Normal file
View file

@ -0,0 +1,56 @@
#include "externals.hh"
#include "window.hh"
#include "imgui_impl_sdl.h"
T_Window::T_Window( )
{
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER , 1 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE , 24 );
SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE , 8 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION , 2 );
SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION , 2 );
SDL_DisplayMode current;
SDL_GetCurrentDisplayMode( 0 , &current );
window = SDL_CreateWindow( "DEMO",
SDL_WINDOWPOS_CENTERED , SDL_WINDOWPOS_CENTERED ,
1280 , 720 ,
SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE );
gl = SDL_GL_CreateContext( window );
glewInit( );
if ( !GLEW_VERSION_4_5 ) {
fprintf( stderr , "OpenGL 4.5 required\n" );
exit( 1 );
}
ImGui_ImplSdl_Init( window );
}
T_Window::~T_Window( )
{
ImGui_ImplSdl_Shutdown( );
SDL_GL_DeleteContext( gl );
SDL_DestroyWindow( window );
SDL_Quit( );
}
void T_Window::startFrame(
__rd__ const bool capture ,
__rd__ ImVec2 const& mouseInitial ) const
{
ImGui_ImplSdl_NewFrame( window , capture , mouseInitial );
}
void T_Window::warpMouse(
__rd__ ImVec2 const& pos ) const
{
SDL_WarpMouseInWindow( window , pos.x , pos.y );
}
void T_Window::swap( ) const
{
SDL_GL_SwapWindow( window );
}

22
window.hh Normal file
View file

@ -0,0 +1,22 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
#endif
struct T_Window
{
T_Window( );
~T_Window( );
void startFrame( __rd__ const bool capture ,
__rd__ ImVec2 const& mouseInitial ) const;
void warpMouse( __rd__ ImVec2 const& pos ) const;
void swap( ) const;
private:
SDL_Window * window;
SDL_GLContext gl;
};