Hi,
Sorry, but I send it again so that leading '>' are gone.
after some time spending on other task, I have now restarted my project
using the OpenSG library.
As you can see below I have spend some time into the OpenSG framework
and did reach a lot.
But now I'm stuck and need some input from outside.
I have written some new classes in order to handle rendering into
multiple windows and viewports
with the same scene graph, possibly with different camera setups.
However, I'm facing a situation that when I have more then two windows
the rendering of one
window stalls for some time and eventually all windows get frozen.
With only one or two windows all is working perfektly fine.
What is happening when one window stalls for some time I don't know.
But, when all windows
eventually freeze I could see that the the program endlessly runs into
the glErr macro in the
function RenderAction::start().
With the help of the gliIntercept tool I could see that the last call
before the error
GL_INVALID_OPERATION (0x502) was a call to glDisable(GL_SCISSOR_TEST).
Extract from the log:
glGetError()=GL_NO_ERROR
glLoadMatrixf([-0.766076,0.445564,-0.463248,0.000000,-0.393384,0.244951,
0.886141,0.000000,0.508305,0.861088,-0.012371,0.000000,49.977875,41.0812
68,-234.204254,1.000000])
glCallList(3)
glDisable(GL_LIGHTING)
glDisable(GL_COLOR_MATERIAL)
glDisable(GL_LIGHT0)
glDepthMask(true)
glFinish()
wglSwapBuffers(0x0000)=false
glGetError()=GL_NO_ERROR
wglMakeCurrent(0x0000,0x0000)=true
wglMakeCurrent(0x0000,0x10001)=false
wglMakeCurrent(0x0000,0x10001)=false
glViewport(0,0,600,227)
glDisable(GL_SCISSOR_TEST)
glGetError()=GL_INVALID_OPERATION
Below I try to outline some of my code. It is unfortunately a little bit
lengthy so I don't show it all.
The protagonists are instances form the following classes: SceneManager,
CompositeViewer, View, GLCanvas and Gc3SystemData
So I ask for some help. Can someone tell me what I'm doing wrong? Is
this a multthreading issue? What is disturbing me most is
that I do not have any problems with two windows but with more than two
of them.
With best regards
Johannes
SceneManager :
This one is used as a singleton and holds the scene. Since I
have situations when I need to render small parts of my scene
dynamically without flickering, I have a setup with the split
into static and dynamic parts. However, for my current problem
this part of my implementation is not in use at all.
class SceneManager : private boost::noncopyable
{
public:
osg::NodePtr getRoot () const;
void setRoot (osg::NodePtr node);
osg::NodePtr getDynamicRoot () const;
void setDynamicRoot (osg::NodePtr node);
osg::SwitchPtr getSwitchCore () const;
osg::NodePtr getInternalRoot () const;
osg::NodePtr getRootBeacon () const;
osg::NodePtr getHighlight () const;
void setHighlight (osg::NodePtr obj);
void updateHighlight ();
typedef osg::DirectionalLightPtr DLight;
DLight getHeadlight () const;
void setHeadlight (bool on);
bool getHeadlightState () const;
void turnHeadlightOn ();
void turnHeadlightOff ();
public:
SceneManager();
~SceneManager();
private:
//
// You have to grant friendship the the Creator policy class.
//
friend Loki::CreateUsingNew< SceneManager >;
private:
void initialize ();
void highlightChanged();
osg::NodePtr _internalRoot;
osg::NodePtr _internalStatic;
osg::NodePtr _internalDynamic;
osg::NodePtr _switchNode;
osg::NodePtr _staticRoot;
osg::NodePtr _dynamicRoot;
osg::NodePtr _highlight;
osg::NodePtr _highlightNode;
osg::SimpleMaterialPtr _highlightMaterial;
osg::GeoPositions3fPtr _highlightPoints;
osg::DirectionalLightPtr _headlight;
osg::TransformPtr _cartesian;
osg::NodePtr _cartesianNode;
};
typedef Loki::SingletonHolder< SceneManager > TheSceneManagerT;
void SceneManager::initialize() // Called on startup
{
_internalStatic = Node::create();
{
FCEditGuard guard(_internalStatic);
_internalStatic->setCore(Group::create());
}
_internalDynamic = Node::create();
{
FCEditGuard guard(_internalDynamic);
_internalDynamic->setCore(Group::create());
}
SwitchPtr switch_core = Switch::create();
{
FCEditGuard guard(switch_core);
switch_core->setChoice(Switch::ALL);
}
_switchNode = Node::create();
{
FCEditGuard guard(_switchNode);
_switchNode->setCore(switch_core);
_switchNode->addChild(_internalStatic);
_switchNode->addChild(_internalDynamic);
}
// the camera and light beacon
_cartesianNode = Node::create();
_cartesian = Transform::create();
{
FCEditGuard guard(_cartesianNode);
_cartesianNode->setCore(_cartesian);
}
// the headlight
_internalRoot = Node::create();
_headlight = DirectionalLight::create();
addRefCP(_internalRoot);
{
FCEditGuard guard(_internalRoot);
_internalRoot->setCore(_headlight);
_internalRoot->addChild(_cartesianNode);
_internalRoot->addChild(_switchNode);
}
{
FCEditGuard guard(_headlight);
_headlight->setAmbient (.3, .3, .3, 1);
_headlight->setDiffuse ( 1, 1, 1, 1);
_headlight->setSpecular ( 1, 1, 1, 1);
_headlight->setDirection( 0, 0, 1);
_headlight->setBeacon (_cartesianNode);
}
}
void SceneManager::setRoot(NodePtr root) // This is called after
I have constructed my scene
{
if(_staticRoot != root)
{
if(_staticRoot != NullFC)
{
FCEditGuard guard(_internalStatic, Node::ChildrenFieldMask);
_internalStatic->subChild(_staticRoot);
}
_staticRoot = root;
if(_staticRoot != NullFC)
{
FCEditGuard guard(_internalStatic, Node::ChildrenFieldMask);
_internalStatic->addChild(_staticRoot);
}
}
}
CompositeViewer :
This class administer a set of View objects, the WindowPtr and
the RenderAction. It provides public Render function
and the following entry functions: mouseMove, mouseButtonPress,
mouseButtonRelease, resize and redraw.
class CompositeViewer;
typedef boost::shared_ptr<CompositeViewer> CompositeViewerT;
class CompositeViewer : public
boost::enable_shared_from_this<CompositeViewer>
, private boost::noncopyable
{
private:
typedef std::vector<ViewT> VecViewsT;
public:
typedef VecViewsT::iterator iterator;
typedef VecViewsT::const_iterator const_iterator;
void push_back (ViewT view);
iterator insert (iterator pos, ViewT view);
void erase (ViewT view);
void erase (iterator iter);
ViewT operator[] (VecViewsT::size_type idx) const;
ViewT at (VecViewsT::size_type idx) const;
void clear ();
iterator find (ViewT view);
const_iterator find (ViewT view) const;
iterator begin ();
const_iterator begin () const;
iterator end ();
const_iterator end () const;
public:
osg::WindowPtr getWindow ();
osg::DrawActionBase* getAction ();
void setWindow (osg::WindowPtr win);
void setAction (osg::RenderAction* action);
void Render ();
void TickRender ();
void setDynamicMode (bool flag);
bool getDynamicMode () const;
void setRenderStatic (bool flag);
void setRenderDynamic(bool flag);
void redraw ();
void resize (osg::UInt16 width, osg::UInt16
height);
void mouseMove (osg::Int16 x,
osg::Int16 y);
void mouseButtonPress (osg::UInt16 button,
osg::Int16 x, osg::Int16 y);
void mouseButtonRelease (osg::UInt16 button,
osg::Int16 x, osg::Int16 y);
void key (osg::UChar8 key,
osg::Int16 x, osg::Int16 y);
public:
static CompositeViewerT create();
~CompositeViewer();
protected:
CompositeViewer();
private:
void DoRenderStatic ();
void DoRenderDynamic ();
void DoRender ();
enum {
RENDER_STATIC = 0,
RENDER_DYNAMIC = 1
};
private:
VecViewsT _views;
osg::WindowPtr _win;
osg::RenderAction* _action;
osg::RenderAction* _ownAction;
int _iDynamicCnt;
bool _bRenderStatic;
bool _bRenderDynamic;
};
// Multiple views are possible, but the problem case does use multiple
CompositeViewer each
// containing exactly one View instance.
void CompositeViewer::push_back(ViewT view)
{
iterator iter = find(view);
if (iter != end())
return;
_views.push_back(view);
beginEditCP(_win);
_win->addPort(view->getPort());
endEditCP(_win);
view->setViewer(shared_from_this());
}
WindowPtr CompositeViewer::getWindow()
{
return _win;
}
void CompositeViewer::setWindow(WindowPtr win)
{
_win = win;
}
DrawActionBase *CompositeViewer::getAction()
{
return _action;
}
void CompositeViewer::setAction(RenderAction *action)
{
BOOST_FOREACH(ViewT& view, _views)
{
bool statstate = view->getStatistics();
if(_action != NULL && statstate)
view->setStatistics(false);
if(action == NULL)
{
_action = _ownAction;
}
else
{
_action = action;
}
if(statstate)
view->setStatistics(true);
}
}
void CompositeViewer::redraw()
{
if (!_action) {
_ownAction = RenderAction::create();
_action = _ownAction;
}
BOOST_FOREACH(ViewT& view, _views) {
assert(view->getSceneManager());
if (view->getSceneManager()->getInternalRoot() == NullFC)
{
view->showAll();
}
if (view->getNavigatorOn() && view->getNavigator())
view->getNavigator()->updateCameraTransformation();
view->getSceneManager()->updateHighlight();
}
_win->render(_action);
}
void CompositeViewer::Render()
{
if (!_win) return;
if (!_iDynamicCnt) {
redraw(); // This is the branch
which is used in the problem scenario. The other is not called at all.
_win->deactivate();
} else {
DoRenderStatic();
}
}
void CompositeViewer::resize(UInt16 width, UInt16 height)
{
_win->resize(width, height);
if (_iDynamicCnt) {
BOOST_FOREACH(ViewT& view, _views) {
if (!view->getPassive()) {
view->onResize();
}
}
_bRenderStatic = true;
}
}
void CompositeViewer::mouseMove(osg::Int16 x, osg::Int16 y)
{
BOOST_FOREACH(ViewT& view, _views) {
view->mouseMove(x, y);
}
}
View :
This class carries the viewport, background, camera, navigator,
and a lot of other stuff not relevant for the case.
typedef boost::logic::tribool TriBoolT;
class CompositeViewer;
typedef boost::shared_ptr<CompositeViewer> CompositeViewerT;
class View;
typedef boost::shared_ptr<View> ViewT;
class View : public boost::enable_shared_from_this<View>
, private boost::noncopyable
{
public:
enum {
MouseLeft = 0,
MouseMiddle = 1,
MouseRight = 2,
MouseUp = 3,
MouseDown = 4,
NoButton = -1
};
public:
typedef boost::tuple<osg::Real32, osg::Real32, osg::Real32,
osg::Real32> DimT;
DimT getDimensions () const;
osg::ViewportPtr getPort ();
osg::NodePtr getRoot () const;
SceneManager* getSceneManager () const;
osg::CameraPtr getCamera () const;
TriBoolT getPerspective () const;
osg::Navigator* getNavigator () const;
bool getNavigatorOn () const;
CompositeViewerT getViewer () const;
bool getStatistics () const;
bool getPassive () const;
bool getDepthClearBgnd () const;
osg::BackgroundPtr getBackground () const;
void setDimensions (osg::Real32 left,
osg::Real32 bottom, osg::Real32 right, osg::Real32 top);
void setRoot (osg::NodePtr root);
void setSceneManager (SceneManager* p);
void setCamera (osg::CameraPtr camera);
void setPerspective (TriBoolT perspective);
void setNavigator (osg::Navigator* navigator);
void setNavigatorOn (bool on);
void setNavigationMode (osg::Navigator::Mode
new_mode);
bool setClickCenter (bool mode);
void setStatistics (bool on);
void setViewer (CompositeViewerT viewer);
void setPassive (bool passive);
void setDepthClearBgnd (bool flag);
void setBackground (osg::BackgroundPtr bg);
void restoreBackground (bool image);
void setDynamicMode (bool flag);
void setGrabForeground (bool flag);
void onResize ();
osg::Line calcViewRay (osg::Int16 x,
osg::Int16 y);
Frustum calcViewFrustum (osg::Int16 x,
osg::Int16 y, osg::Int16 size, osg::Pnt3f* ap = NULL);
Frustum calcViewFrustum (osg::Int16 x0,
osg::Int16 y0, osg::Int16 x1, osg::Int16 y1, osg::Pnt3f* ap = NULL);
osg::FrustumVolume calcViewFrustumVolume (osg::Int16 x,
osg::Int16 y, osg::Int16 size, osg::Pnt3f* ap = NULL);
osg::FrustumVolume calcViewFrustumVolume (osg::Int16 x0,
osg::Int16 y0, osg::Int16 x1, osg::Int16 y1, osg::Pnt3f* ap = NULL);
void getViewMatrix (osg::Matrix& m)
const;
void getProjectionMatrix (osg::Matrix& m)
const;
void getProjectionTranslation (osg::Matrix& m)
const;
osg::Matrix computeWindowMatrix () const;
void idle ();
void showAll ();
void useOpenSGLogo ();
void mouseMove (osg::Int16 x, osg::Int16
y);
void mouseButtonPress (osg::UInt16 button,
osg::Int16 x, osg::Int16 y);
void mouseButtonRelease (osg::UInt16 button,
osg::Int16 x, osg::Int16 y);
void key (osg::UChar8 key,
osg::Int16 x, osg::Int16 y);
public:
static ViewT create();
~View();
protected:
View();
private:
void initialize();
private:
osg::ViewportPtr _viewport;
osg::ImageForegroundPtr _foreground;
osg::StatisticsForegroundPtr _statforeground;
osg::BackgroundPtr _background;
osg::BackgroundPtr _passiveBackground;
bool _statstate;
osg::CameraPtr _camera;
TriBoolT _perspective; // true, false,
boost::logic::indeterminate
osg::Navigator* _navigator;
bool _navigatorOn;
osg::Int16 _lastx;
osg::Int16 _lasty;
osg::UInt16 _mousebuttons;
SceneManager* _sceneManager;
CompositeViewerT _viewer; // A
View knows about the Viewer it belongs to
osg::Real32 _left, _bottom, _right, _top;
bool _passive;
bool _depthClearBgnd;
bool _initialized;
osg::GrabForegroundPtr _grabForeground;
osg::ImagePtr _grabImage;
osg::ImageBackgroundPtr _imageBackground;
bool _bDynamicMode;
};
NodePtr View::getRoot() const
{
assert(_sceneManager);
return _sceneManager->getRoot();
}
void View::setRoot(NodePtr root)
{
assert(_sceneManager);
_sceneManager->setRoot(root);
}
CameraPtr View::getCamera(void) const
{
return _camera;
}
void View::setCamera(CameraPtr camera)
{
if(camera == NullFC)
return;
if (camera->getTypeId() == PerspectiveCamera::getClassTypeId())
_perspective = true;
else if (camera->getTypeId() ==
OrthographicCamera::getClassTypeId())
_perspective = false;
else
_perspective = boost::logic::indeterminate;
{
FCEditGuard guard(camera);
camera->setBeacon(_camera->getBeacon());
camera->setNear (_camera->getNear());
camera->setFar (_camera->getFar());
}
if (_viewport != NullFC) {
FCEditGuard guard(_viewport);
_viewport->setCamera(camera);
}
subRefCP(_camera);
_camera = camera;
addRefCP(_camera);
}
Navigator* View::getNavigator(void) const
{
return _navigator;
}
void View::setNavigator(Navigator* navigator)
{
if (_navigator)
delete _navigator;
_navigator = navigator;
if (_navigator) {
if (_viewport != NullFC)
_navigator->setViewport(_viewport);
if (_sceneManager)
_navigator->setCameraTransformation(_sceneManager->getRootBeacon());
}
}
CompositeViewerT View::getViewer() const
{
return _viewer;
}
void View::setViewer(CompositeViewerT viewer)
{
if (_viewer) {
_viewer->erase(shared_from_this());
}
_viewer = viewer;
}
void View::mouseMove(Int16 x, Int16 y)
{
if (!_navigatorOn || !_navigator)
return;
if (_mousebuttons)
_navigator->moveTo(x,y);
_lastx = x;
_lasty = y;
}
void View::initialize()
{
if (_initialized)
return;
_initialized = true;
assert(_sceneManager);
// the camera
if (_perspective) {
PerspectiveCameraPtr camera = PerspectiveCamera::create();
addRefCP(camera);
FCEditGuard guard(camera);
camera->setBeacon(_sceneManager->getRootBeacon());
camera->setFov (deg2rad(60.f));
camera->setNear (0.1f);
camera->setFar (10000.f);
_camera = camera;
} else if (!_perspective) {
OrthographicCameraPtr camera = OrthographicCamera::create();
addRefCP(camera);
FCEditGuard guard(camera);
camera->setBeacon(_sceneManager->getRootBeacon());
camera->setVerticalSize(0);
camera->setNear (0.1f);
camera->setFar (10000.f);
_camera = camera;
} else {
MatrixCameraPtr camera = MatrixCamera::create();
addRefCP(camera);
FCEditGuard guard(camera);
camera->setBeacon(_sceneManager->getRootBeacon());
camera->setNear (0.1f);
camera->setFar (10000.f);
Matrix m;
m.setIdentity();
camera->setProjectionMatrix(m);
camera->setModelviewMatrix(m);
_camera = camera;
}
if(_viewport == NullFC)
{
_foreground = ImageForeground::create();
BackgroundPtr bg;
if (_passive) {
if (_depthClearBgnd)
_passiveBackground = DepthClearBackground::create();
else
_passiveBackground = PassiveBackground::create();
bg = _passiveBackground;
} else {
SolidBackgroundPtr bgnd = SolidBackground::create();
FCEditGuard guard(bgnd);
bgnd->setColor(Color3f(0, 0, 0));
_background = bgnd;
bg = _background;
}
_viewport = Viewport::create();
{
FCEditGuard guard(_viewport);
_viewport->setCamera(_camera);
_viewport->setRoot(_sceneManager->getInternalRoot());
_viewport->setSize(_left, _bottom, _right, _top);
_viewport->setBackground(bg);
_viewport->getForegrounds().push_back(_foreground);
}
}
if (_navigator) {
_navigator->setViewport(_viewport);
_navigator->setCameraTransformation(_sceneManager->getRootBeacon());
}
}
GLCanvas :
This class is a child class of the gui toolkit window class I'm
using. Actually, it contains only
a pointer to the Gc3SystemData instance which contains the
CompositeViewer instance.
The example instance is just a convenience I use to build
different test programs with
minimal code change. It contains the actual start up code.
class Gc3SystemData;
class Example;
class GLCanvas : public ZafWindow
{
public:
GLCanvas();
virtual ~GLCanvas();
public:
void SetExample(Example* p) { _example.reset(p); }
Gc3SystemData* pSystemData() const { return _pSystemData; }
void Render(); // Delegate to _pSystemData->Render()
void TickRender();
void SleepTickTimer();
void WakeTickTimer();
void AddVisualizer (components::VisualizerT visualizer);
void RemoveVisualizer(components::VisualizerT visualizer);
void PushVisualizer (components::VisualizerT
cursor);
void PopVisualizer ();
components::VisualizerT TopVisualizer () const;
protected:
virtual ZafEventType Event (const ZafEventStruct& event);
// Delegate to _pSystemData
virtual ZafEventType OSEvent (const ZafEventStruct& event);
// Delegate to _pSystemData
virtual ZafEventType Draw (const ZafEventStruct& event,
ZafEventType ccode); // Delegate to Render()
private:
void InitializeTickTimer();
void DeinitalizeTickTimer();
private:
Gc3SystemData* _pSystemData;
tools::timer_ptr _spTimer;
boost::scoped_ptr<Example> _example;
};
Gc3SystemData :
This class wraps the CompositeViewer for the window toolkit and
handles the operating system requests for drawing and mouse.
typedef graphic::CompositeViewerT ViewerT;
class Gc3SystemData
{
public:
ViewerT getViewer () { return _viewer; }
void Event (const ZafEventStruct& event);
void OSEvent (const ZafEventStruct& event);
void Render ();
void TickRender ();
bool eIsInitialized () { return _bIsInitialized; }
void AddVisualizer (components::VisualizerT
visualizer);
void RemoveVisualizer(components::VisualizerT
visualizer);
void PushVisualizer (components::VisualizerT
visualizer);
void PopVisualizer ();
components::VisualizerT TopVisualizer () const;
int Width () const;
int Height () const;
private:
void Initialize ();
public:
explicit Gc3SystemData (HWND hWnd);
~Gc3SystemData ();
private:
HWND _hWnd;
ViewerT _viewer;
bool _bIsInitialized;
typedef std::vector<components::VisualizerT> VecVisualizerT;
VecVisualizerT _vecVisualizer; // for things like tripods,
clipplane visualization etc.
typedef std::stack<components::VisualizerT> StackVisualizerT;
StackVisualizerT _stackVisualizer; // for things like
selection box etc.
};
Gc3SystemData::Gc3SystemData(HWND hWnd)
: _hWnd(hWnd)
, _viewer(graphic::CompositeViewer::create())
, _bIsInitialized(false)
, _vecVisualizer()
, _stackVisualizer()
{
DWORD dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
PIXELFORMATDESCRIPTOR pixelFormat = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
dwFlags,
PFD_TYPE_RGBA,
24,
0, 0, 0, 0, 0, 0,
0, 0,
0, 0, 0, 0, 0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
HDC hdc = ::GetDC(_hWnd);
if (!hdc) {
::DestroyWindow(_hWnd);
return;
}
int pixelFormatIndex = ::ChoosePixelFormat(hdc, &pixelFormat);
if (!pixelFormatIndex) {
::ReleaseDC(_hWnd, hdc);
::DestroyWindow(_hWnd);
return;
}
if (!::SetPixelFormat(hdc, pixelFormatIndex, &pixelFormat)) {
::ReleaseDC(_hWnd, hdc);
::DestroyWindow(_hWnd);
return;
}
Initialize();
}
void Gc3SystemData::Initialize()
{
osg::osgInit(0,NULL);
osg::WIN32WindowPtr window = osg::WIN32Window::create();
window->setHwnd(_hWnd);
window->init();
window->deactivate();
graphic::ViewT view(graphic::View::create());
osg::Navigator* nav = new osg::Navigator;
nav->setMode(osg::Navigator::TRACKBALL);
view->setNavigator(nav);
view->setSceneManager(&graphic::TheSceneManagerT::Instance());
_viewer->setWindow(window);
_viewer->push_back(view);
_bIsInitialized = true;
}
void Gc3SystemData::OSEvent(const ZafEventStruct& event)
{
if (!_vecVisualizer.empty()) {
VecVisualizerT::iterator iter;
for (iter = _vecVisualizer.begin(); iter !=
_vecVisualizer.end(); ++iter) {
components::VisualizerT vis = *iter;
vis->OSEvent(event);
}
}
if (!_stackVisualizer.empty())
_stackVisualizer.top()->OSEvent(event);
switch (event.osEvent.message) {
case WM_SIZE:
{
int w = LOWORD(event.osEvent.lParam);
int h = HIWORD(event.osEvent.lParam);
_viewer->resize(w, h);
}
break;
case WM_LBUTTONDOWN:
{
int x = LOWORD(event.osEvent.lParam);
int y = HIWORD(event.osEvent.lParam);
_viewer->mouseButtonPress(graphic::View::MouseLeft, x,
y);
}
break;
...
case WM_MOUSEMOVE:
{
int x = LOWORD(event.osEvent.lParam);
int y = HIWORD(event.osEvent.lParam);
_viewer->mouseMove(x, y);
}
break;
}
}
void Gc3SystemData::Render()
{
if (_bIsInitialized) {
_viewer->Render();
}
}
void Gc3SystemData::TickRender()
{
if (_bIsInitialized) {
_viewer->TickRender();
}
}
int Main(int argc, char** argv) // The main entry point of the program
{
ZafWindow* window1 = new ZafWindow(0, 0, 600, 800);
ZafWindow* window2 = new ZafWindow(0, 0, 600, 800);
ZafWindow* window3 = new ZafWindow(0, 0, 600, 800);
GLCanvas* pCanvas1 = new GLCanvas;
GLCanvas* pCanvas2 = new GLCanvas;
GLCanvas* pCanvas3 = new GLCanvas;
MultipleGenericOpenSG* pExample1 = new
MultipleGenericOpenSG(pCanvas1);
MultipleGenericOpenSG* pExample2 = new
MultipleGenericOpenSG(pCanvas2);
MultipleGenericOpenSG* pExample3 = new
MultipleGenericOpenSG(pCanvas3);
window1->Add(pCanvas1);
window2->Add(pCanvas2);
window3->Add(pCanvas3);
// Center the window.
zafWindowManager->Center(window1);
zafWindowManager->Center(window2);
zafWindowManager->Center(window3);
// Add the window to the window manager.
zafWindowManager->Add(window1);
zafWindowManager->Add(window2);
zafWindowManager->Add(window3);
int ret1 = pExample1->Main(argc, argv);
int ret2 = pExample2->Main(argc, argv);
int ret3 = pExample3->Main(argc, argv);
return ret1;
}
class MultipleGenericOpenSG : public Example
{
public:
explicit MultipleGenericOpenSG(GLCanvas* p) : Example(p);
virtual ~MultipleGenericOpenSG(){};
public:
virtual int Main(int argc, char** argv);
virtual void Run ();
};
MultipleGenericOpenSG ::MultipleGenericOpenSG (GLCanvas* p)
: Example(p)
{
p->SetExample(this);
}
int MultipleGenericOpenSG::Main(int argc, char** argv)
{
Example::Main(argc, argv);
Run();
return 0;
}
void MultipleGenericOpenSG::Run()
{
//
// The entity manager is responsible for storing loaded Acis
entities
//
acis::EntityManager sEntMan;
//
// static because root should be only created once in this example
// root contains the complete scene
static components::FileHandler fileHandler(sEntMan);
static osg::NodePtr root = fileHandler.Evaluate(_sCmdOptMap);
// sCmdOptMap contains file to load
components::SetupViewer setupViewer(_pGLCanvas, true);
setupViewer.setup(root);
}
SetupViewer :
Helper class for conveniently setup the scene
class SetupViewer
{
public:
void setup (osg::NodePtr root);
void setup (osg::NodePtr root_static, osg::NodePtr
root_dynamic);
void changeBackground(bool flag);
public:
explicit SetupViewer (GLCanvas* pGLCanvas, bool perspective);
virtual ~SetupViewer ();
private:
GLCanvas* _pGLCanvas;
bool _perspective;
};
SetupViewer::SetupViewer(GLCanvas* pGLCanvas, bool perspective)
: _pGLCanvas(pGLCanvas)
, _perspective(perspective)
{
}
void SetupViewer::setup(osg::NodePtr root)
{
using namespace osg;
GradientBackgroundPtr background = GradientBackground::create();
{
FCEditGuard guard(background);
background->addLine(Color3f(0,0,0), 0);
background->addLine(Color3f(1,1,1), 1);
}
ViewerT viewer = _pGLCanvas->pSystemData()->getViewer();
(*viewer)[0]->setPerspective(_perspective);
(*viewer)[0]->setBackground(background);
(*viewer)[0]->setRoot(root); // This
delegates to SceneManager instance
(*viewer)[0]->showAll();
}
____________
Virus checked by G DATA AntiVirusKit
Version: AVK 18.3780 from 14.05.2008
Virus news: www.antiviruslab.com
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users