wip for effects in models

multi-index for effect attributes
This commit is contained in:
Tim Moore
2009-11-13 22:41:10 +01:00
parent 6a7c200002
commit 6db9138eeb
6 changed files with 110 additions and 41 deletions
+10 -4
View File
@@ -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
{ {
+90 -31
View File
@@ -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.
+6 -3
View File
@@ -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,
+1
View File
@@ -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
-3
View File
@@ -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