Effects framework
This commit is contained in:
61
simgear/scene/material/Effect.cxx
Normal file
61
simgear/scene/material/Effect.cxx
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "Effect.hxx"
|
||||
#include "Technique.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/RenderInfo>
|
||||
#include <osg/StateSet>
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <simgear/structure/OSGUtils.hxx>
|
||||
|
||||
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
Effect::Effect(const Effect& rhs, const CopyOp& copyop)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
transform(rhs.techniques.begin(), rhs.techniques.end(),
|
||||
backRefInsertIterator(techniques),
|
||||
bind(simgear::clone_ref<Technique>, _1, copyop));
|
||||
}
|
||||
// There should always be a valid technique in an effect.
|
||||
|
||||
Technique* Effect::chooseTechnique(RenderInfo* info)
|
||||
{
|
||||
BOOST_FOREACH(ref_ptr<Technique>& technique, techniques)
|
||||
{
|
||||
if (technique->valid(info) == Technique::VALID)
|
||||
return technique.get();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Effect::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
BOOST_FOREACH(const ref_ptr<Technique>& technique, techniques)
|
||||
{
|
||||
technique->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
}
|
||||
|
||||
void Effect::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
BOOST_FOREACH(const ref_ptr<Technique>& technique, techniques)
|
||||
{
|
||||
technique->releaseGLObjects(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
57
simgear/scene/material/Effect.hxx
Normal file
57
simgear/scene/material/Effect.hxx
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
|
||||
#ifndef SIMGEAR_EFFECT_HXX
|
||||
#define SIMGEAR_EFFECT_HXX 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class Drawable;
|
||||
class StateSet;
|
||||
class RenderInfo;
|
||||
}
|
||||
|
||||
namespace osgUtil
|
||||
{
|
||||
class CullVisitor;
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class Technique;
|
||||
|
||||
class Effect : public osg::Object
|
||||
{
|
||||
public:
|
||||
META_Object(simgear,Effect)
|
||||
Effect() {}
|
||||
Effect(const Effect& rhs,
|
||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||
osg::StateSet* getDefaultStateSet();
|
||||
std::vector<osg::ref_ptr<Technique> > techniques;
|
||||
Technique* chooseTechnique(osg::RenderInfo* renderInfo);
|
||||
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
||||
virtual void releaseGLObjects(osg::State* state = 0) const;
|
||||
protected:
|
||||
~Effect() {}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
2
simgear/scene/material/EffectData.cxx
Normal file
2
simgear/scene/material/EffectData.cxx
Normal file
@@ -0,0 +1,2 @@
|
||||
#include "EffectData.hxx"
|
||||
|
||||
47
simgear/scene/material/EffectData.hxx
Normal file
47
simgear/scene/material/EffectData.hxx
Normal file
@@ -0,0 +1,47 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_EFFECT_DATA_HXX
|
||||
#define SIMGEAR_EFFECT_DATA_HXX 1
|
||||
|
||||
#include <osg/Vec4f>
|
||||
|
||||
#include "EffectElement.hxx"
|
||||
#include "EffectElementBuilder.hxx"
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class ParamaterContext;
|
||||
|
||||
template<typename T>
|
||||
class EffectData : public EffectElement
|
||||
{
|
||||
public:
|
||||
EffectData() {}
|
||||
EffectData(const EffectData& rhs) _value(rhs._value) {}
|
||||
virtual ~EffectData() {}
|
||||
T getValue(const ParameterContext*) const {return _value};
|
||||
void setValue(const T& value) { _value = value; }
|
||||
private:
|
||||
T _value;
|
||||
};
|
||||
|
||||
typedef EffectData<float> EffectFloat;
|
||||
typedef EffectData<osg::Vec4f> EffectVec4f;
|
||||
|
||||
|
||||
}
|
||||
#endif
|
||||
28
simgear/scene/material/EffectElement.hxx
Normal file
28
simgear/scene/material/EffectElement.hxx
Normal file
@@ -0,0 +1,28 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_EFFECT_ELEMENT_HXX
|
||||
#define SIMGEAR_EFFECT_ELEMENT_HXX 1
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class EffectElement
|
||||
{
|
||||
protected:
|
||||
~EffectElement() {}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
41
simgear/scene/material/EffectElementBuilder.hxx
Normal file
41
simgear/scene/material/EffectElementBuilder.hxx
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_EFFECT_BUILDER_HXX
|
||||
#define SIMGEAR_EFFECT_BUILDER_HXX 1
|
||||
|
||||
#include <simgear/xml/easyxml.hxx>
|
||||
#include "EffectElement.hxx"
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class ElementBuilder;
|
||||
|
||||
class EffectElementBuilder
|
||||
{
|
||||
public:
|
||||
EffectElementBuilder(ElementBuilder* builder);
|
||||
EffectElementBuilder(const EffectElementBuilder& rhs);
|
||||
virtual ~EffectElementBuilder();
|
||||
virtual void initialize(const XMLAttributes& attributes);
|
||||
virtual void processSubElement(EffectElement* subElement);
|
||||
virtual void processData(const char* data, int length);
|
||||
virtual EffectElement* finalize();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
62
simgear/scene/material/EffectGeode.cxx
Normal file
62
simgear/scene/material/EffectGeode.cxx
Normal file
@@ -0,0 +1,62 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "EffectGeode.hxx"
|
||||
#include "Effect.hxx"
|
||||
#include "Technique.hxx"
|
||||
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
void EffectGeode::traverse(NodeVisitor& nv)
|
||||
{
|
||||
CullVisitor* cv = dynamic_cast<CullVisitor*>(&nv);
|
||||
if (!cv || !_effect.valid()) {
|
||||
Geode::traverse(nv);
|
||||
return;
|
||||
}
|
||||
Technique* technique = _effect->chooseTechnique(&cv->getRenderInfo());
|
||||
if (!technique) {
|
||||
Geode::traverse(nv);
|
||||
return;
|
||||
}
|
||||
for (DrawablesIterator beginItr = _drawables.begin();
|
||||
beginItr != _drawables.end();
|
||||
beginItr = technique->processDrawables(beginItr, _drawables.end(), cv,
|
||||
isCullingActive()))
|
||||
;
|
||||
}
|
||||
|
||||
void EffectGeode::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
if (_effect.valid())
|
||||
_effect->resizeGLObjectBuffers(maxSize);
|
||||
Geode::resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
void EffectGeode::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
if (_effect.valid())
|
||||
_effect->releaseGLObjects(state);
|
||||
Geode::releaseGLObjects(state);
|
||||
}
|
||||
|
||||
}
|
||||
43
simgear/scene/material/EffectGeode.hxx
Normal file
43
simgear/scene/material/EffectGeode.hxx
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_EFFECT_GEODE_HXX
|
||||
#define SIMGEAR_EFFECT_GEODE_HXX 1
|
||||
|
||||
#include <osg/Geode>
|
||||
|
||||
#include "Effect.hxx"
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class EffectGeode : public osg::Geode
|
||||
{
|
||||
public:
|
||||
EffectGeode();
|
||||
EffectGeode(const EffectGeode& rhs,
|
||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||
META_Node(simgear,EffectGeode);
|
||||
virtual void traverse(osg::NodeVisitor& nv);
|
||||
Effect* getEffect() const { return _effect.get(); }
|
||||
void setEffect(Effect* effect);
|
||||
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
||||
virtual void releaseGLObjects(osg::State* = 0) const;
|
||||
typedef DrawableList::iterator DrawablesIterator;
|
||||
private:
|
||||
osg::ref_ptr<Effect> _effect;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
4
simgear/scene/material/ElementBuilder.cxx
Normal file
4
simgear/scene/material/ElementBuilder.cxx
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "ElementBuilder.hxx"
|
||||
|
||||
|
||||
|
||||
9
simgear/scene/material/ElementBuilder.hxx
Normal file
9
simgear/scene/material/ElementBuilder.hxx
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef SIMGEAR_ELEMENT_BUILDER_HXX
|
||||
#define SIMGEAR_ELEMENT_BUILDER_HXX 1
|
||||
|
||||
#include <simgear/xml/XMLStaticParser.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -5,11 +5,19 @@ lib_LIBRARIES = libsgmaterial.a
|
||||
noinst_HEADERS =
|
||||
|
||||
include_HEADERS = \
|
||||
Effect.hxx \
|
||||
EffectGeode.hxx \
|
||||
Pass.hxx \
|
||||
Technique.hxx \
|
||||
mat.hxx \
|
||||
matlib.hxx \
|
||||
matmodel.hxx
|
||||
|
||||
libsgmaterial_a_SOURCES = \
|
||||
Effect.cxx \
|
||||
EffectGeode.cxx \
|
||||
Pass.cxx \
|
||||
Technique.cxx \
|
||||
mat.cxx \
|
||||
matlib.cxx \
|
||||
matmodel.cxx
|
||||
|
||||
27
simgear/scene/material/Pass.cxx
Normal file
27
simgear/scene/material/Pass.cxx
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "Pass.hxx"
|
||||
|
||||
#include <simgear/structure/OSGUtils.hxx>
|
||||
|
||||
#include <osg/StateSet>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
Pass::Pass(const Pass& rhs, const osg::CopyOp& copyop) :
|
||||
_stateSet(clone_ref(rhs._stateSet, copyop))
|
||||
{
|
||||
}
|
||||
|
||||
void Pass::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
if (_stateSet.valid())
|
||||
_stateSet->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
void Pass::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
if (_stateSet.valid())
|
||||
_stateSet->releaseGLObjects(state);
|
||||
}
|
||||
|
||||
}
|
||||
48
simgear/scene/material/Pass.hxx
Normal file
48
simgear/scene/material/Pass.hxx
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_PASS_HXX
|
||||
#define SIMGEAR_PASS_HXX 1
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Object>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class StateSet;
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
class Pass : public osg::Object
|
||||
{
|
||||
public:
|
||||
META_Object(simgear,Pass);
|
||||
Pass() {}
|
||||
Pass(const Pass& rhs,
|
||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||
osg::StateSet* getStateSet() { return _stateSet.get(); }
|
||||
void setStateSet(osg::StateSet* stateSet) { _stateSet = stateSet; }
|
||||
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
||||
virtual void releaseGLObjects(osg::State* state = 0) const;
|
||||
protected:
|
||||
osg::ref_ptr<osg::StateSet> _stateSet;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
180
simgear/scene/material/Technique.cxx
Normal file
180
simgear/scene/material/Technique.cxx
Normal file
@@ -0,0 +1,180 @@
|
||||
#include "Technique.hxx"
|
||||
#include "Pass.hxx"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <osg/GLExtensions>
|
||||
#include <osg/Math>
|
||||
#include <osgUtil/CullVisitor>
|
||||
|
||||
#include <simgear/structure/OSGUtils.hxx>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
using namespace osg;
|
||||
using namespace osgUtil;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
struct ValidateOperation : GraphicsOperation
|
||||
{
|
||||
ValidateOperation(Technique* technique_)
|
||||
: GraphicsOperation(opName, false), technique(technique_)
|
||||
{
|
||||
}
|
||||
virtual void operator() (GraphicsContext* gc);
|
||||
osg::ref_ptr<Technique> technique;
|
||||
static const std::string opName;
|
||||
};
|
||||
|
||||
const std::string ValidateOperation::opName("ValidateOperation");
|
||||
|
||||
|
||||
void ValidateOperation::operator() (GraphicsContext* gc)
|
||||
{
|
||||
technique->validateInContext(gc);
|
||||
}
|
||||
}
|
||||
|
||||
Technique::Technique() : _glVersion(1.1f)
|
||||
{
|
||||
}
|
||||
|
||||
Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
|
||||
_contextMap(rhs._contextMap), _shadowingStateSet(rhs._shadowingStateSet),
|
||||
_glVersion(rhs._glVersion)
|
||||
{
|
||||
using namespace std;
|
||||
using namespace boost;
|
||||
transform(rhs.passes.begin(), rhs.passes.end(),
|
||||
backRefInsertIterator(passes),
|
||||
bind(simgear::clone_ref<Pass>, _1, copyop));
|
||||
|
||||
}
|
||||
|
||||
Technique::~Technique()
|
||||
{
|
||||
}
|
||||
|
||||
Technique::Status Technique::valid(osg::RenderInfo* renderInfo)
|
||||
{
|
||||
unsigned contextID = renderInfo->getContextID();
|
||||
ContextInfo& contextInfo = _contextMap[contextID];
|
||||
Status status = contextInfo.valid();
|
||||
if (status != UNKNOWN)
|
||||
return status;
|
||||
Status newStatus = QUERY_IN_PROGRESS;
|
||||
// lock and spawn validity check.
|
||||
if (!contextInfo.valid.compareAndSwap(status, newStatus)) {
|
||||
// Lost the race with another thread spawning a request
|
||||
return contextInfo.valid();
|
||||
}
|
||||
ref_ptr<ValidateOperation> validOp = new ValidateOperation(this);
|
||||
renderInfo->getState()->getGraphicsContext()->getGraphicsThread()
|
||||
->add(validOp.get());
|
||||
return newStatus;
|
||||
}
|
||||
|
||||
Technique::Status Technique::getValidStatus(const RenderInfo* renderInfo) const
|
||||
{
|
||||
ContextInfo& contextInfo = _contextMap[renderInfo->getContextID()];
|
||||
return contextInfo.valid();
|
||||
}
|
||||
|
||||
void Technique::validateInContext(GraphicsContext* gc)
|
||||
{
|
||||
ContextInfo& contextInfo = _contextMap[gc->getState()->getContextID()];
|
||||
Status oldVal = contextInfo.valid();
|
||||
Status newVal = INVALID;
|
||||
if (getGLVersionNumber() >= _glVersion)
|
||||
newVal = VALID;
|
||||
contextInfo.valid.compareAndSwap(oldVal, newVal);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
enum NumDrawables {NUM_DRAWABLES = 128};
|
||||
}
|
||||
|
||||
EffectGeode::DrawablesIterator
|
||||
Technique::processDrawables(const EffectGeode::DrawablesIterator& begin,
|
||||
const EffectGeode::DrawablesIterator& end,
|
||||
CullVisitor* cv,
|
||||
bool isCullingActive)
|
||||
{
|
||||
RefMatrix& matrix = *cv->getModelViewMatrix();
|
||||
float depth[NUM_DRAWABLES];
|
||||
EffectGeode::DrawablesIterator itr = begin;
|
||||
bool computeNearFar
|
||||
= cv->getComputeNearFarMode() != CullVisitor::DO_NOT_COMPUTE_NEAR_FAR;
|
||||
for (int i = 0; i < NUM_DRAWABLES && itr != end; ++itr, ++i) {
|
||||
Drawable* drawable = itr->get();
|
||||
const BoundingBox& bb = drawable->getBound();
|
||||
if ((drawable->getCullCallback()
|
||||
&& drawable->getCullCallback()->cull(cv, drawable,
|
||||
&cv->getRenderInfo()))
|
||||
|| (isCullingActive && cv->isCulled(bb))) {
|
||||
depth[i] = FLT_MAX;
|
||||
continue;
|
||||
}
|
||||
if (computeNearFar && bb.valid()) {
|
||||
if (!cv->updateCalculatedNearFar(matrix, *drawable, false)) {
|
||||
depth[i] = FLT_MAX;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
depth[i] = (bb.valid()
|
||||
? cv->getDistanceFromEyePoint(bb.center(), false)
|
||||
: 0.0f);
|
||||
if (isNaN(depth[i]))
|
||||
depth[i] = FLT_MAX;
|
||||
}
|
||||
EffectGeode::DrawablesIterator drawablesEnd = itr;
|
||||
BOOST_FOREACH(ref_ptr<Pass>& pass, passes)
|
||||
{
|
||||
cv->pushStateSet(pass->getStateSet());
|
||||
int i = 0;
|
||||
for (itr = begin; itr != drawablesEnd; ++itr, ++i) {
|
||||
if (depth[i] != FLT_MAX)
|
||||
cv->addDrawableAndDepth(itr->get(), &matrix, depth[i]);
|
||||
}
|
||||
cv->popStateSet();
|
||||
}
|
||||
return drawablesEnd;
|
||||
}
|
||||
|
||||
void Technique::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
if (_shadowingStateSet.valid())
|
||||
_shadowingStateSet->resizeGLObjectBuffers(maxSize);
|
||||
BOOST_FOREACH(ref_ptr<Pass>& pass, passes) {
|
||||
pass->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
_contextMap.resize(maxSize);
|
||||
}
|
||||
|
||||
void Technique::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
if (_shadowingStateSet.valid())
|
||||
_shadowingStateSet->releaseGLObjects(state);
|
||||
BOOST_FOREACH(const ref_ptr<Pass>& pass, passes)
|
||||
{
|
||||
pass->releaseGLObjects(state);
|
||||
}
|
||||
if (state == 0) {
|
||||
for (int i = 0; i < _contextMap.size(); ++i) {
|
||||
ContextInfo& info = _contextMap[i];
|
||||
Status oldVal = info.valid();
|
||||
info.valid.compareAndSwap(oldVal, UNKNOWN);
|
||||
}
|
||||
} else {
|
||||
ContextInfo& info = _contextMap[state->getContextID()];
|
||||
Status oldVal = info.valid();
|
||||
info.valid.compareAndSwap(oldVal, UNKNOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
112
simgear/scene/material/Technique.hxx
Normal file
112
simgear/scene/material/Technique.hxx
Normal file
@@ -0,0 +1,112 @@
|
||||
// Copyright (C) 2008 Timothy Moore timoore@redhat.com
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program 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
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_TECHNIQUE_HXX
|
||||
#define SIMGEAR_TECHNIQUE_HXX 1
|
||||
|
||||
#include "EffectGeode.hxx"
|
||||
|
||||
#include <simgear/structure/SGAtomic.hxx>
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
#include <osg/buffered_value>
|
||||
#include <osg/Geode>
|
||||
#include <osg/Object>
|
||||
#include <osg/GraphicsThread>
|
||||
|
||||
namespace osg
|
||||
{
|
||||
class CopyOp;
|
||||
class Drawable;
|
||||
class RenderInfo;
|
||||
class StateSet;
|
||||
}
|
||||
|
||||
namespace osgUtil
|
||||
{
|
||||
class CullVisitor;
|
||||
}
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class Pass;
|
||||
|
||||
class Technique : public osg::Object
|
||||
{
|
||||
public:
|
||||
META_Object(simgear,Technique);
|
||||
Technique();
|
||||
Technique(const Technique& rhs,
|
||||
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
|
||||
virtual ~Technique();
|
||||
enum Status
|
||||
{
|
||||
UNKNOWN,
|
||||
QUERY_IN_PROGRESS,
|
||||
INVALID,
|
||||
VALID
|
||||
};
|
||||
/** Returns the validity of a technique in a state. If we don't
|
||||
* know, a query will be launched.
|
||||
*/
|
||||
virtual Status valid(osg::RenderInfo* renderInfo);
|
||||
/** Returns the validity of the technique without launching a
|
||||
* query.
|
||||
*/
|
||||
Status getValidStatus(const osg::RenderInfo* renderInfo) const;
|
||||
/** Tests and sets the validity of the Technique. Must be run in a
|
||||
*graphics context.
|
||||
*/
|
||||
virtual void validateInContext(osg::GraphicsContext* gc);
|
||||
|
||||
virtual EffectGeode::DrawablesIterator
|
||||
processDrawables(const EffectGeode::DrawablesIterator& begin,
|
||||
const EffectGeode::DrawablesIterator& end,
|
||||
osgUtil::CullVisitor* cv,
|
||||
bool isCullingActive);
|
||||
std::vector<osg::ref_ptr<Pass> > passes;
|
||||
osg::StateSet* getShadowingStateSet() { return _shadowingStateSet.get(); }
|
||||
void setShadowingStateSet(osg::StateSet* ss) { _shadowingStateSet = ss; }
|
||||
virtual void resizeGLObjectBuffers(unsigned int maxSize);
|
||||
virtual void releaseGLObjects(osg::State* state = 0) const;
|
||||
// Initial validity testing. Either the minimum OpenGL version
|
||||
// must be supported, or the list of extensions must be supported.
|
||||
float getGLVersion() { return _glVersion; }
|
||||
void setGLVersion(float glVersion) { _glVersion = glVersion; }
|
||||
std::vector<std::string> glExtensions;
|
||||
protected:
|
||||
// Validity of technique in a graphics context.
|
||||
struct ContextInfo : public osg::Referenced
|
||||
{
|
||||
ContextInfo() : valid(UNKNOWN) {}
|
||||
ContextInfo(const ContextInfo& rhs) : valid(rhs.valid()) {}
|
||||
ContextInfo& operator=(const ContextInfo& rhs)
|
||||
{
|
||||
valid = rhs.valid();
|
||||
}
|
||||
Swappable<Status> valid;
|
||||
};
|
||||
typedef osg::buffered_object<ContextInfo> ContextMap;
|
||||
mutable ContextMap _contextMap;
|
||||
osg::ref_ptr<osg::StateSet> _shadowingStateSet;
|
||||
float _glVersion;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@@ -113,4 +113,86 @@ private:
|
||||
unsigned mValue;
|
||||
};
|
||||
|
||||
// Value that can be atomically compared and swapped.
|
||||
class SGSwappable
|
||||
{
|
||||
public:
|
||||
typedef unsigned long value_type;
|
||||
SGSwappable(unsigned long value = 0) : mValue(value) {}
|
||||
operator unsigned long() const
|
||||
{
|
||||
#if defined(SGATOMIC_USE_GCC4_BUILTINS)
|
||||
__sync_synchronize();
|
||||
return mValue;
|
||||
#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
|
||||
__synchronize();
|
||||
return mValue;
|
||||
#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
|
||||
return static_cast<long const volatile &>(mValue);
|
||||
#else
|
||||
SGGuard<SGMutex> lock(mMutex);
|
||||
return mValue;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool compareAndSwap(unsigned long oldVal, unsigned long newVal)
|
||||
{
|
||||
#if defined(SGATOMIC_USE_GCC4_BUILTINS)
|
||||
return __sync_bool_compare_and_swap(&mValue, oldVal, newVal);
|
||||
#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
|
||||
return __compare_and_swap(&mValue, oldVal, newVal);
|
||||
#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED)
|
||||
long previous
|
||||
= InterlockedCompareExchange(reinterpret_cast<long volatile*>(&mValue),
|
||||
(long)newVal,
|
||||
(long)oldVal);
|
||||
return previous == (long)oldVal;
|
||||
#else
|
||||
SGGuard<SGMutex> lock(mMutex);
|
||||
if (oldVal == mValue) {
|
||||
mValue = newVal;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
SGSwappable(const SGAtomic&);
|
||||
SGSwappable& operator=(const SGAtomic&);
|
||||
|
||||
#if !defined(SGATOMIC_USE_GCC4_BUILTINS) \
|
||||
&& !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \
|
||||
&& !defined(SGATOMIC_USE_WIN32_INTERLOCKED)
|
||||
mutable SGMutex mMutex;
|
||||
#endif
|
||||
#ifdef SGATOMIC_USE_WIN32_INTERLOCKED
|
||||
__declspec(align(32))
|
||||
#endif
|
||||
value_type mValue;
|
||||
|
||||
};
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
// Typesafe wrapper around SGSwappable
|
||||
template <typename T>
|
||||
class Swappable : private SGSwappable
|
||||
{
|
||||
public:
|
||||
Swappable(const T& value) : SGSwappable(static_cast<value_type>(value))
|
||||
{
|
||||
}
|
||||
T operator() () const
|
||||
{
|
||||
return static_cast<T>(SGSwappable::operator unsigned long ());
|
||||
}
|
||||
bool compareAndSwap(const T& oldVal, const T& newVal)
|
||||
{
|
||||
return SGSwappable::compareAndSwap(static_cast<value_type>(oldVal),
|
||||
static_cast<value_type>(newVal));
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
126
simgear/xml/XMLStaticParser.hxx
Normal file
126
simgear/xml/XMLStaticParser.hxx
Normal file
@@ -0,0 +1,126 @@
|
||||
// Template for defining an XML parser based on an element type and
|
||||
// builder classes
|
||||
|
||||
#ifndef SIMGEAR_XMLSTATICPARSER_HXX
|
||||
#define SIMGEAR_XMLSTATICPARSER_HXX 1
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <stack>
|
||||
#include <auto_ptr>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Referenced>
|
||||
|
||||
#include "easyxml.hxx"
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
|
||||
template <typename Element> class XMLStaticParser;
|
||||
|
||||
// Parser object. Instantiated for each new element encountered.
|
||||
|
||||
template<typename Element>
|
||||
struct ElementBuilder : public osg::Referenced
|
||||
{
|
||||
ElementBuilder(XMLStaticParser<Element>* builder) {}
|
||||
ElementBuilder(const ElementBuilder& rhs) const {}
|
||||
virtual ~ElementBuilder() {}
|
||||
virtual void initialize(const XMLAttributes& attributes) = 0;
|
||||
virtual void processSubElement(Element* subElement) = 0;
|
||||
virtual void processData(const char* data, int length) = 0;
|
||||
virtual Element* finalize() = 0;
|
||||
// Create element parser from prototype
|
||||
virtual ElementBuilder* clone() const = 0;
|
||||
};
|
||||
|
||||
template<typename Element>
|
||||
struct BuilderFactory : public osg::Referenced
|
||||
{
|
||||
typedef ElementBuilder<Element> builder_type;
|
||||
typedef std::map<std::string, osg::ref_ptr<const ElementBuilder> >
|
||||
BuilderMap;
|
||||
BuilderMap builderMap;
|
||||
~virtual BuilderFactory() {}
|
||||
static void registerBuilder(const std::string& name,
|
||||
const builder_type* prototype)
|
||||
{
|
||||
if (!builderFactory.valid())
|
||||
builderFactory = new BuilderFactory;
|
||||
builderFactory->builderMap[name] = prototype;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Element>
|
||||
class XMLStaticParser : public XMLVisitor
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
static osg::ref_ptr<BuilderFactory> builderFactory;
|
||||
|
||||
|
||||
|
||||
static ElementBuilder* makeBuilder(const std::string& name)
|
||||
{
|
||||
BuilderMap::iterator iter = builderFactory->builderMap.find(name);
|
||||
if (iter == builderFactory->builderMap.end())
|
||||
return 0;
|
||||
return iter->second->clone();
|
||||
}
|
||||
|
||||
typedef std::stack<osg::ref_ptr<ElementBuilder> > BuilderStack;
|
||||
BuilderStack builderStack;
|
||||
|
||||
Element* result;
|
||||
|
||||
XMLStaticParser() : result(0) {}
|
||||
virtual ~XMLStaticParser() {}
|
||||
|
||||
virtual void startXML()
|
||||
{
|
||||
builderStack.push(makeBuilder(""));
|
||||
}
|
||||
|
||||
virtual void endXML()
|
||||
{
|
||||
// Stack should have only the initial builder
|
||||
result = builderStack.top()->finalize();
|
||||
}
|
||||
|
||||
virtual void startElement(const char* name, const XMLAttributes& atts)
|
||||
{
|
||||
ElementBuilder* builder = makeBuilder(name);
|
||||
if (builder) {
|
||||
builderStack.push(builder);
|
||||
builder->initialize(atts);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void endElement(const char* name)
|
||||
{
|
||||
Element* result = builderStack.top()->finalize();
|
||||
builderStack.pop();
|
||||
if (!builderStack.empty())
|
||||
builderStack.top()->processSubElement(result);
|
||||
}
|
||||
|
||||
virtual void data(const char* s, int length)
|
||||
{
|
||||
builderStack.top()->processData(s, length);
|
||||
}
|
||||
|
||||
struct RegisterBuilderProxy
|
||||
{
|
||||
RegisterBuilderProxy(const char* name, ElementBuilder* builder)
|
||||
{
|
||||
registerBuilder(name, builder);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template <typename E>
|
||||
static osg::ref_ptr<BuilderFactory<E> > builderFactory;
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user