Modified Files:
configure.ac src/Main/Makefile.am src/Main/fg_os.cxx src/Main/fg_os.hxx src/Main/fg_os_sdl.cxx src/Main/main.cxx src/Main/renderer.cxx src/Main/renderer.hxx src/Network/jpg-httpd.cxx Added Files: src/Main/FGManipulator.cxx src/Main/FGManipulator.hxx src/Main/fg_os_osgviewer.cxx: Tim Moore: Make use of osgViewer.
This commit is contained in:
parent
d694d0a205
commit
7443b8b5e8
12 changed files with 690 additions and 77 deletions
|
@ -199,11 +199,18 @@ base_LIBS="$LIBS"
|
|||
|
||||
dnl Check for SDL if enabled.
|
||||
AC_ARG_ENABLE(sdl, [ --enable-sdl Configure to use SDL instead of GLUT], [enable_sdl="$enableval"])
|
||||
AC_ARG_ENABLE(osgviewer, [ --enable-osgviewer Configure to use osgViewer], [enable_osgviewer="$enableval"])
|
||||
AM_CONDITIONAL(USE_SDL, test "x$enable_sdl" = "xyes")
|
||||
AM_CONDITIONAL(USE_OSGVIEWER, test "x$enable_osgviewer" = "xyes")
|
||||
if test "x$enable_sdl" = "xyes"; then
|
||||
AC_DEFINE([PU_USE_SDL], 1, [Define to use SDL])
|
||||
else
|
||||
AC_DEFINE([PU_USE_GLUT], 1, [Define to use glut])
|
||||
if test "x$enable_osgviewer" = "xyes"; then
|
||||
AC_DEFINE([ENABLE_OSGVIEWER], 1, [Define to use osgViewer in renderer])
|
||||
AC_DEFINE([PU_USE_NATIVE], 1, [Define to use native system])
|
||||
else
|
||||
AC_DEFINE([PU_USE_GLUT], 1, [Define to use glut])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl check for OpenGL related libraries
|
||||
|
|
181
src/Main/FGManipulator.cxx
Normal file
181
src/Main/FGManipulator.cxx
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include <osg/Math>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include <plib/pu.h>
|
||||
#include "FGManipulator.hxx"
|
||||
|
||||
// The manipulator is responsible for updating a Viewer's camera. It's
|
||||
// event handling method is also a convenient place to run the the FG
|
||||
// idle and draw handlers.
|
||||
|
||||
void FGManipulator::setByMatrix(const osg::Matrixd& matrix)
|
||||
{
|
||||
// Yuck
|
||||
position = matrix.getTrans();
|
||||
attitude = matrix.getRotate();
|
||||
}
|
||||
|
||||
osg::Matrixd FGManipulator::getMatrix() const
|
||||
{
|
||||
return osg::Matrixd::rotate(attitude) * osg::Matrixd::translate(position);
|
||||
}
|
||||
|
||||
osg::Matrixd FGManipulator::getInverseMatrix() const
|
||||
{
|
||||
return (osg::Matrixd::translate(-position)
|
||||
* osg::Matrixd::rotate(attitude.inverse())) ;
|
||||
}
|
||||
|
||||
// Not used, but part of the interface.
|
||||
void FGManipulator::setNode(osg::Node* node)
|
||||
{
|
||||
_node = node;
|
||||
}
|
||||
|
||||
const osg::Node* FGManipulator::getNode() const
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
osg::Node* FGManipulator::getNode()
|
||||
{
|
||||
return _node.get();
|
||||
}
|
||||
|
||||
namespace {
|
||||
// All the usual translation from window system to FG / plib
|
||||
int osgToFGModifiers(int modifiers)
|
||||
{
|
||||
int result = 0;
|
||||
if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_SHIFT |
|
||||
osgGA::GUIEventAdapter::MODKEY_RIGHT_SHIFT))
|
||||
result |= KEYMOD_SHIFT;
|
||||
if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_CTRL |
|
||||
osgGA::GUIEventAdapter::MODKEY_RIGHT_CTRL))
|
||||
result |= KEYMOD_CTRL;
|
||||
if (modifiers & (osgGA::GUIEventAdapter::MODKEY_LEFT_ALT |
|
||||
osgGA::GUIEventAdapter::MODKEY_RIGHT_ALT))
|
||||
result |= KEYMOD_ALT;
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void FGManipulator::init(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& us)
|
||||
{
|
||||
currentModifiers = osgToFGModifiers(ea.getModKeyMask());
|
||||
(void)handle(ea, us);
|
||||
}
|
||||
|
||||
namespace {
|
||||
void eventToViewport(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& us,
|
||||
int& x, int& y)
|
||||
{
|
||||
osgViewer::Viewer* viewer = dynamic_cast<osgViewer::Viewer*>(&us);
|
||||
osg::Viewport* viewport = viewer->getCamera()->getViewport();
|
||||
const osg::GraphicsContext::Traits* traits
|
||||
= viewer->getCamera()->getGraphicsContext()->getTraits();
|
||||
x = (int)ea.getX();
|
||||
y = (int)ea.getY();
|
||||
if (ea.getMouseYOrientation()
|
||||
== osgGA::GUIEventAdapter::Y_INCREASING_UPWARDS)
|
||||
y = (int)traits->height - y;
|
||||
}
|
||||
}
|
||||
|
||||
bool FGManipulator::handle(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& us)
|
||||
{
|
||||
int x, y;
|
||||
switch (ea.getEventType()) {
|
||||
case osgGA::GUIEventAdapter::FRAME:
|
||||
if (idleHandler)
|
||||
(*idleHandler)();
|
||||
if (drawHandler)
|
||||
(*drawHandler)();
|
||||
return true;
|
||||
case osgGA::GUIEventAdapter::KEYDOWN:
|
||||
case osgGA::GUIEventAdapter::KEYUP:
|
||||
{
|
||||
int key, modmask;
|
||||
handleKey(ea, key, modmask);
|
||||
eventToViewport(ea, us, x, y);
|
||||
if (keyHandler)
|
||||
(*keyHandler)(key, modmask, x, y);
|
||||
}
|
||||
return true;
|
||||
case osgGA::GUIEventAdapter::PUSH:
|
||||
case osgGA::GUIEventAdapter::RELEASE:
|
||||
{
|
||||
eventToViewport(ea, us, x, y);
|
||||
int button = 0;
|
||||
switch (ea.getButton()) {
|
||||
case osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON:
|
||||
button = 0;
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::MIDDLE_MOUSE_BUTTON:
|
||||
button = 1;
|
||||
break;
|
||||
case osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON:
|
||||
button = 2;
|
||||
break;
|
||||
}
|
||||
if (mouseClickHandler)
|
||||
(*mouseClickHandler)(button,
|
||||
(ea.getEventType()
|
||||
== osgGA::GUIEventAdapter::RELEASE), x, y);
|
||||
return true;
|
||||
}
|
||||
case osgGA::GUIEventAdapter::MOVE:
|
||||
case osgGA::GUIEventAdapter::DRAG:
|
||||
eventToViewport(ea, us, x, y);
|
||||
if (mouseMotionHandler)
|
||||
(*mouseMotionHandler)(x, y);
|
||||
return true;
|
||||
case osgGA::GUIEventAdapter::RESIZE:
|
||||
if (windowResizeHandler)
|
||||
(*windowResizeHandler)(ea.getWindowWidth(), ea.getWindowHeight());
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FGManipulator::handleKey(const osgGA::GUIEventAdapter& ea, int& key,
|
||||
int& modifiers)
|
||||
{
|
||||
key = ea.getKey();
|
||||
// XXX Probably other translations are needed too.
|
||||
switch (key) {
|
||||
case osgGA::GUIEventAdapter::KEY_Escape: key = 0x1b; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Return: key = '\n'; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Left: key = PU_KEY_LEFT; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Up: key = PU_KEY_UP; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Right: key = PU_KEY_RIGHT; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Down: key = PU_KEY_DOWN; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Page_Up: key = PU_KEY_PAGE_UP; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Page_Down: key = PU_KEY_PAGE_DOWN; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Home: key = PU_KEY_HOME; break;
|
||||
case osgGA::GUIEventAdapter::KEY_End: key = PU_KEY_END; break;
|
||||
case osgGA::GUIEventAdapter::KEY_Insert: key = PU_KEY_INSERT; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F1: key = PU_KEY_F1; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F2: key = PU_KEY_F2; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F3: key = PU_KEY_F3; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F4: key = PU_KEY_F4; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F5: key = PU_KEY_F5; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F6: key = PU_KEY_F6; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F7: key = PU_KEY_F7; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F8: key = PU_KEY_F8; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F9: key = PU_KEY_F9; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F10: key = PU_KEY_F10; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F11: key = PU_KEY_F11; break;
|
||||
case osgGA::GUIEventAdapter::KEY_F12: key = PU_KEY_F12; break;
|
||||
}
|
||||
modifiers = osgToFGModifiers(ea.getModKeyMask());
|
||||
currentModifiers = modifiers;
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::KEYUP)
|
||||
modifiers |= KEYMOD_RELEASED;
|
||||
}
|
||||
|
124
src/Main/FGManipulator.hxx
Normal file
124
src/Main/FGManipulator.hxx
Normal file
|
@ -0,0 +1,124 @@
|
|||
#ifndef FGMANIPULATOR_H
|
||||
#define FGMANIPULATOR_H 1
|
||||
|
||||
#include <osg/Quat>
|
||||
#include <osgGA/MatrixManipulator>
|
||||
|
||||
#include "fg_os.hxx"
|
||||
|
||||
class FGManipulator : public osgGA::MatrixManipulator {
|
||||
public:
|
||||
FGManipulator() :
|
||||
idleHandler(0), drawHandler(0), windowResizeHandler(0), keyHandler(0),
|
||||
mouseClickHandler(0), mouseMotionHandler(0), currentModifiers(0)
|
||||
{}
|
||||
virtual ~FGManipulator() {}
|
||||
|
||||
virtual const char* className() const {return "FGManipulator"; }
|
||||
|
||||
/** set the position of the matrix manipulator using a 4x4 Matrix.*/
|
||||
virtual void setByMatrix(const osg::Matrixd& matrix);
|
||||
|
||||
virtual void setByInverseMatrix(const osg::Matrixd& matrix)
|
||||
{ setByMatrix(osg::Matrixd::inverse(matrix)); }
|
||||
|
||||
/** get the position of the manipulator as 4x4 Matrix.*/
|
||||
virtual osg::Matrixd getMatrix() const;
|
||||
|
||||
/** get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix.*/
|
||||
virtual osg::Matrixd getInverseMatrix() const;
|
||||
|
||||
virtual void setNode(osg::Node* node);
|
||||
|
||||
const osg::Node* getNode() const;
|
||||
|
||||
osg::Node* getNode();
|
||||
|
||||
virtual void init(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& us);
|
||||
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& us);
|
||||
|
||||
void setIdleHandler(fgIdleHandler idleHandler)
|
||||
{
|
||||
this->idleHandler = idleHandler;
|
||||
}
|
||||
|
||||
fgIdleHandler getIdleHandler() const
|
||||
{
|
||||
return idleHandler;
|
||||
}
|
||||
|
||||
void setDrawHandler(fgDrawHandler drawHandler)
|
||||
{
|
||||
this->drawHandler = drawHandler;
|
||||
}
|
||||
|
||||
fgDrawHandler getDrawHandler() const
|
||||
{
|
||||
return drawHandler;
|
||||
}
|
||||
|
||||
void setWindowResizeHandler(fgWindowResizeHandler windowResizeHandler)
|
||||
{
|
||||
this->windowResizeHandler = windowResizeHandler;
|
||||
}
|
||||
|
||||
fgWindowResizeHandler getWindowResizeHandler() const
|
||||
{
|
||||
return windowResizeHandler;
|
||||
}
|
||||
|
||||
void setKeyHandler(fgKeyHandler keyHandler)
|
||||
{
|
||||
this->keyHandler = keyHandler;
|
||||
}
|
||||
|
||||
fgKeyHandler getKeyHandler() const
|
||||
{
|
||||
return keyHandler;
|
||||
}
|
||||
|
||||
void setMouseClickHandler(fgMouseClickHandler mouseClickHandler)
|
||||
{
|
||||
this->mouseClickHandler = mouseClickHandler;
|
||||
}
|
||||
|
||||
fgMouseClickHandler getMouseClickHandler()
|
||||
{
|
||||
return mouseClickHandler;
|
||||
}
|
||||
|
||||
void setMouseMotionHandler(fgMouseMotionHandler mouseMotionHandler)
|
||||
{
|
||||
this->mouseMotionHandler = mouseMotionHandler;
|
||||
}
|
||||
|
||||
fgMouseMotionHandler getMouseMotionHandler()
|
||||
{
|
||||
return mouseMotionHandler;
|
||||
}
|
||||
|
||||
int getCurrentModifiers() const
|
||||
{
|
||||
return currentModifiers;
|
||||
}
|
||||
void setPosition(const osg::Vec3d position) { this->position = position; }
|
||||
void setAttitude(const osg::Quat attitude) { this->attitude = attitude; }
|
||||
|
||||
protected:
|
||||
osg::ref_ptr<osg::Node> _node;
|
||||
fgIdleHandler idleHandler;
|
||||
fgDrawHandler drawHandler;
|
||||
fgWindowResizeHandler windowResizeHandler;
|
||||
fgKeyHandler keyHandler;
|
||||
fgMouseClickHandler mouseClickHandler;
|
||||
fgMouseMotionHandler mouseMotionHandler;
|
||||
int currentModifiers;
|
||||
osg::Vec3d position;
|
||||
osg::Quat attitude;
|
||||
void handleKey(const osgGA::GUIEventAdapter& ea, int& key, int& modifiers);
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
EXTRA_DIST = 3dfx.sh runfgfs.in runfgfs.bat.in \
|
||||
fg_os_sdl.cxx fg_os.cxx fg_os.hxx
|
||||
fg_os_sdl.cxx fg_os.cxx fg_os_osgviewer.cxx fg_os.hxx
|
||||
|
||||
MPLAYER_LIBS = $(top_builddir)/src/MultiPlayer/libMultiPlayer.a
|
||||
|
||||
|
@ -18,8 +18,12 @@ endif
|
|||
if USE_SDL
|
||||
GFX_CODE = fg_os_sdl.cxx fg_os.hxx
|
||||
else
|
||||
if USE_OSGVIEWER
|
||||
GFX_CODE = fg_os_osgviewer.cxx fg_os.hxx
|
||||
else
|
||||
GFX_CODE = fg_os.cxx fg_os.hxx
|
||||
endif
|
||||
endif
|
||||
|
||||
JSBSIM_LIBS = \
|
||||
$(top_builddir)/src/FDM/JSBSim/libJSBSim.a \
|
||||
|
@ -55,6 +59,7 @@ libMain_a_SOURCES = \
|
|||
util.cxx util.hxx \
|
||||
viewer.cxx viewer.hxx \
|
||||
viewmgr.cxx viewmgr.hxx \
|
||||
FGManipulator.cxx FGManipulator.hxx \
|
||||
$(GFX_CODE)
|
||||
|
||||
fgfs_SOURCES = bootstrap.cxx
|
||||
|
@ -99,7 +104,7 @@ fgfs_LDADD = \
|
|||
-lsgstructure -lsgenvironment \
|
||||
-lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet \
|
||||
-lplibsg -lplibul \
|
||||
-losgUtil -losgDB -losgSim -losg -lOpenThreads \
|
||||
-losgViewer -losgFX -losgUtil -losgDB -losgSim -losg -lOpenThreads \
|
||||
$(THREAD_LIBS) \
|
||||
$(network_LIBS) \
|
||||
-lz \
|
||||
|
|
|
@ -236,3 +236,7 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
|
|||
glutReshapeFunc(GLUTreshape);
|
||||
}
|
||||
|
||||
// Noop; the graphics context is always current
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -76,4 +76,5 @@ void fgRegisterKeyHandler(fgKeyHandler func);
|
|||
void fgRegisterMouseClickHandler(fgMouseClickHandler func);
|
||||
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func);
|
||||
|
||||
void fgMakeCurrent();
|
||||
#endif // _FG_OS_HXX
|
||||
|
|
165
src/Main/fg_os_osgviewer.cxx
Normal file
165
src/Main/fg_os_osgviewer.cxx
Normal file
|
@ -0,0 +1,165 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/Group>
|
||||
#include <osg/Matrixd>
|
||||
#include <osg/Viewport>
|
||||
#include <osgViewer/StatsHandler>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgGA/MatrixManipulator>
|
||||
|
||||
#include "fg_os.hxx"
|
||||
#include "util.hxx"
|
||||
#include "globals.hxx"
|
||||
#include "renderer.hxx"
|
||||
|
||||
// fg_os implementation using OpenSceneGraph's osgViewer::Viewer class
|
||||
// to create the graphics window and run the event/update/render loop.
|
||||
//
|
||||
// fg_os callback registration APIs
|
||||
//
|
||||
|
||||
|
||||
// Event handling and scene graph update is all handled by a
|
||||
// manipulator. See FGManipulator.cpp
|
||||
void fgRegisterIdleHandler(fgIdleHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setIdleHandler(func);
|
||||
}
|
||||
|
||||
void fgRegisterDrawHandler(fgDrawHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setDrawHandler(func);
|
||||
}
|
||||
|
||||
void fgRegisterWindowResizeHandler(fgWindowResizeHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setWindowResizeHandler(func);
|
||||
}
|
||||
|
||||
void fgRegisterKeyHandler(fgKeyHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setKeyHandler(func);
|
||||
}
|
||||
|
||||
void fgRegisterMouseClickHandler(fgMouseClickHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setMouseClickHandler(func);
|
||||
}
|
||||
|
||||
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
|
||||
{
|
||||
globals->get_renderer()->getManipulator()->setMouseMotionHandler(func);
|
||||
}
|
||||
|
||||
// Redraw "happens" every frame whether you want it or not.
|
||||
void fgRequestRedraw()
|
||||
{
|
||||
}
|
||||
|
||||
//
|
||||
// fg_os implementation
|
||||
//
|
||||
|
||||
|
||||
static osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||
|
||||
void fgOSOpenWindow(int w, int h, int bpp,
|
||||
bool alpha, bool stencil, bool fullscreen)
|
||||
{
|
||||
viewer = new osgViewer::Viewer;
|
||||
// Avoid complications with fg's custom drawables.
|
||||
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits
|
||||
= new osg::GraphicsContext::Traits;
|
||||
int cbits = (bpp <= 16) ? 5 : 8;
|
||||
int zbits = (bpp <= 16) ? 16 : 24;
|
||||
traits->width = w;
|
||||
traits->height = h;
|
||||
traits->red = traits->green = traits->blue = cbits;
|
||||
traits->depth = zbits;
|
||||
if (alpha)
|
||||
traits->alpha = 8;
|
||||
if (stencil)
|
||||
traits->stencil = 8;
|
||||
if (fullscreen)
|
||||
traits->windowDecoration = false;
|
||||
else
|
||||
traits->windowDecoration = true;
|
||||
traits->supportsResize = true;
|
||||
traits->doubleBuffer = true;
|
||||
osg::GraphicsContext* gc
|
||||
= osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
viewer->getCamera()->setGraphicsContext(gc);
|
||||
// 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.
|
||||
viewer->getCamera()->setViewport(new osg::Viewport(0, 0,
|
||||
traits->width,
|
||||
traits->height));
|
||||
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());
|
||||
}
|
||||
|
||||
static int status = 0;
|
||||
|
||||
void fgOSExit(int code)
|
||||
{
|
||||
viewer->setDone(true);
|
||||
status = code;
|
||||
}
|
||||
|
||||
void fgOSMainLoop()
|
||||
{
|
||||
viewer->run();
|
||||
fgExit(status);
|
||||
}
|
||||
|
||||
int fgGetKeyModifiers()
|
||||
{
|
||||
return globals->get_renderer()->getManipulator()->getCurrentModifiers();
|
||||
}
|
||||
|
||||
void fgWarpMouse(int x, int y)
|
||||
{
|
||||
viewer->requestWarpPointer((float)x, (float)y);
|
||||
}
|
||||
|
||||
// Noop
|
||||
void fgOSInit(int* argc, char** argv)
|
||||
{
|
||||
}
|
||||
|
||||
void fgOSFullScreen()
|
||||
{
|
||||
// Noop, but is probably doable
|
||||
|
||||
}
|
||||
|
||||
// No support in OSG yet
|
||||
void fgSetMouseCursor(int cursor)
|
||||
{
|
||||
}
|
||||
|
||||
int fgGetMouseCursor()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
osg::GraphicsContext* gc = viewer->getCamera()->getGraphicsContext();
|
||||
gc->makeCurrent();
|
||||
}
|
|
@ -407,3 +407,8 @@ static void initCursors()
|
|||
cursors[i].hoty);
|
||||
}
|
||||
}
|
||||
|
||||
// Noop; the graphics context is always current
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -603,6 +603,9 @@ static void fgMainLoop( void ) {
|
|||
// then on.
|
||||
|
||||
static void fgIdleFunction ( void ) {
|
||||
// Some intialization requires a valid graphics context, in
|
||||
// particular that of plib. Boo, hiss!
|
||||
fgMakeCurrent();
|
||||
if ( idle_state == 0 ) {
|
||||
idle_state++;
|
||||
|
||||
|
|
|
@ -358,6 +358,9 @@ FGRenderer::FGRenderer()
|
|||
#ifdef FG_JPEG_SERVER
|
||||
jpgRenderFrame = FGRenderer::update;
|
||||
#endif
|
||||
#ifdef ENABLE_OSGVIEWER
|
||||
manipulator = new FGManipulator;
|
||||
#endif
|
||||
}
|
||||
|
||||
FGRenderer::~FGRenderer()
|
||||
|
@ -368,20 +371,38 @@ FGRenderer::~FGRenderer()
|
|||
}
|
||||
|
||||
// Initialize various GL/view parameters
|
||||
// XXX This should be called "preinit" or something, as it initializes
|
||||
// critical parts of the scene graph in addition to the splash screen.
|
||||
void
|
||||
FGRenderer::splashinit( void ) {
|
||||
// Add the splash screen node
|
||||
mRealRoot->addChild(fgCreateSplashNode());
|
||||
sceneView->setSceneData(mRealRoot.get());
|
||||
|
||||
sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
|
||||
sceneView->setFrameStamp(mFrameStamp.get());
|
||||
sceneView->setUpdateVisitor(mUpdateVisitor.get());
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if (viewer) {
|
||||
sceneView = 0;
|
||||
mRealRoot = dynamic_cast<osg::Group*>(viewer->getSceneData());
|
||||
mRealRoot->addChild(fgCreateSplashNode());
|
||||
osgViewer::Scene* scene = viewer->getScene();
|
||||
scene->setFrameStamp(mFrameStamp.get());
|
||||
// Scene doesn't seem to pass the frame stamp to the update
|
||||
// visitor automatically.
|
||||
mUpdateVisitor->setFrameStamp(mFrameStamp.get());
|
||||
scene->setUpdateVisitor(mUpdateVisitor.get());
|
||||
} else {
|
||||
// Add the splash screen node
|
||||
mRealRoot->addChild(fgCreateSplashNode());
|
||||
sceneView->setSceneData(mRealRoot.get());
|
||||
sceneView->setDefaults(osgUtil::SceneView::COMPILE_GLOBJECTS_AT_INIT);
|
||||
sceneView->setFrameStamp(mFrameStamp.get());
|
||||
sceneView->setUpdateVisitor(mUpdateVisitor.get());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FGRenderer::init( void ) {
|
||||
|
||||
// The viewer can call this before the graphics context is current
|
||||
// in the main thread; indeed, in a multithreaded setup it might
|
||||
// never be current in the main thread.
|
||||
fgMakeCurrent();
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
osg::initNotifyLevel();
|
||||
|
||||
// The number of polygon-offset "units" to place between layers. In
|
||||
|
@ -406,9 +427,13 @@ FGRenderer::init( void ) {
|
|||
glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
|
||||
glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
|
||||
|
||||
|
||||
sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
if (viewer) {
|
||||
viewer->getCamera()
|
||||
->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
} else {
|
||||
sceneView->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
sceneView->getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
}
|
||||
|
||||
|
||||
osg::StateSet* stateSet = mRoot->getOrCreateStateSet();
|
||||
|
@ -521,6 +546,7 @@ FGRenderer::init( void ) {
|
|||
mRealRoot->addChild(sw);
|
||||
mRealRoot->addChild(FGCreateRedoutNode());
|
||||
mRealRoot->addChild(guiCamera);
|
||||
// sceneView->getState()->setCheckForGLErrors(osg::State::ONCE_PER_ATTRIBUTE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -529,7 +555,7 @@ void
|
|||
FGRenderer::update( bool refresh_camera_settings ) {
|
||||
bool scenery_loaded = fgGetBool("sim/sceneryloaded")
|
||||
|| fgGetBool("sim/sceneryloaded-override");
|
||||
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if ( idle_state < 1000 || !scenery_loaded ) {
|
||||
fgSetDouble("/sim/startup/splash-alpha", 1.0);
|
||||
|
||||
|
@ -537,10 +563,11 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
globals->set_sim_time_sec( 0.0 );
|
||||
|
||||
// the splash screen is now in the scenegraph
|
||||
sceneView->update();
|
||||
sceneView->cull();
|
||||
sceneView->draw();
|
||||
|
||||
if (!viewer) {
|
||||
sceneView->update();
|
||||
sceneView->cull();
|
||||
sceneView->draw();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -586,18 +613,30 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
SGVec3d position = current__view->getViewPosition();
|
||||
SGQuatd attitude = current__view->getViewOrientation();
|
||||
SGVec3d osgPosition = attitude.transform(-position);
|
||||
mCameraView->setPosition(osgPosition.osg());
|
||||
mCameraView->setAttitude(inverse(attitude).osg());
|
||||
if (viewer) {
|
||||
FGManipulator *manipulator
|
||||
= globals->get_renderer()->getManipulator();
|
||||
manipulator->setPosition(position.osg());
|
||||
manipulator->setAttitude(attitude.osg());
|
||||
} else {
|
||||
mCameraView->setPosition(osgPosition.osg());
|
||||
mCameraView->setAttitude(inverse(attitude).osg());
|
||||
}
|
||||
}
|
||||
|
||||
osg::Camera *camera;
|
||||
if (viewer)
|
||||
camera = viewer->getCamera();
|
||||
else
|
||||
camera = sceneView->getCamera();
|
||||
if ( skyblend ) {
|
||||
|
||||
if ( fgGetBool("/sim/rendering/textures") ) {
|
||||
SGVec4f clearColor(l->adj_fog_color());
|
||||
sceneView->getCamera()->setClearColor(clearColor.osg());
|
||||
camera->setClearColor(clearColor.osg());
|
||||
}
|
||||
} else {
|
||||
SGVec4f clearColor(l->sky_color());
|
||||
sceneView->getCamera()->setClearColor(clearColor.osg());
|
||||
camera->setClearColor(clearColor.osg());
|
||||
}
|
||||
|
||||
// update fog params if visibility has changed
|
||||
|
@ -756,8 +795,10 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
// shadows->endOfFrame();
|
||||
|
||||
// need to call the update visitor once
|
||||
mFrameStamp->setReferenceTime(globals->get_sim_time_sec());
|
||||
mFrameStamp->setFrameNumber(1+mFrameStamp->getFrameNumber());
|
||||
if (!viewer) {
|
||||
mFrameStamp->setReferenceTime(globals->get_sim_time_sec());
|
||||
mFrameStamp->setFrameNumber(1+mFrameStamp->getFrameNumber());
|
||||
}
|
||||
mFrameStamp->setCalendarTime(*globals->get_time_params()->getGmt());
|
||||
mUpdateVisitor->setViewData(current__view->getViewPosition(),
|
||||
current__view->getViewOrientation());
|
||||
|
@ -767,15 +808,24 @@ FGRenderer::update( bool refresh_camera_settings ) {
|
|||
l->adj_fog_color(),
|
||||
l->get_sun_angle()*SGD_RADIANS_TO_DEGREES);
|
||||
mUpdateVisitor->setVisibility(actual_visibility);
|
||||
|
||||
if (fgGetBool("/sim/panel-hotspots"))
|
||||
sceneView->setCullMask(sceneView->getCullMask()|SG_NODEMASK_PICK_BIT);
|
||||
else
|
||||
sceneView->setCullMask(sceneView->getCullMask()&(~SG_NODEMASK_PICK_BIT));
|
||||
|
||||
sceneView->update();
|
||||
sceneView->cull();
|
||||
sceneView->draw();
|
||||
bool hotspots = fgGetBool("/sim/panel-hotspots");
|
||||
if (viewer) {
|
||||
if (hotspots)
|
||||
camera->setCullMask(camera->getCullMask()|SG_NODEMASK_PICK_BIT);
|
||||
else
|
||||
camera->setCullMask(camera->getCullMask()
|
||||
& ~SG_NODEMASK_PICK_BIT);
|
||||
} else {
|
||||
if (hotspots)
|
||||
sceneView->setCullMask(sceneView->getCullMask()
|
||||
|SG_NODEMASK_PICK_BIT);
|
||||
else
|
||||
sceneView->setCullMask(sceneView->getCullMask()
|
||||
&(~SG_NODEMASK_PICK_BIT));
|
||||
sceneView->update();
|
||||
sceneView->cull();
|
||||
sceneView->draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -793,8 +843,13 @@ FGRenderer::resize( int width, int height ) {
|
|||
} else {
|
||||
view_h = height;
|
||||
}
|
||||
|
||||
sceneView->getViewport()->setViewport(0, height - view_h, width, view_h);
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if (viewer)
|
||||
viewer->getCamera()->getViewport()->setViewport(0, height - view_h,
|
||||
width, view_h);
|
||||
else
|
||||
sceneView->getViewport()->setViewport(0, height - view_h,
|
||||
width, view_h);
|
||||
|
||||
static int lastwidth = 0;
|
||||
static int lastheight = 0;
|
||||
|
@ -842,11 +897,17 @@ static void fgHackFrustum() {
|
|||
= fgGetNode("/sim/current-view/frustum-bottom-pct");
|
||||
static SGPropertyNode *top_pct
|
||||
= fgGetNode("/sim/current-view/frustum-top-pct");
|
||||
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
double left, right;
|
||||
double bottom, top;
|
||||
double zNear, zFar;
|
||||
sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top, zNear, zFar);
|
||||
if (viewer)
|
||||
viewer->getCamera()->getProjectionMatrixAsFrustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
else
|
||||
sceneView->getProjectionMatrixAsFrustum(left, right, bottom, top,
|
||||
zNear, zFar);
|
||||
// cout << " l = " << f->getLeft()
|
||||
// << " r = " << f->getRight()
|
||||
// << " b = " << f->getBot()
|
||||
|
@ -883,8 +944,11 @@ static void fgHackFrustum() {
|
|||
} else {
|
||||
t = top;
|
||||
}
|
||||
|
||||
sceneView->setProjectionMatrixAsFrustum(l, r, b, t, zNear, zFar);
|
||||
if (viewer)
|
||||
viewer->getCamera()->setProjectionMatrixAsFrustum(l, r, b, t,
|
||||
zNear, zFar);
|
||||
else
|
||||
sceneView->setProjectionMatrixAsFrustum(l, r, b, t, zNear, zFar);
|
||||
}
|
||||
|
||||
|
||||
|
@ -906,10 +970,15 @@ static float fov_far = 1000.0;
|
|||
void FGRenderer::setFOV( float w, float h ) {
|
||||
fov_width = w;
|
||||
fov_height = h;
|
||||
|
||||
sceneView->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if (viewer)
|
||||
viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
else
|
||||
sceneView->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
// fully specify the view frustum before hacking it (so we don't
|
||||
// accumulate hacked effects
|
||||
fgHackFrustum();
|
||||
|
@ -925,10 +994,15 @@ void FGRenderer::setNearFar( float n, float f ) {
|
|||
n = 0.1;
|
||||
fov_near = n;
|
||||
fov_far = f;
|
||||
|
||||
sceneView->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if (viewer)
|
||||
viewer->getCamera()->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
else
|
||||
sceneView->setProjectionMatrixAsPerspective(fov_height,
|
||||
fov_width/fov_height,
|
||||
fov_near, fov_far);
|
||||
|
||||
// fully specify the view frustum before hacking it (so we don't
|
||||
// accumulate hacked effects
|
||||
|
@ -939,40 +1013,54 @@ bool
|
|||
FGRenderer::pick( unsigned x, unsigned y,
|
||||
std::vector<SGSceneryPick>& pickList )
|
||||
{
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
// wipe out the return ...
|
||||
pickList.resize(0);
|
||||
|
||||
// we can get called early ...
|
||||
if (!sceneView.valid())
|
||||
return false;
|
||||
|
||||
osg::Node* sceneData = globals->get_scenery()->get_scene_graph();
|
||||
if (!sceneData)
|
||||
return false;
|
||||
osg::Viewport* viewport = sceneView->getViewport();
|
||||
if (!viewport)
|
||||
osg::Viewport* viewport = 0;
|
||||
osg::Matrix projection;
|
||||
osg::Matrix modelview;
|
||||
|
||||
if (sceneView.valid()) {
|
||||
viewport = sceneView->getViewport();
|
||||
if (!viewport)
|
||||
return false;
|
||||
// don't know why, but the update has partly happened somehow,
|
||||
// so update the scenery part of the viewer
|
||||
FGViewer *current_view = globals->get_current_view();
|
||||
// Force update of center dependent values ...
|
||||
current_view->set_dirty();
|
||||
SGVec3d position = current_view->getViewPosition();
|
||||
SGQuatd attitude = current_view->getViewOrientation();
|
||||
SGVec3d osgPosition = attitude.transform(-position);
|
||||
mCameraView->setPosition(osgPosition.osg());
|
||||
mCameraView->setAttitude(inverse(attitude).osg());
|
||||
|
||||
osg::Matrix projection(sceneView->getProjectionMatrix());
|
||||
osg::Matrix modelview(sceneView->getViewMatrix());
|
||||
|
||||
osg::NodePathList nodePath = sceneData->getParentalNodePaths();
|
||||
// modify the view matrix so that it accounts for this nodePath's
|
||||
// accumulated transform
|
||||
if (!nodePath.empty())
|
||||
modelview.preMult(computeLocalToWorld(nodePath.front()));
|
||||
} else if (viewer) {
|
||||
// I don't think the Viewer case needs to update the camera
|
||||
// matrices before picking. The user has clicked on the old scene
|
||||
// -- that which is displayed in the front buffer -- so we need to
|
||||
// use the camera state in effect for that view of the scene.
|
||||
osg::Camera *camera = viewer->getCamera();
|
||||
viewport = camera->getViewport();
|
||||
projection = camera->getProjectionMatrix();
|
||||
modelview = camera->getViewMatrix();
|
||||
// Accumulated transforms? Don't think that applies for the
|
||||
// Viewer's camera.
|
||||
} else { // we can get called early ...
|
||||
return false;
|
||||
|
||||
// don't know why, but the update has partly happened somehow,
|
||||
// so update the scenery part of the viewer
|
||||
FGViewer *current_view = globals->get_current_view();
|
||||
// Force update of center dependent values ...
|
||||
current_view->set_dirty();
|
||||
SGVec3d position = current_view->getViewPosition();
|
||||
SGQuatd attitude = current_view->getViewOrientation();
|
||||
SGVec3d osgPosition = attitude.transform(-position);
|
||||
mCameraView->setPosition(osgPosition.osg());
|
||||
mCameraView->setAttitude(inverse(attitude).osg());
|
||||
|
||||
osg::Matrix projection(sceneView->getProjectionMatrix());
|
||||
osg::Matrix modelview(sceneView->getViewMatrix());
|
||||
|
||||
osg::NodePathList nodePath = sceneData->getParentalNodePaths();
|
||||
// modify the view matrix so that it accounts for this nodePath's
|
||||
// accumulated transform
|
||||
if (!nodePath.empty())
|
||||
modelview.preMult(computeLocalToWorld(nodePath.front()));
|
||||
|
||||
}
|
||||
// swap the y values ...
|
||||
y = viewport->height() - y;
|
||||
// set up the pick visitor
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
#include <simgear/scene/sky/sky.hxx>
|
||||
#include <simgear/scene/util/SGPickCallback.hxx>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
|
||||
#include "FGManipulator.hxx"
|
||||
|
||||
#define FG_ENABLE_MULTIPASS_CLOUDS 1
|
||||
|
||||
class SGSky;
|
||||
|
@ -51,6 +55,23 @@ public:
|
|||
*/
|
||||
static bool pick( unsigned x, unsigned y,
|
||||
std::vector<SGSceneryPick>& pickList );
|
||||
|
||||
/** Get and set the OSG Viewer object, if any.
|
||||
*/
|
||||
osgViewer::Viewer* getViewer() { return viewer.get(); }
|
||||
const osgViewer::Viewer* getViewer() const { return viewer.get(); }
|
||||
void setViewer(osgViewer::Viewer* viewer) { this->viewer = viewer; }
|
||||
/** Get and set the manipulator object, if any.
|
||||
*/
|
||||
FGManipulator* getManipulator() { return manipulator.get(); }
|
||||
const FGManipulator* getManipulator() const { return manipulator.get(); }
|
||||
void setManipulator(FGManipulator* manipulator)
|
||||
{
|
||||
this->manipulator = manipulator;
|
||||
}
|
||||
protected:
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||
osg::ref_ptr<FGManipulator> manipulator;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/renderer.hxx>
|
||||
|
||||
#include "jpg-httpd.hxx"
|
||||
|
||||
|
@ -106,7 +107,15 @@ void HttpdImageChannel :: foundTerminator( void ) {
|
|||
SG_LOG( SG_IO, SG_DEBUG, "<<<<<<<<< HTTP Request : " << pRequest );
|
||||
|
||||
double left, right, bottom, top, zNear, zFar;
|
||||
sceneView->getCamera()->getProjectionMatrixAsFrustum( left, right, bottom, top, zNear, zFar );
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
if (viewer)
|
||||
viewer->getCamera()->getProjectionMatrixAsFrustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
else
|
||||
sceneView->getCamera()->getProjectionMatrixAsFrustum(left, right,
|
||||
bottom, top,
|
||||
zNear, zFar);
|
||||
JpgFactory->setFrustum( left, right, bottom, top, zNear, zFar );
|
||||
|
||||
nImageLen = JpgFactory -> render();
|
||||
|
|
Loading…
Add table
Reference in a new issue