wip for effects in models
multi-index for effect attributes
This commit is contained in:
@@ -73,6 +73,8 @@ using namespace std;
|
|||||||
using namespace osg;
|
using namespace osg;
|
||||||
using namespace osgUtil;
|
using namespace osgUtil;
|
||||||
|
|
||||||
|
using namespace effect;
|
||||||
|
|
||||||
Effect::Effect()
|
Effect::Effect()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -305,7 +307,7 @@ struct MaterialBuilder : public PassAttributeBuilder
|
|||||||
const osgDB::ReaderWriter::Options* options);
|
const osgDB::ReaderWriter::Options* options);
|
||||||
};
|
};
|
||||||
|
|
||||||
EffectNameValue<Material::ColorMode> colorModes[] =
|
EffectNameValue<Material::ColorMode> colorModeInit[] =
|
||||||
{
|
{
|
||||||
{ "ambient", Material::AMBIENT },
|
{ "ambient", Material::AMBIENT },
|
||||||
{ "ambient-and-diffuse", Material::AMBIENT_AND_DIFFUSE },
|
{ "ambient-and-diffuse", Material::AMBIENT_AND_DIFFUSE },
|
||||||
@@ -314,6 +316,7 @@ EffectNameValue<Material::ColorMode> colorModes[] =
|
|||||||
{ "specular", Material::SPECULAR },
|
{ "specular", Material::SPECULAR },
|
||||||
{ "off", Material::OFF }
|
{ "off", Material::OFF }
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
|
||||||
|
|
||||||
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
|
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
|
||||||
const SGPropertyNode* prop,
|
const SGPropertyNode* prop,
|
||||||
@@ -394,7 +397,7 @@ struct AlphaTestBuilder : public PassAttributeBuilder
|
|||||||
|
|
||||||
InstallAttributeBuilder<AlphaTestBuilder> installAlphaTest("alpha-test");
|
InstallAttributeBuilder<AlphaTestBuilder> installAlphaTest("alpha-test");
|
||||||
|
|
||||||
EffectNameValue<TexEnv::Mode> texEnvModes[] =
|
EffectNameValue<TexEnv::Mode> texEnvModesInit[] =
|
||||||
{
|
{
|
||||||
{"add", TexEnv::ADD},
|
{"add", TexEnv::ADD},
|
||||||
{"blend", TexEnv::BLEND},
|
{"blend", TexEnv::BLEND},
|
||||||
@@ -402,6 +405,7 @@ EffectNameValue<TexEnv::Mode> texEnvModes[] =
|
|||||||
{"modulate", TexEnv::MODULATE},
|
{"modulate", TexEnv::MODULATE},
|
||||||
{"replace", TexEnv::REPLACE}
|
{"replace", TexEnv::REPLACE}
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<TexEnv::Mode> texEnvModes(texEnvModesInit);
|
||||||
|
|
||||||
TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
|
TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
|
||||||
{
|
{
|
||||||
@@ -564,7 +568,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
|
|||||||
|
|
||||||
InstallAttributeBuilder<ShaderProgramBuilder> installShaderProgram("program");
|
InstallAttributeBuilder<ShaderProgramBuilder> installShaderProgram("program");
|
||||||
|
|
||||||
EffectNameValue<Uniform::Type> uniformTypes[] =
|
EffectNameValue<Uniform::Type> uniformTypesInit[] =
|
||||||
{
|
{
|
||||||
{"float", Uniform::FLOAT},
|
{"float", Uniform::FLOAT},
|
||||||
{"float-vec3", Uniform::FLOAT_VEC3},
|
{"float-vec3", Uniform::FLOAT_VEC3},
|
||||||
@@ -573,6 +577,7 @@ EffectNameValue<Uniform::Type> uniformTypes[] =
|
|||||||
{"sampler-2d", Uniform::SAMPLER_2D},
|
{"sampler-2d", Uniform::SAMPLER_2D},
|
||||||
{"sampler-3d", Uniform::SAMPLER_3D}
|
{"sampler-3d", Uniform::SAMPLER_3D}
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit);
|
||||||
|
|
||||||
struct UniformBuilder :public PassAttributeBuilder
|
struct UniformBuilder :public PassAttributeBuilder
|
||||||
{
|
{
|
||||||
@@ -660,12 +665,13 @@ struct NameBuilder : public PassAttributeBuilder
|
|||||||
|
|
||||||
InstallAttributeBuilder<NameBuilder> installName("name");
|
InstallAttributeBuilder<NameBuilder> installName("name");
|
||||||
|
|
||||||
EffectNameValue<PolygonMode::Mode> polygonModeModes[] =
|
EffectNameValue<PolygonMode::Mode> polygonModeModesInit[] =
|
||||||
{
|
{
|
||||||
{"fill", PolygonMode::FILL},
|
{"fill", PolygonMode::FILL},
|
||||||
{"line", PolygonMode::LINE},
|
{"line", PolygonMode::LINE},
|
||||||
{"point", PolygonMode::POINT}
|
{"point", PolygonMode::POINT}
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
|
||||||
|
|
||||||
struct PolygonModeBuilder : public PassAttributeBuilder
|
struct PolygonModeBuilder : public PassAttributeBuilder
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,6 +24,10 @@
|
|||||||
|
|
||||||
#include <osgDB/Registry>
|
#include <osgDB/Registry>
|
||||||
|
|
||||||
|
#include <boost/multi_index_container.hpp>
|
||||||
|
#include <boost/multi_index/member.hpp>
|
||||||
|
#include <boost/multi_index/ordered_index.hpp>
|
||||||
|
|
||||||
#include <simgear/props/props.hxx>
|
#include <simgear/props/props.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/structure/SGSharedPtr.hxx>
|
#include <simgear/structure/SGSharedPtr.hxx>
|
||||||
@@ -79,57 +83,112 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simple tables of strings and constants. The table intialization
|
// Tables of strings and constants. We want to reconstruct the effect
|
||||||
// *must* be in alphabetical order.
|
// property tree from OSG state sets, so the tables should be bi-directional.
|
||||||
|
|
||||||
|
// two-way map for building StateSets from property descriptions, and
|
||||||
|
// vice versa. Mostly copied from the boost documentation.
|
||||||
|
|
||||||
|
namespace effect
|
||||||
|
{
|
||||||
|
using boost::multi_index_container;
|
||||||
|
using namespace boost::multi_index;
|
||||||
|
|
||||||
|
// tags for accessing both sides of a bidirectional map
|
||||||
|
|
||||||
|
struct from{};
|
||||||
|
struct to{};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct EffectNameValue
|
struct EffectNameValue
|
||||||
{
|
{
|
||||||
// Don't use std::pair because we want to use aggregate intialization.
|
// Don't use std::pair because we want to use aggregate intialization.
|
||||||
|
|
||||||
const char* first;
|
const char* first;
|
||||||
T second;
|
T second;
|
||||||
class Compare
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
static bool compare(const char* lhs, const char* rhs)
|
|
||||||
{
|
|
||||||
return std::strcmp(lhs, rhs) < 0;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
bool operator()(const EffectNameValue& lhs,
|
|
||||||
const EffectNameValue& rhs) const
|
|
||||||
{
|
|
||||||
return compare(lhs.first, rhs.first);
|
|
||||||
}
|
|
||||||
bool operator()(const char* lhs, const EffectNameValue& rhs) const
|
|
||||||
{
|
|
||||||
return compare(lhs, rhs.first);
|
|
||||||
}
|
|
||||||
bool operator()(const EffectNameValue& lhs, const char* rhs) const
|
|
||||||
{
|
|
||||||
return compare (lhs.first, rhs);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ENV, typename T, int N>
|
// The class template bidirectional_map wraps the specification
|
||||||
bool findAttr(const ENV (&attrs)[N], const SGPropertyNode* prop, T& result)
|
// of a bidirectional map based on multi_index_container.
|
||||||
|
|
||||||
|
template<typename FromType,typename ToType>
|
||||||
|
struct bidirectional_map
|
||||||
{
|
{
|
||||||
|
typedef std::pair<FromType,ToType> value_type;
|
||||||
|
|
||||||
|
/* A bidirectional map can be simulated as a multi_index_container
|
||||||
|
* of pairs of (FromType,ToType) with two unique indices, one
|
||||||
|
* for each member of the pair.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef multi_index_container<
|
||||||
|
value_type,
|
||||||
|
indexed_by<
|
||||||
|
ordered_unique<
|
||||||
|
tag<from>, member<value_type, FromType, &value_type::first> >,
|
||||||
|
ordered_unique<
|
||||||
|
tag<to>, member<value_type, ToType, &value_type::second> >
|
||||||
|
>
|
||||||
|
> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct EffectPropertyMap
|
||||||
|
{
|
||||||
|
typedef typename bidirectional_map<std::string, T>::type BMap;
|
||||||
|
BMap _map;
|
||||||
|
template<int N>
|
||||||
|
EffectPropertyMap(const EffectNameValue<T> (&attrs)[N]);
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
template<int N>
|
||||||
|
EffectPropertyMap<T>::EffectPropertyMap(const EffectNameValue<T> (&attrs)[N])
|
||||||
|
{
|
||||||
|
for (int i = 0; i < N; ++i)
|
||||||
|
_map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool findAttr(const effect::EffectPropertyMap<T>& pMap,
|
||||||
|
const SGPropertyNode* prop,
|
||||||
|
T& result)
|
||||||
|
{
|
||||||
|
using namespace effect;
|
||||||
if (!prop)
|
if (!prop)
|
||||||
return false;
|
return false;
|
||||||
const char* name = prop->getStringValue();
|
const char* name = prop->getStringValue();
|
||||||
if (!name)
|
if (!name)
|
||||||
return false;
|
return false;
|
||||||
std::pair<const ENV*, const ENV*> itrs
|
typename EffectPropertyMap<T>::BMap::iterator itr
|
||||||
= std::equal_range(&attrs[0], &attrs[N], name, typename ENV::Compare());
|
= pMap._map.get<from>().find(name);
|
||||||
if (itrs.first == itrs.second) {
|
if (itr == pMap._map.end()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
result = itrs.first->second;
|
result = itr->second;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::string findName(const effect::EffectPropertyMap<T>& pMap, T value)
|
||||||
|
{
|
||||||
|
using namespace effect;
|
||||||
|
std::string result;
|
||||||
|
typename EffectPropertyMap<T>::BMap::template index_iterator<to>::type itr
|
||||||
|
= pMap._map.get<to>().find(value);
|
||||||
|
if (itr != pMap._map.get<to>().end())
|
||||||
|
result = itr->first;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::string findName(const effect::EffectPropertyMap<T>& pMap, GLenum value)
|
||||||
|
{
|
||||||
|
return findName(pMap, static_cast<T>(value));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a property node from a pass, get its value either from it or
|
* Given a property node from a pass, get its value either from it or
|
||||||
* from the effect parameters.
|
* from the effect parameters.
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ namespace simgear
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace osg;
|
using namespace osg;
|
||||||
|
|
||||||
|
using namespace effect;
|
||||||
|
|
||||||
// Hack to force inclusion of TextureBuilder.cxx in library
|
// Hack to force inclusion of TextureBuilder.cxx in library
|
||||||
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
|
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
|
||||||
const SGPropertyNode*props,
|
const SGPropertyNode*props,
|
||||||
@@ -56,7 +58,7 @@ typedef boost::tuple<string, Texture::FilterMode, Texture::FilterMode,
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
EffectNameValue<Texture::FilterMode> filterModes[] =
|
EffectNameValue<Texture::FilterMode> filterModesInit[] =
|
||||||
{
|
{
|
||||||
{ "linear", Texture::LINEAR },
|
{ "linear", Texture::LINEAR },
|
||||||
{ "linear-mipmap-linear", Texture::LINEAR_MIPMAP_LINEAR},
|
{ "linear-mipmap-linear", Texture::LINEAR_MIPMAP_LINEAR},
|
||||||
@@ -65,8 +67,9 @@ EffectNameValue<Texture::FilterMode> filterModes[] =
|
|||||||
{ "nearest-mipmap-linear", Texture::NEAREST_MIPMAP_LINEAR},
|
{ "nearest-mipmap-linear", Texture::NEAREST_MIPMAP_LINEAR},
|
||||||
{ "nearest-mipmap-nearest", Texture::NEAREST_MIPMAP_NEAREST}
|
{ "nearest-mipmap-nearest", Texture::NEAREST_MIPMAP_NEAREST}
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<Texture::FilterMode> filterModes(filterModesInit);
|
||||||
|
|
||||||
EffectNameValue<Texture::WrapMode> wrapModes[] =
|
EffectNameValue<Texture::WrapMode> wrapModesInit[] =
|
||||||
{
|
{
|
||||||
{"clamp", Texture::CLAMP},
|
{"clamp", Texture::CLAMP},
|
||||||
{"clamp-to-border", Texture::CLAMP_TO_BORDER},
|
{"clamp-to-border", Texture::CLAMP_TO_BORDER},
|
||||||
@@ -74,7 +77,7 @@ EffectNameValue<Texture::WrapMode> wrapModes[] =
|
|||||||
{"mirror", Texture::MIRROR},
|
{"mirror", Texture::MIRROR},
|
||||||
{"repeat", Texture::REPEAT}
|
{"repeat", Texture::REPEAT}
|
||||||
};
|
};
|
||||||
|
EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
|
||||||
|
|
||||||
|
|
||||||
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
|
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
#include <simgear/debug/logstream.hxx>
|
#include <simgear/debug/logstream.hxx>
|
||||||
#include <simgear/props/props_io.hxx>
|
#include <simgear/props/props_io.hxx>
|
||||||
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
#include <simgear/scene/util/SGSceneFeatures.hxx>
|
||||||
|
#include <simgear/scene/util/SplicingVisitor.hxx>
|
||||||
#include <simgear/structure/SGExpression.hxx>
|
#include <simgear/structure/SGExpression.hxx>
|
||||||
|
|
||||||
namespace simgear
|
namespace simgear
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ ModelRegistry::readImage(const string& fileName,
|
|||||||
ScopedLock<ReentrantMutex> lock(readerMutex);
|
ScopedLock<ReentrantMutex> lock(readerMutex);
|
||||||
CallbackMap::iterator iter
|
CallbackMap::iterator iter
|
||||||
= imageCallbackMap.find(getFileExtension(fileName));
|
= imageCallbackMap.find(getFileExtension(fileName));
|
||||||
// XXX Workaround for OSG plugin bug
|
|
||||||
{
|
{
|
||||||
if (iter != imageCallbackMap.end() && iter->second.valid())
|
if (iter != imageCallbackMap.end() && iter->second.valid())
|
||||||
return iter->second->readImage(fileName, opt);
|
return iter->second->readImage(fileName, opt);
|
||||||
@@ -357,8 +356,6 @@ ModelRegistry::readNode(const string& fileName,
|
|||||||
{
|
{
|
||||||
ScopedLock<ReentrantMutex> lock(readerMutex);
|
ScopedLock<ReentrantMutex> lock(readerMutex);
|
||||||
|
|
||||||
// XXX Workaround for OSG plugin bug.
|
|
||||||
// Registry* registry = Registry::instance();
|
|
||||||
ReaderWriter::ReadResult res;
|
ReaderWriter::ReadResult res;
|
||||||
CallbackMap::iterator iter
|
CallbackMap::iterator iter
|
||||||
= nodeCallbackMap.find(getFileExtension(fileName));
|
= nodeCallbackMap.find(getFileExtension(fileName));
|
||||||
|
|||||||
@@ -193,6 +193,9 @@ sgLoad3DModel_internal(const string &path,
|
|||||||
SGPropertyNode *mp = props->getNode("multiplay");
|
SGPropertyNode *mp = props->getNode("multiplay");
|
||||||
if (mp && prop_root && prop_root->getParent())
|
if (mp && prop_root && prop_root->getParent())
|
||||||
copyProperties(mp, prop_root);
|
copyProperties(mp, prop_root);
|
||||||
|
} else {
|
||||||
|
SG_LOG(SG_INPUT, SG_DEBUG, "model without wrapper: "
|
||||||
|
<< modelpath.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::ref_ptr<SGReaderWriterXMLOptions> options
|
osg::ref_ptr<SGReaderWriterXMLOptions> options
|
||||||
|
|||||||
Reference in New Issue
Block a user