From Jan Peciva, "please find attached proposed fix for ON_DEMAND rendering. The biggest issue was
that the windows did not act on repaint request (WM_PAINT, EXPOSE,...) Detailed explanation: - I implemented requestRedraw using the push approach (not using GraphicsWindow::_requestRedraw flag that I was considering) as there may be multiple viewers reading the flag and fighting to reset it after the paint request, while some viewers may not spot the request to redraw - I made windows call GraphicsWindow::requestRedraw when they receive appropriate message (WM_PAINT, EXPOSE, RESIZE,...) - There were issues on Linux that windows did not want to close using x button. Resolved by moving the test for DeleteWindow event from swapBuffersImplementation() to GraphicsWindowX11::checkEvents(). The difficulty was that DeleteWindow event is not coming using _eventDisplay, but through _display. - The last difficulty was that it is necessary to call ViewerBase::checkWindowStatus() to set _done to true when all windows are closed. This did not happened recently in ON_DEMAND run scheme. I put the call to checkWindowStatus() to eventTraversal. "
This commit is contained in:
parent
efec8a13a1
commit
c13b7d26b7
@ -30,6 +30,9 @@ extern "C"
|
||||
|
||||
namespace osgViewer {
|
||||
|
||||
class View;
|
||||
|
||||
|
||||
/** Base class for providing Windowing API agnostic access to creating and managing graphics window and events.
|
||||
* Note, the GraphicsWindow is subclassed from osg::GraphicsContext, and to provide an implemention you'll need to implement its
|
||||
* range of pure virtual functions, you'll find these all have naming convention methodNameImplemention(..).
|
||||
@ -180,8 +183,13 @@ class OSGVIEWER_EXPORT GraphicsWindow : public osg::GraphicsContext, public osgG
|
||||
|
||||
public:
|
||||
|
||||
typedef std::list<osgViewer::View*> Views;
|
||||
/** Returns the list of views (osgViewer::View) attached to this GraphicsWindow.
|
||||
* Internally, the method walks through all the cameras and collects all the views attached to the cameras.*/
|
||||
void getViews(Views& views);
|
||||
|
||||
// Override from GUIActionAdapter
|
||||
virtual void requestRedraw() {}
|
||||
virtual void requestRedraw();
|
||||
|
||||
// Override from GUIActionAdapter
|
||||
virtual void requestContinuousUpdate(bool /*needed*/=true) {}
|
||||
|
@ -195,9 +195,6 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object
|
||||
osgUtil::IncrementalCompileOperation* getIncrementalCompileOperation() { return _incrementalCompileOperation.get(); }
|
||||
|
||||
|
||||
/** Check to see if windows are still open, if not set viewer done to true. */
|
||||
void checkWindowStatus();
|
||||
|
||||
enum FrameScheme
|
||||
{
|
||||
ON_DEMAND,
|
||||
@ -253,6 +250,15 @@ class OSGVIEWER_EXPORT ViewerBase : public virtual osg::Object
|
||||
typedef std::vector<osgViewer::View*> Views;
|
||||
virtual void getViews(Views& views, bool onlyValid=true) = 0;
|
||||
|
||||
/** Check to see if any windows are still open. If not, set viewer done to true. */
|
||||
void checkWindowStatus();
|
||||
|
||||
/** Check to see if windows are still open using the list of contexts given as a parameter.
|
||||
* If no windows are open, stop rendering threads and set viewer done to true.
|
||||
* This function is more effective than checkWindowStatus() as it does not query
|
||||
* the context list and should be used whenever context list is already available in your code.*/
|
||||
void checkWindowStatus(const Contexts& contexts);
|
||||
|
||||
virtual double elapsedTime() = 0;
|
||||
|
||||
virtual osg::FrameStamp* getViewerFrameStamp() = 0;
|
||||
|
@ -23,6 +23,7 @@ SET(TARGET_H
|
||||
|
||||
SET(LIB_COMMON_FILES
|
||||
CompositeViewer.cpp
|
||||
GraphicsWindow.cpp
|
||||
HelpHandler.cpp
|
||||
Renderer.cpp
|
||||
Scene.cpp
|
||||
|
@ -688,6 +688,10 @@ void CompositeViewer::eventTraversal()
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
// set done if there are no windows
|
||||
checkWindowStatus(contexts);
|
||||
if (_done) return;
|
||||
|
||||
Scenes scenes;
|
||||
getScenes(scenes);
|
||||
|
||||
|
60
src/osgViewer/GraphicsWindow.cpp
Normal file
60
src/osgViewer/GraphicsWindow.cpp
Normal file
@ -0,0 +1,60 @@
|
||||
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2011 Robert Osfield
|
||||
*
|
||||
* This library is open source and may be redistributed and/or modified under
|
||||
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
|
||||
* (at your option) any later version. The full license is in LICENSE file
|
||||
* included with this distribution, and on the openscenegraph.org website.
|
||||
*
|
||||
* This library 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
|
||||
* OpenSceneGraph Public License for more details.
|
||||
*/
|
||||
|
||||
#include <osgViewer/GraphicsWindow>
|
||||
#include <osgViewer/View>
|
||||
#include <osgViewer/ViewerBase>
|
||||
|
||||
using namespace osgViewer;
|
||||
|
||||
|
||||
void GraphicsWindow::getViews(Views& views)
|
||||
{
|
||||
views.clear();
|
||||
osgViewer::View *prev = NULL;
|
||||
|
||||
for(Cameras::iterator it = _cameras.begin();
|
||||
it != _cameras.end();
|
||||
it++)
|
||||
{
|
||||
osgViewer::View *v = dynamic_cast<osgViewer::View*>((*it)->getView());
|
||||
if (v)
|
||||
// perform a simple test to reduce the number of duplicates
|
||||
if (v != prev)
|
||||
// append view
|
||||
views.push_back(v);
|
||||
}
|
||||
|
||||
// remove duplicates
|
||||
views.sort();
|
||||
views.unique();
|
||||
}
|
||||
|
||||
void GraphicsWindow::requestRedraw()
|
||||
{
|
||||
Views views;
|
||||
getViews(views);
|
||||
|
||||
if (views.empty())
|
||||
{
|
||||
OSG_INFO << "GraphicsWindow::requestRedraw(): No views assigned yet." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for(Views::iterator it = views.begin();
|
||||
it != views.end();
|
||||
it++)
|
||||
{
|
||||
(*it)->requestRedraw();
|
||||
}
|
||||
}
|
@ -1833,7 +1833,7 @@ bool GraphicsWindowWin32::realizeImplementation()
|
||||
}
|
||||
}
|
||||
protected:
|
||||
HDC _hdc;
|
||||
HDC _hdc;
|
||||
HGLRC _hglrc;
|
||||
} restoreContext;
|
||||
|
||||
@ -2355,6 +2355,7 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W
|
||||
PAINTSTRUCT paint;
|
||||
::BeginPaint(hwnd, &paint);
|
||||
::EndPaint(hwnd, &paint);
|
||||
requestRedraw();
|
||||
}
|
||||
break;
|
||||
|
||||
@ -2467,10 +2468,15 @@ LRESULT GraphicsWindowWin32::handleNativeWindowingEvent( HWND hwnd, UINT uMsg, W
|
||||
int windowWidth = (clientRect.right == 0) ? 1 : clientRect.right ;
|
||||
int windowHeight = (clientRect.bottom == 0) ? 1 : clientRect.bottom;;
|
||||
|
||||
// send resize event if window position or size was changed
|
||||
if (windowX!=_traits->x || windowY!=_traits->y || windowWidth!=_traits->width || windowHeight!=_traits->height)
|
||||
{
|
||||
resized(windowX, windowY, windowWidth, windowHeight);
|
||||
getEventQueue()->windowResize(windowX, windowY, windowWidth, windowHeight, resizeTime);
|
||||
|
||||
// request redraw if window size was changed
|
||||
if (windowWidth!=_traits->width || windowHeight!=_traits->height)
|
||||
requestRedraw();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -1090,25 +1090,6 @@ void GraphicsWindowX11::swapBuffersImplementation()
|
||||
#endif
|
||||
glXSwapBuffers( _display, _window );
|
||||
#endif
|
||||
|
||||
|
||||
while( XPending(_display) )
|
||||
{
|
||||
XEvent ev;
|
||||
XNextEvent( _display, &ev );
|
||||
|
||||
switch( ev.type )
|
||||
{
|
||||
case ClientMessage:
|
||||
{
|
||||
if (static_cast<Atom>(ev.xclient.data.l[0]) == _deleteWindow)
|
||||
{
|
||||
OSG_INFO<<"DeleteWindow event received"<<std::endl;
|
||||
getEventQueue()->closeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsWindowX11::checkEvents()
|
||||
@ -1154,6 +1135,7 @@ void GraphicsWindowX11::checkEvents()
|
||||
}
|
||||
case Expose :
|
||||
OSG_INFO<<"Expose x="<<ev.xexpose.x<<" y="<<ev.xexpose.y<<" width="<<ev.xexpose.width<<", height="<<ev.xexpose.height<<std::endl;
|
||||
requestRedraw();
|
||||
break;
|
||||
|
||||
case GravityNotify :
|
||||
@ -1461,6 +1443,7 @@ void GraphicsWindowX11::checkEvents()
|
||||
_lastEventType = ev.type;
|
||||
}
|
||||
|
||||
// send window resize event if window position or size was changed
|
||||
if (windowX != _traits->x ||
|
||||
windowY != _traits->y ||
|
||||
windowWidth != _traits->width ||
|
||||
@ -1468,6 +1451,35 @@ void GraphicsWindowX11::checkEvents()
|
||||
{
|
||||
resized(windowX, windowY, windowWidth, windowHeight);
|
||||
getEventQueue()->windowResize(windowX, windowY, windowWidth, windowHeight, resizeTime);
|
||||
|
||||
// request window repaint if window size was changed
|
||||
if (windowWidth != _traits->width ||
|
||||
windowHeight != _traits->height)
|
||||
{
|
||||
requestRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// process events of _display
|
||||
//
|
||||
while( XPending(_display) )
|
||||
{
|
||||
XEvent ev;
|
||||
XNextEvent( _display, &ev );
|
||||
|
||||
switch( ev.type )
|
||||
{
|
||||
case ClientMessage:
|
||||
{
|
||||
if (static_cast<Atom>(ev.xclient.data.l[0]) == _deleteWindow)
|
||||
{
|
||||
OSG_INFO<<"DeleteWindow event received"<<std::endl;
|
||||
getEventQueue()->closeWindow();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -617,6 +617,10 @@ void Viewer::eventTraversal()
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
// set done if there are no windows
|
||||
checkWindowStatus(contexts);
|
||||
if (_done) return;
|
||||
|
||||
osgGA::GUIEventAdapter* eventState = getEventQueue()->getCurrentEventState();
|
||||
osg::Matrix masterCameraVPW = getCamera()->getViewMatrix() * getCamera()->getProjectionMatrix();
|
||||
if (getCamera()->getViewport())
|
||||
|
@ -522,9 +522,11 @@ void ViewerBase::checkWindowStatus()
|
||||
{
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
checkWindowStatus(contexts);
|
||||
}
|
||||
|
||||
// OSG_NOTICE<<"Viewer::checkWindowStatus() - "<<contexts.size()<<std::endl;
|
||||
|
||||
void ViewerBase::checkWindowStatus(const Contexts& contexts)
|
||||
{
|
||||
if (contexts.size()==0)
|
||||
{
|
||||
_done = true;
|
||||
@ -665,9 +667,11 @@ void ViewerBase::renderingTraversals()
|
||||
}
|
||||
}
|
||||
|
||||
// check to see if windows are still valid
|
||||
checkWindowStatus();
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
// check to see if windows are still valid
|
||||
checkWindowStatus(contexts);
|
||||
if (_done) return;
|
||||
|
||||
double beginRenderingTraversals = elapsedTime();
|
||||
@ -760,9 +764,6 @@ void ViewerBase::renderingTraversals()
|
||||
// OSG_NOTICE<<std::endl<<"Start frame"<<std::endl;
|
||||
|
||||
|
||||
Contexts contexts;
|
||||
getContexts(contexts);
|
||||
|
||||
Cameras cameras;
|
||||
getCameras(cameras);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user