Ops - Auto-reload + resize support
This commit is contained in:
parent
c3171aba94
commit
e0e7ab5441
11 changed files with 201 additions and 128 deletions
2
Makefile
2
Makefile
|
@ -27,10 +27,12 @@ COMMON = \
|
|||
shaders.cc \
|
||||
odbg.cc \
|
||||
sync.cc \
|
||||
\
|
||||
ops.cc \
|
||||
opast.cc \
|
||||
opparser.cc \
|
||||
opcomp.cc \
|
||||
opmgr.cc \
|
||||
# END COMMON
|
||||
|
||||
DEMO = \
|
||||
|
|
1
TODO
1
TODO
|
@ -11,7 +11,6 @@ Scripting:
|
|||
type errors
|
||||
* Spill values in the FPU stack runs out
|
||||
* More checks in the execution engine
|
||||
* Reload script on file changes
|
||||
* Re-execute init if shaders are changed
|
||||
(better yet, only execute the parts that are actually needed)
|
||||
* Overrides
|
||||
|
|
107
demo.cc
107
demo.cc
|
@ -3,30 +3,28 @@
|
|||
#include "sync.hh"
|
||||
#include "rendertarget.hh"
|
||||
#include "globals.hh"
|
||||
#include "ops.hh"
|
||||
#include "opcomp.hh"
|
||||
#include <ebcl/Files.hh>
|
||||
#include <ebcl/SRDText.hh>
|
||||
|
||||
|
||||
T_Demo::T_Demo( const uint32_t width ,
|
||||
const uint32_t height )
|
||||
: width( width ) , height( height )
|
||||
{ }
|
||||
|
||||
|
||||
bool T_Demo::initialise( )
|
||||
bool T_Demo::initialise(
|
||||
const uint32_t w ,
|
||||
const uint32_t h )
|
||||
{
|
||||
if ( !program ) {
|
||||
loadProgram( );
|
||||
}
|
||||
|
||||
return true;
|
||||
width = w;
|
||||
height = h;
|
||||
return program && runInit( *program );
|
||||
}
|
||||
|
||||
void T_Demo::render( )
|
||||
{
|
||||
if ( program && !context ) {
|
||||
runInit( );
|
||||
if ( Globals::Ops( ).hasNewProgram( ) ) {
|
||||
auto nProgram{ Globals::Ops( ).program( ) };
|
||||
if ( runInit( *nProgram ) ) {
|
||||
program = std::move( nProgram );
|
||||
}
|
||||
}
|
||||
|
||||
auto& sync( Globals::Sync( ) );
|
||||
|
@ -99,83 +97,34 @@ void WriteSRDError(
|
|||
} // namespace
|
||||
|
||||
|
||||
bool T_Demo::loadProgram( )
|
||||
|
||||
bool T_Demo::runInit(
|
||||
ops::T_OpProgram& p )
|
||||
{
|
||||
using namespace ebcl;
|
||||
const T_String inputName( T_String::Pooled( "demo.srd" ) );
|
||||
T_File input( inputName , E_FileMode::READ_ONLY );
|
||||
auto nContext{ NewOwned< ops::T_OpContext >( p ) };
|
||||
try {
|
||||
input.open( );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Load SRD data
|
||||
T_SRDMemoryTarget srdOut;
|
||||
srdOut.clearComments( true ).clearFlushToken( true );
|
||||
try {
|
||||
T_SRDTextReader srdReader{ srdOut };
|
||||
T_FileInputStream fis{ input };
|
||||
srdReader.read( inputName , fis );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
PrintStreamError( "Could not open" , inputName , e );
|
||||
return false;
|
||||
|
||||
} catch ( X_SRDErrors const& e ) {
|
||||
T_StringBuilder sb;
|
||||
const auto nErrors( e.errors.size( ) );
|
||||
for ( auto i = 0u ; i < nErrors ; i ++ ) {
|
||||
WriteSRDError( sb , e.errors[ i ] );
|
||||
}
|
||||
sb << "No parsing happened due to format errors\n" << '\0';
|
||||
fprintf( stderr , "%s" , sb.data( ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
// Parse the fuck
|
||||
T_OpsParser parser;
|
||||
if ( parser.parse( srdOut.list( ) ) ) {
|
||||
printf( "Parser successful. Compiling...\n" );
|
||||
T_OpsCompiler compiler;
|
||||
program = compiler.compile( *parser.result( ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
T_StringBuilder sb;
|
||||
sb << "- PARSE ERRORS -------------------------\n";
|
||||
const auto nErrors( parser.errors( ).size( ) );
|
||||
for ( auto i = 0u ; i < nErrors ; i ++ ) {
|
||||
WriteSRDError( sb , parser.errors( )[ i ] );
|
||||
}
|
||||
sb << "----------------------------------------\n";
|
||||
sb << '\0';
|
||||
fprintf( stderr , "%s" , sb.data( ) );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void T_Demo::runInit( )
|
||||
{
|
||||
context = NewOwned< ops::T_OpContext >( *program );
|
||||
try {
|
||||
context->run( ops::T_OpContext::R_INIT , 0 , width , height );
|
||||
nContext->run( ops::T_OpContext::R_INIT , 0 , width , height );
|
||||
} catch ( ops::X_OpFailure const& fail ) {
|
||||
printf( "FAILED TO RUN INIT!\n\t%s\n" , fail.what( ) );
|
||||
context->aborted = true;
|
||||
return;
|
||||
nContext.clear( );
|
||||
}
|
||||
if ( !nContext ) {
|
||||
return false;
|
||||
}
|
||||
context = std::move( nContext );
|
||||
|
||||
Globals::Sync( ).clearInputs( );
|
||||
const auto n( context->initialInputs.size( ) );
|
||||
assert( n == program->inputs.size( ) );
|
||||
assert( n == p.inputs.size( ) );
|
||||
for ( auto i = 0u ; i < n ; i ++ ) {
|
||||
Globals::Sync( ).addInput( program->inputs[ i ] ,
|
||||
Globals::Sync( ).addInput( p.inputs[ i ] ,
|
||||
context->initialInputs[ i ] );
|
||||
#ifdef INVASIVE_TRACES
|
||||
printf( "#%d %s pos %d\n" , i , program->inputs[ i ].toOSString( ).data( ) ,
|
||||
Globals::Sync( ).inputPos( program->inputs[ i ] ) );
|
||||
printf( "#%d %s pos %d\n" , i , p.inputs[ i ].toOSString( ).data( ) ,
|
||||
Globals::Sync( ).inputPos( p.inputs[ i ] ) );
|
||||
#endif //INVASIVE_TRACES
|
||||
}
|
||||
Globals::Sync( ).updateCurveCaches( );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
22
demo.hh
22
demo.hh
|
@ -2,24 +2,22 @@
|
|||
|
||||
#include "opcomp.hh"
|
||||
|
||||
namespace ops { class T_OpContext; }
|
||||
|
||||
|
||||
struct T_Demo
|
||||
{
|
||||
T_Demo( ) = delete;
|
||||
T_Demo( ) = default;
|
||||
|
||||
NO_COPY( T_Demo );
|
||||
NO_MOVE( T_Demo );
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
T_Demo( const uint32_t width ,
|
||||
bool initialise( const uint32_t width ,
|
||||
const uint32_t height );
|
||||
|
||||
bool initialise( );
|
||||
void render( );
|
||||
|
||||
bool loadProgram( );
|
||||
void runInit( );
|
||||
|
||||
void handleDND(
|
||||
ImVec2 const& move ,
|
||||
const bool hasCtrl ,
|
||||
|
@ -34,15 +32,17 @@ struct T_Demo
|
|||
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
const uint32_t width;
|
||||
const uint32_t height;
|
||||
|
||||
bool playing = false;
|
||||
|
||||
private:
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
|
||||
T_OwnPtr< ops::T_OpProgram > program;
|
||||
T_OwnPtr< ops::T_OpContext > context;
|
||||
|
||||
private:
|
||||
bool playingPrevious = false;
|
||||
float lastFrame;
|
||||
|
||||
bool runInit( ops::T_OpProgram& program );
|
||||
};
|
||||
|
|
11
demo.srd
11
demo.srd
|
@ -1,12 +1,14 @@
|
|||
(init
|
||||
# Compute viewport size
|
||||
(if (cmp-gt $width $height)
|
||||
(locals aspect-ratio)
|
||||
(set aspect-ratio (div 16 9))
|
||||
(if (cmp-gt (div $width $aspect-ratio) $height)
|
||||
(
|
||||
(set vp-height $height)
|
||||
(set vp-width (mul $height (div 16 9)))
|
||||
(set vp-width (mul $height $aspect-ratio))
|
||||
)(
|
||||
(set vp-width $width)
|
||||
(set vp-height (div $width (div 16 9)))
|
||||
(set vp-height (div $width $aspect-ratio))
|
||||
)
|
||||
)
|
||||
# Viewport location
|
||||
|
@ -448,7 +450,8 @@
|
|||
# FIXME temp - we'll need to do init right before this
|
||||
# can be moved back to initialisation
|
||||
(uniforms-i prg-fxaa 0 0)
|
||||
(uniforms prg-fxaa 1 $vp-width $vp-height)
|
||||
(uniforms prg-fxaa 1
|
||||
$vp-x $vp-y $vp-width $vp-height)
|
||||
|
||||
(main-output)
|
||||
(viewport 0 0 $width $height)
|
||||
|
|
13
globals.cc
13
globals.cc
|
@ -2,12 +2,14 @@
|
|||
#include "globals.hh"
|
||||
|
||||
#include "filewatcher.hh"
|
||||
#include "profiling.hh"
|
||||
#include "texture.hh"
|
||||
#include "shaders.hh"
|
||||
#include "window.hh"
|
||||
#include "odbg.hh"
|
||||
#include "opcomp.hh"
|
||||
#include "ops.hh"
|
||||
#include "profiling.hh"
|
||||
#include "shaders.hh"
|
||||
#include "sync.hh"
|
||||
#include "texture.hh"
|
||||
#include "window.hh"
|
||||
|
||||
|
||||
T_OwnPtr< T_FilesWatcher > Globals::watcher_;
|
||||
|
@ -17,6 +19,7 @@ T_OwnPtr< T_SyncManager > Globals::sync_;
|
|||
T_OwnPtr< T_TextureManager > Globals::textures_;
|
||||
T_OwnPtr< T_ShaderManager > Globals::shaders_;
|
||||
T_OwnPtr< T_OutputDebugger > Globals::odbg_;
|
||||
T_OwnPtr< T_ScriptManager > Globals::ops_;
|
||||
|
||||
|
||||
void Globals::Init( )
|
||||
|
@ -28,10 +31,12 @@ void Globals::Init( )
|
|||
textures_ = NewOwned< T_TextureManager >( );
|
||||
shaders_ = NewOwned< T_ShaderManager >( );
|
||||
odbg_ = NewOwned< T_OutputDebugger >( );
|
||||
ops_ = NewOwned< T_ScriptManager >( );
|
||||
}
|
||||
|
||||
void Globals::Shutdown( )
|
||||
{
|
||||
ops_.clear( );
|
||||
odbg_.clear( );
|
||||
shaders_.clear( );
|
||||
textures_.clear( );
|
||||
|
|
17
globals.hh
17
globals.hh
|
@ -11,6 +11,7 @@ struct T_TextureManager;
|
|||
struct T_ShaderManager;
|
||||
struct T_OutputDebugger;
|
||||
struct T_SyncManager;
|
||||
struct T_ScriptManager;
|
||||
|
||||
|
||||
struct Globals
|
||||
|
@ -25,13 +26,15 @@ struct Globals
|
|||
static T_TextureManager& Textures( ) { return *textures_; }
|
||||
static T_ShaderManager& Shaders( ) { return *shaders_; }
|
||||
static T_OutputDebugger& ODbg( ) { return *odbg_; }
|
||||
static T_ScriptManager& Ops( ) { return *ops_; }
|
||||
|
||||
private:
|
||||
static ebcl::T_OwnPtr< T_FilesWatcher > watcher_;
|
||||
static ebcl::T_OwnPtr< T_Window > window_;
|
||||
static ebcl::T_OwnPtr< T_Profiler > profiler_;
|
||||
static ebcl::T_OwnPtr< T_SyncManager > sync_;
|
||||
static ebcl::T_OwnPtr< T_ShaderManager > shaders_;
|
||||
static ebcl::T_OwnPtr< T_TextureManager > textures_;
|
||||
static ebcl::T_OwnPtr< T_OutputDebugger > odbg_;
|
||||
static T_OwnPtr< T_FilesWatcher > watcher_;
|
||||
static T_OwnPtr< T_Window > window_;
|
||||
static T_OwnPtr< T_Profiler > profiler_;
|
||||
static T_OwnPtr< T_SyncManager > sync_;
|
||||
static T_OwnPtr< T_ShaderManager > shaders_;
|
||||
static T_OwnPtr< T_TextureManager > textures_;
|
||||
static T_OwnPtr< T_OutputDebugger > odbg_;
|
||||
static T_OwnPtr< T_ScriptManager > ops_;
|
||||
};
|
||||
|
|
31
main.cc
31
main.cc
|
@ -7,7 +7,9 @@
|
|||
#include "window.hh"
|
||||
#include "shaders.hh"
|
||||
#include "odbg.hh"
|
||||
#include "ops.hh"
|
||||
#include "rendertarget.hh"
|
||||
#include "sync.hh"
|
||||
|
||||
using ebcl::T_Optional;
|
||||
|
||||
|
@ -47,27 +49,30 @@ struct T_Main
|
|||
T_Main::T_Main( )
|
||||
{
|
||||
Globals::Init( );
|
||||
prevSize = ImVec2( 1280 , 720 );
|
||||
prevSize = ImVec2( -1 , -1 );
|
||||
}
|
||||
|
||||
void T_Main::mainLoop( )
|
||||
{
|
||||
auto& p( Globals::Profiler( ) );
|
||||
while ( !done ) {
|
||||
if ( demo ) {
|
||||
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
|
||||
if ( prevSize.x != dspSize.x || prevSize.y != dspSize.y ) {
|
||||
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
|
||||
if ( prevSize.x != dspSize.x || prevSize.y != dspSize.y ) {
|
||||
const auto doit( prevSize.x > 0 );
|
||||
prevSize = dspSize;
|
||||
if ( doit ) {
|
||||
stopResize = ResizeDelay;
|
||||
prevSize = dspSize;
|
||||
}
|
||||
}
|
||||
|
||||
bool needInit( !demo );
|
||||
if ( stopResize > 0 ) {
|
||||
stopResize --;
|
||||
if ( stopResize == 0 ) {
|
||||
demo.clear( );
|
||||
needInit = true;
|
||||
}
|
||||
}
|
||||
if ( !demo ) {
|
||||
if ( needInit ) {
|
||||
initDemo( );
|
||||
}
|
||||
|
||||
|
@ -100,18 +105,18 @@ T_Main::~T_Main( )
|
|||
|
||||
void T_Main::initDemo( )
|
||||
{
|
||||
assert( !demo );
|
||||
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
|
||||
if ( dspSize.x < 0 || dspSize.y < 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !demo ) {
|
||||
demo.setNew( );
|
||||
}
|
||||
|
||||
printf( "init w/ dspsize %dx%d\n" , int( dspSize.x ) , int( dspSize.y ) );
|
||||
demo.setNew( dspSize.x , dspSize.y );
|
||||
if ( demo->initialise( ) ) {
|
||||
if ( demo->initialise( (uint32_t) dspSize.x , (uint32_t) dspSize.y ) ) {
|
||||
Globals::Profiler( ).clear( );
|
||||
} else {
|
||||
demo.clear( );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,9 +212,7 @@ void T_Main::makeUI( )
|
|||
void T_Main::render( )
|
||||
{
|
||||
if ( demo ) {
|
||||
Globals::Profiler( ).start( "Render" );
|
||||
demo->render( );
|
||||
glFinish( ); Globals::Profiler( ).end( "Render" );
|
||||
|
||||
Globals::Profiler( ).start( "Debug" );
|
||||
T_Rendertarget::MainOutput( );
|
||||
|
|
40
opcomp.hh
40
opcomp.hh
|
@ -1,14 +1,11 @@
|
|||
#pragma once
|
||||
#ifndef REAL_BUILD
|
||||
# include "externals.hh"
|
||||
#endif
|
||||
#include "filewatcher.hh"
|
||||
#include "opast.hh"
|
||||
#include <ebcl/SRDData.hh>
|
||||
|
||||
|
||||
/*= PARSER ===================================================================*/
|
||||
|
||||
namespace opast { class T_RootNode; }
|
||||
|
||||
// Parser output. Consists in a root node as well as other details (table of
|
||||
// constants, data types, etc...)
|
||||
struct T_OpsParserOutput
|
||||
|
@ -31,6 +28,7 @@ class T_OpsParser : public ebcl::A_PrivateImplementation
|
|||
|
||||
T_Array< ebcl::T_SRDError > const& errors( ) const noexcept
|
||||
{ return errors_; }
|
||||
|
||||
T_OwnPtr< T_OpsParserOutput > result( ) noexcept
|
||||
{ return std::move( output_ ); }
|
||||
};
|
||||
|
@ -48,3 +46,35 @@ class T_OpsCompiler : public ebcl::A_PrivateImplementation
|
|||
|
||||
ops::P_OpProgram compile( T_OpsParserOutput const& input ) noexcept;
|
||||
};
|
||||
|
||||
|
||||
/*= SCRIPT MANAGER =============================================================*/
|
||||
|
||||
// The script manager watches over the demo's script, attempting to reload it if
|
||||
// it is changed.
|
||||
class T_ScriptManager
|
||||
{
|
||||
private:
|
||||
T_WatchedFiles watcher_;
|
||||
|
||||
T_OpsParser parser_;
|
||||
T_OpsCompiler compiler_;
|
||||
|
||||
ops::P_OpProgram output_;
|
||||
T_Array< ebcl::T_SRDError > errors_;
|
||||
|
||||
public:
|
||||
T_ScriptManager( ) noexcept;
|
||||
|
||||
bool hasNewProgram( ) const noexcept
|
||||
{ return bool( output_ ); }
|
||||
|
||||
ops::P_OpProgram program( ) noexcept
|
||||
{ return std::move( output_ ); }
|
||||
|
||||
T_Array< ebcl::T_SRDError > const& errors( ) const noexcept
|
||||
{ return errors_; }
|
||||
|
||||
private:
|
||||
void loadScript( ) noexcept;
|
||||
};
|
||||
|
|
78
opmgr.cc
Normal file
78
opmgr.cc
Normal file
|
@ -0,0 +1,78 @@
|
|||
#include "externals.hh"
|
||||
#include "globals.hh"
|
||||
#include "opcomp.hh"
|
||||
#include "ops.hh"
|
||||
|
||||
#include <ebcl/Files.hh>
|
||||
#include <ebcl/SRDIO.hh>
|
||||
#include <ebcl/SRDText.hh>
|
||||
|
||||
|
||||
/*= T_ScriptManager ============================================================*/
|
||||
|
||||
T_ScriptManager::T_ScriptManager( ) noexcept
|
||||
: watcher_( Globals::Watcher( ) , [this](){
|
||||
loadScript( );
|
||||
} ) ,
|
||||
parser_( ) , compiler_( )
|
||||
{
|
||||
watcher_.watch( T_String::Pooled( "demo.srd" ) );
|
||||
loadScript( );
|
||||
}
|
||||
|
||||
void T_ScriptManager::loadScript( ) noexcept
|
||||
{
|
||||
output_.clear( );
|
||||
errors_.clear( );
|
||||
|
||||
using namespace ebcl;
|
||||
const T_String inputName( T_String::Pooled( "demo.srd" ) );
|
||||
T_File input( inputName , E_FileMode::READ_ONLY );
|
||||
try {
|
||||
input.open( );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "could not open: " << e.what( );
|
||||
if ( e.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) {
|
||||
sb << " (error code " << e.systemError( ) << ")";
|
||||
}
|
||||
errors_.addNew( std::move( sb ) ,
|
||||
T_SRDLocation{ inputName , 1 , 1 } );
|
||||
return;
|
||||
}
|
||||
|
||||
// Load SRD data
|
||||
T_SRDMemoryTarget srdOut;
|
||||
srdOut.clearComments( true ).clearFlushToken( true );
|
||||
try {
|
||||
T_SRDTextReader srdReader{ srdOut };
|
||||
T_FileInputStream fis{ input };
|
||||
srdReader.read( inputName , fis );
|
||||
} catch ( X_StreamError const& e ) {
|
||||
T_StringBuilder sb;
|
||||
sb << "could not load: " << e.what( );
|
||||
if ( e.code( ) == ebcl::E_StreamError::SYSTEM_ERROR ) {
|
||||
sb << " (error code " << e.systemError( ) << ")";
|
||||
}
|
||||
errors_.addNew( std::move( sb ) ,
|
||||
T_SRDLocation{ inputName , 1 , 1 } );
|
||||
return;
|
||||
|
||||
} catch ( X_SRDErrors const& e ) {
|
||||
T_StringBuilder sb;
|
||||
const auto nErrors( e.errors.size( ) );
|
||||
errors_.ensureCapacity( nErrors );
|
||||
for ( auto i = 0u ; i < nErrors ; i ++ ) {
|
||||
errors_.add( e.errors[ i ] );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the fuck
|
||||
if ( !parser_.parse( srdOut.list( ) ) ) {
|
||||
errors_.addAll( parser_.errors( ) );
|
||||
return;
|
||||
}
|
||||
output_ = compiler_.compile( *parser_.result( ) );
|
||||
// FIXME - errors from compiler
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
//! include chunks/fxaa-3.11.glsl
|
||||
|
||||
layout( location = 0 ) uniform sampler2D u_Input;
|
||||
layout( location = 1 ) uniform vec2 u_Resolution;
|
||||
layout( location = 1 ) uniform vec4 u_Viewport;
|
||||
layout( location = 2 ) uniform vec3 u_Parameters;
|
||||
|
||||
#define uSPQuality (u_Parameters.x)
|
||||
|
@ -22,13 +22,14 @@ layout( location = 0 ) out vec4 o_Color;
|
|||
|
||||
void main( void )
|
||||
{
|
||||
vec2 coords = gl_FragCoord.xy - u_Viewport.xy;
|
||||
o_Color = FxaaPixelShader(
|
||||
( gl_FragCoord.xy / u_Resolution ) , // pos (vec2)
|
||||
( coords / u_Viewport.zw ) , // pos (vec2)
|
||||
vec4( 0 ) , // unused (vec4)
|
||||
u_Input , // input texture
|
||||
u_Input , // (unused) input texture
|
||||
u_Input , // (unused) input texture
|
||||
vec2( 1 ) / u_Resolution , // 1/resolution (vec2)
|
||||
vec2( 1 ) / u_Viewport.zw , // 1/resolution (vec2)
|
||||
vec4( 0 ) , // unused (vec4)
|
||||
vec4( 0 ) , // unused (vec4)
|
||||
vec4( 0 ) , // unused (vec4)
|
||||
|
|
Loading…
Reference in a new issue