diff --git a/control.cc b/control.cc index 1943fd4..1801ff5 100644 --- a/control.cc +++ b/control.cc @@ -37,6 +37,23 @@ char const* X_OpFailure::what( ) const noexcept } +/*= T_Context ================================================================*/ + +T_Context& T_Context::store( + __rd__ std::string const& name , + __rd__ const float value ) +{ + const auto vPos( varPos.find( name ) ); + if ( vPos == varPos.end( ) ) { + varPos.emplace( name , varValues.size( ) ); + varValues.push_back( value ); + } else { + varValues[ vPos->second ] = value; + } + return *this; +} + + /*= T_Op =====================================================================*/ T_Op::T_Op( __rd__ const E_Op op ) @@ -113,16 +130,7 @@ void OPStoreVariable::execute( throw error( "stack is empty" ); } - const auto vPos( ctx.varPos.find( variable ) ); - uint32_t pos; - if ( vPos == ctx.varPos.end( ) ) { - pos = ctx.varValues.size( ); - ctx.varPos.emplace( variable , pos ); - } else { - pos = vPos->second; - } - - ctx.varValues[ pos ] = ctx.opStack.back( ); + ctx.store( variable , ctx.opStack.back( ) ); ctx.opStack.pop_back( ); } @@ -234,11 +242,12 @@ void OPSetUniform::execute( throw error( err ); } - void* funcs[] = { + typedef void (*F_SetUniform_)( int , int , int , void* ); + void const* const funcs[] = { &glProgramUniform1fv , &glProgramUniform2fv , &glProgramUniform3fv , &glProgramUniform4fv , &glProgramUniform1iv , &glProgramUniform2iv , &glProgramUniform3iv , &glProgramUniform4iv , }; - void (*func)( int , int , int , void* ) = (void (*)( int , int , int , void* )) funcs[ count + ( integer ? 4 : 0 ) ]; + const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] }; if ( integer ) { int values[ count ]; diff --git a/control.hh b/control.hh index 376720e..5a4d3b0 100644 --- a/control.hh +++ b/control.hh @@ -16,6 +16,10 @@ namespace cops { std::map< std::string , uint32_t > varPos; std::vector< float > opStack; + + T_Context& store( + __rd__ std::string const& name , + __rd__ const float value ); }; class X_OpFailure : public std::exception @@ -95,6 +99,15 @@ namespace cops { using P_Op = std::unique_ptr< T_Op >; using T_Operations = std::vector< P_Op >; + template< typename T > + inline T_Operations& operator <<( + __rw__ T_Operations& ops , + __rw__ T&& item ) + { + ops.emplace_back( new T( std::move( item ) ) ); + return ops; + } + /*====================================================================*/ struct OPLoadConstant : public T_Op diff --git a/dof.cc b/dof.cc index 86aab82..9de40ec 100644 --- a/dof.cc +++ b/dof.cc @@ -50,41 +50,76 @@ void T_DoFPass::render( U_RES_TIME = 4 }; + using namespace cops; auto& tm( Globals::Textures( ) ); - rtPass1_.activate( ); - if ( spPass1_.valid( ) ) { - const auto id( spPass1_.program( E_ShaderType::FRAGMENT ) ); - spPass1_.enable( ); - glProgramUniform1i( id , U_INPUT , 0 ); - glProgramUniform1i( id , U_DEPTH , 1 ); - glProgramUniform4fv( id , U_PARAMS , 1 , filterParams_ ); - glProgramUniform1f( id , U_SAMPLES , nSamples_ ); - glProgramUniform3f( id , U_RES_TIME , imageInput_.width( ) , - imageInput_.height( ) , - 0 ); + 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( ) + ; - tm.bind( 0 , imageInput_ , *tm.sampler( "linear-edge" ) ); - tm.bind( 1 , depthInput_ , *tm.sampler( "linear-edge" ) ); + GL_CHECK( { + printf( "GL fail in DoF" ); + } ); - glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); - } - rtPass2_.activate( ); - if ( spPass2_.valid( ) ) { - const auto id( spPass2_.program( E_ShaderType::FRAGMENT ) ); - spPass2_.enable( ); - glProgramUniform1i( id , U_INPUT , 0 ); - glProgramUniform1i( id , U_DEPTH , 1 ); - glProgramUniform4fv( id , U_PARAMS , 1 , filterParams_ ); - glProgramUniform1f( id , U_SAMPLES , nSamples_ ); - glProgramUniform3f( id , U_RES_TIME , - imageInput_.width( ) , - imageInput_.height( ) , - position ); + cops::T_Context ctx; + ctx.store( "time" , position ); + ctx.store( "width" , imageInput_.width( ) ); + ctx.store( "height" , imageInput_.height( ) ); + cops::Execute( ops_ , ctx ); - tm.bind( 0 , txPass1_ , *tm.sampler( "linear-edge" ) ); - - glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); - } PEND( ); } diff --git a/dof.hh b/dof.hh index 5dcfc3e..df3baf1 100644 --- a/dof.hh +++ b/dof.hh @@ -1,6 +1,7 @@ #pragma once #include "rendertarget.hh" #include "shaders.hh" +#include "control.hh" struct T_SyncData; @@ -35,5 +36,8 @@ struct T_DoFPass // SharpDist/SharpRange/Falloff/MaxBlur float filterParams_[ 4 ]; int nSamples_; + + // XXX experimenting with control system + cops::T_Operations ops_; }; diff --git a/rendertarget.hh b/rendertarget.hh index a5c0055..099166c 100644 --- a/rendertarget.hh +++ b/rendertarget.hh @@ -63,6 +63,7 @@ struct T_Rendertarget bool activate( ); + GLuint id( ) const { return id_; } uint32_t width( ) const { return width_; } uint32_t height( ) const { return height_; } diff --git a/shaders.cc b/shaders.cc index 22bb72b..3ecbe77 100644 --- a/shaders.cc +++ b/shaders.cc @@ -334,6 +334,15 @@ void T_ShaderPipeline::enable( ) const } } +GLuint T_ShaderPipeline::id( ) const +{ + if ( smIndex_ >= 0 ) { + return Globals::Shaders( ).pipelines_[ smIndex_ ].id; + } else { + return 0; + } +} + GLuint T_ShaderPipeline::program( __rd__ const E_ShaderType program ) const { diff --git a/shaders.hh b/shaders.hh index eec6847..e17e132 100644 --- a/shaders.hh +++ b/shaders.hh @@ -104,6 +104,7 @@ struct T_ShaderPipeline bool valid( ) const noexcept; void enable( ) const; + GLuint id( ) const; GLuint program( __rd__ const E_ShaderType program ) const;