Control system: function calls
This commit is contained in:
parent
7b9595777a
commit
647e247916
4 changed files with 143 additions and 57 deletions
72
control.cc
72
control.cc
|
@ -8,14 +8,26 @@ using namespace cops;
|
||||||
/*= Command execution ========================================================*/
|
/*= Command execution ========================================================*/
|
||||||
|
|
||||||
void cops::Execute(
|
void cops::Execute(
|
||||||
__rd__ T_Operations const& operations ,
|
__rd__ T_Operations const& operations ,
|
||||||
__rw__ T_Context& context )
|
__rw__ T_Context& context )
|
||||||
{
|
{
|
||||||
for ( auto const& op : operations ) {
|
for ( auto const& op : operations ) {
|
||||||
op->execute( context );
|
op->execute( context );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T_Operations& T_Program::function(
|
||||||
|
__rd__ std::string const& name ,
|
||||||
|
__rd__ const uint32_t args )
|
||||||
|
{
|
||||||
|
const auto p( functions.find( name ) );
|
||||||
|
if ( p == functions.end( ) ) {
|
||||||
|
return functions.emplace( name , T_Function{ name , args } ).first->second.operations;
|
||||||
|
}
|
||||||
|
assert( p->second.arguments == args );
|
||||||
|
return p->second.operations;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*= X_OpFailure ==============================================================*/
|
/*= X_OpFailure ==============================================================*/
|
||||||
|
|
||||||
|
@ -188,10 +200,10 @@ void OPDup::execute(
|
||||||
__rw__ T_Context& ctx ) const
|
__rw__ T_Context& ctx ) const
|
||||||
{
|
{
|
||||||
if ( ctx.opStack.size( ) <= stackIndex ) {
|
if ( ctx.opStack.size( ) <= stackIndex ) {
|
||||||
std::string err( "stack does not have " );
|
std::ostringstream oss;
|
||||||
err += stackIndex + 1;
|
oss << "stack does not have " << ( stackIndex + 1 )
|
||||||
err += " items";
|
<< " items (only " << ctx.opStack.size( ) << ")";
|
||||||
throw error( err );
|
throw error( oss.str( ) );
|
||||||
}
|
}
|
||||||
ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) );
|
ctx.opStack.push_back( *( ctx.opStack.end( ) - stackIndex - 1 ) );
|
||||||
}
|
}
|
||||||
|
@ -224,20 +236,17 @@ void OPXchg::execute(
|
||||||
// or, you know, a program name
|
// or, you know, a program name
|
||||||
|
|
||||||
OPSetUniform::OPSetUniform(
|
OPSetUniform::OPSetUniform(
|
||||||
__rd__ const uint32_t program ,
|
|
||||||
__rd__ const uint32_t uniform ,
|
|
||||||
__rd__ const uint32_t count ,
|
__rd__ const uint32_t count ,
|
||||||
__rd__ const bool integer )
|
__rd__ const bool integer )
|
||||||
: T_Op( OP_SET_UNIFORM ) , program( program ) , uniform( uniform ) ,
|
: T_Op( OP_SET_UNIFORM ) , count( count ) , integer( integer )
|
||||||
count( count ) , integer( integer )
|
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
void OPSetUniform::execute(
|
void OPSetUniform::execute(
|
||||||
__rw__ T_Context& ctx ) const
|
__rw__ T_Context& ctx ) const
|
||||||
{
|
{
|
||||||
if ( count == 0 || ctx.opStack.size( ) < count ) {
|
if ( count == 0 || ctx.opStack.size( ) < count + 2 ) {
|
||||||
std::string err( "stack does not have " );
|
std::string err( "stack does not have " );
|
||||||
err += count;
|
err += count + 2;
|
||||||
err += " items";
|
err += " items";
|
||||||
throw error( err );
|
throw error( err );
|
||||||
}
|
}
|
||||||
|
@ -249,6 +258,11 @@ void OPSetUniform::execute(
|
||||||
};
|
};
|
||||||
const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] };
|
const F_SetUniform_ func{ *(F_SetUniform_*) funcs[ count + ( integer ? 4 : 0 ) - 1 ] };
|
||||||
|
|
||||||
|
const GLuint program( ctx.opStack.back( ) );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
const GLuint uniform( ctx.opStack.back( ) );
|
||||||
|
ctx.opStack.pop_back( );
|
||||||
|
|
||||||
if ( integer ) {
|
if ( integer ) {
|
||||||
int values[ count ];
|
int values[ count ];
|
||||||
auto i = count;
|
auto i = count;
|
||||||
|
@ -367,3 +381,37 @@ void OPFullscreen::execute(
|
||||||
glBindVertexArray( 0 );
|
glBindVertexArray( 0 );
|
||||||
glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 );
|
glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*= Flow control =============================================================*/
|
||||||
|
|
||||||
|
OPCall::OPCall(
|
||||||
|
__rd__ std::string const& function )
|
||||||
|
: T_Op( OP_CALL ) , function( function )
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void OPCall::execute(
|
||||||
|
__rw__ T_Context& ctx ) const
|
||||||
|
{
|
||||||
|
auto fp( ctx.program->functions.find( function ) );
|
||||||
|
if ( fp == ctx.program->functions.end( ) ) {
|
||||||
|
throw error( "function '" + function + "' not found" );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto const& func( fp->second );
|
||||||
|
const auto ssz( ctx.opStack.size( ) );
|
||||||
|
if ( ssz < func.arguments ) {
|
||||||
|
std::string err;
|
||||||
|
err = "function '" + function + "' requires ";
|
||||||
|
err += func.arguments;
|
||||||
|
err += " argument";
|
||||||
|
err += ( func.arguments > 1 ? "s" : "" );
|
||||||
|
throw error( err );
|
||||||
|
}
|
||||||
|
|
||||||
|
Execute( func.operations , ctx );
|
||||||
|
if ( ctx.opStack.size( ) < ssz ) {
|
||||||
|
throw error( "function '" + function + "' ate the stack" );
|
||||||
|
}
|
||||||
|
ctx.opStack.resize( ssz - func.arguments );
|
||||||
|
}
|
||||||
|
|
66
control.hh
66
control.hh
|
@ -7,8 +7,12 @@ struct T_SyncData;
|
||||||
|
|
||||||
namespace cops {
|
namespace cops {
|
||||||
|
|
||||||
|
struct T_Program;
|
||||||
|
|
||||||
struct T_Context
|
struct T_Context
|
||||||
{
|
{
|
||||||
|
T_Program const* program;
|
||||||
|
|
||||||
float const* time;
|
float const* time;
|
||||||
T_SyncData const* sync;
|
T_SyncData const* sync;
|
||||||
|
|
||||||
|
@ -71,7 +75,9 @@ namespace cops {
|
||||||
OP_SET_VIEWPORT ,
|
OP_SET_VIEWPORT ,
|
||||||
//
|
//
|
||||||
OP_CLEAR ,
|
OP_CLEAR ,
|
||||||
OP_FULLSCREEN
|
OP_FULLSCREEN ,
|
||||||
|
//
|
||||||
|
OP_CALL
|
||||||
};
|
};
|
||||||
|
|
||||||
struct T_Op
|
struct T_Op
|
||||||
|
@ -86,8 +92,8 @@ namespace cops {
|
||||||
virtual void execute(
|
virtual void execute(
|
||||||
__rw__ T_Context& ctx ) const = 0;
|
__rw__ T_Context& ctx ) const = 0;
|
||||||
|
|
||||||
std::string source;
|
std::string source{};
|
||||||
uint32_t line;
|
uint32_t line{0};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
X_OpFailure error(
|
X_OpFailure error(
|
||||||
|
@ -108,6 +114,42 @@ namespace cops {
|
||||||
return ops;
|
return ops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Execute(
|
||||||
|
__rd__ T_Operations const& operations ,
|
||||||
|
__rw__ T_Context& context );
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
struct T_Function
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
uint32_t arguments;
|
||||||
|
T_Operations operations;
|
||||||
|
|
||||||
|
T_Function( __rd__ std::string const& name ,
|
||||||
|
__rd__ const uint32_t arguments )
|
||||||
|
: name( name ) , arguments( arguments )
|
||||||
|
{ }
|
||||||
|
DEF_COPY( T_Function );
|
||||||
|
DEF_MOVE( T_Function );
|
||||||
|
};
|
||||||
|
|
||||||
|
struct T_Program
|
||||||
|
{
|
||||||
|
std::map< std::string , T_Function > functions;
|
||||||
|
T_Operations main;
|
||||||
|
|
||||||
|
T_Operations& function(
|
||||||
|
__rd__ std::string const& name ,
|
||||||
|
__rd__ const uint32_t args );
|
||||||
|
|
||||||
|
void execute( __rw__ T_Context& context )
|
||||||
|
{
|
||||||
|
context.program = this;
|
||||||
|
Execute( main , context );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/*====================================================================*/
|
/*====================================================================*/
|
||||||
|
|
||||||
struct OPLoadConstant : public T_Op
|
struct OPLoadConstant : public T_Op
|
||||||
|
@ -199,15 +241,11 @@ namespace cops {
|
||||||
struct OPSetUniform : public T_Op
|
struct OPSetUniform : public T_Op
|
||||||
{
|
{
|
||||||
OPSetUniform(
|
OPSetUniform(
|
||||||
__rd__ const uint32_t program ,
|
|
||||||
__rd__ const uint32_t uniform ,
|
|
||||||
__rd__ const uint32_t count ,
|
__rd__ const uint32_t count ,
|
||||||
__rd__ const bool integer );
|
__rd__ const bool integer );
|
||||||
void execute(
|
void execute(
|
||||||
__rw__ T_Context& ctx ) const override;
|
__rw__ T_Context& ctx ) const override;
|
||||||
|
|
||||||
uint32_t program;
|
|
||||||
uint32_t uniform;
|
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
bool integer;
|
bool integer;
|
||||||
};
|
};
|
||||||
|
@ -269,10 +307,16 @@ namespace cops {
|
||||||
__rw__ T_Context& ctx ) const override;
|
__rw__ T_Context& ctx ) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*====================================================================*/
|
/*--------------------------------------------------------------------*/
|
||||||
|
|
||||||
void Execute(
|
struct OPCall : public T_Op
|
||||||
__rd__ T_Operations const& operations ,
|
{
|
||||||
__rw__ T_Context& context );
|
explicit OPCall(
|
||||||
|
__rd__ std::string const& function );
|
||||||
|
void execute(
|
||||||
|
__rw__ T_Context& ctx ) const override;
|
||||||
|
|
||||||
|
std::string function;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace cops
|
} // namespace cops
|
||||||
|
|
59
dof.cc
59
dof.cc
|
@ -55,9 +55,8 @@ void T_DoFPass::render(
|
||||||
const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) );
|
const auto idPass1( spPass1_.program( E_ShaderType::FRAGMENT ) );
|
||||||
const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
|
const auto idPass2( spPass2_.program( E_ShaderType::FRAGMENT ) );
|
||||||
const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
|
const auto idSampler( tm.sampler( "linear-edge" )->id( ) );
|
||||||
ops_.clear( );
|
T_Program program;
|
||||||
ops_
|
program.function( "SetDofUniforms" , 1 )
|
||||||
// First pass
|
|
||||||
<< OPLoadVariable( "height" )
|
<< OPLoadVariable( "height" )
|
||||||
<< OPLoadVariable( "width" )
|
<< OPLoadVariable( "width" )
|
||||||
<< OPLoadConstant( 0 )
|
<< OPLoadConstant( 0 )
|
||||||
|
@ -65,48 +64,46 @@ void T_DoFPass::render(
|
||||||
<< OPLoadVariable( "time" )
|
<< OPLoadVariable( "time" )
|
||||||
<< OPLoadVariable( "height" )
|
<< OPLoadVariable( "height" )
|
||||||
<< OPLoadVariable( "width" )
|
<< OPLoadVariable( "width" )
|
||||||
|
<< OPLoadConstant( U_RES_TIME )
|
||||||
|
<< OPDup( 8 )
|
||||||
<< OPLoadConstant( nSamples_ )
|
<< OPLoadConstant( nSamples_ )
|
||||||
|
<< OPLoadConstant( U_SAMPLES )
|
||||||
|
<< OPDup( 11 )
|
||||||
<< OPLoadConstant( filterParams_[ 3 ] )
|
<< OPLoadConstant( filterParams_[ 3 ] )
|
||||||
<< OPLoadConstant( filterParams_[ 2 ] )
|
<< OPLoadConstant( filterParams_[ 2 ] )
|
||||||
<< OPLoadConstant( filterParams_[ 1 ] )
|
<< OPLoadConstant( filterParams_[ 1 ] )
|
||||||
<< OPLoadConstant( filterParams_[ 0 ] )
|
<< OPLoadConstant( filterParams_[ 0 ] )
|
||||||
|
<< OPLoadConstant( U_PARAMS )
|
||||||
|
<< OPDup( 17 )
|
||||||
<< OPLoadConstant( 1 )
|
<< OPLoadConstant( 1 )
|
||||||
|
<< OPLoadConstant( U_DEPTH )
|
||||||
|
<< OPDup( 20 )
|
||||||
<< OPLoadConstant( 0 )
|
<< OPLoadConstant( 0 )
|
||||||
<< OPSetUniform( idPass1 , U_INPUT , 1 , true )
|
<< OPLoadConstant( U_INPUT )
|
||||||
<< OPSetUniform( idPass1 , U_DEPTH , 1 , true )
|
<< OPDup( 23 )
|
||||||
<< OPSetUniform( idPass1 , U_PARAMS , 4 , false )
|
<< OPSetUniform( 1 , true )
|
||||||
<< OPSetUniform( idPass1 , U_SAMPLES , 1 , false )
|
<< OPSetUniform( 1 , true )
|
||||||
<< OPSetUniform( idPass1 , U_RES_TIME , 3 , false )
|
<< OPSetUniform( 4 , false )
|
||||||
|
<< OPSetUniform( 1 , false )
|
||||||
|
<< OPSetUniform( 3 , false )
|
||||||
|
<< OPSetViewport( )
|
||||||
|
;
|
||||||
|
|
||||||
|
program.main
|
||||||
|
// First pass
|
||||||
|
<< OPLoadConstant( idPass1 )
|
||||||
|
<< OPCall( "SetDofUniforms" )
|
||||||
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler )
|
<< OPUseTexture( 0 , imageInput_.id( ) , idSampler )
|
||||||
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler )
|
<< OPUseTexture( 1 , depthInput_.id( ) , idSampler )
|
||||||
<< OPUsePipeline( spPass1_.id( ) )
|
<< OPUsePipeline( spPass1_.id( ) )
|
||||||
<< OPUseFramebuffer( rtPass1_.id( ) )
|
<< OPUseFramebuffer( rtPass1_.id( ) )
|
||||||
<< OPSetViewport( )
|
|
||||||
<< OPFullscreen( )
|
<< OPFullscreen( )
|
||||||
// Second pass
|
// Second pass
|
||||||
<< OPLoadVariable( "height" )
|
<< OPLoadConstant( idPass2 )
|
||||||
<< OPLoadVariable( "width" )
|
<< OPCall( "SetDofUniforms" )
|
||||||
<< 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 )
|
<< OPUseTexture( 0 , txPass1_.id( ) , idSampler )
|
||||||
<< OPUsePipeline( spPass2_.id( ) )
|
<< OPUsePipeline( spPass2_.id( ) )
|
||||||
<< OPUseFramebuffer( rtPass2_.id( ) )
|
<< OPUseFramebuffer( rtPass2_.id( ) )
|
||||||
<< OPSetViewport( )
|
|
||||||
<< OPFullscreen( )
|
<< OPFullscreen( )
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -114,11 +111,11 @@ void T_DoFPass::render(
|
||||||
printf( "GL fail in DoF" );
|
printf( "GL fail in DoF" );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
cops::T_Context ctx;
|
T_Context ctx;
|
||||||
ctx.store( "time" , position );
|
ctx.store( "time" , position );
|
||||||
ctx.store( "width" , imageInput_.width( ) );
|
ctx.store( "width" , imageInput_.width( ) );
|
||||||
ctx.store( "height" , imageInput_.height( ) );
|
ctx.store( "height" , imageInput_.height( ) );
|
||||||
cops::Execute( ops_ , ctx );
|
program.execute( ctx );
|
||||||
|
|
||||||
PEND( );
|
PEND( );
|
||||||
}
|
}
|
||||||
|
|
3
dof.hh
3
dof.hh
|
@ -36,8 +36,5 @@ struct T_DoFPass
|
||||||
// SharpDist/SharpRange/Falloff/MaxBlur
|
// SharpDist/SharpRange/Falloff/MaxBlur
|
||||||
float filterParams_[ 4 ];
|
float filterParams_[ 4 ];
|
||||||
int nSamples_;
|
int nSamples_;
|
||||||
|
|
||||||
// XXX experimenting with control system
|
|
||||||
cops::T_Operations ops_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue