]> git.mxchange.org Git - flightgear.git/blobdiff - src/Main/fg_os.cxx
Add the alpha test back in so the instruments won't disappear after changing the...
[flightgear.git] / src / Main / fg_os.cxx
index 4a1eb9c0fbb9c1c578c7336b17ff7bfa6bf03ee2..dfce9b2aaad59e61957e7b334271683764f90d6d 100644 (file)
-// 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)
@@ -92,32 +113,44 @@ static void GLUTspecialkey(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);
 }
 
 //
@@ -127,6 +160,7 @@ static void GLUTreshape(int w, int h)
 void fgOSInit(int* argc, char** argv)
 {
     glutInit(argc, argv);
+    WindowSystemAdapter::setWSA(new WindowSystemAdapter);
 }
 
 void fgOSFullScreen()
@@ -139,6 +173,11 @@ void fgOSMainLoop()
     glutMainLoop();
 }
 
+void fgOSExit(int code)
+{
+    exit(code);
+}
+
 static int CurrentCursor = MOUSE_CURSOR_POINTER;
 
 int fgGetMouseCursor()
@@ -160,6 +199,7 @@ void fgSetMouseCursor(int cursor)
 
 void fgWarpMouse(int x, int y)
 {
+    globals->get_renderer()->getManipulator()->setMouseWarped();
     glutWarpPointer(x, y);
 }
 
@@ -172,23 +212,44 @@ int fgGetKeyModifiers()
     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)
+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 && 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();
     }
@@ -202,8 +263,37 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha)
     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());
 }