demotool/dof.cc
2017-10-15 09:34:03 +02:00

138 lines
4.1 KiB
C++

#include "externals.hh"
#include "dof.hh"
#include "profiling.hh"
#include "globals.hh"
#include "odbg.hh"
namespace {
static const std::string Name_( "DoF" );
}
#define PSTART() Globals::Profiler( ).start( Name_ )
#define PEND() do { glFinish( ); Globals::Profiler( ).end( Name_ ); } while ( 0 )
T_DoFPass::T_DoFPass(
__rw__ T_Texture& imageInput ,
__rw__ T_Texture& depthInput )
: imageInput_( imageInput ) , depthInput_( depthInput ) ,
txPass1_( imageInput.width( ) , imageInput.height( ) ,
E_TexType::RGB16F ) ,
txOutput_( imageInput.width( ) , imageInput.height( ) ,
E_TexType::RGB16F ) ,
rtPass1_( T_RendertargetSetup( ).add( txPass1_ ).create( ) ) ,
rtPass2_( T_RendertargetSetup( ).add( txOutput_ ).create( ) ) ,
filterParams_{ 15 , 25 , 100 , 16 } ,
nSamples_( 16 )
{
txPass1_.wrap( E_TexWrap::CLAMP_EDGE );
Globals::ODbg( ).registerTexture( txPass1_ , E_ODbgMode::HDR , "DoF 1st pass" );
Globals::ODbg( ).registerTexture( txOutput_ , E_ODbgMode::HDR , "DoF output" );
spPass1_ = Globals::Shaders( ).pipeline({
"fullscreen.v.glsl" , "dof-pass1.f.glsl" });
spPass2_ = Globals::Shaders( ).pipeline({
"fullscreen.v.glsl" , "dof-pass2.f.glsl" });
}
void T_DoFPass::render(
__rd__ const float position ,
__rd__ T_SyncData const& )
{
PSTART( );
enum {
U_INPUT = 0 ,
U_DEPTH = 1 ,
U_PARAMS = 2 ,
U_SAMPLES = 3 ,
U_RES_TIME = 4
};
using namespace cops;
auto& tm( Globals::Textures( ) );
const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) );
const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
ops_.clear( );
ops_
// First pass
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( 0 )
<< OPLoadConstant( 0 )
<< OPLoadVariable( "time" )
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( nSamples_ )
<< OPLoadConstant( filterParams_[ 3 ] )
<< OPLoadConstant( filterParams_[ 2 ] )
<< OPLoadConstant( filterParams_[ 1 ] )
<< OPLoadConstant( filterParams_[ 0 ] )
<< OPLoadConstant( 1 )
<< OPLoadConstant( 0 )
<< OPSetUniform( idPass1 , U_INPUT , 1 , true )
<< OPSetUniform( idPass1 , U_DEPTH , 1 , true )
<< OPSetUniform( idPass1 , U_PARAMS , 4 , false )
<< OPSetUniform( idPass1 , U_SAMPLES , 1 , false )
<< OPSetUniform( idPass1 , U_RES_TIME , 3 , false )
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler )
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler )
<< OPUsePipeline( spPass1_.id( ) )
<< OPUseFramebuffer( rtPass1_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( )
// Second pass
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( 0 )
<< OPLoadConstant( 0 )
<< OPLoadVariable( "time" )
<< OPLoadVariable( "height" )
<< OPLoadVariable( "width" )
<< OPLoadConstant( nSamples_ )
<< OPLoadConstant( filterParams_[ 3 ] )
<< OPLoadConstant( filterParams_[ 2 ] )
<< OPLoadConstant( filterParams_[ 1 ] )
<< OPLoadConstant( filterParams_[ 0 ] )
<< OPLoadConstant( 1 )
<< OPLoadConstant( 0 )
<< OPSetUniform( idPass2 , U_INPUT , 1 , true )
<< OPSetUniform( idPass2 , U_DEPTH , 1 , true )
<< OPSetUniform( idPass2 , U_PARAMS , 4 , false )
<< OPSetUniform( idPass2 , U_SAMPLES , 1 , false )
<< OPSetUniform( idPass2 , U_RES_TIME , 3 , false )
<< OPUseTexture( 0 , txPass1_.id( ) , idSampler )
<< OPUsePipeline( spPass2_.id( ) )
<< OPUseFramebuffer( rtPass2_.id( ) )
<< OPSetViewport( )
<< OPFullscreen( )
;
GL_CHECK( {
printf( "GL fail in DoF" );
} );
cops::T_Context ctx;
ctx.store( "time" , position );
ctx.store( "width" , imageInput_.width( ) );
ctx.store( "height" , imageInput_.height( ) );
cops::Execute( ops_ , ctx );
PEND( );
}
void T_DoFPass::makeUI( )
{
if ( !ImGui::CollapsingHeader( "Depth of field" ) ) {
return;
}
ImGui::DragFloat( "Sharp distance" , filterParams_ , .25 , 0.25 , 1000 );
ImGui::DragFloat( "Sharp range" , &filterParams_[ 1 ] , .1 , 0.1 , 100 );
ImGui::DragFloat( "Blur falloff" , &filterParams_[ 2 ] , .5 , 0.5 , 1000 );
ImGui::DragFloat( "Max blur" , &filterParams_[ 3 ] , .1 , .1 , 100 );
ImGui::DragInt( "Samples" , &nSamples_ , .2 , 1 , 32 );
}