OpenSceneGraph/examples/osgsimpleviewerProducer/osgsimpleviewerProducer.cpp
2006-12-20 21:13:29 +00:00

244 lines
8.2 KiB
C++

// C++ source file - (C) 2003 Robert Osfield, released under the OSGPL.
//
// Simple example of use of Producer::RenderSurface + KeyboardMouseCallback + SimpleViewer
#include <Producer/RenderSurface>
#include <Producer/KeyboardMouse>
#include <Producer/Trackball>
#include <osgDB/ReadFile>
#include <osgViewer/SimpleViewer>
#include <osgGA/TrackballManipulator>
#include <osgGA/StateSetManipulator>
// ----------- Begining of glue classes to adapter Producer's keyboard mouse events to osgGA's abstraction events.
class MyKeyboardMouseCallback : public Producer::KeyboardMouseCallback
{
public:
MyKeyboardMouseCallback(osgGA::EventQueue* eventQueue) :
_done(false),
_eventQueue(eventQueue)
{
}
virtual void shutdown()
{
_done = true;
}
virtual void specialKeyPress( Producer::KeyCharacter key )
{
if (key==Producer::KeyChar_Escape)
shutdown();
_eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
}
virtual void specialKeyRelease( Producer::KeyCharacter key )
{
_eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
}
virtual void keyPress( Producer::KeyCharacter key)
{
_eventQueue->keyPress( (osgGA::GUIEventAdapter::KeySymbol) key );
}
virtual void keyRelease( Producer::KeyCharacter key)
{
_eventQueue->keyRelease( (osgGA::GUIEventAdapter::KeySymbol) key );
}
virtual void mouseMotion( float mx, float my )
{
_eventQueue->mouseMotion( mx, my );
}
virtual void buttonPress( float mx, float my, unsigned int mbutton )
{
_eventQueue->mouseButtonPress(mx, my, mbutton);
}
virtual void buttonRelease( float mx, float my, unsigned int mbutton )
{
_eventQueue->mouseButtonRelease(mx, my, mbutton);
}
bool done() { return _done; }
private:
bool _done;
osg::ref_ptr<osgGA::EventQueue> _eventQueue;
};
#if 1
// first approach uses a custom GraphicsWindow
// then uses multiple inheritance to create a SimpleViewerWindowProducer
class GraphicsWindowProducer : public virtual osgViewer::GraphicsWindow, public Producer::RenderSurface
{
public:
GraphicsWindowProducer()
{
// create a KeyboardMouseCallback to handle the mouse events within this applications
_kbmcb = new MyKeyboardMouseCallback(getEventQueue());
// set up a KeyboardMouse to manage the events comming in from the RenderSurface
_kbm = new Producer::KeyboardMouse(this);
_kbm->setCallback(_kbmcb.get());
// set the mouse input range.
// Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
getEventQueue()->setUseFixedMouseInputRange(true);
getEventQueue()->setMouseInputRange(-1.0, -1.0, 1.0, 1.0);
// Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits.
// we need to construct the event queue so that it knows about this convention.
getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
}
void setWindowRectangle(int x, int y, unsigned int width, unsigned int height, bool resize = true)
{
Producer::RenderSurface::setWindowRectangle(x, y, width, height, resize);
getEventQueue()->windowResize(x,y,width,height);
}
void realize() { Producer::RenderSurface::realize(); _kbm->startThread(); }
bool isRealized() const { return Producer::RenderSurface::isRealized(); }
void swapBuffers() { return Producer::RenderSurface::swapBuffers(); }
protected:
osg::ref_ptr<Producer::KeyboardMouse> _kbm;
osg::ref_ptr<MyKeyboardMouseCallback> _kbmcb;
};
class SimplerViewerProducer : public osgViewer::SimpleViewer, public GraphicsWindowProducer
{
public:
SimplerViewerProducer() {}
};
int main( int argc, char **argv )
{
if (argc<2)
{
std::cout << argv[0] <<": requires filename argument." << std::endl;
return 1;
}
// load the scene.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
if (!loadedModel)
{
std::cout << argv[0] <<": No data loaded." << std::endl;
return 1;
}
// create the window to draw to.
SimplerViewerProducer viewer;
viewer.setWindowName("osgkeyboardmouse");
viewer.setWindowRectangle(100,100,800,600);
viewer.useBorder(true);
viewer.realize();
// create the view of the scene.
viewer.setSceneData(loadedModel.get());
// create a tracball manipulator to move the camera around in response to keyboard/mouse events
viewer.setCameraManipulator( new osgGA::TrackballManipulator );
// main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
while( viewer.isRealized() )
{
// update the window dimensions, in case the window has been resized.
viewer.getEventQueue()->windowResize(0,0,viewer.getWindowWidth(),viewer.getWindowHeight());
viewer.frame();
// Swap Buffers
viewer.swapBuffers();
}
return 0;
}
#else
// Second approach is to leave Producer and SimpleViewer decoupled, with the integration done mannually in the main loop
int main( int argc, char **argv )
{
if (argc<2)
{
std::cout << argv[0] <<": requires filename argument." << std::endl;
return 1;
}
// load the scene.
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(argv[1]);
if (!loadedModel)
{
std::cout << argv[0] <<": No data loaded." << std::endl;
return 1;
}
// create the window to draw to.
osg::ref_ptr<Producer::RenderSurface> renderSurface = new Producer::RenderSurface;
renderSurface->setWindowName("osgkeyboardmouse");
renderSurface->setWindowRectangle(100,100,800,600);
renderSurface->useBorder(true);
renderSurface->realize();
// create the view of the scene.
osgViewer::SimpleViewer viewer;
viewer.setSceneData(loadedModel.get());
// set up a KeyboardMouse to manage the events comming in from the RenderSurface
osg::ref_ptr<Producer::KeyboardMouse> kbm = new Producer::KeyboardMouse(renderSurface.get());
// create a KeyboardMouseCallback to handle the mouse events within this applications
osg::ref_ptr<MyKeyboardMouseCallback> kbmcb = new MyKeyboardMouseCallback(viewer.getEventQueue());
// create a tracball manipulator to move the camera around in response to keyboard/mouse events
viewer.setCameraManipulator( new osgGA::TrackballManipulator );
// set the window dimensions
viewer.getEventQueue()->getCurrentEventState()->setWindowRectangle(100,100,800,600);
// set the mouse input range.
// Producer defaults to using non-dimensional units, so we pass this onto osgGA, most windowing toolkits use pixel coords so use the window size instead.
viewer.getEventQueue()->setUseFixedMouseInputRange(true);
viewer.getEventQueue()->setMouseInputRange(-1.0, -1.0, 1.0, 1.0);
// Producer has the y axis increase upwards, like OpenGL, and contary to most Windowing toolkits.
// we need to construct the event queue so that it knows about this convention.
viewer.getEventQueue()->getCurrentEventState()->setMouseYOrientation(osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS);
// main loop (note, window toolkits which take control over the main loop will require a window redraw callback containing the code below.)
while( renderSurface->isRealized() && !kbmcb->done())
{
// update the window dimensions, in case the window has been resized.
viewer.getEventQueue()->windowResize(0,0,renderSurface->getWindowWidth(),renderSurface->getWindowHeight(), false);
// pass any keyboard mouse events onto the local keyboard mouse callback.
kbm->update( *kbmcb );
viewer.frame();
// Swap Buffers
renderSurface->swapBuffers();
}
return 0;
}
#endif