This example plugin creates a new driver that demonstrates how to use OpenGL draw calls from a subclass of osg::Drawable that gets added to the normalized 2D camera of all DtOsgChannels.
Make a DtReticleDrawable which is subclassed from osg::Drawable:
class DtReticleDrawable : public osg::Drawable
Override drawImplementation to make some OpenGL calls:
virtual void drawImplementation(osg::RenderInfo& state) const
{
osg::Viewport* viewport = state.getCurrentCamera()->getViewport();
if (!viewport)
{
return;
}
int width = viewport->width();
int height = viewport->height();
float aspect = viewport->width() / viewport->height();
if (width >= height)
{
gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
}
else
{
gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
}
int lineWidth = 10;
if ((width * .01) < lineWidth)
{
lineWidth = width * .01;
}
float radius = 0.5;
float centerX = 0.0;
float centerY = 0.0;
for (int i=0; i < 360; i++)
{
float radians = i * M_DEG2RAD;
centerY + sin(radians)*radius);
}
Instantiate a DtReticleDrawable when the driver starts up and put it into an osg::Geode so it can be added to cameras:
virtual bool onStart()
{
myReticle = new DtReticleDrawable();
myReticleGeode = new osg::Geode();
myReticleGeode->setName("Reticle Geode");
myReticleGeode->addDrawable(myReticle);
Next make sure it's added to all the current channels:
DtWindowManager::WindowList wins =
myAgentManager.de().display()->windowManager().windows();
DtWindowManager::WindowList::iterator winIter = wins.begin();
for(winIter; winIter != wins.end(); ++winIter)
{
DtChannelManager::ChannelMap channels =
(*winIter)->channelManager().channels();
DtChannelManager::ChannelMap::iterator chanIter=channels.begin();
for(chanIter; chanIter!=channels.end(); ++chanIter)
{
DtOsgChannel* osgChannel =
dynamic_cast<DtOsgChannel*>(chanIter->second);
if (osgChannel)
{
osgChannel->normalizedOverlayCamera()->addChild(myReticleGeode);
}
}
}
To get the reticle geode added to any new channels, hook up signal_channelCreated from the drivers constructor:
mySignalConnections += DtChannelManagerSignaler::instance(
myAgentManager.de()).signal_channelCreated.connect(
boost::bind(&DtExampleGLDrawingDriver::slot_channelCreated,
this,
_1, _2));
And then add it from the callback:
void slot_channelCreated(DtChannelManager* mgr, DtChannel* channel)
{
DtOsgChannel* osgChannel = dynamic_cast<DtOsgChannel*>(channel);
if (!osgChannel || !myReticleGeode)
{
return;
}
osgChannel->normalizedOverlayCamera()->addChild(myReticleGeode);
Building the Example
VR-Vantage includes pre-built versions of the example plug-in. To build it yourself, follow the instructions at Building VR-Vantage Examples, Applications, and Plug-ins.
Running the Example
This example is a plug-in. You can run it by running ./bin/exampleGLDrawingPlugin_stealth.bat (on Windows) or ./bin/exampleGLDrawingPlugin_stealth.sh (on Linux). For more information about running examples, please see Running Applications and Examples.
Example Source Files
exampleGLDrawingPlugin.cxx
#ifdef _WIN32
#ifdef EXAMPLEGLDRAWINGPLUGIN_EXPORTS
#define DT_DLL_EXAMPLEGLDRAWINGPLUGIN __declspec ( dllexport )
#else
#define DT_DLL_EXAMPLEGLDRAWINGPLUGIN __declspec ( dllimport )
#endif
#else
#define DT_DLL_EXAMPLEGLDRAWINGPLUGIN
#endif
#define DT_DE_PLUGIN_EXPORT_MACRO DT_DLL_EXAMPLEGLDRAWINGPLUGIN
#include <matrix/vlMath.h>
#include <osg/Drawable>
#include <osg/Geode>
#include <GL/gl.h>
#include <GL/glu.h>
#include <boost/bind.hpp>
using namespace makVrv;
class DtReticleDrawable : public osg::Drawable
{
public:
DtReticleDrawable()
{
setSupportsDisplayList(false);
setUseDisplayList(false);
};
DtReticleDrawable(const DtReticleDrawable& reticle,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY) :
{
setSupportsDisplayList(false);
setUseDisplayList(false);
}
virtual ~DtReticleDrawable()
{
};
META_Object(test, DtReticleDrawable)
virtual void drawImplementation(osg::RenderInfo& state) const
{
osg::Viewport* viewport = state.getCurrentCamera()->getViewport();
if (!viewport)
{
return;
}
int width = viewport->width();
int height = viewport->height();
float aspect = viewport->width() / viewport->height();
if (width >= height)
{
gluOrtho2D(-1.0 * aspect, 1.0 * aspect, -1.0, 1.0);
}
else
{
gluOrtho2D(-1.0, 1.0, -1.0 / aspect, 1.0 / aspect);
}
int lineWidth = 10;
if ((width * .01) < lineWidth)
{
lineWidth = width * .01;
}
float radius = 0.5;
float centerX = 0.0;
float centerY = 0.0;
for (int i=0; i < 360; i++)
{
float radians = i * M_DEG2RAD;
centerY + sin(radians)*radius);
}
float extra = 0.06;
}
};
{
public:
: makVrv::
DtDriver( am,
"DtExampleGLDrawingDriver" )
{
myAgentManager.de()).signal_channelCreated.connect(
boost::bind(&DtExampleGLDrawingDriver::slot_channelCreated,
this,
_1, _2));
}
virtual ~DtExampleGLDrawingDriver()
{
}
{
}
{
if (!osgChannel || !myReticleGeode)
{
return;
}
}
virtual bool onStart()
{
myReticle = new DtReticleDrawable();
myReticleGeode = new osg::Geode();
myReticleGeode->setName("Reticle Geode");
myReticleGeode->addDrawable(myReticle);
myAgentManager.de().display()->windowManager().windows();
DtWindowManager::WindowList::iterator winIter = wins.begin();
for(winIter; winIter != wins.end(); ++winIter)
{
(*winIter)->channelManager().channels();
DtChannelManager::ChannelMap::iterator chanIter=channels.begin();
for(chanIter; chanIter!=channels.end(); ++chanIter)
{
if (osgChannel)
{
}
}
}
return true;
}
virtual bool onStop()
{
return true;
}
virtual bool onTick()
{
return true;
}
protected:
osg::ref_ptr<DtReticleDrawable> myReticle;
osg::ref_ptr<osg::Geode> myReticleGeode;
};
{
DtExampleGLDrawingDriver* driver =
}
{
{
}
}
{
return true;
}