#include <stdlib.h>
+// Boost
+#include <boost/algorithm/string/case_conv.hpp>
#include <boost/foreach.hpp>
#include <simgear/compiler.h>
using namespace flightgear;
using namespace osg;
-static osg::ref_ptr<osgViewer::Viewer> viewer;
-static osg::ref_ptr<osg::Camera> mainCamera;
+osg::ref_ptr<osgViewer::Viewer> viewer;
static void setStereoMode( const char * mode )
{
virtual void notify(osg::NotifySeverity severity, const char *message)
{
SG_LOG(SG_GL, translateSeverity(severity), message);
+
+ // Detect whether a osg::Reference derived object is deleted with a non-zero
+ // reference count. In this case trigger a segfault to get a stack trace.
+ if( strstr(message, "the final reference count was") )
+ {
+
+ int* trigger_segfault = 0;
+ *trigger_segfault = 0;
+ }
}
private:
}
};
+class NotifyLevelListener : public SGPropertyChangeListener
+{
+public:
+ void valueChanged(SGPropertyNode* node)
+ {
+ osg::NotifySeverity severity = osg::WARN;
+ string val = boost::to_lower_copy(string(node->getStringValue()));
+
+ if (val == "fatal") {
+ severity = osg::FATAL;
+ } else if (val == "warn") {
+ severity = osg::WARN;
+ } else if (val == "notice") {
+ severity = osg::NOTICE;
+ } else if (val == "info") {
+ severity = osg::INFO;
+ } else if ((val == "debug") || (val == "debug-info")) {
+ severity = osg::DEBUG_INFO;
+ }
+
+ osg::setNotifyLevel(severity);
+ }
+};
+
+void updateOSGNotifyLevel()
+{
+ }
+
void fgOSOpenWindow(bool stencil)
{
osg::setNotifyHandler(new NotifyLogger);
- //osg::setNotifyLevel(osg::DEBUG_INFO);
-
+
viewer = new osgViewer::Viewer;
viewer->setDatabasePager(FGScenery::getPagerSingleton());
- CameraGroup* cameraGroup = 0;
+
std::string mode;
mode = fgGetString("/sim/rendering/multithreading-mode", "SingleThreaded");
if (mode == "AutomaticSelection")
else
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
WindowBuilder::initWindowBuilder(stencil);
- WindowBuilder *windowBuilder = WindowBuilder::getWindowBuilder();
-
- // Look for windows, camera groups, and the old syntax of
- // top-level cameras
- SGPropertyNode* renderingNode = fgGetNode("/sim/rendering");
- SGPropertyNode* cgroupNode = renderingNode->getNode("camera-group", true);
- bool oldSyntax = !cgroupNode->hasChild("camera");
- if (oldSyntax) {
- for (int i = 0; i < renderingNode->nChildren(); ++i) {
- SGPropertyNode* propNode = renderingNode->getChild(i);
- const char* propName = propNode->getName();
- if (!strcmp(propName, "window") || !strcmp(propName, "camera")) {
- SGPropertyNode* copiedNode
- = cgroupNode->getNode(propName, propNode->getIndex(), true);
- copyProperties(propNode, copiedNode);
- }
- }
- vector<SGPropertyNode_ptr> cameras = cgroupNode->getChildren("camera");
- SGPropertyNode* masterCamera = 0;
- BOOST_FOREACH(SGPropertyNode_ptr& camera, cameras) {
- if (camera->getDoubleValue("shear-x", 0.0) == 0.0
- && camera->getDoubleValue("shear-y", 0.0) == 0.0) {
- masterCamera = camera.ptr();
- break;
- }
- }
- if (!masterCamera) {
- masterCamera = cgroupNode->getChild("camera", cameras.size(), true);
- setValue(masterCamera->getNode("window/name", true),
- windowBuilder->getDefaultWindowName());
- }
- SGPropertyNode* nameNode = masterCamera->getNode("window/name");
- if (nameNode)
- setValue(cgroupNode->getNode("gui/window/name", true),
- nameNode->getStringValue());
- }
- cameraGroup = CameraGroup::buildCameraGroup(viewer.get(), cgroupNode);
- Camera* guiCamera = getGUICamera(cameraGroup);
- if (guiCamera) {
- Viewport* guiViewport = guiCamera->getViewport();
- fgSetInt("/sim/startup/xsize", guiViewport->width());
- fgSetInt("/sim/startup/ysize", guiViewport->height());
- }
+ CameraGroup::buildDefaultGroup(viewer.get());
+
FGEventHandler* manipulator = globals->get_renderer()->getEventHandler();
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
if (wsa->windows.size() != 1) {
// The viewer won't start without some root.
viewer->setSceneData(new osg::Group);
globals->get_renderer()->setViewer(viewer.get());
- CameraGroup::setDefault(cameraGroup);
+}
+void fgOSResetProperties()
+{
+ SGPropertyNode* osgLevel = fgGetNode("/sim/rendering/osg-notify-level", true);
+ NotifyLevelListener* l = new NotifyLevelListener;
+ globals->addListenerToCleanup(l);
+ osgLevel->addChangeListener(l, true);
+
+ osg::Camera* guiCamera = getGUICamera(CameraGroup::getDefault());
+ if (guiCamera) {
+ Viewport* guiViewport = guiCamera->getViewport();
+ fgSetInt("/sim/startup/xsize", guiViewport->width());
+ fgSetInt("/sim/startup/ysize", guiViewport->height());
+ }
+
DisplaySettings * displaySettings = DisplaySettings::instance();
fgTie("/sim/rendering/osg-displaysettings/eye-separation", displaySettings, &DisplaySettings::getEyeSeparation, &DisplaySettings::setEyeSeparation );
fgTie("/sim/rendering/osg-displaysettings/screen-distance", displaySettings, &DisplaySettings::getScreenDistance, &DisplaySettings::setScreenDistance );
viewer->setDone(true);
viewer->getDatabasePager()->cancel();
status = code;
+
+ // otherwise we crash if OSG does logging during static destruction, eg
+ // GraphicsWindowX11, since OSG statics may have been created before the
+ // sglog static, despite our best efforts in boostrap.cxx
+ osg::setNotifyHandler(new osg::StandardNotifyHandler);
}
int fgOSMainLoop()
{
- ref_ptr<FGEventHandler> manipulator
- = globals->get_renderer()->getEventHandler();
viewer->setReleaseContextAtEndOfFrameHint(false);
if (!viewer->isRealized())
viewer->realize();
while (!viewer->done()) {
- fgIdleHandler idleFunc = manipulator->getIdleHandler();
+ fgIdleHandler idleFunc = globals->get_renderer()->getEventHandler()->getIdleHandler();
if (idleFunc)
(*idleFunc)();
globals->get_renderer()->update();
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
}
+void fgOSCloseWindow()
+{
+ FGScenery::resetPagerSingleton();
+ flightgear::CameraGroup::setDefault(NULL);
+ WindowSystemAdapter::setWSA(NULL);
+ viewer = NULL;
+}
+
void fgOSFullScreen()
{
std::vector<osgViewer::GraphicsWindow*> windows;
viewer->getWindows(windows);
- if (windows.size() == 0)
+ if (windows.empty())
return; // Huh?!?
/* Toggling window fullscreen is only supported for the main GUI window.
void fgSetMouseCursor(int cursor)
{
_cursor = cursor;
-
+ if (!viewer)
+ return;
+
std::vector<osgViewer::GraphicsWindow*> windows;
viewer->getWindows(windows);
BOOST_FOREACH(osgViewer::GraphicsWindow* gw, windows) {