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
11 #include <osgViewer/Viewer>
12 #include <osgViewer/ViewerEventHandlers>
14 #include <simgear/compiler.h>
16 #if defined( __APPLE__)
17 # include <GLUT/glut.h>
23 #include <Scenery/scenery.hxx>
25 #include "globals.hxx"
26 #include "renderer.hxx"
27 #include "fg_props.hxx"
28 #include "WindowSystemAdapter.hxx"
29 #include "CameraGroup.hxx"
31 using namespace flightgear;
34 // Native glut callbacks.
35 // These translate the glut event model into osgGA events
38 static osg::ref_ptr<osgViewer::Viewer> viewer;
39 static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
41 static int GlutModifiers = 0;
42 static unsigned int getOSGModifiers(int modifiers);
44 static void callKeyHandler(int k, int mods, int x, int y)
49 case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
50 case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
51 case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
52 case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
53 case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
54 case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
55 case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
56 case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
57 case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
58 case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
59 case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
60 case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
61 case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
62 case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
63 case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
64 case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
65 case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
66 case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
67 case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
68 case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
69 case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
70 case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
71 case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
72 case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
73 case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
74 case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
75 default: key = k; break;
77 unsigned int osgModifiers = getOSGModifiers(mods);
78 osgGA::EventQueue& queue = *gw->getEventQueue();
79 queue.getCurrentEventState()->setModKeyMask(osgModifiers);
80 if (mods & KEYMOD_RELEASED)
81 queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
83 queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
86 static void GLUTmotion (int x, int y)
90 gw->getEventQueue()->mouseMotion(x, y);
93 static void GLUTmouse (int button, int updown, int x, int y)
95 GlutModifiers = glutGetModifiers();
98 gw->getEventQueue()->mouseButtonPress(x, y, button+1);
100 gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
104 static void GLUTspecialkeyup(int k, int x, int y)
106 GlutModifiers = glutGetModifiers();
107 callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
110 static void GLUTspecialkey(int k, int x, int y)
112 GlutModifiers = glutGetModifiers();
113 callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
116 static unsigned char release_keys[256];
118 static void GLUTkeyup(unsigned char k, int x, int y)
120 GlutModifiers = glutGetModifiers();
121 callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
124 static void GLUTkey(unsigned char k, int x, int y)
126 GlutModifiers = glutGetModifiers();
128 if (k >= 1 && k <= 26) {
129 release_keys[k + '@'] = k;
130 release_keys[k + '`'] = k;
131 } else if (k >= 'A' && k <= 'Z') {
132 release_keys[k - '@'] = k;
133 release_keys[tolower(k)] = k;
134 } else if (k >= 'a' && k <= 'z') {
135 release_keys[k - '`'] = k;
136 release_keys[toupper(k)] = k;
138 callKeyHandler(k, fgGetKeyModifiers(), x, y);
141 static void GLUTdraw()
148 static void GLUTreshape(int w, int h)
150 // update the window dimensions, in case the window has been resized.
151 gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
152 gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
157 // fg_os API definition
160 void fgOSInit(int* argc, char** argv)
162 glutInit(argc, argv);
163 WindowSystemAdapter::setWSA(new WindowSystemAdapter);
166 void fgOSFullScreen()
176 void fgOSExit(int code)
181 static int CurrentCursor = MOUSE_CURSOR_POINTER;
183 int fgGetMouseCursor()
185 return CurrentCursor;
188 void fgSetMouseCursor(int cursor)
190 CurrentCursor = cursor;
191 if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
192 else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
193 else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
194 else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
195 else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
196 // Otherwise, pass it through unchanged...
197 glutSetCursor(cursor);
200 void fgWarpMouse(int x, int y)
202 globals->get_renderer()->getManipulator()->setMouseWarped();
203 glutWarpPointer(x, y);
206 int fgGetKeyModifiers()
209 if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
210 if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
211 if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
215 static unsigned int getOSGModifiers(int glutModifiers)
217 unsigned int result = 0;
218 if (glutModifiers & GLUT_ACTIVE_SHIFT)
219 result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
220 if (glutModifiers & GLUT_ACTIVE_CTRL)
221 result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
222 if(glutModifiers & GLUT_ACTIVE_ALT)
223 result |= osgGA::GUIEventAdapter::MODKEY_ALT;
227 void fgOSOpenWindow(bool stencil)
229 int w = fgGetInt("/sim/startup/xsize");
230 int h = fgGetInt("/sim/startup/ysize");
231 int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
232 bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
233 bool fullscreen = fgGetBool("/sim/startup/fullscreen");
234 WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
235 int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
237 if(alpha) mode |= GLUT_ALPHA;
238 if(stencil && bpp > 16) mode |= GLUT_STENCIL;
240 glutInitDisplayMode(mode);
241 glutInitWindowSize(w, h);
242 if(!fgGetBool("/sim/startup/game-mode")) {
243 glutCreateWindow("FlightGear");
245 char game_mode_str[20];
246 SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
248 int hz = p->getIntValue();
249 snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
251 snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
253 glutGameModeString( game_mode_str );
257 // Register these here. Calling them before the window is open
259 glutMotionFunc(GLUTmotion);
260 glutPassiveMotionFunc(GLUTmotion);
261 glutMouseFunc(GLUTmouse);
262 glutSpecialUpFunc(GLUTspecialkeyup);
263 glutSpecialFunc(GLUTspecialkey);
264 glutKeyboardUpFunc(GLUTkeyup);
265 glutKeyboardFunc(GLUTkey);
266 glutDisplayFunc(GLUTdraw);
267 glutReshapeFunc(GLUTreshape);
271 viewer = new osgViewer::Viewer;
272 gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
273 GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
274 window->flags |= GraphicsWindow::GUI;
275 viewer->setDatabasePager(FGScenery::getPagerSingleton());
276 // now the main camera ...
277 osg::Camera* camera = new osg::Camera;
278 // If a viewport isn't set on the camera, then it's hard to dig it
279 // out of the SceneView objects in the viewer, and the coordinates
280 // of mouse events are somewhat bizzare.
281 camera->setViewport(new osg::Viewport(0, 0, realw, realh));
282 camera->setProjectionResizePolicy(osg::Camera::FIXED);
283 CameraGroup* cgroup = new CameraGroup(viewer.get());
284 cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, camera,
285 osg::Matrixd::identity(), osg::Matrixd::identity(),
287 cgroup->buildGUICamera(0, window);
288 CameraGroup::setDefault(cgroup);
289 viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
290 // Let FG handle the escape key with a confirmation
291 viewer->setKeyEventSetsDone(0);
292 osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
293 statsHandler->setKeyEventTogglesOnScreenStats('*');
294 statsHandler->setKeyEventPrintsOutStats(0);
295 viewer->addEventHandler(statsHandler);
296 // The viewer won't start without some root.
297 viewer->setSceneData(new osg::Group);
298 globals->get_renderer()->setViewer(viewer.get());