#include "externals.hh" #include "common.hh" #include "c-sync.hh" #include "c-undo.hh" #include "ui.hh" #include "ui-app.hh" #include "ui-demo.hh" #include "ui-imgui-sdl.hh" #include "ui-odbg.hh" #include "ui-opemu.hh" #include "ui-profiling.hh" #include "ui-rendertarget.hh" #include "ui-sequencer.hh" #include "ui-shaders.hh" #include "ui-sync.hh" #include "ui-utilities.hh" /*= T_Main ===================================================================*/ struct T_Main { static constexpr uint32_t ResizeDelay = 50; T_Main( ); ~T_Main( ); void mainLoop( ); private: bool done = false; uint32_t stopResize = 0; ImVec2 prevSize; T_Optional< T_Demo > demo; T_Optional< T_SyncView > sequencer; void initDemo( ); void startIteration( ); void makeUI( ); void render( ); }; /*----------------------------------------------------------------------------*/ T_Main::T_Main( ) { UI::Init( ); prevSize = ImVec2( -1 , -1 ); } void T_Main::mainLoop( ) { auto& m( UI::Main( ) ); auto& p( UI::Profiler( ) ); while ( !m.exiting( ) ) { // Check whether there's a resize in progress 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; } } // If there was a resize and some time has passed, // re-initialise the demo. bool needInit( !demo ); if ( stopResize > 0 ) { stopResize --; if ( stopResize == 0 ) { needInit = true; } } if ( needInit ) { initDemo( ); } #warning FIXME remove this if ( !sequencer ) { sequencer.setNew( ); } // Update file watcher and shaders Common::Watcher( ).check( ); UI::Shaders( ).update( ); // Display glFinish( ); p.startFrame( ); p.start( "Full frame" ); m.handleEvents( ); if ( !m.exiting( ) ) { makeUI( ); render( ); m.render( ); } p.end( "Full frame" ); m.swap( ); p.endFrame( ); } } T_Main::~T_Main( ) { demo.clear( ); UI::Shutdown( ); } /*----------------------------------------------------------------------------*/ void T_Main::initDemo( ) { 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 ) ); if ( demo->initialise( (uint32_t) dspSize.x , (uint32_t) dspSize.y ) ) { UI::Profiler( ).clear( ); } } void T_Main::makeUI( ) { using namespace ImGui; auto& undo( Common::Undo( ) ); bool eSequencer{ sequencer }; if ( BeginMainMenuBar( ) ) { if ( BeginMenu( "File" ) ) { UI::Main( ).actionMenu( "Save curves" ); UI::Main( ).actionMenu( "Reload curves" ); Separator( ); if ( MenuItem( "Undo" , "C-z" , false , undo.canUndo( ) ) ) { undo.undo( ); } if ( MenuItem( "Redo" , "C-Z" , false , undo.canRedo( ) ) ) { undo.redo( ); } Separator( ); if ( MenuItem( "Quit" ) ) { done = true; } EndMenu( ); } if ( BeginMenu( "Views" ) ) { MenuItemCheckbox( "Input overrides" , &UI::Sync( ).overridesWindowEnabled( ) ); MenuItemCheckbox( "Output debugger" , &UI::ODbg( ).uiEnabled( ) ); MenuItemCheckbox( "Profiler" , &UI::Profiler( ).uiEnabled( ) ); MenuItemCheckbox( "Sequencer" , &eSequencer ); MenuItemCheckbox( "Shaders" , &UI::Shaders( ).uiEnabled( ) ); EndMenu( ); } EndMainMenuBar( ); } if ( eSequencer && !sequencer ) { sequencer.setNew( ); } else if ( !eSequencer && sequencer ) { sequencer.clear( ); } UI::Profiler( ).makeUI( ); UI::ODbg( ).makeUI( ); UI::Shaders( ).makeUI( ); UI::Sync( ).makeOverridesWindow( ); if ( sequencer && !sequencer->display( ) ) { sequencer.clear( ); } } void T_Main::render( ) { if ( demo ) { demo->render( ); UI::Profiler( ).start( "Debug" ); T_Rendertarget::MainOutput( ); if ( UI::ODbg( ).isActive( ) ) { UI::ODbg( ).debugOutput( ); } glFinish( ); UI::Profiler( ).end( "Debug" ); } else { T_Rendertarget::MainOutput( ); glClearColor( 0 , 0 , 0 , 1 ); glClear( GL_COLOR_BUFFER_BIT ); } } /*============================================================================*/ int main( int , char** ) { T_Main m; m.mainLoop( ); return 0; }