2017-10-01 18:51:02 +02:00
|
|
|
#include "externals.hh"
|
|
|
|
#include "dof.hh"
|
|
|
|
#include "profiling.hh"
|
2017-10-04 11:20:27 +02:00
|
|
|
#include "globals.hh"
|
2017-10-06 14:29:01 +02:00
|
|
|
#include "odbg.hh"
|
2017-10-30 18:29:52 +01:00
|
|
|
#include "sync.hh"
|
2017-10-06 14:29:01 +02:00
|
|
|
|
2017-10-01 18:51:02 +02:00
|
|
|
|
|
|
|
namespace {
|
2017-11-03 11:55:26 +01:00
|
|
|
static char const* const Name_( "DoF" );
|
2017-10-01 18:51:02 +02:00
|
|
|
}
|
|
|
|
|
2017-10-04 18:08:37 +02:00
|
|
|
#define PSTART() Globals::Profiler( ).start( Name_ )
|
|
|
|
#define PEND() do { glFinish( ); Globals::Profiler( ).end( Name_ ); } while ( 0 )
|
2017-10-01 18:51:02 +02:00
|
|
|
|
|
|
|
|
|
|
|
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( ) ) ,
|
2017-10-30 19:04:10 +01:00
|
|
|
rtPass2_( T_RendertargetSetup( ).add( txOutput_ ).create( ) )
|
2017-10-01 18:51:02 +02:00
|
|
|
{
|
2017-10-01 19:40:38 +02:00
|
|
|
txPass1_.wrap( E_TexWrap::CLAMP_EDGE );
|
|
|
|
|
2017-10-06 14:29:01 +02:00
|
|
|
Globals::ODbg( ).registerTexture( txPass1_ , E_ODbgMode::HDR , "DoF 1st pass" );
|
|
|
|
Globals::ODbg( ).registerTexture( txOutput_ , E_ODbgMode::HDR , "DoF output" );
|
|
|
|
|
2017-10-04 17:37:55 +02:00
|
|
|
spPass1_ = Globals::Shaders( ).pipeline({
|
|
|
|
"fullscreen.v.glsl" , "dof-pass1.f.glsl" });
|
|
|
|
spPass2_ = Globals::Shaders( ).pipeline({
|
|
|
|
"fullscreen.v.glsl" , "dof-pass2.f.glsl" });
|
2017-10-01 18:51:02 +02:00
|
|
|
}
|
|
|
|
|
2017-10-30 18:29:52 +01:00
|
|
|
void T_DoFPass::render( )
|
2017-10-01 18:51:02 +02:00
|
|
|
{
|
|
|
|
PSTART( );
|
|
|
|
enum {
|
|
|
|
U_INPUT = 0 ,
|
|
|
|
U_DEPTH = 1 ,
|
|
|
|
U_PARAMS = 2 ,
|
|
|
|
U_SAMPLES = 3 ,
|
|
|
|
U_RES_TIME = 4
|
|
|
|
};
|
2017-10-02 14:48:16 +02:00
|
|
|
|
2017-10-15 09:34:03 +02:00
|
|
|
using namespace cops;
|
2017-10-04 11:20:27 +02:00
|
|
|
auto& tm( Globals::Textures( ) );
|
2017-10-15 09:34:03 +02:00
|
|
|
const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) );
|
|
|
|
const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
|
|
|
|
const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
|
2017-10-15 10:22:24 +02:00
|
|
|
T_Program program;
|
|
|
|
program.function( "SetDofUniforms" , 1 )
|
2017-10-15 09:34:03 +02:00
|
|
|
<< OPLoadVariable( "height" )
|
|
|
|
<< OPLoadVariable( "width" )
|
|
|
|
<< OPLoadConstant( 0 )
|
|
|
|
<< OPLoadConstant( 0 )
|
|
|
|
<< OPLoadVariable( "time" )
|
|
|
|
<< OPLoadVariable( "height" )
|
|
|
|
<< OPLoadVariable( "width" )
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( U_RES_TIME )
|
|
|
|
<< OPDup( 8 )
|
2017-11-05 21:06:38 +01:00
|
|
|
<< OPLoadInput( "dof-samples" )
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( U_SAMPLES )
|
|
|
|
<< OPDup( 11 )
|
2017-11-05 21:06:38 +01:00
|
|
|
<< OPLoadInput( "dof-max-blur" )
|
|
|
|
<< OPLoadInput( "dof-falloff" )
|
|
|
|
<< OPLoadInput( "dof-sharp-range" )
|
|
|
|
<< OPLoadInput( "dof-sharp-distance" )
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( U_PARAMS )
|
|
|
|
<< OPDup( 17 )
|
2017-10-15 09:34:03 +02:00
|
|
|
<< OPLoadConstant( 1 )
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( U_DEPTH )
|
|
|
|
<< OPDup( 20 )
|
2017-10-15 09:34:03 +02:00
|
|
|
<< OPLoadConstant( 0 )
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( U_INPUT )
|
|
|
|
<< OPDup( 23 )
|
|
|
|
<< OPSetUniform( 1 , true )
|
|
|
|
<< OPSetUniform( 1 , true )
|
|
|
|
<< OPSetUniform( 4 , false )
|
|
|
|
<< OPSetUniform( 1 , false )
|
|
|
|
<< OPSetUniform( 3 , false )
|
|
|
|
<< OPSetViewport( )
|
|
|
|
;
|
|
|
|
|
|
|
|
program.main
|
|
|
|
// First pass
|
|
|
|
<< OPLoadConstant( idPass1 )
|
|
|
|
<< OPCall( "SetDofUniforms" )
|
2017-10-15 09:34:03 +02:00
|
|
|
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler )
|
|
|
|
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler )
|
|
|
|
<< OPUsePipeline( spPass1_.id( ) )
|
|
|
|
<< OPUseFramebuffer( rtPass1_.id( ) )
|
|
|
|
<< OPFullscreen( )
|
|
|
|
// Second pass
|
2017-10-15 10:22:24 +02:00
|
|
|
<< OPLoadConstant( idPass2 )
|
|
|
|
<< OPCall( "SetDofUniforms" )
|
2017-10-15 09:34:03 +02:00
|
|
|
<< OPUseTexture( 0 , txPass1_.id( ) , idSampler )
|
|
|
|
<< OPUsePipeline( spPass2_.id( ) )
|
|
|
|
<< OPUseFramebuffer( rtPass2_.id( ) )
|
|
|
|
<< OPFullscreen( )
|
|
|
|
;
|
|
|
|
|
|
|
|
GL_CHECK( {
|
|
|
|
printf( "GL fail in DoF" );
|
|
|
|
} );
|
|
|
|
|
2017-10-15 10:22:24 +02:00
|
|
|
T_Context ctx;
|
2017-10-30 18:29:52 +01:00
|
|
|
ctx.store( "time" , Globals::Sync( ).time( ) );
|
2017-10-15 09:34:03 +02:00
|
|
|
ctx.store( "width" , imageInput_.width( ) );
|
|
|
|
ctx.store( "height" , imageInput_.height( ) );
|
2017-10-15 10:22:24 +02:00
|
|
|
program.execute( ctx );
|
2017-10-02 14:48:16 +02:00
|
|
|
|
2017-10-01 18:51:02 +02:00
|
|
|
PEND( );
|
|
|
|
}
|
|
|
|
|
|
|
|
void T_DoFPass::makeUI( )
|
|
|
|
{
|
2017-10-30 19:04:10 +01:00
|
|
|
#if 0
|
2017-10-01 19:22:28 +02:00
|
|
|
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 );
|
2017-10-30 19:04:10 +01:00
|
|
|
#endif
|
2017-10-01 18:51:02 +02:00
|
|
|
}
|