Clean up OSG camera setup and interface to plib PUI
Switch to defining PU_USE_NONE and providing our own callback functions to pui for "get window" and "get window size." A new WindowSystemAdapter class assigns ID numbers to windows for the purpose of identifying them to plib; the window size can be extracted from the osg::GraphicsContext class in all the different implementations (osgViewer, glut, sdl). Implement a GraphicsContextOperation that runs code in a particular graphics context, perhaps in another thread, and provides an isFinished() method to test if the operation has finished. This allows us to initialize plib PUI properly if there are multiple graphics contexts without using fgMakeCurrent(). fgMakeCurrent() can't work in multi-threaded OSG configurations. Eliminate fgMakeCurrent() and all its uses, either by using GraphicsContextOperation or by seeing that it is not necessary. Attach the GUI camera as a slave camera. Don't manipulate the OSG state in the drawImplementation() functions for SGHUDAndPanelDrawable and SGPuDrawable; it's not needed.
This commit is contained in:
parent
c92dcc6b24
commit
580ebf637b
18 changed files with 649 additions and 295 deletions
17
configure.ac
17
configure.ac
|
@ -206,17 +206,14 @@ AM_CONDITIONAL(USE_GLUT, test "x$enable_glut" = "xyes")
|
|||
if test "x$enable_sdl" != "xyes" -a "x$enable_glut" != "xyes" -a "x$enable_osgviewer" != "xno"; then
|
||||
enable_osgviewer="yes"
|
||||
fi
|
||||
if test "x$enable_osgviewer" = "xyes"; then
|
||||
AC_DEFINE([USE_OSGVIEWER], 1, [Define to use osgViewer in renderer])
|
||||
AC_DEFINE([ENABLE_OSGVIEWER], 1, [Define to use osgViewer in renderer])
|
||||
AC_DEFINE([PU_USE_NATIVE], 1, [Define to use native system])
|
||||
elif test "x$enable_sdl" = "xyes"; then
|
||||
AC_DEFINE([PU_USE_SDL], 1, [Define to use SDL])
|
||||
elif test "x$enable_glut" = "xyes"; then
|
||||
AC_DEFINE([PU_USE_GLUT], 1, [Define to use glut])
|
||||
else
|
||||
AC_MSG_ERROR([One (and only one) of --enable-osgviewer, --enable-sdl, or --enable-glut must be supplied])
|
||||
if test \( "x$enable_osgviewer" = "xyes" \
|
||||
-a \( "x$enable_sdl" = "xyes" -o "x$enable_glut" = "xyes" \) \) \
|
||||
-o \( "x$enable_sdl" = "xyes" -a "x$enable_glut" = "xyes" \); then
|
||||
echo " Only one of --enable-osgviewer, --enable-sdl, or --enable -glut may"
|
||||
echo " be supplied."
|
||||
exit
|
||||
fi
|
||||
AC_DEFINE([PU_USE_NONE], 1, [Define to use application's pu callbacks])
|
||||
|
||||
AC_ARG_ENABLE(osgdebug, [ --enable-osgdebug Use OSG debug libraries], [enable_osgdebug="$enableval"])
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..\..\..;..\..\src;..\..\src\include;..\..\..\SimGear;"..\..\..\pthreads-w32-2-7-0-release";..\..\src\FDM\JSBSim;..\..\..\OpenSceneGraph\include;..\..\..\OpenThreads\include;..\..\..\3rdParty\include"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ENABLE_OSGVIEWER;PU_USE_NATIVE"
|
||||
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
|
||||
StringPooling="TRUE"
|
||||
BasicRuntimeChecks="0"
|
||||
RuntimeLibrary="3"
|
||||
|
@ -88,7 +88,7 @@
|
|||
Name="VCCLCompilerTool"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="..\..\..;..\..\src;..\..\src\include;..\..\src\FDM\JSBSim;..\..\..\SimGear;"..\..\..\pthreads-w32-2-7-0-release";..\..\..\OpenSceneGraph\include;..\..\..\Producer\include;..\..\..\OpenThreads\include;..\..\..\3rdParty\include"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS;ENABLE_OSGVIEWER;PU_USE_NATIVE"
|
||||
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;HAVE_CONFIG_H;FGFS;ENABLE_AUDIO_SUPPORT;_FG_NDEBUG;ENABLE_THREADS=1;FG_ENABLE_MULTIPASS_CLOUDS;ENABLE_SP_FMDS;_USE_MATH_DEFINES;FG_JPEG_SERVER;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
|
||||
StringPooling="TRUE"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="TRUE"
|
||||
|
|
|
@ -566,7 +566,7 @@ void fgCockpitUpdate( osg::State* state ) {
|
|||
|
||||
|
||||
struct FuncTable {
|
||||
char *name;
|
||||
const char *name;
|
||||
FLTFNPTR func;
|
||||
} fn_table[] = {
|
||||
{ "agl", get_agl },
|
||||
|
|
105
src/GUI/gui.cxx
105
src/GUI/gui.cxx
|
@ -34,6 +34,8 @@
|
|||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <simgear/structure/exception.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/props/props.hxx>
|
||||
|
@ -45,12 +47,15 @@
|
|||
#include <Main/main.hxx>
|
||||
#include <Main/globals.hxx>
|
||||
#include <Main/fg_props.hxx>
|
||||
#include <Main/WindowSystemAdapter.hxx>
|
||||
#include <GUI/new_gui.hxx>
|
||||
|
||||
#include "gui.h"
|
||||
#include "gui_local.hxx"
|
||||
#include "layout.hxx"
|
||||
|
||||
using namespace osg;
|
||||
using namespace flightgear;
|
||||
|
||||
puFont guiFnt = 0;
|
||||
|
||||
|
@ -59,48 +64,76 @@ puFont guiFnt = 0;
|
|||
init the gui
|
||||
_____________________________________________________________________*/
|
||||
|
||||
|
||||
void guiInit()
|
||||
namespace
|
||||
{
|
||||
char *mesa_win_state;
|
||||
class GUIInitOperation : public GraphicsContextOperation
|
||||
{
|
||||
public:
|
||||
GUIInitOperation() : GraphicsContextOperation(std::string("GUI init"))
|
||||
{
|
||||
}
|
||||
void run(GraphicsContext* gc)
|
||||
{
|
||||
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||
wsa->puInitialize();
|
||||
puSetDefaultStyle ( PUSTYLE_SMALL_SHADED ); //PUSTYLE_DEFAULT
|
||||
puSetDefaultColourScheme (0.8, 0.8, 0.9, 1);
|
||||
|
||||
// Initialize PUI
|
||||
#ifndef PU_USE_NONE
|
||||
puInit();
|
||||
#endif
|
||||
puSetDefaultStyle ( PUSTYLE_SMALL_SHADED ); //PUSTYLE_DEFAULT
|
||||
puSetDefaultColourScheme (0.8, 0.8, 0.9, 1);
|
||||
FGFontCache *fc = globals->get_fontcache();
|
||||
puFont *GuiFont
|
||||
= fc->get(globals->get_locale()->getStringValue("font",
|
||||
"typewriter.txf"),
|
||||
15);
|
||||
puSetDefaultFonts(*GuiFont, *GuiFont);
|
||||
guiFnt = puGetDefaultLabelFont();
|
||||
|
||||
FGFontCache *fc = globals->get_fontcache();
|
||||
puFont *GuiFont = fc->get(globals->get_locale()->getStringValue("font", "typewriter.txf"), 15);
|
||||
puSetDefaultFonts(*GuiFont, *GuiFont);
|
||||
guiFnt = puGetDefaultLabelFont();
|
||||
|
||||
LayoutWidget::setDefaultFont(GuiFont, 15);
|
||||
LayoutWidget::setDefaultFont(GuiFont, 15);
|
||||
|
||||
if (!fgHasNode("/sim/startup/mouse-pointer")) {
|
||||
// no preference specified for mouse pointer, attempt to autodetect...
|
||||
// Determine if we need to render the cursor, or if the windowing
|
||||
// system will do it. First test if we are rendering with glide.
|
||||
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
|
||||
// Test for the MESA_GLX_FX env variable
|
||||
if ( (mesa_win_state = getenv( "MESA_GLX_FX" )) != NULL) {
|
||||
// test if we are fullscreen mesa/glide
|
||||
if ( (mesa_win_state[0] == 'f') ||
|
||||
(mesa_win_state[0] == 'F') ) {
|
||||
puShowCursor ();
|
||||
if (!fgHasNode("/sim/startup/mouse-pointer")) {
|
||||
// no preference specified for mouse pointer, attempt to autodetect...
|
||||
// Determine if we need to render the cursor, or if the windowing
|
||||
// system will do it. First test if we are rendering with
|
||||
// glide.
|
||||
// XXX Not bloody likely in 2008...
|
||||
if ( strstr ( general.get_glRenderer(), "Glide" ) ) {
|
||||
// Test for the MESA_GLX_FX env variable
|
||||
char *mesa_win_state = getenv( "MESA_GLX_FX" );
|
||||
if (mesa_win_state != NULL) {
|
||||
// test if we are fullscreen mesa/glide
|
||||
if ( (mesa_win_state[0] == 'f') ||
|
||||
(mesa_win_state[0] == 'F') ) {
|
||||
puShowCursor ();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if ( !fgGetBool("/sim/startup/mouse-pointer") ) {
|
||||
// don't show pointer
|
||||
} else {
|
||||
// force showing pointer
|
||||
puShowCursor();
|
||||
}
|
||||
// mouse_active = ~mouse_active;
|
||||
} else if ( !fgGetBool("/sim/startup/mouse-pointer") ) {
|
||||
// don't show pointer
|
||||
} else {
|
||||
// force showing pointer
|
||||
puShowCursor();
|
||||
// mouse_active = ~mouse_active;
|
||||
}
|
||||
|
||||
// MOUSE_VIEW mode stuff
|
||||
initMouseQuat();
|
||||
};
|
||||
|
||||
ref_ptr<GUIInitOperation> initOp;
|
||||
}
|
||||
|
||||
void guiStartInit()
|
||||
{
|
||||
initOp = new GUIInitOperation;
|
||||
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||
GraphicsContext* gc = wsa->getGUIGraphicsContext();
|
||||
gc->add(initOp.get());
|
||||
}
|
||||
|
||||
bool guiFinishInit()
|
||||
{
|
||||
if (!initOp.valid())
|
||||
return false;
|
||||
if (!initOp->isFinished())
|
||||
return false;
|
||||
initMouseQuat();
|
||||
initOp = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
|
||||
|
||||
// gui.cxx
|
||||
extern void guiInit();
|
||||
extern void guiStartInit();
|
||||
extern bool guiFinishInit();
|
||||
extern void mkDialog(const char *txt);
|
||||
extern void guiErrorMessage(const char *txt);
|
||||
extern void guiErrorMessage(const char *txt, const sg_throwable &throwable);
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
|
||||
/* Special single config.h for MSVC8 build */
|
||||
|
||||
#define ENABLE_OSGVIEWER
|
||||
#define PU_USE_NATIVE
|
||||
|
||||
#define ENABLE_OSGVIEWER
|
||||
#define PU_USE_NATIVE
|
||||
|
||||
/* Define to enable plib joystick support */
|
||||
#ifndef ENABLE_PLIB_JOYSTICK
|
||||
#define ENABLE_PLIB_JOYSTICK
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
|
||||
/* Special single config.h for MSVC6 build - Geoff McLane - 23 July, 2003 */
|
||||
|
||||
#define ENABLE_OSGVIEWER
|
||||
#define PU_USE_NATIVE
|
||||
|
||||
/* Define to enable plib joystick support */
|
||||
#ifndef ENABLE_PLIB_JOYSTICK
|
||||
#define ENABLE_PLIB_JOYSTICK
|
||||
|
|
|
@ -327,8 +327,6 @@ FGInput::doMouseClick (int b, int updown, int x, int y, bool mainWindow, const o
|
|||
}
|
||||
|
||||
if (mode.pass_through) {
|
||||
// The pu stuff seems to need that. May be it does opengl picking ...
|
||||
fgMakeCurrent();
|
||||
if (0 <= x && 0 <= y && puMouse(b, updown, x, y))
|
||||
return;
|
||||
else if (0 <= x && 0 <= y && (globals->get_current_panel() != 0) &&
|
||||
|
|
|
@ -62,6 +62,7 @@ libMain_a_SOURCES = \
|
|||
viewmgr.cxx viewmgr.hxx \
|
||||
FGManipulator.cxx FGManipulator.hxx \
|
||||
ViewPartitionNode.cxx ViewPartitionNode.hxx \
|
||||
WindowSystemAdapter.hxx WindowSystemAdapter.cxx \
|
||||
$(GFX_CODE)
|
||||
|
||||
fgfs_SOURCES = bootstrap.cxx
|
||||
|
|
118
src/Main/WindowSystemAdapter.cxx
Normal file
118
src/Main/WindowSystemAdapter.cxx
Normal file
|
@ -0,0 +1,118 @@
|
|||
// Copyright (C) 2008 Tim Moore
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <plib/pu.h>
|
||||
|
||||
#include<algorithm>
|
||||
#include <functional>
|
||||
|
||||
#include "WindowSystemAdapter.hxx"
|
||||
|
||||
using namespace osg;
|
||||
using namespace std;
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
ref_ptr<WindowSystemAdapter> WindowSystemAdapter::_wsa;
|
||||
|
||||
void GraphicsContextOperation::operator()(GraphicsContext* gc)
|
||||
{
|
||||
run(gc);
|
||||
++done;
|
||||
}
|
||||
|
||||
WindowSystemAdapter::WindowSystemAdapter() :
|
||||
_nextWindowID(0), _nextCameraID(0), _isPuInitialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
GraphicsWindow*
|
||||
WindowSystemAdapter::registerWindow(GraphicsContext* gc,
|
||||
const string& windowName)
|
||||
{
|
||||
GraphicsWindow* window = new GraphicsWindow(gc, windowName,
|
||||
_nextWindowID++);
|
||||
windows.push_back(window);
|
||||
return window;
|
||||
}
|
||||
|
||||
Camera3D*
|
||||
WindowSystemAdapter::registerCamera3D(GraphicsWindow* gw, Camera* camera,
|
||||
const string& cameraName)
|
||||
{
|
||||
Camera3D* camera3D = new Camera3D(gw, camera, cameraName);
|
||||
cameras.push_back(camera3D);
|
||||
return camera3D;
|
||||
}
|
||||
|
||||
GraphicsWindow*
|
||||
WindowSystemAdapter::getGUIWindow()
|
||||
{
|
||||
WindowVector::const_iterator contextIter
|
||||
= std::find_if(windows.begin(), windows.end(),
|
||||
FlagTester<GraphicsWindow>(GraphicsWindow::GUI));
|
||||
if (contextIter == windows.end())
|
||||
return 0;
|
||||
else
|
||||
return contextIter->get();
|
||||
}
|
||||
|
||||
int
|
||||
WindowSystemAdapter::getGUIWindowID()
|
||||
{
|
||||
const GraphicsWindow* gw = getGUIWindow();
|
||||
if (!gw)
|
||||
return -1;
|
||||
else
|
||||
return gw->id;
|
||||
}
|
||||
|
||||
GraphicsContext*
|
||||
WindowSystemAdapter::getGUIGraphicsContext()
|
||||
{
|
||||
GraphicsWindow* gw = getGUIWindow();
|
||||
if (!gw)
|
||||
return 0;
|
||||
else
|
||||
return gw->gc.get();
|
||||
}
|
||||
|
||||
|
||||
int WindowSystemAdapter::puGetWindow()
|
||||
{
|
||||
WindowSystemAdapter* wsa = getWSA();
|
||||
return wsa->getGUIWindowID();
|
||||
}
|
||||
|
||||
void WindowSystemAdapter::puGetWindowSize(int* width, int* height)
|
||||
{
|
||||
// XXX This will have to be different when multiple cameras share
|
||||
// a single window.
|
||||
WindowSystemAdapter* wsa = getWSA();
|
||||
const GraphicsContext* gc = wsa->getGUIGraphicsContext();
|
||||
const GraphicsContext::Traits *traits = gc->getTraits();
|
||||
*width = traits->width;
|
||||
*height = traits->height;
|
||||
}
|
||||
|
||||
bool WindowSystemAdapter::puInitialize()
|
||||
{
|
||||
puSetWindowFuncs(puGetWindow, 0, puGetWindowSize, 0);
|
||||
puRealInit();
|
||||
}
|
150
src/Main/WindowSystemAdapter.hxx
Normal file
150
src/Main/WindowSystemAdapter.hxx
Normal file
|
@ -0,0 +1,150 @@
|
|||
// Copyright (C) 2008 Tim Moore
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU General Public License as
|
||||
// published by the Free Software Foundation; either version 2 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful, but
|
||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
// General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef FLIGHTGEAR_WINDOWSYSTEMADAPTER_HXX
|
||||
#define FLIGHTGEAR_WINDOWSYSTEMADAPTER_HXX 1
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#include <osg/Referenced>
|
||||
#include <osg/Camera>
|
||||
#include <osg/GraphicsContext>
|
||||
#include <osg/GraphicsThread>
|
||||
|
||||
#include <simgear/structure/SGAtomic.hxx>
|
||||
|
||||
// Flexible Camera and window support
|
||||
namespace flightgear
|
||||
{
|
||||
/** A window opened by default or via rendering properties
|
||||
*/
|
||||
class GraphicsWindow : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
GraphicsWindow(osg::GraphicsContext* gc_, const std::string& name_,
|
||||
int id_, unsigned flags_ = 0) :
|
||||
gc(gc_), name(name_), id(id_), flags(flags_)
|
||||
{
|
||||
}
|
||||
/** The OSG graphics context for this window.
|
||||
*/
|
||||
osg::ref_ptr<osg::GraphicsContext> gc;
|
||||
/** The window's internal name.
|
||||
*/
|
||||
std::string name;
|
||||
enum Flags {
|
||||
/** The GUI (and 2D cockpit) will be drawn on this window.
|
||||
*/
|
||||
GUI = 1
|
||||
};
|
||||
int id;
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
/** Camera associated with a 3d view. The camera might occupy an
|
||||
* entire window or share one with other cameras.
|
||||
*/
|
||||
class Camera3D : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
Camera3D(GraphicsWindow* window_, osg::Camera* camera_, const std::string& name_,
|
||||
unsigned flags_ = 0) :
|
||||
window(window_), camera(camera_), name(name_), flags(flags_)
|
||||
{
|
||||
}
|
||||
osg::ref_ptr<GraphicsWindow> window;
|
||||
osg::ref_ptr<osg::Camera> camera;
|
||||
std::string name;
|
||||
enum Flags {
|
||||
SHARES_WINDOW = 1, /**< Camera shares window with other cameras*/
|
||||
MASTER = 2 /**< Camera has same view as master camera*/
|
||||
};
|
||||
unsigned flags;
|
||||
};
|
||||
|
||||
typedef std::vector<osg::ref_ptr<GraphicsWindow> > WindowVector;
|
||||
typedef std::vector<osg::ref_ptr<Camera3D> > Camera3DVector;
|
||||
|
||||
/**
|
||||
* An operation that is run once with a particular GraphicsContext
|
||||
* current.
|
||||
*/
|
||||
class GraphicsContextOperation : public osg::GraphicsOperation
|
||||
{
|
||||
public:
|
||||
GraphicsContextOperation(const std::string& name) :
|
||||
osg::GraphicsOperation(name, false)
|
||||
{
|
||||
}
|
||||
virtual void operator()(osg::GraphicsContext* gc);
|
||||
virtual void run(osg::GraphicsContext* gc) = 0;
|
||||
bool isFinished() const { return done != 0; }
|
||||
private:
|
||||
SGAtomic done;
|
||||
};
|
||||
|
||||
/** Adapter from windows system / graphics context management API to
|
||||
* functions used by flightgear. This papers over the difference
|
||||
* between osgViewer Viewer, which handles multiple windows, graphics
|
||||
* threads, etc., and the embedded viewer used with GLUT and SDL.
|
||||
*/
|
||||
class WindowSystemAdapter : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
WindowSystemAdapter();
|
||||
virtual ~WindowSystemAdapter() {}
|
||||
WindowVector windows;
|
||||
Camera3DVector cameras;
|
||||
GraphicsWindow* registerWindow(osg::GraphicsContext* gc,
|
||||
const std::string& windowName);
|
||||
Camera3D* registerCamera3D(GraphicsWindow* gw, osg::Camera* camera,
|
||||
const std::string& cameraName);
|
||||
GraphicsWindow* getGUIWindow();
|
||||
int getGUIWindowID();
|
||||
osg::GraphicsContext* getGUIGraphicsContext();
|
||||
/** Initialize the plib pui interface library. This might happen
|
||||
*in another thread and may be deferred.
|
||||
*/
|
||||
virtual bool puInitialize();
|
||||
/** Returns true if pui initialization has finished.
|
||||
*/
|
||||
template<typename T>
|
||||
class FlagTester : public std::unary_function<osg::ref_ptr<T>, bool>
|
||||
{
|
||||
public:
|
||||
FlagTester(unsigned flags_) : flags(flags_) {}
|
||||
bool operator() (const osg::ref_ptr<T>& obj)
|
||||
{
|
||||
return (obj->flags & flags) != 0;
|
||||
}
|
||||
unsigned flags;
|
||||
};
|
||||
static WindowSystemAdapter* getWSA() { return _wsa.get(); }
|
||||
static void setWSA(WindowSystemAdapter* wsa) { _wsa = wsa; }
|
||||
protected:
|
||||
int _nextWindowID;
|
||||
int _nextCameraID;
|
||||
osg::ref_ptr<GraphicsContextOperation> _puInitOp;
|
||||
bool _isPuInitialized;
|
||||
static osg::ref_ptr<WindowSystemAdapter> _wsa;
|
||||
// Default callbacks for plib
|
||||
static int puGetWindow();
|
||||
static void puGetWindowSize(int* width, int* height);
|
||||
|
||||
};
|
||||
}
|
||||
#endif
|
|
@ -21,6 +21,9 @@
|
|||
#include "globals.hxx"
|
||||
#include "renderer.hxx"
|
||||
#include "fg_props.hxx"
|
||||
#include "WindowSystemAdapter.hxx"
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
//
|
||||
// Native glut callbacks.
|
||||
|
@ -153,6 +156,7 @@ static void GLUTreshape(int w, int h)
|
|||
void fgOSInit(int* argc, char** argv)
|
||||
{
|
||||
glutInit(argc, argv);
|
||||
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
|
||||
}
|
||||
|
||||
void fgOSFullScreen()
|
||||
|
@ -216,10 +220,16 @@ static unsigned int getOSGModifiers(int glutModifiers)
|
|||
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 && bpp > 16) mode |= GLUT_STENCIL;
|
||||
|
||||
|
@ -256,18 +266,21 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
|
|||
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::ref_ptr<osg::Camera> camera = new osg::Camera;
|
||||
osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
|
||||
osg::Camera* camera = new osg::Camera;
|
||||
mainCamera = camera;
|
||||
osg::Camera::ProjectionResizePolicy rsp = osg::Camera::VERTICAL;
|
||||
// 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(rsp);
|
||||
//viewer->addSlave(camera.get());
|
||||
camera->setProjectionResizePolicy(osg::Camera::FIXED);
|
||||
Camera3D* cam3D = wsa->registerCamera3D(window, camera, string("main"));
|
||||
cam3D->flags |= Camera3D::MASTER;
|
||||
// Add as a slave for compatibility with the non-embedded osgViewer.
|
||||
viewer->addSlave(camera);
|
||||
viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
|
||||
// Let FG handle the escape key with a confirmation
|
||||
viewer->setKeyEventSetsDone(0);
|
||||
|
@ -280,11 +293,6 @@ void fgOSOpenWindow(int w, int h, int bpp, bool alpha,
|
|||
globals->get_renderer()->setViewer(viewer.get());
|
||||
}
|
||||
|
||||
// Noop; the graphics context is always current
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
}
|
||||
|
||||
bool fgOSIsMainCamera(const osg::Camera*)
|
||||
{
|
||||
return true;
|
||||
|
@ -294,3 +302,8 @@ bool fgOSIsMainContext(const osg::GraphicsContext*)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::GraphicsContext* fgOSGetMainContext()
|
||||
{
|
||||
return gw.get();
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
#ifndef _FG_OS_HXX
|
||||
#define _FG_OS_HXX
|
||||
|
||||
// Plib pui needs to know at compile time what toolkit is in use.
|
||||
// Change this when we move to something other than glut.
|
||||
// #define PU_USE_GLUT -- moved to configure.ac -- EMH
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/Camera>
|
||||
#include <osg/GraphicsContext>
|
||||
|
||||
|
||||
enum { MOUSE_BUTTON_LEFT,
|
||||
MOUSE_BUTTON_MIDDLE,
|
||||
|
@ -45,8 +49,7 @@ enum { KEYMOD_NONE = 0,
|
|||
//
|
||||
|
||||
void fgOSInit(int* argc, char** argv);
|
||||
void fgOSOpenWindow(int w, int h, int bpp, bool alpha, bool stencil,
|
||||
bool fullscreen);
|
||||
void fgOSOpenWindow(bool stencil);
|
||||
void fgOSFullScreen();
|
||||
void fgOSMainLoop();
|
||||
void fgOSExit(int code);
|
||||
|
@ -82,9 +85,17 @@ void fgRegisterKeyHandler(fgKeyHandler func);
|
|||
void fgRegisterMouseClickHandler(fgMouseClickHandler func);
|
||||
void fgRegisterMouseMotionHandler(fgMouseMotionHandler func);
|
||||
|
||||
void fgMakeCurrent();
|
||||
|
||||
bool fgOSIsMainCamera(const osg::Camera* camera);
|
||||
bool fgOSIsMainContext(const osg::GraphicsContext* context);
|
||||
|
||||
/** Get graphics context of the main camera. This is the principal
|
||||
* window in multi-window configurations, or the only window in an
|
||||
* embedded configuration. The GUI will be added to this context.
|
||||
*/
|
||||
osg::GraphicsContext* fgOSGetMainContext();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // _FG_OS_HXX
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
#include <config.h>
|
||||
#include <plib/pu.h>
|
||||
#include <osg/GraphicsContext>
|
||||
|
||||
#include "fg_os.hxx"
|
||||
#include "globals.hxx"
|
||||
#include "renderer.hxx"
|
||||
|
@ -60,3 +64,5 @@ void fgRegisterMouseMotionHandler(fgMouseMotionHandler func)
|
|||
void fgRequestRedraw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <simgear/compiler.h>
|
||||
|
@ -45,6 +50,7 @@
|
|||
#include "util.hxx"
|
||||
#include "globals.hxx"
|
||||
#include "renderer.hxx"
|
||||
#include "WindowSystemAdapter.hxx"
|
||||
|
||||
#if (FG_OSG_VERSION >= 19008)
|
||||
#define OSG_HAS_MOUSE_CURSOR_PATCH
|
||||
|
@ -57,8 +63,12 @@
|
|||
// fg_os implementation
|
||||
//
|
||||
|
||||
using namespace std;
|
||||
using namespace flightgear;
|
||||
using namespace osg;
|
||||
|
||||
|
||||
|
||||
static osg::ref_ptr<osgViewer::Viewer> viewer;
|
||||
static osg::ref_ptr<osg::Camera> mainCamera;
|
||||
|
||||
|
@ -67,59 +77,24 @@ static osg::ref_ptr<osg::Camera> mainCamera;
|
|||
|
||||
namespace
|
||||
{
|
||||
struct fgResizeCallback : public GraphicsContext::ResizedCallback
|
||||
// silly function for making the default window and camera names
|
||||
std::string makeName(const string& prefix, int num)
|
||||
{
|
||||
fgResizeCallback(Camera* slaveCamera)
|
||||
: mainSlaveCamera(slaveCamera)
|
||||
{}
|
||||
|
||||
virtual void resizedImplementation(GraphicsContext* gc, int x, int y,
|
||||
int width, int height);
|
||||
ref_ptr<Camera> mainSlaveCamera;
|
||||
};
|
||||
|
||||
void fgResizeCallback::resizedImplementation(GraphicsContext* gc,
|
||||
int x, int y,
|
||||
int width, int height)
|
||||
{
|
||||
View* view = mainSlaveCamera->getView();
|
||||
View::Slave* slave = (view ?
|
||||
view->findSlaveForCamera(mainSlaveCamera.get()) : 0);
|
||||
if (slave) {
|
||||
Matrixd projOffset(slave->_projectionOffset);
|
||||
gc->resizedImplementation(x, y, width, height);
|
||||
// Restore projection offsets changed by
|
||||
// GraphicsContext::resizedImplementation
|
||||
slave->_projectionOffset = projOffset;
|
||||
} else {
|
||||
gc->resizedImplementation(x, y, width, height);
|
||||
}
|
||||
|
||||
std::stringstream stream;
|
||||
stream << prefix << num;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
}
|
||||
void fgOSOpenWindow(int w, int h, int bpp,
|
||||
bool alpha, bool stencil, bool fullscreen)
|
||||
GraphicsContext::Traits*
|
||||
makeDefaultTraits(GraphicsContext::WindowingSystemInterface* wsi, bool stencil)
|
||||
{
|
||||
osg::GraphicsContext::WindowingSystemInterface* wsi;
|
||||
wsi = osg::GraphicsContext::getWindowingSystemInterface();
|
||||
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");
|
||||
|
||||
viewer = new osgViewer::Viewer;
|
||||
viewer->setDatabasePager(FGScenery::getPagerSingleton());
|
||||
std::string mode;
|
||||
mode = fgGetString("/sim/rendering/multithreading-mode", "SingleThreaded");
|
||||
if (mode == "AutomaticSelection")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::AutomaticSelection);
|
||||
else if (mode == "CullDrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext);
|
||||
else if (mode == "DrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
|
||||
else if (mode == "CullThreadPerCameraDrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext);
|
||||
else
|
||||
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits;
|
||||
traits = new osg::GraphicsContext::Traits;
|
||||
GraphicsContext::Traits* traits = new osg::GraphicsContext::Traits;
|
||||
traits->readDISPLAY();
|
||||
int cbits = (bpp <= 16) ? 5 : 8;
|
||||
int zbits = (bpp <= 16) ? 16 : 24;
|
||||
|
@ -132,10 +107,10 @@ void fgOSOpenWindow(int w, int h, int bpp,
|
|||
traits->doubleBuffer = true;
|
||||
traits->mipMapGeneration = true;
|
||||
traits->windowName = "FlightGear";
|
||||
// XXX should check per window too.
|
||||
traits->sampleBuffers = fgGetBool("/sim/rendering/multi-sample-buffers", traits->sampleBuffers);
|
||||
traits->samples = fgGetBool("/sim/rendering/multi-samples", traits->samples);
|
||||
traits->vsync = fgGetBool("/sim/rendering/vsync-enable", traits->vsync);
|
||||
|
||||
if (fullscreen) {
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
|
@ -156,96 +131,166 @@ void fgOSOpenWindow(int w, int h, int bpp,
|
|||
#endif
|
||||
traits->supportsResize = true;
|
||||
}
|
||||
return traits;
|
||||
}
|
||||
|
||||
osg::Camera::ProjectionResizePolicy rsp = osg::Camera::VERTICAL;
|
||||
void setTraitsFromProperties(GraphicsContext::Traits* traits,
|
||||
const SGPropertyNode* winNode,
|
||||
GraphicsContext::WindowingSystemInterface* wsi)
|
||||
{
|
||||
traits->hostName
|
||||
= winNode->getStringValue("host-name", traits->hostName.c_str());
|
||||
traits->displayNum = winNode->getIntValue("display", traits->displayNum);
|
||||
traits->screenNum = winNode->getIntValue("screen", traits->screenNum);
|
||||
if (winNode->getBoolValue("fullscreen",
|
||||
fgGetBool("/sim/startup/fullscreen"))) {
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
wsi->getScreenResolution(*traits, width, height);
|
||||
traits->windowDecoration = false;
|
||||
traits->width = width;
|
||||
traits->height = height;
|
||||
traits->supportsResize = false;
|
||||
} else {
|
||||
traits->windowDecoration = winNode->getBoolValue("decoration", true);
|
||||
traits->width = winNode->getIntValue("width", traits->width);
|
||||
traits->height = winNode->getIntValue("height", traits->height);
|
||||
traits->supportsResize = true;
|
||||
}
|
||||
traits->x = winNode->getIntValue("x", traits->x);
|
||||
traits->y = winNode->getIntValue("y", traits->y);
|
||||
if (winNode->hasChild("window-name"))
|
||||
traits->windowName = winNode->getStringValue("window-name");
|
||||
else if (winNode->hasChild("name"))
|
||||
traits->windowName = winNode->getStringValue("name");
|
||||
}
|
||||
|
||||
} //namespace
|
||||
|
||||
void fgOSOpenWindow(bool stencil)
|
||||
{
|
||||
osg::GraphicsContext::WindowingSystemInterface* wsi;
|
||||
wsi = osg::GraphicsContext::getWindowingSystemInterface();
|
||||
|
||||
viewer = new osgViewer::Viewer;
|
||||
viewer->setDatabasePager(FGScenery::getPagerSingleton());
|
||||
std::string mode;
|
||||
mode = fgGetString("/sim/rendering/multithreading-mode", "SingleThreaded");
|
||||
if (mode == "AutomaticSelection")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::AutomaticSelection);
|
||||
else if (mode == "CullDrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::CullDrawThreadPerContext);
|
||||
else if (mode == "DrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::DrawThreadPerContext);
|
||||
else if (mode == "CullThreadPerCameraDrawThreadPerContext")
|
||||
viewer->setThreadingModel(osgViewer::Viewer::CullThreadPerCameraDrawThreadPerContext);
|
||||
else
|
||||
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> traits
|
||||
= makeDefaultTraits(wsi, stencil);
|
||||
|
||||
// Ok, first the children.
|
||||
// that achieves some magic ordering og the slaves so that we end up
|
||||
// in the main window more often.
|
||||
// This can be sorted out better when we got rid of glut and sdl.
|
||||
FGManipulator* manipulator = globals->get_renderer()->getManipulator();
|
||||
int nCameras = 0;
|
||||
string defaultName("slave");
|
||||
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||
if (fgHasNode("/sim/rendering/camera")) {
|
||||
SGPropertyNode* renderingNode = fgGetNode("/sim/rendering");
|
||||
for (int i = 0; i < renderingNode->nChildren(); ++i) {
|
||||
SGPropertyNode* cameraNode = renderingNode->getChild(i);
|
||||
if (strcmp(cameraNode->getName(), "camera") != 0)
|
||||
continue;
|
||||
SGPropertyNode* renderingNode = fgGetNode("/sim/rendering");
|
||||
for (int i = 0; i < renderingNode->nChildren(); ++i) {
|
||||
SGPropertyNode* cameraNode = renderingNode->getChild(i);
|
||||
if (strcmp(cameraNode->getName(), "camera") != 0)
|
||||
continue;
|
||||
|
||||
// get a new copy of the traits struct
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> cameraTraits;
|
||||
cameraTraits = new osg::GraphicsContext::Traits(*traits);
|
||||
// get a new copy of the traits struct
|
||||
osg::ref_ptr<osg::GraphicsContext::Traits> cameraTraits;
|
||||
cameraTraits = new osg::GraphicsContext::Traits(*traits);
|
||||
double shearx = cameraNode->getDoubleValue("shear-x", 0);
|
||||
double sheary = cameraNode->getDoubleValue("shear-y", 0);
|
||||
setTraitsFromProperties(cameraTraits.get(), cameraNode, wsi);
|
||||
// FIXME, currently this is too much of a problem to route
|
||||
// the resize events. When we do no longer need sdl and
|
||||
// such this can be simplified
|
||||
cameraTraits->supportsResize = false;
|
||||
|
||||
double shearx = cameraNode->getDoubleValue("shear-x", 0);
|
||||
double sheary = cameraNode->getDoubleValue("shear-y", 0);
|
||||
cameraTraits->hostName
|
||||
= cameraNode->getStringValue("host-name", traits->hostName.c_str());
|
||||
cameraTraits->displayNum
|
||||
= cameraNode->getIntValue("display", traits->displayNum);
|
||||
cameraTraits->screenNum
|
||||
= cameraNode->getIntValue("screen", traits->screenNum);
|
||||
if (cameraNode->getBoolValue("fullscreen", fullscreen)) {
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
wsi->getScreenResolution(*cameraTraits, width, height);
|
||||
cameraTraits->windowDecoration = false;
|
||||
cameraTraits->width = width;
|
||||
cameraTraits->height = height;
|
||||
cameraTraits->supportsResize = false;
|
||||
} else {
|
||||
cameraTraits->windowDecoration = true;
|
||||
cameraTraits->width = cameraNode->getIntValue("width", w);
|
||||
cameraTraits->height = cameraNode->getIntValue("height", h);
|
||||
cameraTraits->supportsResize = true;
|
||||
// ok found a camera configuration, add a new slave if possible
|
||||
GraphicsContext* gc
|
||||
= GraphicsContext::createGraphicsContext(cameraTraits.get());
|
||||
if (gc) {
|
||||
gc->realize();
|
||||
Camera *camera = new Camera;
|
||||
camera->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.
|
||||
camera->setViewport(new Viewport(0, 0, cameraTraits->width,
|
||||
cameraTraits->height));
|
||||
const char* cameraName = cameraNode->getStringValue("name");
|
||||
string cameraNameString = (cameraName ? string(cameraName)
|
||||
: makeName(defaultName, i));
|
||||
GraphicsWindow* window = wsa->registerWindow(gc,
|
||||
cameraNameString);
|
||||
Camera3D* cam3D = wsa->registerCamera3D(window, camera,
|
||||
cameraNameString);
|
||||
if (shearx == 0 && sheary == 0)
|
||||
cam3D->flags |= Camera3D::MASTER;
|
||||
viewer->addSlave(camera, Matrix::translate(-shearx, -sheary, 0),
|
||||
Matrix());
|
||||
} else {
|
||||
SG_LOG(SG_GENERAL, SG_WARN,
|
||||
"Couldn't create graphics context on "
|
||||
<< cameraTraits->hostName << ":"
|
||||
<< cameraTraits->displayNum
|
||||
<< "." << cameraTraits->screenNum);
|
||||
}
|
||||
}
|
||||
// FIXME, currently this is too much of a problem to route the resize
|
||||
// events. When we do no longer need sdl and such this
|
||||
// can be simplified
|
||||
cameraTraits->supportsResize = false;
|
||||
|
||||
// ok found a camera configuration, add a new slave ...
|
||||
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
|
||||
|
||||
osg::GraphicsContext* gc;
|
||||
gc = osg::GraphicsContext::createGraphicsContext(cameraTraits.get());
|
||||
if( gc != NULL ) {
|
||||
gc->realize();
|
||||
camera->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.
|
||||
camera->setViewport(new osg::Viewport(0, 0, cameraTraits->width, cameraTraits->height));
|
||||
camera->setProjectionResizePolicy(rsp);
|
||||
viewer->addSlave(camera.get(), osg::Matrix::translate(-shearx, -sheary, 0), osg::Matrix());
|
||||
nCameras++;
|
||||
}
|
||||
}
|
||||
if (nCameras > 1)
|
||||
manipulator->setResizable(false);
|
||||
}
|
||||
|
||||
// now the main camera ...
|
||||
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
|
||||
mainCamera = camera;
|
||||
osg::GraphicsContext* gc;
|
||||
gc = osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
gc->realize();
|
||||
gc->makeCurrent();
|
||||
camera->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.
|
||||
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
|
||||
camera->setProjectionResizePolicy(rsp);
|
||||
if (nCameras == 0) {
|
||||
// Only one principal camera
|
||||
gc->setResizedCallback(new fgResizeCallback(camera.get()));
|
||||
// XXX mainCamera's purpose is to establish a "main graphics
|
||||
// context" that can be made current (if necessary). But that
|
||||
// should be a context established with a window. It's used to
|
||||
// choose whether to render the GUI and panel camera nodes, but
|
||||
// that's obsolete because the GUI is rendered in its own
|
||||
// slave. And it's used to translate mouse event coordinates, but
|
||||
// that's bogus because mouse clicks should work on any camera. In
|
||||
// short, mainCamera must die :)
|
||||
Camera3DVector::iterator citr
|
||||
= find_if(wsa->cameras.begin(), wsa->cameras.end(),
|
||||
WindowSystemAdapter::FlagTester<Camera3D>(Camera3D::MASTER));
|
||||
if (citr == wsa->cameras.end()) {
|
||||
// Create a camera aligned with the master camera. Eventually
|
||||
// this will be optional.
|
||||
Camera* camera = new osg::Camera;
|
||||
mainCamera = camera;
|
||||
osg::GraphicsContext* gc
|
||||
= osg::GraphicsContext::createGraphicsContext(traits.get());
|
||||
gc->realize();
|
||||
gc->makeCurrent();
|
||||
camera->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.
|
||||
camera->setViewport(new osg::Viewport(0, 0,
|
||||
traits->width, traits->height));
|
||||
GraphicsWindow* window = wsa->registerWindow(gc, string("main"));
|
||||
window->flags |= GraphicsWindow::GUI;
|
||||
Camera3D* camera3d = wsa->registerCamera3D(window, camera,
|
||||
string("main"));
|
||||
camera3d->flags |= Camera3D::MASTER;
|
||||
// Why a slave? It seems to be the easiest way to assign cameras,
|
||||
// for which we've created the graphics context ourselves, to
|
||||
// the viewer.
|
||||
viewer->addSlave(camera);
|
||||
} else {
|
||||
mainCamera = (*citr)->camera;
|
||||
}
|
||||
// Why a slave? It seems to be the easiest way to assign cameras,
|
||||
// for which we've created the graphics context ourselves, to the viewer.
|
||||
viewer->addSlave(camera.get());
|
||||
|
||||
viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
|
||||
if (wsa->cameras.size() != 1) {
|
||||
manipulator->setResizable(false);
|
||||
}
|
||||
viewer->getCamera()->setProjectionResizePolicy(osg::Camera::FIXED);
|
||||
viewer->setCameraManipulator(manipulator);
|
||||
// Let FG handle the escape key with a confirmation
|
||||
viewer->setKeyEventSetsDone(0);
|
||||
// The viewer won't start without some root.
|
||||
|
@ -288,9 +333,9 @@ void fgWarpMouse(int x, int y)
|
|||
1.0f - 2.0f * (float)y / ysize);
|
||||
}
|
||||
|
||||
// Noop
|
||||
void fgOSInit(int* argc, char** argv)
|
||||
{
|
||||
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
|
||||
}
|
||||
|
||||
// Noop
|
||||
|
@ -345,16 +390,6 @@ int fgGetMouseCursor()
|
|||
return _cursor;
|
||||
}
|
||||
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
if (!mainCamera.valid())
|
||||
return;
|
||||
osg::GraphicsContext* gc = mainCamera->getGraphicsContext();
|
||||
if (!gc)
|
||||
return;
|
||||
gc->makeCurrent();
|
||||
}
|
||||
|
||||
bool fgOSIsMainContext(const osg::GraphicsContext* context)
|
||||
{
|
||||
if (!mainCamera.valid())
|
||||
|
@ -374,3 +409,16 @@ bool fgOSIsMainCamera(const osg::Camera* camera)
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
GraphicsContext* fgOSGetMainContext()
|
||||
{
|
||||
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||
WindowVector::iterator contextIter
|
||||
= std::find_if(wsa->windows.begin(), wsa->windows.end(),
|
||||
WindowSystemAdapter::FlagTester<GraphicsWindow>(GraphicsWindow::GUI));
|
||||
if (contextIter == wsa->windows.end())
|
||||
return 0;
|
||||
else
|
||||
return (*contextIter)->gc.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
#include <simgear/debug/logstream.hxx>
|
||||
|
||||
#include <SDL/SDL.h>
|
||||
#include <plib/pu.h>
|
||||
|
||||
#include <Scenery/scenery.hxx>
|
||||
#include "fg_os.hxx"
|
||||
#include "globals.hxx"
|
||||
#include "renderer.hxx"
|
||||
#include "fg_props.hxx"
|
||||
#include "WindowSystemAdapter.hxx"
|
||||
|
||||
using namespace flightgear;
|
||||
|
||||
//
|
||||
// fg_os callback registration APIs
|
||||
|
@ -34,11 +37,16 @@ static osg::ref_ptr<osgViewer::Viewer> viewer;
|
|||
static osg::ref_ptr<osg::Camera> mainCamera;
|
||||
static osg::ref_ptr<osgViewer::GraphicsWindowEmbedded> gw;
|
||||
|
||||
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");
|
||||
int cbits = (bpp <= 16) ? 5 : 8;
|
||||
int zbits = (bpp <= 16) ? 16 : 24;
|
||||
WindowSystemAdapter* wsa = WindowSystemAdapter::getWSA();
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) == -1)
|
||||
throw sg_throwable(string("Failed to initialize SDL: ")
|
||||
|
@ -84,17 +92,20 @@ void fgOSOpenWindow(int w, int h, int bpp,
|
|||
viewer = new osgViewer::Viewer;
|
||||
viewer->setDatabasePager(FGScenery::getPagerSingleton());
|
||||
gw = viewer->setUpViewerAsEmbeddedInWindow(0, 0, realw, realh);
|
||||
GraphicsWindow* window = wsa->registerWindow(gw.get(), string("main"));
|
||||
window->flags |= GraphicsWindow::GUI;
|
||||
// now the main camera ...
|
||||
//osg::ref_ptr<osg::Camera> camera = new osg::Camera;
|
||||
osg::ref_ptr<osg::Camera> camera = viewer->getCamera();
|
||||
osg::Camera* camera = new osg::Camera;
|
||||
mainCamera = camera;
|
||||
osg::Camera::ProjectionResizePolicy rsp = osg::Camera::VERTICAL;
|
||||
// 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(rsp);
|
||||
//viewer->addSlave(camera.get());
|
||||
camera->setProjectionResizePolicy(osg::Camera::FIXED);
|
||||
Camera3D* cam3D = wsa->registerCamera3D(window, camera, string("main"));
|
||||
cam3D->flags |= Camera3D::MASTER;
|
||||
// Add as a slave for compatibility with the non-embedded osgViewer.
|
||||
viewer->addSlave(camera);
|
||||
viewer->setCameraManipulator(globals->get_renderer()->getManipulator());
|
||||
// Let FG handle the escape key with a confirmation
|
||||
viewer->setKeyEventSetsDone(0);
|
||||
|
@ -265,7 +276,7 @@ void fgWarpMouse(int x, int y)
|
|||
|
||||
void fgOSInit(int* argc, char** argv)
|
||||
{
|
||||
// Nothing to do here. SDL has no command line options.
|
||||
WindowSystemAdapter::setWSA(new WindowSystemAdapter);
|
||||
}
|
||||
|
||||
void fgOSFullScreen()
|
||||
|
@ -281,7 +292,7 @@ static struct cursor_rec {
|
|||
int h;
|
||||
int hotx;
|
||||
int hoty;
|
||||
char *img[32]; // '.' == white, '#' == black, ' ' == transparent
|
||||
const char *img[32]; // '.' == white, '#' == black, ' ' == transparent
|
||||
} cursors[] = {
|
||||
{ MOUSE_CURSOR_POINTER, 0, // must be first!
|
||||
10, 16, 1, 1,
|
||||
|
@ -400,11 +411,6 @@ static void initCursors()
|
|||
}
|
||||
}
|
||||
|
||||
// Noop; the graphics context is always current
|
||||
void fgMakeCurrent()
|
||||
{
|
||||
}
|
||||
|
||||
bool fgOSIsMainCamera(const osg::Camera*)
|
||||
{
|
||||
return true;
|
||||
|
@ -414,3 +420,8 @@ bool fgOSIsMainContext(const osg::GraphicsContext*)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
osg::GraphicsContext* fgOSGetMainContext()
|
||||
{
|
||||
return gw.get();
|
||||
}
|
||||
|
|
|
@ -679,9 +679,6 @@ 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++;
|
||||
|
||||
|
@ -703,10 +700,12 @@ static void fgIdleFunction ( void ) {
|
|||
SG_LOG ( SG_GENERAL, SG_INFO, "Depth buffer bits = " << tmp );
|
||||
|
||||
// Initialize the user interface so that we can use fonts
|
||||
guiInit();
|
||||
guiStartInit();
|
||||
|
||||
|
||||
} else if ( idle_state == 1 ) {
|
||||
if (!guiFinishInit())
|
||||
return;
|
||||
idle_state++;
|
||||
fgSplashProgress("reading aircraft list");
|
||||
|
||||
|
@ -715,23 +714,6 @@ static void fgIdleFunction ( void ) {
|
|||
idle_state++;
|
||||
// Read the list of available aircraft
|
||||
fgReadAircraft();
|
||||
|
||||
// get the address of our OpenGL extensions
|
||||
// if (SGIsOpenGLExtensionSupported("GL_EXT_point_parameters") ) {
|
||||
// glPointParameterIsSupported = true;
|
||||
// glPointParameterfPtr = (glPointParameterfProc)
|
||||
// SGLookupFunction("glPointParameterfEXT");
|
||||
// glPointParameterfvPtr = (glPointParameterfvProc)
|
||||
// SGLookupFunction("glPointParameterfvEXT");
|
||||
// } else if ( SGIsOpenGLExtensionSupported("GL_ARB_point_parameters") ) {
|
||||
// glPointParameterIsSupported = true;
|
||||
// glPointParameterfPtr = (glPointParameterfProc)
|
||||
// SGLookupFunction("glPointParameterfARB");
|
||||
// glPointParameterfvPtr = (glPointParameterfvProc)
|
||||
// SGLookupFunction("glPointParameterfvARB");
|
||||
// } else {
|
||||
// glPointParameterIsSupported = false;
|
||||
// }
|
||||
fgSplashProgress("reading airport & navigation data");
|
||||
|
||||
|
||||
|
@ -1060,12 +1042,7 @@ bool fgMainInit( int argc, char **argv ) {
|
|||
|
||||
// Clouds3D requires an alpha channel
|
||||
// clouds may require stencil buffer
|
||||
fgOSOpenWindow( fgGetInt("/sim/startup/xsize"),
|
||||
fgGetInt("/sim/startup/ysize"),
|
||||
fgGetInt("/sim/rendering/bits-per-pixel"),
|
||||
fgGetBool("/sim/rendering/clouds3d-enable"),
|
||||
get_stencil_buffer,
|
||||
fgGetBool("/sim/startup/fullscreen") );
|
||||
fgOSOpenWindow(get_stencil_buffer);
|
||||
|
||||
// Initialize the splash screen right away
|
||||
fntInit();
|
||||
|
|
|
@ -18,9 +18,6 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
// $Id$
|
||||
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
|
@ -162,11 +159,6 @@ public:
|
|||
{
|
||||
if (!fgOSIsMainContext(state.getGraphicsContext()))
|
||||
return;
|
||||
|
||||
state.pushStateSet(getStateSet());
|
||||
state.apply();
|
||||
state.setActiveTextureUnit(0);
|
||||
state.setClientActiveTextureUnit(0);
|
||||
state.disableAllVertexArrays();
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
|
@ -176,11 +168,6 @@ public:
|
|||
|
||||
glPopClientAttrib();
|
||||
glPopAttrib();
|
||||
|
||||
state.popStateSet();
|
||||
state.dirtyAllModes();
|
||||
state.dirtyAllAttributes();
|
||||
state.dirtyAllVertexArrays();
|
||||
}
|
||||
|
||||
virtual osg::Object* cloneType() const { return new SGPuDrawable; }
|
||||
|
@ -212,14 +199,9 @@ public:
|
|||
{ drawImplementation(*renderInfo.getState()); }
|
||||
void drawImplementation(osg::State& state) const
|
||||
{
|
||||
// std::cout << state.getGraphicsContext() << std::endl;
|
||||
if (!fgOSIsMainContext(state.getGraphicsContext()))
|
||||
return;
|
||||
|
||||
state.pushStateSet(getStateSet());
|
||||
state.apply();
|
||||
state.setActiveTextureUnit(0);
|
||||
state.setClientActiveTextureUnit(0);
|
||||
state.disableAllVertexArrays();
|
||||
|
||||
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
||||
|
@ -240,11 +222,6 @@ public:
|
|||
|
||||
glPopClientAttrib();
|
||||
glPopAttrib();
|
||||
|
||||
state.popStateSet();
|
||||
state.dirtyAllModes();
|
||||
state.dirtyAllAttributes();
|
||||
state.dirtyAllVertexArrays();
|
||||
}
|
||||
|
||||
virtual osg::Object* cloneType() const { return new SGHUDAndPanelDrawable; }
|
||||
|
@ -428,12 +405,41 @@ FGRenderer::splashinit( void ) {
|
|||
#endif
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
// Create a slave camera that will be used to render a fixed GUI-like
|
||||
// element.
|
||||
osg::Camera*
|
||||
makeSlaveCamera(osg::Camera::RenderOrder renderOrder, int orderNum)
|
||||
{
|
||||
using namespace osg;
|
||||
Camera* camera = new osg::Camera;
|
||||
GraphicsContext *gc = fgOSGetMainContext();
|
||||
|
||||
camera->setRenderOrder(renderOrder, orderNum);
|
||||
camera->setClearMask(0);
|
||||
camera->setInheritanceMask(CullSettings::ALL_VARIABLES
|
||||
& ~(CullSettings::COMPUTE_NEAR_FAR_MODE
|
||||
| CullSettings::CULLING_MODE));
|
||||
camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
camera->setCullingMode(osg::CullSettings::NO_CULLING);
|
||||
camera->setGraphicsContext(gc);
|
||||
// Establish an initial viewport. This may be altered,
|
||||
// particularly when drawing a 2d panel.
|
||||
const GraphicsContext::Traits *traits = gc->getTraits();
|
||||
camera->setViewport(new Viewport(0, 0, traits->width, traits->height));
|
||||
camera->setProjectionResizePolicy(Camera::FIXED);
|
||||
camera->setReferenceFrame(Transform::ABSOLUTE_RF);
|
||||
camera->setAllowEventFocus(false);
|
||||
globals->get_renderer()->getViewer()->addSlave(camera, false);
|
||||
return camera;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
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();
|
||||
FGRenderer::init( void )
|
||||
{
|
||||
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
|
||||
osg::initNotifyLevel();
|
||||
|
||||
|
@ -534,15 +540,8 @@ FGRenderer::init( void ) {
|
|||
stateSet->setUpdateCallback(new FGFogEnableUpdateCallback);
|
||||
|
||||
// plug in the GUI
|
||||
osg::Camera* guiCamera = new osg::Camera;
|
||||
guiCamera->setRenderOrder(osg::Camera::POST_RENDER, 100);
|
||||
guiCamera->setClearMask(0);
|
||||
GLbitfield inheritanceMask = osg::CullSettings::ALL_VARIABLES;
|
||||
inheritanceMask &= ~osg::CullSettings::COMPUTE_NEAR_FAR_MODE;
|
||||
inheritanceMask &= ~osg::CullSettings::CULLING_MODE;
|
||||
guiCamera->setInheritanceMask(inheritanceMask);
|
||||
guiCamera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
guiCamera->setCullingMode(osg::CullSettings::NO_CULLING);
|
||||
osg::Camera* guiCamera = makeSlaveCamera(osg::Camera::POST_RENDER, 100);
|
||||
guiCamera->setName("GUI");
|
||||
osg::Geode* geode = new osg::Geode;
|
||||
geode->addDrawable(new SGPuDrawable);
|
||||
geode->addDrawable(new SGHUDAndPanelDrawable);
|
||||
|
|
Loading…
Reference in a new issue