Move BlendFunc parsing to separate file for easier reuse.

This commit is contained in:
Thomas Geymayer
2013-06-02 20:38:22 +02:00
parent 8b3b71bce3
commit 7a8d796ac1
5 changed files with 234 additions and 52 deletions

View File

@@ -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)

View File

@@ -24,6 +24,7 @@
#include "Technique.hxx"
#include "Pass.hxx"
#include "TextureBuilder.hxx"
#include "parseBlendFunc.hxx"
#include <algorithm>
#include <functional>
@@ -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")
);
}
};

View File

@@ -0,0 +1,98 @@
// Parse osg::BlendFunc from property nodes
//
// Copyright (C) 2008 - 2010 Tim Moore timoore33@gmail.com
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
//
// 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 <simgear/scene/util/StateAttributeFactory.hxx>
#include <osg/BlendFunc>
using osg::BlendFunc;
namespace simgear
{
//----------------------------------------------------------------------------
extern effect::EffectPropertyMap<BlendFunc::BlendFuncMode> 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

View File

@@ -0,0 +1,52 @@
///@file
/// Parse osg::BlendFunc from property nodes
///
// Copyright (C) 2013 Thomas Geymayer <tomgey@gmail.com>
//
// 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 <simgear/props/propsfwd.hxx>
#include <osg/StateSet>
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_ */

View File

@@ -0,0 +1,63 @@
#include <simgear/compiler.h>
#include "parseBlendFunc.hxx"
#include <simgear/props/props.hxx>
#include <osg/BlendFunc>
#include <iostream>
#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<osg::StateSet> ss = new osg::StateSet;
// default blendfunc
VERIFY( simgear::parseBlendFunc(ss) );
osg::BlendFunc* bf = dynamic_cast<osg::BlendFunc*>(
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<osg::BlendFunc*>(
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;
}