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"
26 // Native glut callbacks.
27 // These translate the glut event model into osgGA events
30 static osg::ref_ptr<osgViewer::Viewer> viewer;
31 static osg::ref_ptr<osg::Camera> mainCamera;
32 static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
34 static int GlutModifiers = 0;
35 static unsigned int getOSGModifiers(int modifiers);
37 static void callKeyHandler(int k, int mods, int x, int y)
42 case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
43 case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
44 case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
45 case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
46 case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
47 case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
48 case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
49 case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
50 case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
51 case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
52 case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
53 case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
54 case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
55 case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
56 case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
57 case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
58 case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
59 case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
60 case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
61 case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
62 case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
63 case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
64 case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
65 case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
66 case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
67 case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
68 default: key = k; break;
70 unsigned int osgModifiers = getOSGModifiers(mods);
71 osgGA::EventQueue& queue = *gw->getEventQueue();
72 queue.getCurrentEventState()->setModKeyMask(osgModifiers);
73 if (mods & KEYMOD_RELEASED)
74 queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
76 queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
79 static void GLUTmotion (int x, int y)
83 gw->getEventQueue()->mouseMotion(x, y);
86 static void GLUTmouse (int button, int updown, int x, int y)
88 GlutModifiers = glutGetModifiers();
91 gw->getEventQueue()->mouseButtonPress(x, y, button+1);
93 gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
97 static void GLUTspecialkeyup(int k, int x, int y)
99 GlutModifiers = glutGetModifiers();
100 callKeyHandler(256 + k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
103 static void GLUTspecialkey(int k, int x, int y)
105 GlutModifiers = glutGetModifiers();
106 callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
109 static unsigned char release_keys[256];
111 static void GLUTkeyup(unsigned char k, int x, int y)
113 GlutModifiers = glutGetModifiers();
114 callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
117 static void GLUTkey(unsigned char k, int x, int y)
119 GlutModifiers = glutGetModifiers();
121 if (k >= 1 && k <= 26) {
122 release_keys[k + '@'] = k;
123 release_keys[k + '`'] = k;
124 } else if (k >= 'A' && k <= 'Z') {
125 release_keys[k - '@'] = k;
126 release_keys[tolower(k)] = k;
127 } else if (k >= 'a' && k <= 'z') {
128 release_keys[k - '`'] = k;
129 release_keys[toupper(k)] = k;
131 callKeyHandler(k, fgGetKeyModifiers(), x, y);
134 static void GLUTdraw()
141 static void GLUTreshape(int w, int h)
143 // update the window dimensions, in case the window has been resized.
144 gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
145 gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
150 // fg_os API definition
153 void fgOSInit(int* argc, char** argv)
155 glutInit(argc, argv);
158 void fgOSFullScreen()
168 void fgOSExit(int code)
173 static int CurrentCursor = MOUSE_CURSOR_POINTER;
175 int fgGetMouseCursor()
177 return CurrentCursor;
180 void fgSetMouseCursor(int cursor)
182 CurrentCursor = cursor;
183 if (cursor == MOUSE_CURSOR_NONE) cursor = GLUT_CURSOR_NONE;
184 else if(cursor == MOUSE_CURSOR_POINTER) cursor = GLUT_CURSOR_INHERIT;
185 else if(cursor == MOUSE_CURSOR_WAIT) cursor = GLUT_CURSOR_WAIT;
186 else if(cursor == MOUSE_CURSOR_CROSSHAIR) cursor = GLUT_CURSOR_CROSSHAIR;
187 else if(cursor == MOUSE_CURSOR_LEFTRIGHT) cursor = GLUT_CURSOR_LEFT_RIGHT;
188 // Otherwise, pass it through unchanged...
189 glutSetCursor(cursor);
192 void fgWarpMouse(int x, int y)
194 globals->get_renderer()->getManipulator()->setMouseWarped();
195 glutWarpPointer(x, y);
198 int fgGetKeyModifiers()
201 if(GlutModifiers & GLUT_ACTIVE_SHIFT) result |= KEYMOD_SHIFT;
202 if(GlutModifiers & GLUT_ACTIVE_CTRL) result |= KEYMOD_CTRL;
203 if(GlutModifiers & GLUT_ACTIVE_ALT) result |= KEYMOD_ALT;
207 static unsigned int getOSGModifiers(int glutModifiers)
209 unsigned int result = 0;
210 if (glutModifiers & GLUT_ACTIVE_SHIFT)
211 result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
212 if (glutModifiers & GLUT_ACTIVE_CTRL)
213 result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
214 if(glutModifiers & GLUT_ACTIVE_ALT)
215 result |= osgGA::GUIEventAdapter::MODKEY_ALT;
219 void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
220 bool stencil, bool fullscreen)
222 int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
223 if(alpha) mode |= GLUT_ALPHA;
224 if(stencil && bpp > 16) mode |= GLUT_STENCIL;
226 glutInitDisplayMode(mode);
227 glutInitWindowSize(w, h);
228 if(!fgGetBool("/sim/startup/game-mode")) {
229 glutCreateWindow("FlightGear");
231 char game_mode_str[20];
232 SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
234 int hz = p->getIntValue();
235 snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
237 snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
239 glutGameModeString( game_mode_str );
243 // Register these here. Calling them before the window is open
245 glutMotionFunc(GLUTmotion);
246 glutPassiveMotionFunc(GLUTmotion);
247 glutMouseFunc(GLUTmouse);
248 glutSpecialUpFunc(GLUTspecialkeyup);
249 glutSpecialFunc(GLUTspecialkey);
250 glutKeyboardUpFunc(GLUTkeyup);
251 glutKeyboardFunc(GLUTkey);
252 glutDisplayFunc(GLUTdraw);
253 glutReshapeFunc(GLUTreshape);
257 viewer = new osgViewer::Viewer;
258 gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
259 viewer->setDatabasePager(FGScenery::getPagerSingleton());
260 // now the main camera ...
261 //osg::ref_ptr<osg::Camera> camera = new osg::Camera;
262 osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
264 osg::Camera::ProjectionResizePolicy rsp = osg::Camera::VERTICAL;
265 // If a viewport isn't set on the camera, then it's hard to dig it
266 // out of the SceneView objects in the viewer, and the coordinates
267 // of mouse events are somewhat bizzare.
268 camera->setViewport(new osg::Viewport(0, 0, realw, realh));
269 camera->setProjectionResizePolicy(rsp);
270 //viewer->addSlave(camera.get());
271 globals->get_renderer()->getManipulator()->setUseEventModifiers(true);
272 viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
273 // Let FG handle the escape key with a confirmation
274 viewer->setKeyEventSetsDone(0);
275 osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
276 statsHandler->setKeyEventTogglesOnScreenStats('*');
277 statsHandler->setKeyEventPrintsOutStats(0);
278 viewer->addEventHandler(statsHandler);
279 // The viewer won't start without some root.
280 viewer->setSceneData(new osg::Group);
281 globals->get_renderer()->setViewer(viewer.get());
284 // Noop; the graphics context is always current
289 bool fgOSIsMainCamera(const osg::Camera*)
294 bool fgOSIsMainContext(const osg::GraphicsContext*)