-// The mac puts this in a weird location (GLUT/glut.h), so the
-// configure script detects the location and defines it as a macro.
+#ifndef _MSC_VER // MSVC really needs a definition for wchar_t
+#define _WCHAR_T_DEFINED 1 // Glut needs this, or else it tries to
+ // redefine it
+#endif
+
#ifdef HAVE_CONFIG_H
# include <config.h>
-# include FG_GLUT_H
-#else
-# include <GL/glut.h>
#endif
-#include <plib/pu.h>
-
-#include "fg_props.hxx"
-#include "fg_os.hxx"
+#include <osg/Matrix>
+#include <osgViewer/Viewer>
+#include <osgViewer/ViewerEventHandlers>
-//
-// fg_os callback registration APIs
-// (These are not glut-specific)
-//
-
-static fgIdleHandler IdleHandler = 0;
-static fgDrawHandler DrawHandler = 0;
-static fgWindowResizeHandler WindowResizeHandler = 0;
-static fgKeyHandler KeyHandler = 0;
-static fgMouseClickHandler MouseClickHandler = 0;
-static fgMouseMotionHandler MouseMotionHandler = 0;
-
-void fgRegisterIdleHandler(fgIdleHandler func)
-{
- IdleHandler = func;
-}
+#include <simgear/compiler.h>
-void fgRegisterDrawHandler(fgDrawHandler func)
-{
- DrawHandler = func;
-}
-
-void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
-{
- WindowResizeHandler = func;
-}
-
-void fgRegisterKeyHandler(fgKeyHandler func)
-{
- KeyHandler = func;
-}
+#if defined( __APPLE__)
+# include <GLUT/glut.h>
+#else
+# include <GL/glut.h>
+#endif
+#include <plib/pu.h>
-void fgRegisterMouseClickHandler(fgMouseClickHandler func)
-{
- MouseClickHandler = func;
-}
+#include <Scenery/scenery.hxx>
+#include "fg_os.hxx"
+#include "globals.hxx"
+#include "renderer.hxx"
+#include "fg_props.hxx"
+#include "WindowSystemAdapter.hxx"
+#include "CameraGroup.hxx"
-void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
-{
- MouseMotionHandler = func;
-}
+using namespace flightgear;
//
// Native glut callbacks.
-// These translate the glut event model into fg*Handler callbacks
+// These translate the glut event model into osgGA events
//
+static osg::ref_ptr<osgViewer::Viewer> viewer;
+static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
+
static int GlutModifiers = 0;
+static unsigned int getOSGModifiers(int modifiers);
static void callKeyHandler(int k, int mods, int x, int y)
{
- int puiup = mods & KEYMOD_RELEASED ? PU_UP : PU_DOWN;
- if(puKeyboard(k, puiup))
- return;
- if(KeyHandler) (*KeyHandler)(k, mods, x, y);
+
+ int key = 0;
+ switch (k) {
+ case 0x1b: key = osgGA::GUIEventAdapter::KEY_Escape; break;
+ case '\n': key = osgGA::GUIEventAdapter::KEY_Return; break;
+ case '\b': key = osgGA::GUIEventAdapter::KEY_BackSpace; break;
+ case 0x7f: key = osgGA::GUIEventAdapter::KEY_Delete; break;
+ case '\t': key = osgGA::GUIEventAdapter::KEY_Tab; break;
+ case PU_KEY_LEFT: key = osgGA::GUIEventAdapter::KEY_Left; break;
+ case PU_KEY_UP: key = osgGA::GUIEventAdapter::KEY_Up; break;
+ case PU_KEY_RIGHT: key = osgGA::GUIEventAdapter::KEY_Right; break;
+ case PU_KEY_DOWN: key = osgGA::GUIEventAdapter::KEY_Down; break;
+ case PU_KEY_PAGE_UP: key = osgGA::GUIEventAdapter::KEY_Page_Up; break;
+ case PU_KEY_PAGE_DOWN: key = osgGA::GUIEventAdapter::KEY_Page_Down; break;
+ case PU_KEY_HOME: key = osgGA::GUIEventAdapter::KEY_Home; break;
+ case PU_KEY_END: key = osgGA::GUIEventAdapter::KEY_End; break;
+ case PU_KEY_INSERT: key = osgGA::GUIEventAdapter::KEY_Insert; break;
+ case PU_KEY_F1: key = osgGA::GUIEventAdapter::KEY_F1; break;
+ case PU_KEY_F2: key = osgGA::GUIEventAdapter::KEY_F2; break;
+ case PU_KEY_F3: key = osgGA::GUIEventAdapter::KEY_F3; break;
+ case PU_KEY_F4: key = osgGA::GUIEventAdapter::KEY_F4; break;
+ case PU_KEY_F5: key = osgGA::GUIEventAdapter::KEY_F5; break;
+ case PU_KEY_F6: key = osgGA::GUIEventAdapter::KEY_F6; break;
+ case PU_KEY_F7: key = osgGA::GUIEventAdapter::KEY_F7; break;
+ case PU_KEY_F8: key = osgGA::GUIEventAdapter::KEY_F8; break;
+ case PU_KEY_F9: key = osgGA::GUIEventAdapter::KEY_F9; break;
+ case PU_KEY_F10: key = osgGA::GUIEventAdapter::KEY_F10; break;
+ case PU_KEY_F11: key = osgGA::GUIEventAdapter::KEY_F11; break;
+ case PU_KEY_F12: key = osgGA::GUIEventAdapter::KEY_F12; break;
+ default: key = k; break;
+ }
+ unsigned int osgModifiers = getOSGModifiers(mods);
+ osgGA::EventQueue& queue = *gw->getEventQueue();
+ queue.getCurrentEventState()->setModKeyMask(osgModifiers);
+ if (mods & KEYMOD_RELEASED)
+ queue.keyRelease((osgGA::GUIEventAdapter::KeySymbol)key);
+ else
+ queue.keyPress((osgGA::GUIEventAdapter::KeySymbol)key);
}
static void GLUTmotion (int x, int y)
{
- if(MouseMotionHandler) (*MouseMotionHandler)(x, y);
+ if (!gw.valid())
+ return;
+ gw->getEventQueue()->mouseMotion(x, y);
}
static void GLUTmouse (int button, int updown, int x, int y)
{
GlutModifiers = glutGetModifiers();
- if(MouseClickHandler) (*MouseClickHandler)(button, updown, x, y);
+ if (gw.valid()) {
+ if (updown == 0)
+ gw->getEventQueue()->mouseButtonPress(x, y, button+1);
+ else
+ gw->getEventQueue()->mouseButtonRelease(x, y, button+1);
+ }
}
static void GLUTspecialkeyup(int k, int x, int y)
callKeyHandler(256 + k, fgGetKeyModifiers(), x, y);
}
+static unsigned char release_keys[256];
+
static void GLUTkeyup(unsigned char k, int x, int y)
{
GlutModifiers = glutGetModifiers();
- callKeyHandler(k, fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
+ callKeyHandler(release_keys[k], fgGetKeyModifiers() | KEYMOD_RELEASED, x, y);
}
static void GLUTkey(unsigned char k, int x, int y)
{
GlutModifiers = glutGetModifiers();
+ release_keys[k] = k;
+ if (k >= 1 && k <= 26) {
+ release_keys[k + '@'] = k;
+ release_keys[k + '`'] = k;
+ } else if (k >= 'A' && k <= 'Z') {
+ release_keys[k - '@'] = k;
+ release_keys[tolower(k)] = k;
+ } else if (k >= 'a' && k <= 'z') {
+ release_keys[k - '`'] = k;
+ release_keys[toupper(k)] = k;
+ }
callKeyHandler(k, fgGetKeyModifiers(), x, y);
}
-static void GLUTidle()
-{
- if(IdleHandler) (*IdleHandler)();
-}
-
static void GLUTdraw()
{
- if(DrawHandler) (*DrawHandler)();
+ viewer->frame();
glutSwapBuffers();
+ glutPostRedisplay();
}
static void GLUTreshape(int w, int h)
{
- if(WindowResizeHandler) (*WindowResizeHandler)(w, h);
+ // update the window dimensions, in case the window has been resized.
+ gw->resized(gw->getTraits()->x, gw->getTraits()->y, w, h);
+ gw->getEventQueue()->windowResize(gw->getTraits()->x, gw->getTraits()->y,
+ w, h);
}
//
void fgOSInit(int* argc, char** argv)
{
glutInit(argc, argv);
+ WindowSystemAdapter::setWSA(new WindowSystemAdapter);
}
void fgOSFullScreen()
glutMainLoop();
}
+void fgOSExit(int code)
+{
+ exit(code);
+}
+
static int CurrentCursor = MOUSE_CURSOR_POINTER;
int fgGetMouseCursor()
void fgWarpMouse(int x, int y)
{
+ globals->get_renderer()->getManipulator()->setMouseWarped();
glutWarpPointer(x, y);
}
return result;
}
-void fgRequestRedraw()
+static unsigned int getOSGModifiers(int glutModifiers)
{
- glutPostRedisplay();
+ unsigned int result = 0;
+ if (glutModifiers & GLUT_ACTIVE_SHIFT)
+ result |= osgGA::GUIEventAdapter::MODKEY_SHIFT;
+ if (glutModifiers & GLUT_ACTIVE_CTRL)
+ result |= osgGA::GUIEventAdapter::MODKEY_CTRL;
+ if(glutModifiers & GLUT_ACTIVE_ALT)
+ result |= osgGA::GUIEventAdapter::MODKEY_ALT;
+ return result;
}
-void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
- bool stencil, bool fullscreen)
+void fgOSOpenWindow(bool stencil)
{
+ int w = fgGetInt("/sim/startup/xsize");
+ int h = fgGetInt("/sim/startup/ysize");
+ int bpp = fgGetInt("/sim/rendering/bits-per-pixel");
+ bool alpha = fgGetBool("/sim/rendering/clouds3d-enable");
+ bool fullscreen = fgGetBool("/sim/startup/fullscreen");
+ WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
int mode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE;
+
if(alpha) mode |= GLUT_ALPHA;
- if(stencil) mode |= GLUT_STENCIL;
+ if(stencil && bpp > 16) mode |= GLUT_STENCIL;
glutInitDisplayMode(mode);
glutInitWindowSize(w, h);
if(!fgGetBool("/sim/startup/game-mode")) {
glutCreateWindow("FlightGear");
} else {
- char game_mode_str[256];
- sprintf(game_mode_str, "width=%d height=%d bpp=%d", w, h, bpp);
+ char game_mode_str[20];
+ SGPropertyNode *p = fgGetNode("/sim/frame-rate-throttle-hz", false);
+ if (p) {
+ int hz = p->getIntValue();
+ snprintf(game_mode_str, 20, "%dx%d:%d@%d", w, h, bpp, hz);
+ } else {
+ snprintf(game_mode_str, 20, "%dx%d:%d", w, h, bpp);
+ }
glutGameModeString( game_mode_str );
glutEnterGameMode();
}
glutSpecialFunc(GLUTspecialkey);
glutKeyboardUpFunc(GLUTkeyup);
glutKeyboardFunc(GLUTkey);
- glutIdleFunc(GLUTidle);
glutDisplayFunc(GLUTdraw);
glutReshapeFunc(GLUTreshape);
-
+ // XXX
+ int realw = w;
+ int realh = h;
+ viewer = new osgViewer::Viewer;
+ gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
+ GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
+ window->flags |= GraphicsWindow::GUI;
+ viewer->setDatabasePager(FGScenery::getPagerSingleton());
+ // now the main camera ...
+ osg::Camera* camera = new osg::Camera;
+ // If a viewport isn't set on the camera, then it's hard to dig it
+ // out of the SceneView objects in the viewer, and the coordinates
+ // of mouse events are somewhat bizzare.
+ camera->setViewport(new osg::Viewport(0, 0, realw, realh));
+ camera->setProjectionResizePolicy(osg::Camera::FIXED);
+ CameraGroup* cgroup = new CameraGroup(viewer.get());
+ cgroup->addCamera(CameraGroup::DO_INTERSECTION_TEST, camera,
+ osg::Matrixd::identity(), osg::Matrixd::identity(),
+ true);
+ cgroup->buildGUICamera(0, window);
+ CameraGroup::setDefault(cgroup);
+ viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
+ // Let FG handle the escape key with a confirmation
+ viewer->setKeyEventSetsDone(0);
+ osgViewer::StatsHandler* statsHandler = new osgViewer::StatsHandler;
+ statsHandler->setKeyEventTogglesOnScreenStats('*');
+ statsHandler->setKeyEventPrintsOutStats(0);
+ viewer->addEventHandler(statsHandler);
+ // The viewer won't start without some root.
+ viewer->setSceneData(new osg::Group);
+ globals->get_renderer()->setViewer(viewer.get());
}