From 7a8d796ac17c62415f147b498f86d07ab03494e8 Mon Sep 17 00:00:00 2001 From: Thomas Geymayer Date: Sun, 2 Jun 2013 20:38:22 +0200 Subject: [PATCH] Move BlendFunc parsing to separate file for easier reuse. --- simgear/scene/material/CMakeLists.txt | 10 ++ simgear/scene/material/Effect.cxx | 63 +++--------- simgear/scene/material/parseBlendFunc.cxx | 98 +++++++++++++++++++ simgear/scene/material/parseBlendFunc.hxx | 52 ++++++++++ .../scene/material/parseBlendFunc_test.cxx | 63 ++++++++++++ 5 files changed, 234 insertions(+), 52 deletions(-) create mode 100644 simgear/scene/material/parseBlendFunc.cxx create mode 100644 simgear/scene/material/parseBlendFunc.hxx create mode 100644 simgear/scene/material/parseBlendFunc_test.cxx diff --git a/simgear/scene/material/CMakeLists.txt b/simgear/scene/material/CMakeLists.txt index ccd0b279..ba53896a 100644 --- a/simgear/scene/material/CMakeLists.txt +++ b/simgear/scene/material/CMakeLists.txt @@ -11,6 +11,7 @@ set(HEADERS matlib.hxx matmodel.hxx mipmap.hxx + parseBlendFunc.hxx ) set(SOURCES @@ -27,7 +28,16 @@ set(SOURCES matlib.cxx matmodel.cxx mipmap.cxx + parseBlendFunc.cxx ) simgear_scene_component(material scene/material "${SOURCES}" "${HEADERS}") + +if(ENABLE_TESTS) + +add_executable(test_parseBlendFunc parseBlendFunc_test.cxx ) +add_test(parseBlendFunc ${EXECUTABLE_OUTPUT_PATH}/test_parseBlendFunc) +target_link_libraries(test_parseBlendFunc ${TEST_LIBS} ${OPENSCENEGRAPH_LIBRARIES}) + +endif(ENABLE_TESTS) \ No newline at end of file diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index 70f8e8fe..669898aa 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -24,6 +24,7 @@ #include "Technique.hxx" #include "Pass.hxx" #include "TextureBuilder.hxx" +#include "parseBlendFunc.hxx" #include #include @@ -453,58 +454,16 @@ struct BlendBuilder : public PassAttributeBuilder pass->setMode(GL_BLEND, StateAttribute::OFF); return; } - const SGPropertyNode* psource - = getEffectPropertyChild(effect, prop, "source"); - const SGPropertyNode* pdestination - = getEffectPropertyChild(effect, prop, "destination"); - const SGPropertyNode* psourceRGB - = getEffectPropertyChild(effect, prop, "source-rgb"); - const SGPropertyNode* psourceAlpha - = getEffectPropertyChild(effect, prop, "source-alpha"); - const SGPropertyNode* pdestRGB - = getEffectPropertyChild(effect, prop, "destination-rgb"); - const SGPropertyNode* pdestAlpha - = getEffectPropertyChild(effect, prop, "destination-alpha"); - BlendFunc::BlendFuncMode sourceMode = BlendFunc::ONE; - BlendFunc::BlendFuncMode destMode = BlendFunc::ZERO; - if (psource) - findAttr(blendFuncModes, psource, sourceMode); - if (pdestination) - findAttr(blendFuncModes, pdestination, destMode); - if (psource && pdestination - && !(psourceRGB || psourceAlpha || pdestRGB || pdestAlpha) - && sourceMode == BlendFunc::SRC_ALPHA - && destMode == BlendFunc::ONE_MINUS_SRC_ALPHA) { - pass->setAttributeAndModes(StateAttributeFactory::instance() - ->getStandardBlendFunc()); - return; - } - BlendFunc* blendFunc = new BlendFunc; - if (psource) - blendFunc->setSource(sourceMode); - if (pdestination) - blendFunc->setDestination(destMode); - if (psourceRGB) { - BlendFunc::BlendFuncMode sourceRGBMode; - findAttr(blendFuncModes, psourceRGB, sourceRGBMode); - blendFunc->setSourceRGB(sourceRGBMode); - } - if (pdestRGB) { - BlendFunc::BlendFuncMode destRGBMode; - findAttr(blendFuncModes, pdestRGB, destRGBMode); - blendFunc->setDestinationRGB(destRGBMode); - } - if (psourceAlpha) { - BlendFunc::BlendFuncMode sourceAlphaMode; - findAttr(blendFuncModes, psourceAlpha, sourceAlphaMode); - blendFunc->setSourceAlpha(sourceAlphaMode); - } - if (pdestAlpha) { - BlendFunc::BlendFuncMode destAlphaMode; - findAttr(blendFuncModes, pdestAlpha, destAlphaMode); - blendFunc->setDestinationAlpha(destAlphaMode); - } - pass->setAttributeAndModes(blendFunc); + + parseBlendFunc( + pass, + getEffectPropertyChild(effect, prop, "source"), + getEffectPropertyChild(effect, prop, "destination"), + getEffectPropertyChild(effect, prop, "source-rgb"), + getEffectPropertyChild(effect, prop, "destination-rgb"), + getEffectPropertyChild(effect, prop, "source-alpha"), + getEffectPropertyChild(effect, prop, "destination-alpha") + ); } }; diff --git a/simgear/scene/material/parseBlendFunc.cxx b/simgear/scene/material/parseBlendFunc.cxx new file mode 100644 index 00000000..d747a7e0 --- /dev/null +++ b/simgear/scene/material/parseBlendFunc.cxx @@ -0,0 +1,98 @@ +// Parse osg::BlendFunc from property nodes +// +// Copyright (C) 2008 - 2010 Tim Moore timoore33@gmail.com +// Copyright (C) 2013 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#include "parseBlendFunc.hxx" +#include "EffectBuilder.hxx" +#include +#include + +using osg::BlendFunc; + +namespace simgear +{ + + //---------------------------------------------------------------------------- + extern effect::EffectPropertyMap blendFuncModes; + + //---------------------------------------------------------------------------- + bool parseBlendFunc( osg::StateSet* ss, + const SGPropertyNode* src, + const SGPropertyNode* dest, + const SGPropertyNode* src_rgb, + const SGPropertyNode* dest_rgb, + const SGPropertyNode* src_alpha, + const SGPropertyNode* dest_alpha ) + { + if( !ss ) + return false; + + BlendFunc::BlendFuncMode src_mode = BlendFunc::ONE; + BlendFunc::BlendFuncMode dest_mode = BlendFunc::ZERO; + + if( src ) + findAttr(blendFuncModes, src, src_mode); + if( dest ) + findAttr(blendFuncModes, dest, dest_mode); + + if( src && dest + && !(src_rgb || src_alpha || dest_rgb || dest_alpha) + && src_mode == BlendFunc::SRC_ALPHA + && dest_mode == BlendFunc::ONE_MINUS_SRC_ALPHA ) + { + ss->setAttributeAndModes( + StateAttributeFactory::instance()->getStandardBlendFunc() + ); + return true; + } + + BlendFunc* blend_func = new BlendFunc; + if( src ) + blend_func->setSource(src_mode); + if( dest ) + blend_func->setDestination(dest_mode); + + if( src_rgb ) + { + BlendFunc::BlendFuncMode sourceRGBMode; + findAttr(blendFuncModes, src_rgb, sourceRGBMode); + blend_func->setSourceRGB(sourceRGBMode); + } + if( dest_rgb) + { + BlendFunc::BlendFuncMode destRGBMode; + findAttr(blendFuncModes, dest_rgb, destRGBMode); + blend_func->setDestinationRGB(destRGBMode); + } + if( src_alpha ) + { + BlendFunc::BlendFuncMode sourceAlphaMode; + findAttr(blendFuncModes, src_alpha, sourceAlphaMode); + blend_func->setSourceAlpha(sourceAlphaMode); + } + if( dest_alpha) + { + BlendFunc::BlendFuncMode destAlphaMode; + findAttr(blendFuncModes, dest_alpha, destAlphaMode); + blend_func->setDestinationAlpha(destAlphaMode); + } + ss->setAttributeAndModes(blend_func); + return true; + } + +} // namespace simgear diff --git a/simgear/scene/material/parseBlendFunc.hxx b/simgear/scene/material/parseBlendFunc.hxx new file mode 100644 index 00000000..b0b71c75 --- /dev/null +++ b/simgear/scene/material/parseBlendFunc.hxx @@ -0,0 +1,52 @@ +///@file +/// Parse osg::BlendFunc from property nodes +/// +// Copyright (C) 2013 Thomas Geymayer +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + +#ifndef SG_PARSE_BLEND_FUNC_HXX_ +#define SG_PARSE_BLEND_FUNC_HXX_ + +#include +#include + +namespace simgear +{ + + /** + * Parse a blend function from the given property nodes and apply it to the + * given osg::StateSet. + * + * @param ss StateState which the blend function will be applied to + * @param src + * @param dest + * @param src_rgb + * @param dest_rgb + * @param src_alpha + * @param dest_alpha + */ + bool parseBlendFunc( osg::StateSet* ss, + const SGPropertyNode* src = 0, + const SGPropertyNode* dest = 0, + const SGPropertyNode* src_rgb = 0, + const SGPropertyNode* dest_rgb = 0, + const SGPropertyNode* src_alpha = 0, + const SGPropertyNode* dest_alpha = 0 ); + +} // namespace simgear + + +#endif /* SG_PARSE_BLEND_FUNC_HXX_ */ diff --git a/simgear/scene/material/parseBlendFunc_test.cxx b/simgear/scene/material/parseBlendFunc_test.cxx new file mode 100644 index 00000000..4993c5b3 --- /dev/null +++ b/simgear/scene/material/parseBlendFunc_test.cxx @@ -0,0 +1,63 @@ +#include + +#include "parseBlendFunc.hxx" +#include +#include + +#include + +#define COMPARE(a, b) \ + if( (a) != (b) ) \ + { \ + std::cerr << "line " << __LINE__ << ": failed: "\ + << #a << " != " << #b << std::endl; \ + return 1; \ + } + +#define VERIFY(a) \ + if( !(a) ) \ + { \ + std::cerr << "line " << __LINE__ << ": failed: "\ + << #a << std::endl; \ + return 1; \ + } + +int main (int ac, char ** av) +{ + osg::ref_ptr ss = new osg::StateSet; + + // default blendfunc + VERIFY( simgear::parseBlendFunc(ss) ); + + osg::BlendFunc* bf = dynamic_cast( + ss->getAttribute(osg::StateAttribute::BLENDFUNC) + ); + + VERIFY( bf ); + COMPARE(bf->getSource(), osg::BlendFunc::SRC_ALPHA); + COMPARE(bf->getDestination(), osg::BlendFunc::ONE_MINUS_SRC_ALPHA); + COMPARE(bf->getSource(), bf->getSourceAlpha()); + COMPARE(bf->getDestination(), bf->getDestinationAlpha()); + + // now set some values + SGPropertyNode_ptr src = new SGPropertyNode, + dest = new SGPropertyNode; + + src->setStringValue("src-alpha"); + dest->setStringValue("constant-color"); + + VERIFY( simgear::parseBlendFunc(ss, src, dest) ); + + bf = dynamic_cast( + ss->getAttribute(osg::StateAttribute::BLENDFUNC) + ); + + VERIFY( bf ); + COMPARE(bf->getSource(), osg::BlendFunc::SRC_ALPHA); + COMPARE(bf->getDestination(), osg::BlendFunc::CONSTANT_COLOR); + COMPARE(bf->getSource(), bf->getSourceAlpha()); + COMPARE(bf->getDestination(), bf->getDestinationAlpha()); + + std::cout << "all tests passed successfully!" << std::endl; + return 0; +} -- 2.39.5