#include "externals.hh" #include "imgui_impl_sdl.h" #include "demo.hh" #include "profiling.hh" /*= T_Main ===================================================================*/ struct T_Main { T_Main( ); ~T_Main( ); void mainLoop( ); private: const std::string projectFile; SDL_Window * window; SDL_GLContext gl; bool done = false; bool capture = false; ImVec2 mouseInitial; ImVec2 mouseMove; T_FilesWatcher watcher; std::unique_ptr< T_ShaderProgram > spCopy; std::unique_ptr< T_Demo > demo; void initDemo( ); void startIteration( ); void handleCapture( ); void makeUI( ); void render( ); void initProgram( ); }; /*----------------------------------------------------------------------------*/ T_Main::T_Main( ) { SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER ); // 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 , ¤t ); 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( ); } void T_Main::mainLoop( ) { auto& p( T_Profiler::Profiler ); while ( !done ) { if ( demo ) { auto const& dspSize( ImGui::GetIO( ).DisplaySize ); if ( demo->width != dspSize.x || demo->height != dspSize.y ) { demo.reset( ); } } if ( !demo ) { initDemo( ); } p.startFrame( ); T_Profiler::Profiler.start( "Full frame" ); startIteration( ); if ( !done ) { handleCapture( ); makeUI( ); watcher.check( ); render( ); T_Profiler::Profiler.end( "Full frame" ); SDL_GL_SwapWindow( window ); p.endFrame( ); } } } T_Main::~T_Main( ) { demo.reset( ); T_TextureManagement::Shutdown( ); ImGui_ImplSdl_Shutdown( ); SDL_GL_DeleteContext( gl ); SDL_DestroyWindow( window ); SDL_Quit( ); } /*----------------------------------------------------------------------------*/ void T_Main::initDemo( ) { assert( !demo ); auto const& dspSize( ImGui::GetIO( ).DisplaySize ); if ( dspSize.x < 0 || dspSize.y < 0 ) { return; } printf( "init w/ dspsize %dx%d\n" , int( dspSize.x ) , int( dspSize.y ) ); demo = std::make_unique< T_Demo >( watcher , dspSize.x , dspSize.y ); if ( demo->initialise( ) ) { T_Profiler::Profiler.clear( ); } else { demo.reset( ); } } void T_Main::startIteration( ) { SDL_Event event; mouseMove = ImVec2( ); while ( SDL_PollEvent( &event ) ) { ImGui_ImplSdl_ProcessEvent( &event ); if ( event.type == SDL_QUIT ) { done = true; return; } if ( capture && event.type == SDL_MOUSEMOTION ) { mouseMove.x += event.motion.xrel; mouseMove.y += event.motion.yrel; } } ImGui_ImplSdl_NewFrame( window , capture , mouseInitial ); ImGui::GetIO( ).MouseDrawCursor = true; } void T_Main::handleCapture( ) { auto const& io( ImGui::GetIO( ) ); const bool lmb( ImGui::IsMouseDown( 0 ) ); const bool mb( lmb || ImGui::IsMouseDown( 1 ) ); const bool appCanGrab( !( ImGui::IsMouseHoveringAnyWindow( ) || io.WantCaptureMouse || io.WantCaptureKeyboard ) ); const bool shift( io.KeyShift ); const bool ctrl( io.KeyCtrl ); if ( capture && !mb ) { capture = false; ImGui::CaptureMouseFromApp( false ); SDL_SetRelativeMouseMode( SDL_FALSE ); SDL_WarpMouseInWindow( window , int( mouseInitial.x ) , int( mouseInitial.y ) ); ImGui::SetMouseCursor( ImGuiMouseCursor_Arrow ); } else if ( capture ) { ImGui::SetMouseCursor( ImGuiMouseCursor_Move ); if ( demo ) { demo->handleDND( mouseMove , ctrl , shift , lmb ); } } else if ( appCanGrab && mb ) { capture = true; mouseInitial = ImGui::GetMousePos( ); ImGui::CaptureMouseFromApp( true ); SDL_SetRelativeMouseMode( SDL_TRUE ); ImGui::SetMouseCursor( ImGuiMouseCursor_Move ); } if ( ( appCanGrab || capture ) && io.MouseWheel && demo ) { demo->handleWheel( io.MouseWheel , ctrl , shift ); } } void T_Main::makeUI( ) { auto const& dspSize( ImGui::GetIO( ).DisplaySize ); ImGui::SetNextWindowSize( ImVec2( 300 , dspSize.y ) , ImGuiSetCond_Once ); ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once ); ImGui::Begin( "Yay! Demo!" ); ImGui::Checkbox( "Profiler" , &T_Profiler::Profiler.uiEnabled( ) ); if ( demo ) { demo->makeUI( ); } ImGui::End( ); T_Profiler::Profiler.makeUI( ); } void T_Main::render( ) { if ( demo ) { T_Profiler::Profiler.start( "Render" ); demo->render( ); glFinish( ); T_Profiler::Profiler.end( "Render" ); } glUseProgram( 0 ); T_TextureManagement::TM( ).reset( ); ImGui::Render( ); } void T_Main::initProgram( ) { spCopy = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher ); spCopy->addFile( "copy.glsl" ); spCopy->load( ); } /*============================================================================*/ int main( int , char** ) { T_Main m; m.mainLoop( ); #if 0 // Frame time history const int nFrameTimes = 200; float frameTimes[ nFrameTimes ]; memset( frameTimes , 0 , sizeof( float ) * nFrameTimes ); #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; }