diff --git a/demo.srd b/demo.srd index 875bd30..62ced5f 100644 --- a/demo.srd +++ b/demo.srd @@ -443,9 +443,20 @@ (min 0) (max 1) (slider)) ) ) + + (section "Color grading" + (color-grading "Lift" + cg-lift-r cg-lift-g cg-lift-b + (base -1) (unit 1)) + (color-grading "Gain" + cg-gain-r cg-gain-g cg-gain-b + (base 0) (unit 1)) + (color-grading "Gamma" + cg-gamma-r cg-gamma-g cg-gamma-b + (base -.9) (unit 1.8)) + ) ) # FIXME: overrides for vignette - # FIXME: overrides for color grading ) ) diff --git a/main.cc b/main.cc index 111812a..0cb6158 100644 --- a/main.cc +++ b/main.cc @@ -208,17 +208,6 @@ void T_Main::makeUI( ) Globals::Shaders( ).makeUI( ); Globals::Sync( ).makeOverridesWindow( ); Globals::Sync( ).makeSequencerWindow( ); - -#warning color grading widget test - static float cgRed = 1 , cgGreen = 1 , cgBlue = 1; - static float wtf[ 3 ] = { 0 , 0 , 0 }; - auto const& dspSize( GetIO( ).DisplaySize ); - SetNextWindowSize( ImVec2( 300 , 300 ) , ImGuiSetCond_Appearing ); - SetNextWindowPos( ImVec2( ( dspSize.x - 300 ) / 2 , (dspSize.y - 300)/2 ) , ImGuiSetCond_Appearing ); - Begin( "Test!" , nullptr , ImGuiWindowFlags_NoCollapse ); - ColorEdit3( "yo" , wtf ); - ColorGradingControls( "lolwut" , &cgRed , &cgGreen , &cgBlue ); - End( ); } void T_Main::render( ) diff --git a/syncoverrides.cc b/syncoverrides.cc index 216cda5..6d301b6 100644 --- a/syncoverrides.cc +++ b/syncoverrides.cc @@ -1,6 +1,7 @@ #include "externals.hh" #include "globals.hh" #include "syncoverrides.hh" +#include "colorgrading.hh" #include @@ -281,8 +282,54 @@ bool IntSetStep_( T_SRDParserData const& data ) return true; } -} // namespace +/*------------------------------------------------------------------------------*/ +using SP_Cg = T_SharedPtr< T_ColorGrading >; + +bool EnterColorGrading_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + SP_Cg ptr{ NewShared< T_ColorGrading >( + input[ 2 ].stringValue( ) , + input[ 3 ].stringValue( ) , + input[ 4 ].stringValue( ) , + input[ 1 ].stringValue( ) ) }; + ptr->location( ) = input[ 0 ].location( ); + *( data.targetData ) = std::move( ptr ); + return true; +} + +bool AddColorGrading_( T_SRDParserData const& data ) +{ + auto& fl( data.currentData->value< SP_Cg >( ) ); + auto& parent( data.targetData->value< SP_Section >( ) ); + parent->overrides.add( fl.makeOwned( ) ); + return true; +} + +bool CgSetBase_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + if ( !data.currentData->value< SP_Cg >( )->setBase( input[ 1 ].floatValue( ) ) ) { + data.errors.add( "duplicate base value" , (*data.input)[ 0 ] ); + } + return true; +} + +bool CgSetUnit_( T_SRDParserData const& data ) +{ + auto const& input( *( data.input ) ); + const float v( input[ 1 ].floatValue( ) ); + if ( v == 0 ) { + data.errors.add( "invalid unit value" , (*data.input)[ 1 ] ); + } else if ( !data.currentData->value< SP_Cg >( )->setUnit( v ) ) { + data.errors.add( "duplicate unit value" , (*data.input)[ 0 ] ); + } + return true; +} + + +} // namespace /*------------------------------------------------------------------------------*/ ebcl::T_SRDParserConfig sov::GetParserConfig( ) @@ -345,6 +392,12 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( ) << EnterContext( "int" ) << OnEnter( EnterInt4_ ) << OnExit( AddInt_ ) ) + // Color grading controls + << ( Rule() << "color-grading" << Text( ) + << ( SRD::Times( 3 ) << Word( ) ) + << EnterContext( "color-grading" ) + << OnEnter( EnterColorGrading_ ) + << OnExit( AddColorGrading_ ) ) ; // Floating point control parameters @@ -365,6 +418,12 @@ ebcl::T_SRDParserConfig sov::GetParserConfig( ) << ( Rule() << "step" << Numeric() << IntSetStep_ ) ; + // Color grading controls + defs.context( "color-grading" ) + << ( Rule() << "base" << Numeric( ) << CgSetBase_ ) + << ( Rule() << "unit" << Numeric( ) << CgSetUnit_ ) + ; + return T_SRDParserConfig{ defs }; } @@ -727,3 +786,55 @@ void T_Integer4::makeEditWidgets( } } } + + +/*= T_ColorGrading =============================================================*/ + +T_ColorGrading::T_ColorGrading( + T_String const& iRed , + T_String const& iGreen , + T_String const& iBlue , + T_String const& title ) noexcept + : A_SyncOverride( "cg" , title ) +{ + inputs_.add( iRed ); + inputs_.add( iGreen ); + inputs_.add( iBlue ); +} + +void T_ColorGrading::makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept +{ + using namespace ImGui; + auto& sinp{ Globals::Sync( ).inputs( ) }; + float v[ 3 ]; + for ( auto i = 0 ; i < 3 ; i ++ ) { + v[ i ] = sinp[ inputPos_[ i ] ]; + } + + char const* const label{ buildLabel( counter , sb ) }; + const bool changed{ ColorGradingControls( + label , + &v[ 0 ] , &v[ 1 ] , &v[ 2 ] , + base( ) , unit( ) ) }; + + if ( changed ) { + for ( auto i = 0 ; i < 3 ; i ++ ) { + sinp[ inputPos_[ i ] ] = v[ i ]; + } + } +} + +bool T_ColorGrading::setBase( + const float v ) noexcept +{ + M_SETOPT_( base_ , v ); +} + +bool T_ColorGrading::setUnit( + const float v ) noexcept +{ + assert( v != 0 ); + M_SETOPT_( unit_ , v ); +} diff --git a/syncoverrides.hh b/syncoverrides.hh index 05ebd7a..da23bf6 100644 --- a/syncoverrides.hh +++ b/syncoverrides.hh @@ -184,6 +184,33 @@ class T_Integer4 : public A_Integer }; +/*= COLOR GRADING CONTROLS =====================================================*/ + +class T_ColorGrading : public A_SyncOverride +{ + private: + T_Optional< float > base_; + T_Optional< float > unit_; + + protected: + void makeEditWidgets( + uint32_t& counter , + T_StringBuilder& sb ) noexcept override; + + public: + T_ColorGrading( T_String const& iRed , + T_String const& iGreen , + T_String const& iBlue , + T_String const& title ) noexcept; + + bool setBase( const float v ) noexcept; + bool setUnit( const float v ) noexcept; + + float base( ) const noexcept { return base_ ? *base_ : 0.f; } + float unit( ) const noexcept { return unit_ ? *unit_ : 1.f; } +}; + + /*= PARSER CONFIGURATION =======================================================*/ // Get a parser configuration that will be able to parse UI override definitions.