]> git.mxchange.org Git - flightgear.git/blob - src/Main/fg_os_osgviewer.cxx
12064723789fa38aa0963c2f4908cc655babd6a2
[flightgear.git] / src / Main / fg_os_osgviewer.cxx
1 #include <stdlib.h>
2
3 #include <simgear/compiler.h>
4 #include <simgear/structure/exception.hxx>
5 #include <simgear/debug/logstream.hxx>
6
7 #include <osg/GraphicsContext>
8 #include <osg/Group>
9 #include <osg/Matrixd>
10 #include <osg/Viewport>
11 #include <osgViewer/StatsHandler>
12 #include <osgViewer/Viewer>
13 #include <osgGA/MatrixManipulator>
14
15 #include "fg_os.hxx"
16 #include "util.hxx"
17 #include "globals.hxx"
18 #include "renderer.hxx"
19
20 // fg_os implementation using OpenSceneGraph's osgViewer::Viewer class
21 // to create the graphics window and run the event/update/render loop.
22 //
23 // fg_os callback registration APIs
24 //
25
26
27 // Event handling and scene graph update is all handled by a
28 // manipulator. See FGManipulator.cpp
29 void fgRegisterIdleHandler(fgIdleHandler func)
30 {
31     globals->get_renderer()->getManipulator()->setIdleHandler(func);
32 }
33
34 void fgRegisterDrawHandler(fgDrawHandler func)
35 {
36     globals->get_renderer()->getManipulator()->setDrawHandler(func);
37 }
38
39 void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
40 {
41     globals->get_renderer()->getManipulator()->setWindowResizeHandler(func);
42 }
43
44 void fgRegisterKeyHandler(fgKeyHandler func)
45 {
46     globals->get_renderer()->getManipulator()->setKeyHandler(func);
47 }
48
49 void fgRegisterMouseClickHandler(fgMouseClickHandler func)
50 {
51     globals->get_renderer()->getManipulator()->setMouseClickHandler(func);
52 }
53
54 void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
55 {
56     globals->get_renderer()->getManipulator()->setMouseMotionHandler(func);
57 }
58
59 // Redraw "happens" every frame whether you want it or not.
60 void fgRequestRedraw()
61 {
62 }
63
64 //
65 // fg_os implementation
66 //
67
68
69 static osg::ref_ptr<osgViewer::Viewer> viewer;
70
71 void fgOSOpenWindow(int w, int h, int bpp,
72                     bool alpha, bool stencil, bool fullscreen)
73 {
74     viewer = new osgViewer::Viewer;
75     // Avoid complications with fg's custom drawables.
76     viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
77     osg::ref_ptr<osg::GraphicsContext::Traits> traits
78         = new osg::GraphicsContext::Traits;
79     int cbits = (bpp <= 16) ?  5 :  8;
80     int zbits = (bpp <= 16) ? 16 : 24;
81     traits->width = w;
82     traits->height = h;
83     traits->red = traits->green = traits->blue = cbits;
84     traits->depth = zbits;
85     if (alpha)
86         traits->alpha = 8;
87     if (stencil)
88         traits->stencil = 8;
89     if (fullscreen)
90         traits->windowDecoration = false;
91     else
92         traits->windowDecoration = true;
93     traits->supportsResize = true;
94     traits->doubleBuffer = true;
95     osg::GraphicsContext* gc
96         = osg::GraphicsContext::createGraphicsContext(traits.get());
97     viewer->getCamera()->setGraphicsContext(gc);
98     // If a viewport isn't set on the camera, then it's hard to dig it
99     // out of the SceneView objects in the viewer, and the coordinates
100     // of mouse events are somewhat bizzare.
101     viewer->getCamera()->setViewport(new osg::Viewport(0, 0,
102                                                        traits->width,
103                                                        traits->height));
104     viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
105     // Let FG handle the escape key with a confirmation
106     viewer->setKeyEventSetsDone(0);
107     osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
108     statsHandler->setKeyEventTogglesOnScreenStats('*');
109     statsHandler->setKeyEventPrintsOutStats(0);
110     viewer->addEventHandler(statsHandler);
111     // The viewer won't start without some root.
112     viewer->setSceneData(new osg::Group);
113     globals->get_renderer()->setViewer(viewer.get());
114 }
115
116 static int status = 0;
117
118 void fgOSExit(int code)
119 {
120     viewer->setDone(true);
121     status = code;
122 }
123
124 void fgOSMainLoop()
125 {
126     viewer->run();
127     fgExit(status);
128 }
129
130 int fgGetKeyModifiers()
131 {
132     return globals->get_renderer()->getManipulator()->getCurrentModifiers();
133 }
134
135 void fgWarpMouse(int x, int y)
136 {
137     viewer->requestWarpPointer((float)x, (float)y);
138 }
139
140 // Noop
141 void fgOSInit(int* argc, char** argv)
142 {
143 }
144
145 void fgOSFullScreen()
146 {
147     // Noop, but is probably doable
148
149 }
150
151 // No support in OSG yet
152 void fgSetMouseCursor(int cursor)
153 {
154 }
155
156 int fgGetMouseCursor()
157 {
158     return 0;
159 }
160
161 void fgMakeCurrent()
162 {
163     osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
164     gc->makeCurrent();
165 }