diff --git a/Makefile b/Makefile index e1f7824..f60cf98 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ DEMO = \ utilities.o \ texture.o \ rendertarget.o \ + raymarcher.o \ bloom.o DEMO_DEPS = $(DEMO:%.o=.%.d) diff --git a/main.cc b/main.cc index 5af1755..acb7a30 100644 --- a/main.cc +++ b/main.cc @@ -5,6 +5,7 @@ #include "texture.hh" #include "rendertarget.hh" #include "bloom.hh" +#include "raymarcher.hh" /*= T_Main ===================================================================*/ @@ -26,15 +27,10 @@ struct T_Main ImVec2 mouseInitial; ImVec2 mouseMove; - T_Camera camera; - T_FilesWatcher watcher; - std::unique_ptr< T_ShaderProgram > spRaymarch; std::unique_ptr< T_ShaderProgram > spCopy; - std::unique_ptr< T_Texture > txRaymarchOutput; - std::unique_ptr< T_Rendertarget > rtRaymarchOutput; - + std::unique_ptr< T_Raymarcher > raymarcher; std::unique_ptr< T_BloomPass > bloomPass; void startIteration( ); @@ -43,13 +39,6 @@ struct T_Main void render( ); void initProgram( ); - - // FIXME: move - int rmIterations = 128; - float rmStep = .9; - float rmEpsilon = .000001; - float rmMaxDist = 50; - float epsLog = log( rmEpsilon ) / log( 10 ); }; /*----------------------------------------------------------------------------*/ @@ -75,13 +64,9 @@ T_Main::T_Main( ) ImGui_ImplSdl_Init( window ); initProgram( ); - - txRaymarchOutput = std::make_unique< T_Texture >( - 1280 , 720 , E_TexType::RGB16F ); - rtRaymarchOutput = std::make_unique < T_Rendertarget >( - T_RendertargetSetup( ).add( *txRaymarchOutput ).create( ) ); - - bloomPass = std::make_unique< T_BloomPass >( watcher , *txRaymarchOutput ); + raymarcher = std::make_unique< T_Raymarcher >( watcher , 1280 , 720 ); + bloomPass = std::make_unique< T_BloomPass >( watcher , + raymarcher->output( ) ); } void T_Main::mainLoop( ) @@ -149,7 +134,7 @@ void T_Main::handleCapture( ) ImGui::SetMouseCursor( ImGuiMouseCursor_Arrow ); } else if ( capture ) { ImGui::SetMouseCursor( ImGuiMouseCursor_Move ); - camera.handleDND( mouseMove , ctrl , shift , lmb ); + raymarcher->camera( ).handleDND( mouseMove , ctrl , shift , lmb ); } else if ( appCanGrab && mb ) { capture = true; mouseInitial = ImGui::GetMousePos( ); @@ -159,7 +144,7 @@ void T_Main::handleCapture( ) } if ( ( appCanGrab || capture ) && io.MouseWheel ) { - camera.handleWheel( io.MouseWheel , ctrl , shift ); + raymarcher->camera( ).handleWheel( io.MouseWheel , ctrl , shift ); } } @@ -171,19 +156,7 @@ void T_Main::makeUI( ) ImGui::SetNextWindowPos( ImVec2( ) , ImGuiSetCond_Once ); ImGui::Begin( "Yay! Demo!" ); - camera.makeUI( ); - - if ( ImGui::CollapsingHeader( "Raymarcher" ) ) { - ImGui::DragInt( "Iterations" , &rmIterations , .1 , 1 , 512 ); - ImGui::DragFloat( "Step" , &rmStep , .005 , .1 , 2 ); - ImGui::DragFloat( "Max. dist." , &rmMaxDist , .1f , - 0.01 , 1000.0 , "%.2f" ); - if ( ImGui::DragFloat( "Epsilon" , &epsLog , .01f , - -10 , -0.5 , "10 ^ %.2f" ) ) { - rmEpsilon = pow( 10 , epsLog ); - } - } - + raymarcher->makeUI( ); bloomPass->makeUI( ); ImGui::End( ); @@ -191,37 +164,7 @@ void T_Main::makeUI( ) void T_Main::render( ) { - auto const& dspSize( ImGui::GetIO( ).DisplaySize ); - - if ( spRaymarch->activate( ) && rtRaymarchOutput->activate( ) ) { - glClearColor( 0 , 1 , 1 , 1 ); - glClear( GL_COLOR_BUFFER_BIT ); - enum { - U_TIME = 0 , - U_RESOLUTION = 1 , - U_CAM_POS = 2 , - U_LOOK_AT = 3 , - U_CAM_UP = 4 , - U_NEAR_PLANE = 5 , - U_LIGHT_DIR = 6 , - U_RAYMARCHER = 7 , - }; - - glUniform1f( U_TIME , 0 ); - glUniform2f( U_RESOLUTION , dspSize.x , dspSize.y ); - - glUniform3fv( U_CAM_POS , 1 , &camera.pos.x ); - glUniform3fv( U_LOOK_AT , 1 , &camera.lookAt.x ); - glUniform3fv( U_CAM_UP , 1 , &camera.up.x ); - glUniform1f( U_NEAR_PLANE , camera.np ); - - glUniform3f( U_LIGHT_DIR , 0 , 1 , 1 ); - - glUniform4f( U_RAYMARCHER , rmIterations , rmStep , - rmEpsilon , rmMaxDist ); - - glRectf( -1, -1 , 1 , 1 ); - } + raymarcher->render( ); bloomPass->render( ); glUseProgram( 0 ); @@ -232,13 +175,6 @@ void T_Main::render( ) void T_Main::initProgram( ) { - spRaymarch = std::make_unique< T_ShaderProgram >( - GL_FRAGMENT_SHADER , watcher ); - spRaymarch->addFile( "raymarch-header.glsl" ); - spRaymarch->addFile( "map.glsl" ); - spRaymarch->addFile( "raymarcher.glsl" ); - spRaymarch->load( ); - spCopy = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER , watcher ); spCopy->addFile( "copy.glsl" ); spCopy->load( ); diff --git a/raymarcher.cc b/raymarcher.cc new file mode 100644 index 0000000..a6a6653 --- /dev/null +++ b/raymarcher.cc @@ -0,0 +1,73 @@ +#include "externals.hh" +#include "utilities.hh" +#include "texture.hh" +#include "rendertarget.hh" +#include "raymarcher.hh" + + +T_Raymarcher::T_Raymarcher( + __rw__ T_FilesWatcher& watcher , + __rd__ const uint32_t width , + __rd__ const uint32_t height ) + : camera_( ) , program_( GL_FRAGMENT_SHADER , watcher ) , + txOutput_( width , height , E_TexType::RGB16F ) , + rtOutput_( T_RendertargetSetup( ).add( txOutput_ ).create( ) ) +{ + program_.addFile( "raymarch-header.glsl" ); + program_.addFile( "map.glsl" ); + program_.addFile( "raymarcher.glsl" ); + program_.load( ); +} + + +void T_Raymarcher::render( ) +{ + if ( !( program_.activate( ) && rtOutput_.activate( ) ) ) { + return; + } + glClearColor( 0 , 1 , 1 , 1 ); + glClear( GL_COLOR_BUFFER_BIT ); + enum { + U_TIME = 0 , + U_RESOLUTION = 1 , + U_CAM_POS = 2 , + U_LOOK_AT = 3 , + U_CAM_UP = 4 , + U_NEAR_PLANE = 5 , + U_LIGHT_DIR = 6 , + U_RAYMARCHER = 7 , + }; + + glUniform1f( U_TIME , 0 ); + glUniform2f( U_RESOLUTION , rtOutput_.width( ) , rtOutput_.height( ) ); + + glUniform3fv( U_CAM_POS , 1 , &camera_.pos.x ); + glUniform3fv( U_LOOK_AT , 1 , &camera_.lookAt.x ); + glUniform3fv( U_CAM_UP , 1 , &camera_.up.x ); + glUniform1f( U_NEAR_PLANE , camera_.np ); + + glUniform3f( U_LIGHT_DIR , 0 , 1 , 1 ); + + glUniform4f( U_RAYMARCHER , rmIterations , rmStep , + rmEpsilon , rmMaxDist ); + + glRectf( -1, -1 , 1 , 1 ); +} + +void T_Raymarcher::makeUI( ) +{ + camera_.makeUI( ); + + if ( !ImGui::CollapsingHeader( "Raymarcher" ) ) { + return; + } + + ImGui::DragInt( "Iterations" , &rmIterations , .1 , 1 , 512 ); + ImGui::DragFloat( "Step" , &rmStep , .005 , .1 , 2 ); + ImGui::DragFloat( "Max. dist." , &rmMaxDist , .1f , + 0.01 , 1000.0 , "%.2f" ); + if ( ImGui::DragFloat( "Epsilon" , &epsLog , .01f , + -10 , -0.5 , "10 ^ %.2f" ) ) { + rmEpsilon = pow( 10 , epsLog ); + } +} diff --git a/raymarcher.hh b/raymarcher.hh new file mode 100644 index 0000000..0418501 --- /dev/null +++ b/raymarcher.hh @@ -0,0 +1,44 @@ +#pragma once +#ifndef REAL_BUILD +# define REAL_BUILD +# include "externals.hh" +# include "texture.hh" +# include "rendertarget.hh" +# include "utilities.hh" +# undef REAL_BUILD +#endif + + +struct T_Raymarcher +{ + public: + T_Raymarcher( ) = delete; + T_Raymarcher( T_Raymarcher const& ) = delete; + T_Raymarcher( T_Raymarcher&& ) = delete; + + T_Raymarcher( __rw__ T_FilesWatcher& watcher , + __rd__ const uint32_t width , + __rd__ const uint32_t height ); + + void render( ); + void makeUI( ); + + T_Camera const& camera( ) const noexcept { return camera_; } + T_Camera& camera( ) noexcept { return camera_; } + + T_Texture& output( ) noexcept { return txOutput_; } + + private: + T_Camera camera_; + + T_ShaderProgram program_; + + T_Texture txOutput_; + T_Rendertarget rtOutput_; + + int rmIterations = 128; + float rmStep = .9; + float rmEpsilon = .000001; + float rmMaxDist = 50; + float epsLog = log( rmEpsilon ) / log( 10 ); +};