Commit 7fc4def0 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[ADD] - added many convenience code and a property adapter for...

[ADD] - added many convenience code and a property adapter for WGEShaderDefineOptions and used it in the postprocessing node.
parent d5a8bd64
......@@ -198,3 +198,8 @@ WItemSelector::operator unsigned int() const
return getItemIndexOfSelected( 0 );
}
WItemSelector::IndexList WItemSelector::getIndexList() const
{
return m_selected;
}
......@@ -225,6 +225,14 @@ public:
*/
operator unsigned int() const;
/**
* Casts the selector to a list of indices currently selected. It contains the list of index in the corresponding WItemSelection. This is
* especially useful if the whole index list is needed without nasty iterations.
*
* \return the list of index.
*/
IndexList getIndexList() const;
protected:
/**
......
......@@ -54,8 +54,8 @@ friend class WPropertiesTest;
public:
// the following typedefs are for convenience.
typedef boost::shared_ptr< WProperties > SharedPtr; //!< shared pointer to object of this type
typedef boost::shared_ptr< const WProperties > ConstSharedPtr; //!< const shared pointer to object of this type
typedef boost::shared_ptr< WProperties > SPtr; //!< shared pointer to object of this type
typedef boost::shared_ptr< const WProperties > ConstSPtr; //!< const shared pointer to object of this type
typedef WProperties* Ptr; //!< pointer to object of this type
typedef const WProperties* ConstPtr; //!< const pointer to object of this type
typedef WProperties& Ref; //!< ref to object of this type
......
......@@ -65,6 +65,15 @@ class WPropertyVariable: public WFlag< T >,
{
friend class WPropertyVariableTest;
public:
/**
* Convenience typedef for a shared_ptr of WPropertyVariable.
*/
typedef boost::shared_ptr< WPropertyVariable< T > > SPtr;
/**
* Convenience typedef for a shared_ptr of const WPropertyVariable.
*/
typedef boost::shared_ptr< const WPropertyVariable< T > > ConstSPtr;
/**
* Create an empty instance just containing a name.
......
......@@ -22,7 +22,9 @@
//
//---------------------------------------------------------------------------
#include "../shaders/WGEShaderDefineOptions.h"
#include "../../common/WPropertyHelper.h"
#include "../shaders/WGEShaderPropertyDefineOptions.h"
#include "WGEPostprocessingNode.h"
......@@ -56,11 +58,30 @@ WGEPostprocessingNode::WGEPostprocessingNode( osg::ref_ptr< osg::Camera > refere
m_active = m_properties->addProperty( "Enable", "If set, post-processing is enabled.", true );
m_showHUD = m_properties->addProperty( "Show HUD", "If set, the intermediate textures are shown.", false );
// Post-processings:
// First: Create a list with name, description and shader define which is used to enable it
typedef WGEShaderPropertyDefineOptions< WPropSelection >::NameDescriptionDefineTuple Tuple;
std::vector< Tuple > namesAndDefs;
namesAndDefs.push_back( Tuple( "None", "This does not do any post-processing.", "WGE_POSTPROCESSOR_NONE" ) );
// Second: create the Shader option object and the corresponding property automatically:
WGEShaderPropertyDefineOptions< WPropSelection >::SPtr activePostprocessorsOpts(
WGEShaderPropertyDefineOptions< WPropSelection >::createSelection(
"Post-processors",
"Select the post-processings you want.",
m_properties,
namesAndDefs
)
);
m_activePostprocessors = activePostprocessorsOpts->getProperty();
// avoid that a user selects nothing
WPropertyHelper::PC_NOTEMPTY::addTo( m_activePostprocessors );
// let the props control some stuff
m_switchCallback = new WGESwitchCallback< WPropBool >( m_active );
m_hudCallback = new WGENodeMaskCallback( m_showHUD );
addUpdateCallback( m_switchCallback );
m_offscreen->getTextureHUD()->addUpdateCallback( m_hudCallback );
addUpdateCallback( new WGESwitchCallback< WPropBool >( m_active ) );
m_offscreen->getTextureHUD()->addUpdateCallback( new WGENodeMaskCallback( m_showHUD ) );
// let the activePostprocessors property control the options in the shader:
m_postProcessShader->addPreprocessor( activePostprocessorsOpts );
}
WGEPostprocessingNode::~WGEPostprocessingNode()
......@@ -78,8 +99,8 @@ WPropGroup WGEPostprocessingNode::getProperties() const
void WGEPostprocessingNode::insert( osg::ref_ptr< osg::Node > node, WGEShader::RefPtr shader )
{
// we need to inject some code to the shader at this point.
shader->addPreprocessor( WGEShaderDefineOptions::SPtr(
new WGEShaderDefineOptions( "WGE_POSTPROCESSING_ENABLED", "WGE_POSTPROCESSING_DISABLED" ) )
shader->addPreprocessor( WGEShaderPreprocessor::SPtr(
new WGEShaderPropertyDefineOptions< WPropBool >( m_active, "WGE_POSTPROCESSING_DISABLED", "WGE_POSTPROCESSING_ENABLED" ) )
);
// insert node to group node of all children
......
......@@ -28,6 +28,7 @@
#include <osg/Switch>
#include "../../common/WPropertyVariable.h"
#include "../../common/WItemSelection.h"
#include "../offscreen/WGEOffscreenRenderNode.h"
#include "../offscreen/WGEOffscreenRenderPass.h"
......@@ -134,16 +135,6 @@ private:
*/
osg::ref_ptr< WGEOffscreenFinalPass > m_postprocess;
/**
* Callback handling en-/disabling of post-processing.
*/
osg::ref_ptr< WGESwitchCallback< WPropBool > > m_switchCallback;
/**
* Callback switching visibility of the HUD
*/
osg::ref_ptr< WGENodeMaskCallback > m_hudCallback;
/**
* This shader actually does post-processing in screen space.
*/
......@@ -163,6 +154,16 @@ private:
* If true, a HUD with intermediate textures is shown.
*/
WPropBool m_showHUD;
/**
* The property containing the currently active method or a combination.
*/
WPropSelection m_activePostprocessors;
/**
* Possible post-processors.
*/
boost::shared_ptr< WItemSelection > m_possiblePostprocessors;
};
#endif // WGEPOSTPROCESSINGNODE_H
......
......@@ -36,7 +36,7 @@ WGEShaderDefineOptions::WGEShaderDefineOptions( std::string first,
std::string option10 ):
WGEShaderPreprocessor(),
m_options( 1, first ),
m_idx( 0 )
m_idx( 1, 0 )
{
// init
if ( !option2.empty() )
......@@ -77,6 +77,14 @@ WGEShaderDefineOptions::WGEShaderDefineOptions( std::string first,
}
}
WGEShaderDefineOptions::WGEShaderDefineOptions( std::vector< std::string > options ):
WGEShaderPreprocessor(),
m_options( options ),
m_idx( 1, 0 )
{
WPrecond( options.size() >= 1, "You need to specify at least one option." );
}
WGEShaderDefineOptions::~WGEShaderDefineOptions()
{
// cleanup
......@@ -89,31 +97,77 @@ std::string WGEShaderDefineOptions::process( const std::string& /*file*/, const
return code;
}
return "#define " + getActiveOptionName() + "\n" + code;
// add a define for every active option
std::stringstream ss;
for ( IdxList::const_iterator iter = m_idx.begin(); iter != m_idx.end(); ++iter )
{
ss << "#define " + getOptionName( *iter ) << std::endl;
}
// add the original code again
ss << code;
return ss.str();
}
size_t WGEShaderDefineOptions::getActiveOption() const
const WGEShaderDefineOptions::IdxList& WGEShaderDefineOptions::getActiveOptions() const
{
return m_idx;
}
std::string WGEShaderDefineOptions::getActiveOptionName() const
std::string WGEShaderDefineOptions::getOptionName( size_t idx ) const
{
return m_options[ m_idx ];
WPrecond( idx < m_options.size(), "Index invalid." );
return m_options[ idx ];
}
void WGEShaderDefineOptions::activateOption( size_t idx )
void WGEShaderDefineOptions::activateOption( size_t idx, bool exclusive )
{
WPrecond( idx < m_options.size(), "Index invalid." );
if ( idx != m_idx )
if ( exclusive )
{
m_idx = idx;
m_idx.clear();
}
// is the option already active?
if ( std::find( m_idx.begin(), m_idx.end(), idx ) == m_idx.end() )
{
m_idx.push_back( idx );
updated();
}
}
void WGEShaderDefineOptions::dactivateOption( size_t idx )
{
IdxList::iterator iter = std::find( m_idx.begin(), m_idx.end(), idx );
if ( iter != m_idx.end() )
{
m_idx.erase( iter );
updated();
}
}
void WGEShaderDefineOptions::activateAllOptions()
{
// simply add all
for ( size_t i = 0; i < m_options.size(); ++i )
{
m_idx.push_back( i );
}
updated();
}
void WGEShaderDefineOptions::deactivateAllOptions()
{
// clear active list
m_idx.clear();
updated();
}
void WGEShaderDefineOptions::addOption( std::string opt )
{
WPrecond( !opt.empty(), "Options need to have a non-empty name." );
if ( std::find( m_options.begin(), m_options.end(), opt ) == m_options.end() )
{
m_options.push_back( opt );
......@@ -123,3 +177,12 @@ void WGEShaderDefineOptions::addOption( std::string opt )
}
}
void WGEShaderDefineOptions::setActivationList( const IdxList& newList )
{
if ( m_idx != newList )
{
m_idx = newList;
updated();
}
}
......@@ -55,11 +55,9 @@ public:
typedef boost::shared_ptr< const WGEShaderDefineOptions > ConstSPtr;
/**
* Default constructor.
*
* \param first the first option. This is active by default
* The type of the index list
*/
explicit WGEShaderDefineOptions( std::string first );
typedef std::vector< size_t > IdxList;
/**
* Create a new instance of this class. The first option is mandatory and is set as default.
......@@ -80,6 +78,13 @@ public:
std::string option6 = "", std::string option7 = "", std::string option8 = "", std::string option9 = "",
std::string option10 = "" );
/**
* Create a new instance of this class. The first option is mandatory and is set as default.
*
* \param options the list of options. Must have a size greater 0.
*/
explicit WGEShaderDefineOptions( std::vector< std::string > options );
/**
* Destructor.
*/
......@@ -100,21 +105,41 @@ public:
*
* \return the index of the active option
*/
size_t getActiveOption() const;
const IdxList& getActiveOptions() const;
/**
* Returns the currently active option's name.
* Returns the name of the specified option.
*
* \param idx the index
*
* \return the name
*/
std::string getActiveOptionName() const;
std::string getOptionName( size_t idx ) const;
/**
* Activates the option specified.
*
* \param idx the option index to activate
* \param exclusive if true, all active options get deactivated and the specified one will be the only active one afterwards
*/
void activateOption( size_t idx, bool exclusive = true );
/**
* De-activates the specified option. If it is not activated, nothing happens.
*
* \param idx the option to deactivate
*/
void activateOption( size_t idx );
void dactivateOption( size_t idx );
/**
* Activates all the options.
*/
void activateAllOptions();
/**
* De-activates all the options.
*/
void deactivateAllOptions();
/**
* Adds the specified string as option which is inserted to the code as "#define NAME" if active. Must be a unique name. If it already exists
......@@ -126,6 +151,13 @@ public:
protected:
/**
* Sets the specified index list as the new activation list. Triggers an update.
*
* \param newList the ne list getting copied to the internal activation list.
*/
void setActivationList( const IdxList& newList );
private:
/**
......@@ -134,9 +166,9 @@ private:
std::vector< std::string > m_options;
/**
* The currently selected option.
* The currently selected options.
*/
size_t m_idx;
IdxList m_idx;
};
#endif // WGESHADERDEFINEOPTIONS_H
......
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include "WGEShaderPropertyDefineOptions.h"
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#ifndef WGESHADERPROPERTYDEFINEOPTIONS_H
#define WGESHADERPROPERTYDEFINEOPTIONS_H
#include <string>
#include <vector>
#include <boost/shared_ptr.hpp>
#include "boost/tuple/tuple.hpp"
#include <boost/signals2.hpp>
#include "../../common/WProperties.h"
#include "../../common/WPropertyTypes.h"
#include "../../common/exceptions/WPreconditionNotMet.h"
#include "WGEShaderDefineOptions.h"
#include "../WExportWGE.h"
template< typename PropType >
class WGEShaderPropertyDefineOptionsIndexAdapter;
/**
* This is a WGEShaderDefineOptions class which additionally uses a property to automatically control the active options. This is very useful if
* you have some WPropInt or WPropSelection which controls some features in your shader. Especially with WPropSelection Instances, you can even
* activate multiple options if your selection allows this ( see WPropertyVariable<>::PropertyConstraint for details ). If used with a WPropBool,
* it is useful to switch on/off an option for example.
*
* \note You can use inherited WGEShaderDefineOptions methods too. This might create some kind of inconsistency since they of course do not
* update the property.
*/
template< typename PropType, typename PropIndexAdapter = WGEShaderPropertyDefineOptionsIndexAdapter< PropType > >
class WGE_EXPORT WGEShaderPropertyDefineOptions: public WGEShaderDefineOptions
{
public:
/**
* Convenience typedef for a boost_shared_ptr< WGEShaderPropertyDefineOptions >.
*/
typedef boost::shared_ptr< WGEShaderPropertyDefineOptions > SPtr;
/**
* Convenience typedef for a boost_shared_ptr< const WGEShaderPropertyDefineOptions >.
*/
typedef boost::shared_ptr< const WGEShaderPropertyDefineOptions > ConstSPtr;
/**
* Create a new instance of this class. The first option is mandatory and is set as default. The specified property controls the activations.
*
* \param prop the property controlling this thing.
*
* \param first fist option. Is default.
* \param option2 another option
* \param option3 another option
* \param option4 another option
* \param option5 another option
* \param option6 another option
* \param option7 another option
* \param option8 another option
* \param option9 another option
* \param option10 another option
*/
WGEShaderPropertyDefineOptions( PropType prop, std::string first,
std::string option2 = "", std::string option3 = "", std::string option4 = "", std::string option5 = "",
std::string option6 = "", std::string option7 = "", std::string option8 = "", std::string option9 = "",
std::string option10 = "" );
/**
* Create a new instance of this class. The first option is mandatory and is set as default. The specified property controls the activations.
*
* \param prop the property controlling this thing.
*
* \param options the list of options. Must have a size greater 0.
*/
WGEShaderPropertyDefineOptions( PropType prop, std::vector< std::string > options );
/**
* Destructor.
*/
virtual ~WGEShaderPropertyDefineOptions();
/**
* This tuple contains name, description and define-name of an option.
*/
typedef boost::tuple< std::string, std::string, std::string > NameDescriptionDefineTuple;
/**
* A little bit more comfortable way to create a list of shader-defines and the corresponding property.
*
* \param propName the name of the property to create
* \param propDescription the description of the property to create
* \param propGroup the owning group of the property
* \param defines the list of names, descriptions and defines
*
* \return a WGEShaderPropertyDefineOptions instance associated with a new property. This can be acquired using getProperty().
*/
static WGEShaderPropertyDefineOptions< PropType, PropIndexAdapter >::SPtr createSelection( std::string propName, std::string propDescription,
WProperties::SPtr propGroup,
std::vector< NameDescriptionDefineTuple > defines )
{
// the item selection:
boost::shared_ptr< WItemSelection > selection( new WItemSelection() );
std::vector< std::string > definesOnly;
// add to the properties possible selection items list and option list
for ( std::vector< NameDescriptionDefineTuple >::const_iterator i = defines.begin(); i != defines.end(); ++i )
{
selection->addItem( ( *i ).get< 0 >(), ( *i ).get< 1 >() );
definesOnly.push_back( ( *i ).get< 2 >() );
}
WPropSelection prop = propGroup->addProperty( propName, propDescription, selection->getSelectorFirst() );
// create the corresponding WGEShaderPropertyDefineOptions instance
WGEShaderPropertyDefineOptions::SPtr defOptions( new WGEShaderPropertyDefineOptions( prop, definesOnly ) );
return defOptions;
}
/**
* Returns the property associated with this instance.
*
* \return
*/
PropType getProperty() const;
protected:
private:
/**
* The property controlling this instance and the active options list.
*/
PropType m_property;
/**
* The connection associated with the properties update condition.
*/
boost::signals2::connection m_connection;
/**
* Called by the property update mechanism. This handles the new value in the property.
*/
void propUpdated();
};
/**
* Class converts the specified property value to an index list. The generic case for all int-castable property types is trivial. WPropSelection
* is a specialization of this class.
*
* \tparam PropType The property. WPropInt for example.
*/
template< typename PropType >
class WGEShaderPropertyDefineOptionsIndexAdapter
{
public:
typedef typename WGEShaderPropertyDefineOptions< PropType >::IdxList IdxList;
/**
* Converts the specified property value to an index list.
*
* \param in the value to convert to an index list
*
* \return the new index list
*/
IdxList operator()( const typename PropType::element_type::ValueType& in ) const
{
return IdxList( 1, typename IdxList::value_type( in ) );
}
};
/**
* Class converts the specified property value to an index list. The generic case for all int-castable property types is trivial. This is the
* specialization for WPropSelection which allows multiple options to be active if the selection has multiple selected items.
*
* \tparam PropType The property. WPropInt for example.
*/
template<>
class WGEShaderPropertyDefineOptionsIndexAdapter< WPropSelection >
{
public: