diff --git a/control.cc b/control.cc index 17c7b44..1943fd4 100644 --- a/control.cc +++ b/control.cc @@ -5,6 +5,18 @@ using namespace cops; +/*= Command execution ========================================================*/ + +void cops::Execute( + __rd__ T_Operations const& operations , + __rw__ T_Context& context ) +{ + for ( auto const& op : operations ) { + op->execute( context ); + } +} + + /*= X_OpFailure ==============================================================*/ X_OpFailure::X_OpFailure( @@ -49,7 +61,7 @@ OPLoadConstant::OPLoadConstant( { } void OPLoadConstant::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { ctx.opStack.push_back( constant ); } @@ -63,7 +75,7 @@ OPLoadVariable::OPLoadVariable( { } void OPLoadVariable::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { const auto vPos( ctx.varPos.find( variable ) ); if ( vPos == ctx.varPos.end( ) ) { @@ -81,7 +93,7 @@ OPLoadInput::OPLoadInput( { } void OPLoadInput::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { ctx.opStack.push_back( ctx.sync->valueOf( input , *( ctx.time ) ) ); } @@ -95,7 +107,7 @@ OPStoreVariable::OPStoreVariable( { } void OPStoreVariable::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.empty( ) ) { throw error( "stack is empty" ); @@ -118,7 +130,7 @@ void OPStoreVariable::execute( /*= Arithmetic operators =====================================================*/ void OPAdd::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.size( ) < 2 ) { throw error( "missing operands in stack" ); @@ -129,7 +141,7 @@ void OPAdd::execute( } void OPMul::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.size( ) < 2 ) { throw error( "missing operands in stack" ); @@ -140,7 +152,7 @@ void OPMul::execute( } void OPNeg::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.empty( ) ) { throw error( "missing operand in stack" ); @@ -149,7 +161,7 @@ void OPNeg::execute( } void OPInv::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.empty( ) || ctx.opStack.back( ) == 0 ) { throw error( "missing operand in stack" ); @@ -165,7 +177,7 @@ OPDup::OPDup( __rd__ const uint32_t stackIndex ) { } void OPDup::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.size( ) <= stackIndex ) { std::string err( "stack does not have " ); @@ -183,7 +195,7 @@ OPXchg::OPXchg( __rd__ const uint32_t stackIndex ) { } void OPXchg::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( ctx.opStack.size( ) <= stackIndex ) { std::string err( "stack does not have " ); @@ -199,6 +211,10 @@ void OPXchg::execute( /*= OPSetUniform =============================================================*/ +// GENERAL FIXME +// program identifier should be an entry in a table +// or, you know, a program name + OPSetUniform::OPSetUniform( __rd__ const uint32_t program , __rd__ const uint32_t uniform , @@ -209,7 +225,7 @@ OPSetUniform::OPSetUniform( { } void OPSetUniform::execute( - __rw__ T_Context& ctx ) + __rw__ T_Context& ctx ) const { if ( count == 0 || ctx.opStack.size( ) < count ) { std::string err( "stack does not have " ); @@ -244,3 +260,101 @@ void OPSetUniform::execute( func( program , uniform , 1 , values ); } } + + +/*= OPUsePipeline ============================================================*/ + +// GENERAL FIXME +// pipeline identifier should be an entry in a table +// or, you know, a program name + +OPUsePipeline::OPUsePipeline( + __rd__ const uint32_t index ) + : T_Op( OP_USE_PIPELINE ) , pipeline( index ) +{ } + +void OPUsePipeline::execute( + __rw__ T_Context& ) const +{ + glBindProgramPipeline( pipeline ); +} + + +/*= OPUseTexture =============================================================*/ + +// GENERAL FIXME +// texture & sampler identifiers should be entries in a table + +OPUseTexture::OPUseTexture( + __rd__ const uint32_t binding , + __rd__ const uint32_t texture , + __rd__ const uint32_t sampler ) + : T_Op( OP_USE_TEXTURE ) , binding( binding ) , + texture( texture ) , sampler( sampler ) +{ } + +void OPUseTexture::execute( + __rw__ T_Context& ) const +{ + glBindTextureUnit( binding , texture ); + glBindSampler( binding , sampler ); +} + + +/*= OPUseFramebuffer =========================================================*/ + +// GENERAL FIXME +// framebuffer identifier should be an entry in a table + +OPUseFramebuffer::OPUseFramebuffer( + __rd__ const uint32_t framebuffer ) + : T_Op( OP_USE_FRAMEBUFFER ) , framebuffer( framebuffer ) +{ } + +void OPUseFramebuffer::execute( + __rw__ T_Context& ) const +{ + glBindFramebuffer( GL_FRAMEBUFFER , framebuffer ); +} + + +/*= OPSetViewport ============================================================*/ + +void OPSetViewport::execute( + __rw__ T_Context& ctx ) const +{ + if ( ctx.opStack.size( ) < 4 ) { + throw error( "stack does not have 4 items" ); + } + glViewport( + *( ctx.opStack.end( ) - 1 ) , + *( ctx.opStack.end( ) - 2 ) , + *( ctx.opStack.end( ) - 3 ) , + *( ctx.opStack.end( ) - 4 ) ); + ctx.opStack.resize( ctx.opStack.size( ) - 4 ); +} + + +/*= Draw commands ============================================================*/ + +void OPClear::execute( + __rw__ T_Context& ctx ) const +{ + if ( ctx.opStack.size( ) < 4 ) { + throw error( "stack does not have 4 items" ); + } + glClearColor( + *( ctx.opStack.end( ) - 1 ) , + *( ctx.opStack.end( ) - 2 ) , + *( ctx.opStack.end( ) - 3 ) , + *( ctx.opStack.end( ) - 4 ) ); + ctx.opStack.resize( ctx.opStack.size( ) - 4 ); + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); +} + +void OPFullscreen::execute( + __rw__ T_Context& ) const +{ + glBindVertexArray( 0 ); + glDrawArrays( GL_TRIANGLE_STRIP , 0 , 4 ); +} diff --git a/control.hh b/control.hh index e63b3c8..376720e 100644 --- a/control.hh +++ b/control.hh @@ -64,6 +64,10 @@ namespace cops { OP_USE_PIPELINE , OP_USE_TEXTURE , OP_USE_FRAMEBUFFER , + OP_SET_VIEWPORT , + // + OP_CLEAR , + OP_FULLSCREEN }; struct T_Op @@ -76,7 +80,7 @@ namespace cops { { return op_; } virtual void execute( - __rw__ T_Context& ctx ) = 0; + __rw__ T_Context& ctx ) const = 0; std::string source; uint32_t line; @@ -88,7 +92,8 @@ namespace cops { private: E_Op op_; }; - using T_Operations = std::vector< cops::T_Op >; + using P_Op = std::unique_ptr< T_Op >; + using T_Operations = std::vector< P_Op >; /*====================================================================*/ @@ -97,7 +102,7 @@ namespace cops { explicit OPLoadConstant( __rd__ const float constant ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; float constant; }; @@ -106,7 +111,7 @@ namespace cops { explicit OPLoadVariable( __rd__ std::string const& variable ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; std::string variable; }; @@ -115,7 +120,7 @@ namespace cops { explicit OPLoadInput( __rd__ std::string const& input ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; std::string input; }; @@ -124,7 +129,7 @@ namespace cops { explicit OPStoreVariable( __rd__ std::string const& variable ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; std::string variable; }; @@ -134,28 +139,28 @@ namespace cops { { OPAdd( ) : T_Op( OP_ADD ) {} void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; }; struct OPMul : public T_Op { OPMul( ) : T_Op( OP_MUL ) {} void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; }; struct OPNeg : public T_Op { OPNeg( ) : T_Op( OP_NEG ) {} void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; }; struct OPInv : public T_Op { OPInv( ) : T_Op( OP_INV ) {} void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; }; /*--------------------------------------------------------------------*/ @@ -164,7 +169,7 @@ namespace cops { { explicit OPDup( uint32_t stackIndex = 0 ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; uint32_t stackIndex; }; @@ -172,7 +177,7 @@ namespace cops { { explicit OPXchg( uint32_t stackIndex = 1 ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; uint32_t stackIndex; }; @@ -186,7 +191,7 @@ namespace cops { __rd__ const uint32_t count , __rd__ const bool integer ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; uint32_t program; uint32_t uniform; @@ -194,17 +199,63 @@ namespace cops { bool integer; }; - struct OPUsePipeline : public T_Op { explicit OPUsePipeline( __rd__ const uint32_t index ); void execute( - __rw__ T_Context& ctx ) override; + __rw__ T_Context& ctx ) const override; uint32_t pipeline; }; + struct OPUseTexture : public T_Op + { + OPUseTexture( + __rd__ const uint32_t binding , + __rd__ const uint32_t texture , + __rd__ const uint32_t sampler = 0 ); + void execute( + __rw__ T_Context& ctx ) const override; + + uint32_t binding; + uint32_t texture; + uint32_t sampler; + }; + + struct OPUseFramebuffer : public T_Op + { + explicit OPUseFramebuffer( + __rd__ const uint32_t framebuffer ); + void execute( + __rw__ T_Context& ctx ) const override; + + uint32_t framebuffer; + }; + + struct OPSetViewport : public T_Op + { + OPSetViewport( ) : T_Op( OP_SET_VIEWPORT ) { } + void execute( + __rw__ T_Context& ctx ) const override; + }; + + /*--------------------------------------------------------------------*/ + + struct OPClear : public T_Op + { + OPClear( ) : T_Op( OP_CLEAR ) { } + void execute( + __rw__ T_Context& ctx ) const override; + }; + + struct OPFullscreen : public T_Op + { + OPFullscreen( ) : T_Op( OP_FULLSCREEN ) { } + void execute( + __rw__ T_Context& ctx ) const override; + }; + /*====================================================================*/ void Execute(