Skip to content

Commit

Permalink
[#104] - 🔨 there is now the possibility to interface with shader vari…
Browse files Browse the repository at this point in the history
…ables through the slot system and it required some addition to elsewhere 👷
  • Loading branch information
aconstlink committed Nov 5, 2024
1 parent 527b6e8 commit f386428
Show file tree
Hide file tree
Showing 14 changed files with 489 additions and 50 deletions.
5 changes: 4 additions & 1 deletion graphics/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ set( sources
"variable/variables.hpp"
"variable/variable_set.hpp"
"variable/type_traits.hpp"
"variable/wire_variable_bridge.h"
"variable/wire_variable_bridge.cpp"

"texture/image.hpp"
)
Expand All @@ -65,7 +67,8 @@ target_link_libraries( ${cur_lib_name}
PUBLIC motor::log
PUBLIC motor::std
PUBLIC motor::concurrent
PUBLIC motor::msl )
PUBLIC motor::msl
PUBLIC motor::wire )

###########################################################
# SECTION: Build Tree
Expand Down
22 changes: 22 additions & 0 deletions graphics/object/msl_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,35 @@ msl_object::this_ref_t msl_object::add_variable_set( motor::graphics::variable_s
return *this ;
}

//****************************************************************************
msl_object::this_ref_t msl_object::fill_variable_sets( size_t const idx ) noexcept
{
if( idx < _vars.size() ) return *this ;

auto old = std::move( _vars ) ;
_vars.resize( idx + 1 ) ;

for( size_t i=0; i<old.size(); ++i ) _vars[i] = old[i] ;
for( size_t i=old.size(); i < _vars.size(); ++i ) _vars[i] =
motor::shared( motor::graphics::variable_set_t() ) ;

return *this ;
}

//****************************************************************************
motor::graphics::variable_set_mtr_safe_t msl_object::get_varibale_set( size_t const id ) const noexcept
{
if( id >= _vars.size() ) return nullptr ;
return motor::share( _vars[ id ] ) ;
}

//****************************************************************************
motor::graphics::variable_set_mtr_t msl_object::borrow_varibale_set( size_t const id ) const noexcept
{
if ( id >= _vars.size() ) return nullptr ;
return motor::share_unsafe( _vars[ id ] ) ;
}

//****************************************************************************
motor::vector< motor::graphics::variable_set_mtr_safe_t > msl_object::get_varibale_sets( void_t ) const noexcept
{
Expand Down
2 changes: 2 additions & 0 deletions graphics/object/msl_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@ namespace motor
public: // variable sets

this_ref_t add_variable_set( motor::graphics::variable_set_mtr_safe_t vs ) noexcept ;
this_ref_t fill_variable_sets( size_t const ) noexcept ;
motor::graphics::variable_set_mtr_safe_t get_varibale_set( size_t const id ) const noexcept ;
motor::graphics::variable_set_mtr_t borrow_varibale_set( size_t const id ) const noexcept ;
motor::vector< motor::graphics::variable_set_mtr_safe_t > get_varibale_sets( void_t ) const noexcept ;
motor::vector< motor::graphics::variable_set_borrow_t::mtr_t > borrow_varibale_sets( void_t ) const noexcept ;

Expand Down
63 changes: 63 additions & 0 deletions graphics/variable/variable_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,15 @@ namespace motor
return var ;
}

bool_t has_data_variable( motor::string_in_t name ) const noexcept
{
for( auto const & d : _variables )
{
if( d.name == name ) return true ;
}
return false ;
}

motor::graphics::data_variable< motor::string_t > * texture_variable(
motor::string_in_t name ) noexcept
{
Expand Down Expand Up @@ -198,6 +207,15 @@ namespace motor
return static_cast< motor::graphics::data_variable< motor::string_t >* >( var ) ;
}

bool_t has_texture_variable( motor::string_in_t name ) const noexcept
{
for ( auto const & d : _textures )
{
if ( d.name == name ) return true ;
}
return false ;
}

motor::graphics::data_variable< motor::string_t > * array_variable(
motor::string_in_t name ) noexcept
{
Expand Down Expand Up @@ -231,6 +249,15 @@ namespace motor
return static_cast< motor::graphics::data_variable< motor::string_t >* >( var ) ;
}

bool_t has_array_variable( motor::string_in_t name ) const noexcept
{
for ( auto const & d : _arrays )
{
if ( d.name == name ) return true ;
}
return false ;
}

