1 #ifndef _MSC_VER // MSVC really needs a definition for wchar_t
2 #define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
10 #include <osgViewer/Viewer>
11 #include <osgViewer/ViewerEventHandlers>
13 #include <simgear/compiler.h>
19 #include <Scenery/scenery.hxx>
21 #include "globals.hxx"
22 #include "renderer.hxx"
23 #include "fg_props.hxx"
24 #include "WindowSystemAdapter.hxx"
26 using namespace flightgear;
29 // Native glut callbacks.
30 // These translate the glut event model into osgGA events
33 static osg::ref_ptr<osgViewer::Viewer> viewer;
34 static osg::ref_ptr<osg::Camera> mainCamera;
35 static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
37 static int GlutModifiers = 0;
38 static unsigned int getOSGModifiers(int modifiers);
40 static void callKeyHandler(int k, int mods, int x, int y)
45 case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
46 case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
47 case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
48 case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
49 case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
50 case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
51 case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
52 case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
53 case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
54 case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
55 case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
56 case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
57 case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
58 case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
59 case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
60 case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
61 case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
62 case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
63 case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
64 case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
65 case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
66 case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
67 case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
68 case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
69 case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
70 case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
71 default: key = k; break;
73 unsigned int osgModifiers = getOSGModifiers(mods);
74 osgGA::EventQueue& queue = *gw->getEventQueue();
75 queue.getCurrentEventState()->setModKeyMask(osgModifiers);
76 if (mods & KEYMOD_RELEASED)
77 queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
79 queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
82 static void GLUTmotion (int x, int y)
86 gw->getEventQueue()->mouseMotion(x, y);
89 static void GLUTmouse (int button, int updown, int x, int y)
91 GlutModifiers = glutGetModifiers();
94 gw->getEventQueue()->mouseButtonPress(x, y, button+1);
96 gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
100 static void GLUTspecialkeyup(int k, int x, int y)
102 GlutModifiers = glutGetModifiers();
103 callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
106 static void GLUTspecialkey(int k, int x, int y)
108 GlutModifiers = glutGetModifiers();
109 callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
112 static unsigned char release_keys[256];
114 static void GLUTkeyup(unsigned char k, int x, int y)
116 GlutModifiers = glutGetModifiers();
117 callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
120 static void GLUTkey(unsigned char k, int x, int y)
122 GlutModifiers = glutGetModifiers();
124 if (k >= 1 && k <= 26) {
125 release_keys[k + '@'] = k;
126 release_keys[k + '`'] = k;
127 } else if (k >= 'A' && k <= 'Z') {
128 release_keys[k - '@'] = k;
129 release_keys[tolower(k)] = k;
130 } else if (k >= 'a' && k <= 'z') {
131 release_keys[k - '`'] = k;
132 release_keys[toupper(k)] = k;
134 callKeyHandler(k, fgGetKeyModifiers(), x, y);
137 static void GLUTdraw()
144 static void GLUTreshape(int w, int h)
146 // update the window dimensions, in case the window has been resized.
147 gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
148 gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
153 // fg_os API definition
156 void fgOSInit(int* argc, char** argv)
158 glutInit(argc, argv);
159 WindowSystemAdapter::setWSA(new WindowSystemAdapter);
162 void fgOSFullScreen()
172 void fgOSExit(int code)
177 static int CurrentCursor = MOUSE_CURSOR_POINTER;
179 int fgGetMouseCursor()
181 return CurrentCursor;
184 void fgSetMouseCursor(int cursor)
186 CurrentCursor = cursor;
187 if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
188 else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
189 else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
190 else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
191 else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
192 // Otherwise, pass it through unchanged...
193 glutSetCursor(cursor);
196 void fgWarpMouse(int x, int y)
198 globals->get_renderer()->getManipulator()->setMouseWarped();
199 glutWarpPointer(x, y);
202 int fgGetKeyModifiers()
205 if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
206 if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
207 if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
211 static unsigned int getOSGModifiers(int glutModifiers)
213 unsigned int result = 0;
214 if (glutModifiers & GLUT_ACTIVE_SHIFT)
215 result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
216 if (glutModifiers & GLUT_ACTIVE_CTRL)
217 result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
218 if(glutModifiers & GLUT_ACTIVE_ALT)
219 result |= osgGA::GUIEventAdapter::MODKEY_ALT;
223 void fgOSOpenWindow(bool stencil)
225 int w = fgGetInt("/sim/startup/xsize");
226 int h = fgGetInt("/sim/startup/ysize");
227 int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
228 bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
229 bool fullscreen = fgGetBool("/sim/startup/fullscreen");
230 WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
231 int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
233 if(alpha) mode |= GLUT_ALPHA;
234 if(stencil && bpp > 16) mode |= GLUT_STENCIL;
236 glutInitDisplayMode(mode);
237 glutInitWindowSize(w, h);
238 if(!fgGetBool("/sim/startup/game-mode")) {
239 glutCreateWindow("FlightGear");
241 char game_mode_str[20];
242 SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
244 int hz = p->getIntValue();
245 snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
247 snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
249 glutGameModeString( game_mode_str );
253 // Register these here. Calling them before the window is open
255 glutMotionFunc(GLUTmotion);
256 glutPassiveMotionFunc(GLUTmotion);
257 glutMouseFunc(GLUTmouse);
258 glutSpecialUpFunc(GLUTspecialkeyup);
259 glutSpecialFunc(GLUTspecialkey);
260 glutKeyboardUpFunc(GLUTkeyup);
261 glutKeyboardFunc(GLUTkey);
262 glutDisplayFunc(GLUTdraw);
263 glutReshapeFunc(GLUTreshape);
267 viewer = new osgViewer::Viewer;
268 gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
269 GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
270 window->flags |= GraphicsWindow::GUI;
271 viewer->setDatabasePager(FGScenery::getPagerSingleton());
272 // now the main camera ...
273 osg::Camera* camera = new osg::Camera;
275 // If a viewport isn't set on the camera, then it's hard to dig it
276 // out of the SceneView objects in the viewer, and the coordinates
277 // of mouse events are somewhat bizzare.
278 camera->setViewport(new osg::Viewport(0, 0, realw, realh));
279 camera->setProjectionResizePolicy(osg::Camera::FIXED);
280 Camera3D* cam3D = wsa->registerCamera3D(window, camera, string("main"));
281 cam3D->flags |= Camera3D::MASTER;
282 // Add as a slave for compatibility with the non-embedded osgViewer.
283 viewer->addSlave(camera);
284 viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
285 // Let FG handle the escape key with a confirmation
286 viewer->setKeyEventSetsDone(0);
287 osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
288 statsHandler->setKeyEventTogglesOnScreenStats('*');
289 statsHandler->setKeyEventPrintsOutStats(0);
290 viewer->addEventHandler(statsHandler);
291 // The viewer won't start without some root.
292 viewer->setSceneData(new osg::Group);
293 globals->get_renderer()->setViewer(viewer.get());
296 bool fgOSIsMainCamera(const osg::Camera*)
301 bool fgOSIsMainContext(const osg::GraphicsContext*)
306 osg::GraphicsContext* fgOSGetMainContext()