]> git.mxchange.org Git - flightgear.git/blob - src/Viewer/fgviewer.cxx
Use names to identify deferred buffers in camera group
[flightgear.git] / src / Viewer / fgviewer.cxx
1 #ifdef HAVE_CONFIG_H
2 #  include "config.h"
3 #endif
4
5 #include <iostream>
6 #include <cstdlib>
7
8 #include <osg/ArgumentParser>
9 #include <osg/Fog>
10 #include <osgDB/ReadFile>
11 #include <osgDB/Registry>
12 #include <osgDB/WriteFile>
13 #include <osgViewer/Renderer>
14 #include <osgViewer/Viewer>
15 #include <osgViewer/ViewerEventHandlers>
16 #include <osgGA/KeySwitchMatrixManipulator>
17 #include <osgGA/TrackballManipulator>
18 #include <osgGA/FlightManipulator>
19 #include <osgGA/DriveManipulator>
20 #include <osgGA/TerrainManipulator>
21 #include <osgGA/StateSetManipulator>
22
23 #include <simgear/props/props.hxx>
24 #include <simgear/props/props_io.hxx>
25 #include <simgear/misc/sg_path.hxx>
26 #include <simgear/scene/material/EffectCullVisitor.hxx>
27 #include <simgear/scene/material/matlib.hxx>
28 #include <simgear/scene/util/SGReaderWriterOptions.hxx>
29 #include <simgear/scene/tgdb/userdata.hxx>
30 #include <simgear/scene/model/ModelRegistry.hxx>
31 #include <simgear/scene/model/modellib.hxx>
32
33 #include <Scenery/scenery.hxx>
34
35 #include <Main/fg_props.hxx>
36 #include <Main/globals.hxx>
37 #include <Main/options.hxx>
38 #include <Main/fg_init.hxx>
39
40 class GraphDumpHandler : public  osgGA::GUIEventHandler
41 {
42 public:
43     GraphDumpHandler() : _keyDump('d') {}
44     void setKeyDump(int key) { _keyDump = key; }
45     int getKeyDump() const { return _keyDump; }
46     bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);
47
48     /** Get the keyboard and mouse usage of this manipulator.*/
49     virtual void getUsage(osg::ApplicationUsage& usage) const;
50 protected:
51     int _keyDump;
52 };
53
54 static void dumpOut(osg::Node* node)
55 {
56     char filename[24];
57     static int count = 1;
58
59     while (count < 1000) {
60         FILE *fp;
61         snprintf(filename, 24, "fgviewer-%03d.osg", count++);
62         if ( (fp = fopen(filename, "r")) == NULL )
63             break;
64         fclose(fp);
65     }
66
67     if (osgDB::writeNodeFile(*node, filename))
68         std::cerr << "Entire scene graph saved to \"" << filename << "\".\n";
69     else
70         std::cerr << "Failed to save to \"" << filename << "\".\n";
71 }
72
73 bool GraphDumpHandler::handle(const osgGA::GUIEventAdapter& ea,
74                               osgGA::GUIActionAdapter& aa)
75 {
76     osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
77     if (!view)
78         return false;
79     if (ea.getHandled())
80         return false;
81     switch(ea.getEventType()) {
82     case osgGA::GUIEventAdapter::KEYUP:
83         if (ea.getKey() == _keyDump) {
84             dumpOut(view->getScene()->getSceneData());
85             return true;
86         }
87         break;
88     default:
89         return false;
90     }
91     return false;
92 }
93
94 void GraphDumpHandler::getUsage(osg::ApplicationUsage& usage) const
95 {
96     std::ostringstream ostr;
97     ostr << char(_keyDump);
98             usage.addKeyboardMouseBinding(ostr.str(),
99                                           "Dump scene graph to file");
100 }
101
102 int
103 fgviewerMain(int argc, char** argv)
104 {
105
106     sgUserDataInit(0);
107
108     // use an ArgumentParser object to manage the program arguments.
109     osg::ArgumentParser arguments(&argc, argv);
110
111     // construct the viewer.
112     osgViewer::Viewer viewer(arguments);
113     osg::Camera* camera = viewer.getCamera();
114     osgViewer::Renderer* renderer
115         = static_cast<osgViewer::Renderer*>(camera->getRenderer());
116     for (int i = 0; i < 2; ++i) {
117         osgUtil::SceneView* sceneView = renderer->getSceneView(i);
118         sceneView->setCullVisitor(new simgear::EffectCullVisitor);
119     }
120     // Shaders expect valid fog
121     osg::StateSet* cameraSS = camera->getOrCreateStateSet();
122     osg::Fog* fog = new osg::Fog;
123     fog->setMode(osg::Fog::EXP2);
124     fog->setColor(osg::Vec4(1.0, 1.0, 1.0, 1.0));
125     fog->setDensity(.0000001);
126     cameraSS->setAttributeAndModes(fog);
127     // ... for some reason, get rid of that FIXME!
128     viewer.setThreadingModel(osgViewer::Viewer::SingleThreaded);
129
130     // set up the camera manipulators.
131     osgGA::KeySwitchMatrixManipulator* keyswitchManipulator;
132     keyswitchManipulator = new osgGA::KeySwitchMatrixManipulator;
133
134     keyswitchManipulator->addMatrixManipulator('1', "Trackball",
135                                                new osgGA::TrackballManipulator);
136     keyswitchManipulator->addMatrixManipulator('2', "Flight",
137                                                new osgGA::FlightManipulator);
138     keyswitchManipulator->addMatrixManipulator('3', "Drive",
139                                                new osgGA::DriveManipulator);
140     keyswitchManipulator->addMatrixManipulator('4', "Terrain",
141                                                new osgGA::TerrainManipulator);
142     viewer.setCameraManipulator(keyswitchManipulator);
143
144     // Usefull stats
145     viewer.addEventHandler(new osgViewer::HelpHandler);
146     viewer.addEventHandler(new osgViewer::StatsHandler);
147     viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) );
148     // Same FIXME ...
149     // viewer.addEventHandler(new osgViewer::ThreadingHandler);
150     viewer.addEventHandler(new osgViewer::LODScaleHandler);
151     viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
152
153     viewer.addEventHandler(new GraphDumpHandler);
154
155     // Extract files to load from arguments now; this way fgInitConfig
156     // won't choke on them.
157     string_list dataFiles;
158     for (int i = arguments.argc() - 1; i >= 0; --i) {
159         if (arguments.isOption(i)) {
160             break;
161         } else {
162             dataFiles.insert(dataFiles.begin(), arguments[i]);
163             arguments.remove(i);
164         }
165     }
166
167     // A subset of full flightgear initialization.
168     // Allocate global data structures.  This needs to happen before
169     // we parse command line options
170
171     globals = new FGGlobals;
172
173     if ( !fgInitConfig(arguments.argc(), arguments.argv()) ) {
174         SG_LOG( SG_GENERAL, SG_ALERT, "Config option parsing failed ..." );
175         exit(-1);
176     }
177
178     osgDB::FilePathList filePathList
179         = osgDB::Registry::instance()->getDataFilePathList();
180     filePathList.push_back(globals->get_fg_root());
181
182     string_list path_list = globals->get_fg_scenery();
183     for (unsigned i = 0; i < path_list.size(); ++i) {
184         filePathList.push_back(path_list[i]);
185     }
186
187     globals->set_matlib( new SGMaterialLib );
188     simgear::SGModelLib::init(globals->get_fg_root(), globals->get_props());
189
190     // Initialize the material property subsystem.
191
192     SGPath mpath( globals->get_fg_root() );
193     mpath.append( fgGetString("/sim/rendering/materials-file") );
194     if ( ! globals->get_matlib()->load(globals->get_fg_root(), mpath.str(),
195             globals->get_props()) ) {
196         SG_LOG( SG_GENERAL, SG_ALERT,
197                 "Error loading materials file " << mpath.str() );
198         exit(-1);
199     }
200
201     globals->set_scenery( new FGScenery );
202     globals->get_scenery()->init();
203     globals->get_scenery()->bind();
204
205     // The file path list must be set in the registry.
206     osgDB::Registry::instance()->getDataFilePathList() = filePathList;
207
208     simgear::SGReaderWriterOptions* options = new simgear::SGReaderWriterOptions;
209     options->getDatabasePathList() = filePathList;
210     options->setMaterialLib(globals->get_matlib());
211     options->setPropertyNode(globals->get_props());
212
213     // read the scene from the list of file specified command line args.
214     osg::ref_ptr<osg::Node> loadedModel;
215     loadedModel = osgDB::readNodeFiles(dataFiles, options);
216
217     // if no model has been successfully loaded report failure.
218     if (!loadedModel.valid()) {
219         std::cerr << arguments.getApplicationName()
220                   << ": No data loaded" << std::endl;
221         return EXIT_FAILURE;
222     }
223
224     // pass the loaded scene graph to the viewer.
225     viewer.setSceneData(loadedModel.get());
226
227     return viewer.run();
228 }