00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "../../common/WPropertyHelper.h"
00026
00027 #include "../shaders/WGEShaderPropertyDefineOptions.h"
00028 #include "../WGEUtils.h"
00029
00030 #include "WGEPostprocessingNode.h"
00031
00032 WGEPostprocessingNode::WGEPostprocessingNode( osg::ref_ptr< osg::Camera > reference, size_t width, size_t height, bool noHud ):
00033 osg::Switch(),
00034 m_offscreen( new WGEOffscreenRenderNode( reference, width, height, noHud ) ),
00035 m_childs( new WGEGroupNode() ),
00036 m_postProcessShader( new WGEShader( "WGEPostprocessor" ) ),
00037 m_properties( boost::shared_ptr< WProperties >( new WProperties( "Post-processing", "Post-processing properties" ) ) )
00038 {
00039
00040 m_render = m_offscreen->addGeometryRenderPass(
00041 m_childs,
00042 "Rendered"
00043 );
00044 m_postprocess = m_offscreen->addFinalOnScreenPass( m_postProcessShader, "Post-processed" );
00045
00046
00047 osg::ref_ptr< osg::Texture2D > renderColorTexture = m_render->attach( osg::Camera::COLOR_BUFFER0 );
00048 osg::ref_ptr< osg::Texture2D > renderNormalTexture = m_render->attach( osg::Camera::COLOR_BUFFER1 );
00049 osg::ref_ptr< osg::Texture2D > renderDepthTexture = m_render->attach( osg::Camera::DEPTH_BUFFER );
00050 m_postprocess->bind( renderColorTexture, 0 );
00051 m_postprocess->bind( renderNormalTexture, 1 );
00052 m_postprocess->bind( renderDepthTexture, 2 );
00053
00054
00055 addChild( m_childs );
00056 addChild( m_offscreen );
00057
00058
00059 m_infoText = m_properties->addProperty( "Hint", "This is for advanced users.",
00060 std::string( "The post-processing has to be seen as facility to create appealing images. The here offered options are not all "
00061 "possibilities. The most powerful effects can be achieved by using custom combinations (using custom GLSL code) of "
00062 "post-processors and is recommended for <b>advanced users</b> only." )
00063 );
00064 m_infoText->setPurpose( PV_PURPOSE_INFORMATION );
00065
00066
00067 m_active = m_properties->addProperty( "Enable", "If set, post-processing is enabled.", true );
00068 m_showHUD = m_properties->addProperty( "Show HUD", "If set, the intermediate textures are shown.", false );
00069
00070
00071
00072 typedef WGEShaderPropertyDefineOptionsTools::NameDescriptionDefineTuple Tuple;
00073 std::vector< Tuple > namesAndDefs;
00074 namesAndDefs.push_back( Tuple( "Color Only", "No Post-Processing.", "WGE_POSTPROCESSOR_COLOR" ) );
00075 namesAndDefs.push_back( Tuple( "Smoothed Color", "Smoothed Color Image using Gauss Filter.", "WGE_POSTPROCESSOR_GAUSSEDCOLOR" ) );
00076 namesAndDefs.push_back( Tuple( "PPL - Phong", "Per-Pixel-Lighting using Phong.", "WGE_POSTPROCESSOR_PPLPHONG" ) );
00077 namesAndDefs.push_back( Tuple( "Cel-Shading", "Under-sampling of the color for cartoon-like shading.", "WGE_POSTPROCESSOR_CELSHADING" ) );
00078 namesAndDefs.push_back( Tuple( "Depth-Cueing", "Use the Depth to fade out the pixel's brightness.", "WGE_POSTPROCESSOR_DEPTHFADING" ) );
00079 namesAndDefs.push_back( Tuple( "Edge", "Edge of Rendered Geometry.", "WGE_POSTPROCESSOR_EDGE" ) );
00080 namesAndDefs.push_back( Tuple( "Depth", "Depth Value only.", "WGE_POSTPROCESSOR_DEPTH" ) );
00081 namesAndDefs.push_back( Tuple( "Smoothed Depth", "Gauss-Smoothed Depth Value only.", "WGE_POSTPROCESSOR_GAUSSEDDEPTH" ) );
00082 namesAndDefs.push_back( Tuple( "Normal", "Geometry Normal.", "WGE_POSTPROCESSOR_NORMAL" ) );
00083 namesAndDefs.push_back( Tuple( "Custom", "Provide Your Own Post-processing-Code.", "WGE_POSTPROCESSOR_CUSTOM" ) );
00084
00085
00086 WGEShaderPropertyDefineOptions< WPropSelection >::SPtr activePostprocessorsOpts(
00087 WGEShaderPropertyDefineOptionsTools::createSelection(
00088 "Post-processors",
00089 "Select the post-processings you want.",
00090 m_properties,
00091 namesAndDefs
00092 )
00093 );
00094 m_activePostprocessors = activePostprocessorsOpts->getProperty();
00095
00096 WPropertyHelper::PC_NOTEMPTY::addTo( m_activePostprocessors );
00097
00098
00099 addUpdateCallback( new WGESwitchCallback< WPropBool >( m_active ) );
00100 m_offscreen->getTextureHUD()->addUpdateCallback( new WGENodeMaskCallback( m_showHUD ) );
00101
00102 m_postProcessShader->addPreprocessor( activePostprocessorsOpts );
00103 }
00104
00105 WGEPostprocessingNode::~WGEPostprocessingNode()
00106 {
00107
00108 m_render->detach( osg::Camera::COLOR_BUFFER0 );
00109 m_render->detach( osg::Camera::COLOR_BUFFER1 );
00110 }
00111
00112 WPropGroup WGEPostprocessingNode::getProperties() const
00113 {
00114 return m_properties;
00115 }
00116
00117 void WGEPostprocessingNode::insert( osg::ref_ptr< osg::Node > node, WGEShader::RefPtr shader )
00118 {
00119
00120 WGEShaderPreprocessor::SPtr preproc( new WGEShaderPropertyDefineOptions< WPropBool >(
00121 m_active, "WGE_POSTPROCESSING_DISABLED", "WGE_POSTPROCESSING_ENABLED" )
00122 );
00123
00124
00125 shader->addPreprocessor( preproc );
00126
00127
00128 NodeShaderAssociation::WriteTicket w = m_nodeShaderAssociation.getWriteTicket();
00129
00130 w->get()[ node ] = std::make_pair( shader, preproc );
00131
00132
00133 m_childs->insert( node );
00134 }
00135
00136 void WGEPostprocessingNode::remove( osg::ref_ptr< osg::Node > node )
00137 {
00138
00139 NodeShaderAssociation::WriteTicket w = m_nodeShaderAssociation.getWriteTicket();
00140
00141
00142 NodeShaderAssociation::Iterator item = w->get().find( node );
00143
00144 if( item != w->get().end() )
00145 {
00146
00147 ( *item ).second.first->removePreprocessor( ( *item ).second.second );
00148 w->get().erase( item );
00149 }
00150
00151
00152 m_childs->remove( node );
00153 }
00154
00155 void WGEPostprocessingNode::clear()
00156 {
00157
00158 NodeShaderAssociation::WriteTicket w = m_nodeShaderAssociation.getWriteTicket();
00159
00160
00161 for( NodeShaderAssociation::Iterator iter = w->get().begin(); iter != w->get().end(); ++iter )
00162 {
00163 ( *iter ).second.first->removePreprocessor( ( *iter ).second.second );
00164 }
00165 w->get().clear();
00166
00167
00168 m_childs->clear();
00169 }
00170
00171 void WGEPostprocessingNode::setEnabled( bool enable )
00172 {
00173 m_active->set( enable );
00174 }
00175