// allows to connect a streamout object with a data buffer in the shader
motor::graphics::data_variable< motor::string_t > * array_variable_streamout(
motor::string_in_t name ) noexcept
Expand Down Expand Up @@ -265,6 +292,42 @@ namespace motor
return static_cast< motor::graphics::data_variable< motor::string_t >* >( var ) ;
}

using for_each_data_var_funk_t = std::function< void_t ( motor::string_in_t, motor::graphics::ivariable_ptr_t ) > ;
void_t for_each_data_variable( for_each_data_var_funk_t f ) const noexcept
{
for( auto const & v : _variables )
{
f( v.name, v.var ) ;
}
}

using for_each_texture_var_funk_t = std::function< void_t ( motor::string_in_t, motor::graphics::data_variable< motor::string_t > * ) > ;

void_t for_each_texture_variable( for_each_texture_var_funk_t f ) const noexcept
{
using ptr_t = motor::graphics::data_variable< motor::string_t > * ;
for ( auto const & v : _textures )
{
f( v.name, reinterpret_cast< ptr_t >( v.var ) ) ;
}
}

void_t for_each_buffer_variable( for_each_texture_var_funk_t f ) const noexcept
{
using ptr_t = motor::graphics::data_variable< motor::string_t > * ;
for ( auto const & v : _arrays )
{
f( v.name, reinterpret_cast< ptr_t >( v.var ) ) ;
}
}

bool_t has_any_variable( motor::string_in_t name ) const noexcept
{
if( this_t::has_data_variable( name ) ) return true ;
if( this_t::has_texture_variable( name ) ) return true ;
if( this_t::has_array_variable( name ) ) return true ;
return false ;
}
private:

template< typename T >
Expand Down
9 changes: 9 additions & 0 deletions graphics/variable/variables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,5 +114,14 @@ namespace motor
return nullptr ;
}
};

template< typename T >
std::pair< bool_t, motor::graphics::data_variable< T > * > cast_data_variable( motor::graphics::ivariable_ptr_t in_var ) noexcept
{
using ret_t = std::pair< bool_t, motor::graphics::data_variable< T > * > ;
auto * ptr = dynamic_cast< motor::graphics::data_variable< T > * >( in_var ) ;
return ptr != nullptr ? ret_t { true, ptr } : ret_t { false, nullptr } ;
}

}
}
118 changes: 118 additions & 0 deletions graphics/variable/wire_variable_bridge.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

#include "wire_variable_bridge.h"

using namespace motor::graphics ;

//*****************************************************************
wire_variable_bridge::wire_variable_bridge( void_t ) noexcept
{
}

//*****************************************************************
wire_variable_bridge::wire_variable_bridge( motor::graphics::variable_set_mtr_safe_t ) noexcept
{
}

//*****************************************************************
wire_variable_bridge::wire_variable_bridge( this_rref_t rhv ) noexcept : _vs( motor::move( rhv._vs ) ),
_inputs( std::move( rhv._inputs ) ), _bindings( std::move( rhv._bindings ) )
{
}

//*****************************************************************
wire_variable_bridge::~wire_variable_bridge( void_t ) noexcept
{
_inputs.clear() ;
}

//*****************************************************************
void_t wire_variable_bridge::pull_data( void_t ) noexcept
{
for( auto & b : _bindings )
{
b.pull_funk( b ) ;
}
}

//*****************************************************************
void_t wire_variable_bridge::update_bindings( void_t ) noexcept
{
this_t::create_bindings() ;

if( _vs == nullptr ) return ;

// clear up every slot which is not in the shader
// variable set.
{
std::vector< motor::string_t > removeables ;

_inputs.for_each_slot( [&] ( motor::string_in_t name, motor::wire::iinput_slot_ptr_t )
{
if ( !_vs->has_any_variable( name ) )
{
removeables.emplace_back( name ) ;
}
} ) ;

for ( auto const & name : removeables )
{
_inputs.remove( name ) ;
}
}
}

//*****************************************************************
void_t wire_variable_bridge::update_bindings( motor::graphics::variable_set_mtr_safe_t vs ) noexcept
{
motor::release( motor::move( _vs ) ) ;
_vs = motor::move( vs ) ;
this_t::update_bindings() ;
}

//*****************************************************************
motor::wire::inputs_ptr_t wire_variable_bridge::borrow_inputs( void_t ) noexcept
{
return &_inputs ;
}

//*****************************************************************
motor::wire::inputs_cptr_t wire_variable_bridge::borrow_inputs( void_t ) const noexcept
{
return &_inputs ;
}

//*****************************************************************
void_t wire_variable_bridge::create_bindings( void_t ) noexcept
{
_bindings.clear() ;

if( _vs == nullptr )
{
_inputs.clear() ;
return ;
}

_vs->for_each_data_variable( [&]( motor::string_in_t name, motor::graphics::ivariable_ptr_t var )
{
if( this_t::make_binding< int_t >( name, var ) ) return ;
if( this_t::make_binding< float_t >( name, var ) ) return ;
if( this_t::make_binding< uint_t >( name, var ) ) return ;
if( this_t::make_binding< motor::math::vec2f_t >( name, var ) ) return ;
if( this_t::make_binding< motor::math::vec3f_t >( name, var ) ) return ;
if( this_t::make_binding< motor::math::vec4f_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec2i_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec3i_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec4i_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec2ui_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec3ui_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::vec4ui_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::mat2f_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::mat3f_t >( name, var ) ) return ;
if ( this_t::make_binding< motor::math::mat4f_t >( name, var ) ) return ;
} ) ;

_vs->for_each_texture_variable( [&] ( motor::string_in_t name, motor::graphics::data_variable<motor::string_t> * var )
{
if( this_t::make_binding< motor::string_t >( name, var ) ) return ;
} ) ;
}
97 changes: 97 additions & 0 deletions graphics/variable/wire_variable_bridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#pragma once
#include "../api.h"
#include "../typedefs.h"

#include "variable_set.hpp"

#include <motor/wire/slot/sheet.hpp>

namespace motor
{
namespace graphics
{
class MOTOR_GRAPHICS_API wire_variable_bridge
{
motor_this_typedefs( wire_variable_bridge ) ;

private:

motor::graphics::variable_set_mtr_t _vs = nullptr ;
motor::wire::inputs_t _inputs ;

// will only hold borrowed pointers.
// ref counted pointers are stored above.
// binding in this case means:
// shader var to slot binding
struct variable_binding
{
using pull_funk_t = std::function< void_t ( variable_binding & ) > ;
motor::graphics::ivariable_ptr_t gvar ;
motor::wire::iinput_slot_ptr_t slot ;
pull_funk_t pull_funk ;
};

motor::vector< variable_binding > _bindings ;

public:

wire_variable_bridge( void_t ) noexcept ;
wire_variable_bridge( motor::graphics::variable_set_mtr_safe_t ) noexcept ;
wire_variable_bridge( this_rref_t ) noexcept ;
wire_variable_bridge( this_cref_t ) = delete ;
~wire_variable_bridge( void_t ) noexcept ;

public: // update interface

// pull data from inputs slots to graphics variables
void_t pull_data( void_t ) noexcept ;

// redo graphics variables to inputs bindings
void_t update_bindings( void_t ) noexcept ;

// redo graphics variables to inputs bindings
// by introducing a new variable set
void_t update_bindings( motor::graphics::variable_set_mtr_safe_t ) noexcept ;

public: // get/set

motor::wire::inputs_ptr_t borrow_inputs( void_t ) noexcept ;
motor::wire::inputs_cptr_t borrow_inputs( void_t ) const noexcept ;

private:

void_t create_bindings( void_t ) noexcept ;

template< typename T >
bool_t make_binding( motor::string_in_t name, motor::graphics::ivariable_ptr_t var ) noexcept
{
using type_t = T ;

auto [a, b] = motor::graphics::cast_data_variable< type_t >( var ) ;
if ( a )
{
using slot_t = motor::wire::input_slot< type_t > ;
using var_t = motor::graphics::data_variable< type_t > ;

auto s = _inputs.get_or_add( name, motor::shared( slot_t( b->get() ) ) ) ;
b->set( ((slot_t*)s.mtr())->get_value() ) ;

_bindings.emplace_back( variable_binding
{
var, motor::move( s ),
[=] ( this_t::variable_binding & v )
{
auto * s_local = reinterpret_cast<slot_t *>( v.slot ) ;
auto * v_local = reinterpret_cast<var_t *>( v.gvar ) ;

v_local->set( s_local->get_value() ) ;
}
} ) ;
return true ;
}
return false ;
}
};
motor_typedef( wire_variable_bridge ) ;
}
}
1 change: 1 addition & 0 deletions scene/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ add_library( ${cur_alias_name} ALIAS ${cur_lib_name} )
target_link_libraries( ${cur_lib_name}
PUBLIC motor::gfx
PUBLIC motor::graphics
PUBLIC motor::wire
PUBLIC motor::core
)

Expand Down
Loading

0 comments on commit f386428

Please sign in to comment.