6a67be2e32
forcing users to use osgDB::readRef*File() methods. The later is preferable as it closes a potential threading bug when using paging databases in conjunction with the osgDB::Registry Object Cache. This threading bug occurs when one thread gets an object from the Cache via an osgDB::read*File() call where only a pointer to the object is passed back, so taking a reference to the object is delayed till it gets reassigned to a ref_ptr<>, but at the same time another thread calls a flush of the Object Cache deleting this object as it's referenceCount is now zero. Using osgDB::readREf*File() makes sure the a ref_ptr<> is passed back and the referenceCount never goes to zero. To ensure the OSG builds when OSG_PROVIDE_READFILE is to OFF the many cases of osgDB::read*File() usage had to be replaced with a ref_ptr<> osgDB::readRef*File() usage. The avoid this change causing lots of other client code to be rewritten to handle the use of ref_ptr<> in place of C pointer I introduced a serious of templte methods in various class to adapt ref_ptr<> to the underly C pointer to be passed to old OSG API's, example of this is found in include/osg/Group: bool addChild(Node* child); // old method which can only be used with a Node* tempalte<class T> bool addChild(const osg::ref_ptr<T>& child) { return addChild(child.get()); } // adapter template method These changes together cover 149 modified files, so it's a large submission. This extent of changes are warrent to make use of the Object Cache and multi-threaded loaded more robust. git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/branches/OpenSceneGraph-3.4@15165 16af8721-9629-0410-8352-f15c8da7e697
90 lines
3.0 KiB
C++
90 lines
3.0 KiB
C++
// -*-c++-*-
|
|
|
|
/*
|
|
* Draw an outline around a model.
|
|
*/
|
|
|
|
#include <osg/Group>
|
|
#include <osg/PositionAttitudeTransform>
|
|
|
|
#include <osgDB/ReadFile>
|
|
#include <osgViewer/Viewer>
|
|
|
|
#include <osgFX/Outline>
|
|
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
osg::ArgumentParser arguments(&argc,argv);
|
|
arguments.getApplicationUsage()->setCommandLineUsage(arguments.getApplicationName()+" [options] <file>");
|
|
arguments.getApplicationUsage()->addCommandLineOption("--testOcclusion","Test occlusion by other objects");
|
|
arguments.getApplicationUsage()->addCommandLineOption("-h or --help","Display this information");
|
|
|
|
bool testOcclusion = false;
|
|
while (arguments.read("--testOcclusion")) { testOcclusion = true; }
|
|
|
|
// load outlined object
|
|
std::string modelFilename = arguments.argc() > 1 ? arguments[1] : "dumptruck.osgt";
|
|
osg::ref_ptr<osg::Node> outlineModel = osgDB::readRefNodeFile(modelFilename);
|
|
if (!outlineModel)
|
|
{
|
|
osg::notify(osg::FATAL) << "Unable to load model '" << modelFilename << "'\n";
|
|
return -1;
|
|
}
|
|
|
|
// create scene
|
|
osg::ref_ptr<osg::Group> root = new osg::Group;
|
|
|
|
{
|
|
// create outline effect
|
|
osg::ref_ptr<osgFX::Outline> outline = new osgFX::Outline;
|
|
root->addChild(outline);
|
|
|
|
outline->setWidth(8);
|
|
outline->setColor(osg::Vec4(1,1,0,1));
|
|
outline->addChild(outlineModel);
|
|
}
|
|
|
|
if (testOcclusion)
|
|
{
|
|
// load occluder
|
|
std::string occludedModelFilename = "cow.osgt";
|
|
osg::ref_ptr<osg::Node> occludedModel = osgDB::readRefNodeFile(occludedModelFilename);
|
|
if (!occludedModel)
|
|
{
|
|
osg::notify(osg::FATAL) << "Unable to load model '" << occludedModelFilename << "'\n";
|
|
return -1;
|
|
}
|
|
|
|
// occluder offset
|
|
const osg::BoundingSphere& bsphere = outlineModel->getBound();
|
|
const osg::Vec3 occluderOffset = osg::Vec3(0,1,0) * bsphere.radius() * 1.2f;
|
|
|
|
// occluder behind outlined model
|
|
osg::ref_ptr<osg::PositionAttitudeTransform> modelTransform0 = new osg::PositionAttitudeTransform;
|
|
modelTransform0->setPosition(bsphere.center() + occluderOffset);
|
|
modelTransform0->addChild(occludedModel);
|
|
root->addChild(modelTransform0);
|
|
|
|
// occluder in front of outlined model
|
|
osg::ref_ptr<osg::PositionAttitudeTransform> modelTransform1 = new osg::PositionAttitudeTransform;
|
|
modelTransform1->setPosition(bsphere.center() - occluderOffset);
|
|
modelTransform1->addChild(occludedModel);
|
|
root->addChild(modelTransform1);
|
|
}
|
|
|
|
// must have stencil buffer...
|
|
osg::DisplaySettings::instance()->setMinimumNumStencilBits(1);
|
|
|
|
// construct the viewer
|
|
osgViewer::Viewer viewer;
|
|
viewer.setSceneData(root);
|
|
|
|
// must clear stencil buffer...
|
|
unsigned int clearMask = viewer.getCamera()->getClearMask();
|
|
viewer.getCamera()->setClearMask(clearMask | GL_STENCIL_BUFFER_BIT);
|
|
viewer.getCamera()->setClearStencil(0);
|
|
|
|
return viewer.run();
|
|
}
|