[osg-users] loosing some textures when moving window to 2nd screen

Robert Osfield robert.osfield at gmail.com
Thu Sep 20 06:51:05 PDT 2007


HI Christer,

Are you working under Windows?  NVidia hardware?

There has been various threads on osg-users over the last few months
about moving windows across screens and then problems ensuing.  Please
read through these to get an understanding of the problem and
solutions w.r.t driver settings.

Robert.

On 9/20/07, Christer Wigren <wigren at foi.se> wrote:
> Hi,
>
> We are using wxwidgets with multiple windows on a WindowsXP machine. A
> problem that we have come across is that (when running  with 1 graphics
> card but two screens) the textures sometimes disappears on some of the
> windows when moved from one screen to the next (see attached images). If
> the window is moved on the same screen everything is fine.  I have
> attached (without the 3D models) sample code (a modified version of the
> osgviewerWX example) that will reproduce the problem on my machine. Any
> thoughts?
>
> /Christer
>
>
>
> // For compilers that support precompilation, includes "wx.h".
> #include "wx/wxprec.h"
>
> #ifdef __BORLANDC__
> #pragma hdrstop
> #endif
>
> #ifndef WX_PRECOMP
> #include "wx/wx.h"
> #endif
>
> #include "osgviewerWX.h"
>
>
> #include <osgViewer/ViewerEventHandlers>
> #include <osgGA/TrackballManipulator>
> #include <osgDB/ReadFile>
> #include <osg/MatrixTransform>
> #include <wx/image.h>
> #include <wx/menu.h>
> #include <wx/statline.h>
> #include "wx/listctrl.h"
>
> // `Main program' equivalent, creating windows and returning main app frame
> bool wxOsgApp::OnInit()
> {
>     // Create the main frame window
>     MainFrame *frame1 = new MainFrame(NULL, wxT("wxWidgets OSG Sample"),
>         wxDefaultPosition, wxDefaultSize);
>
>         wxFrame* frame2 = new wxFrame(frame1, wxID_ANY, "Extra window 2", wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE);
>
>     // create osg canvas
>     //    - initialize
>
>
>     int width = 800;
>     int height = 600;
>
>     GraphicsWindowWX* gw1 = new GraphicsWindowWX(frame1, wxID_ANY, wxDefaultPosition,
>                                                 wxSize(width, height), wxSUNKEN_BORDER);
>
>     GraphicsWindowWX* gw2 = new GraphicsWindowWX(frame2, wxID_ANY, wxDefaultPosition,
>                                                 wxSize(width, height), wxSUNKEN_BORDER);
>
>     osgViewer::CompositeViewer *viewer = new osgViewer::CompositeViewer;
>         viewer->setThreadingModel(osgViewer::CompositeViewer::ThreadingModel::ThreadPerCamera);
>
>         osgViewer::View* view1 = new osgViewer::View;
>         osgViewer::View* view2 = new osgViewer::View;
>
>     // load the scene.
>     osg::Node* loadedModel1 = osgDB::readNodeFile("D:/MySVN/EWSim/data/FoiLoggo/loggo.osg");
>     if (!loadedModel1)
>     {
>         return false;
>     }
>
>         osgDB::Registry::instance()->getDataFilePathList().push_back("D:/MySVN/EWSim/data/EngelHolmMap");
>         osg::Node* loadedModel2 = osgDB::readNodeFile("aaaLOD_TOP.osg");
>     if (!loadedModel2)
>     {
>         return false;
>     }
>         osgDB::Registry::instance()->getDataFilePathList().pop_back();
>
>     view1->getCamera()->setGraphicsContext(gw1);
>     view1->getCamera()->setViewport(0,0,width,height);
>     view1->addEventHandler(new osgViewer::StatsHandler);
>     view1->setSceneData(loadedModel1);
>     view1->setCameraManipulator(new osgGA::TrackballManipulator);
>         viewer->addView(view1);
>
>         osg::Camera* pCamera = new osg::Camera;
>         view2->setCamera(pCamera);
>     view2->getCamera()->setGraphicsContext(gw2);
>     view2->getCamera()->setViewport(0,0,width,height);
>     view2->addEventHandler(new osgViewer::StatsHandler);
>     view2->setSceneData(loadedModel2);
>         osg::Viewport* pViewport2 = view2->getCamera()->getViewport();
>         double dAspectRatio = pViewport2->aspectRatio();
>         double clippingNearDistance     = 2.0;
>         double clippingFarDistance      = 300000.0;
>         view2->getCamera()->setProjectionMatrixAsOrtho(
>                 -50000,
>                 50000,
>                 -37500,
>                 37500,
>                 2,
>                 300000
>         );
>         //osg::Vec3 vecCameraPos = loadedModel2->getBound().center();
>         osg::Vec3 vecCameraPos = osg::Vec3(18748, -12503, 34512);
>         osg::Vec3 vecLookAtPos = vecCameraPos;
>         vecCameraPos.z() += 35000.0;
>
>         view2->getCamera()->setViewMatrixAsLookAt(
>                 vecCameraPos,
>                 vecLookAtPos,
>                 osg::Vec3(
>                         0,
>                         1,
>                         0
>                 )
>         );
>
>         viewer->addView(view2);
>
>     frame1->SetViewer(viewer);
>
>     /* Show the frame */
>     frame1->Show(true);
>         frame2->Show(true);
>
>     return true;
> }
>
> IMPLEMENT_APP(wxOsgApp)
>
> BEGIN_EVENT_TABLE(MainFrame, wxFrame)
>     EVT_IDLE(MainFrame::OnIdle)
> END_EVENT_TABLE()
>
> /* My frame constructor */
> MainFrame::MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
>     const wxSize& size, long style)
>     : wxFrame(frame, wxID_ANY, title, pos, size, style)
> {
> }
>
> void MainFrame::SetViewer(osgViewer::CompositeViewer *viewer)
> {
>     _viewer = viewer;
> }
>
> void MainFrame::OnIdle(wxIdleEvent &event)
> {
>     _viewer->frame();
>
>     event.RequestMore();
> }
>
> BEGIN_EVENT_TABLE(GraphicsWindowWX, wxGLCanvas)
>     EVT_SIZE            (GraphicsWindowWX::OnSize            )
>     EVT_PAINT            (GraphicsWindowWX::OnPaint            )
>     EVT_ERASE_BACKGROUND(GraphicsWindowWX::OnEraseBackground)
>     EVT_KEY_DOWN        (GraphicsWindowWX::OnKeyDown        )
>     EVT_KEY_UP            (GraphicsWindowWX::OnKeyUp            )
>     EVT_MOUSE_EVENTS    (GraphicsWindowWX::OnMouse            )
> END_EVENT_TABLE()
>
> GraphicsWindowWX::GraphicsWindowWX(wxWindow *parent, wxWindowID id,
>     const wxPoint& pos, const wxSize& size, long style, const wxString& name)
>     : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name)
> {
>     // default cursor to standard
>     _oldCursor = *wxSTANDARD_CURSOR;
>
>     _traits = new GraphicsContext::Traits;
>     _traits->x = pos.x;
>     _traits->y = pos.y;
>     _traits->width = size.x;
>     _traits->height = size.y;
>
>     init();
>
> }
>
> void GraphicsWindowWX::init()
> {
>     if (valid())
>     {
>         setState( new osg::State );
>         getState()->setGraphicsContext(this);
>
>         if (_traits.valid() && _traits->sharedContext)
>         {
>             getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
>             incrementContextIDUsageCount( getState()->getContextID() );
>         }
>         else
>         {
>             getState()->setContextID( osg::GraphicsContext::createNewContextID() );
>         }
>     }
> }
>
> GraphicsWindowWX::~GraphicsWindowWX()
> {
> }
>
> void GraphicsWindowWX::OnPaint( wxPaintEvent& WXUNUSED(event) )
> {
>     /* must always be here */
>     wxPaintDC dc(this);
> }
>
> void GraphicsWindowWX::OnSize(wxSizeEvent& event)
> {
>     // this is also necessary to update the context on some platforms
>     wxGLCanvas::OnSize(event);
>
>     // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
>     int width, height;
>     GetClientSize(&width, &height);
>
>     // update the window dimensions, in case the window has been resized.
>     getEventQueue()->windowResize(0, 0, width, height);
>     resized(0,0,width,height);
> }
>
> void GraphicsWindowWX::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
> {
>     /* Do nothing, to avoid flashing on MSW */
> }
>
> void GraphicsWindowWX::OnKeyDown(wxKeyEvent &event)
> {
> #if 0
>     int key = event.GetUnicodeKey();
> #else
>     int key = event.GetKeyCode();
> #endif
>     getEventQueue()->keyPress(key);
>
>     // propagate event
>     event.Skip();
> }
>
> void GraphicsWindowWX::OnKeyUp(wxKeyEvent &event)
> {
> #if 0
>     int key = event.GetUnicodeKey();
> #else
>     int key = event.GetKeyCode();
> #endif
>     getEventQueue()->keyRelease(key);
>
>     // propagate event
>     event.Skip();
> }
>
> void GraphicsWindowWX::OnMouse(wxMouseEvent& event)
> {
>     if (event.ButtonDown()) {
>         int button = event.GetButton();
>         getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(), button);
>     }
>     else if (event.ButtonUp()) {
>         int button = event.GetButton();
>         getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(), button);
>     }
>     else if (event.Dragging()) {
>         getEventQueue()->mouseMotion(event.GetX(), event.GetY());
>     }
> }
>
> void GraphicsWindowWX::grabFocus()
> {
>     // focus this window
>     SetFocus();
> }
>
> void GraphicsWindowWX::grabFocusIfPointerInWindow()
> {
>     // focus this window, if the pointer is in the window
>     wxPoint pos = wxGetMousePosition();
>     if (this == wxFindWindowAtPoint(pos)) {
>         SetFocus();
>     }
> }
>
> void GraphicsWindowWX::useCursor(bool cursorOn)
> {
>     if (cursorOn) {
>
>         // show the old cursor
>         SetCursor(_oldCursor);
>     }
>     else {
>
>         // remember the old cursor
>         _oldCursor = GetCursor();
>
>         // hide the cursor
>         //    - can't find a way to do this neatly, so create a 1x1, transparent image
>         wxImage image(1,1);
>         image.SetMask(true);
>         image.SetMaskColour(0, 0, 0);
>         wxCursor cursor(image);
>         SetCursor(cursor);
>     }
> }
>
> bool GraphicsWindowWX::makeCurrentImplementation()
> {
>     SetCurrent();
>     return true;
> }
>
> void GraphicsWindowWX::swapBuffersImplementation()
> {
>     SwapBuffers();
> }
>
>
> #ifndef _WXSIMPLEVIEWERWX_H_
> #define _WXSIMPLEVIEWERWX_H_
>
> #include "wx/defs.h"
> #include "wx/app.h"
> #include "wx/cursor.h"
> #include "wx/glcanvas.h"
> #include <osgViewer/CompositeViewer>
> #include <string>
>
> class GraphicsWindowWX: public wxGLCanvas, public osgViewer::GraphicsWindow
> {
> public:
>     GraphicsWindowWX(wxWindow *parent, wxWindowID id = wxID_ANY,
>         const wxPoint& pos = wxDefaultPosition,
>         const wxSize& size = wxDefaultSize, long style = 0,
>         const wxString& name = wxT("TestGLCanvas"));
>
>     ~GraphicsWindowWX();
>
>     void init();
>
>     void OnPaint(wxPaintEvent& event);
>     void OnSize(wxSizeEvent& event);
>     void OnEraseBackground(wxEraseEvent& event);
>     void OnKeyDown(wxKeyEvent &event);
>     void OnKeyUp(wxKeyEvent &event);
>     void OnMouse(wxMouseEvent &event);
>
>     //
>     // GraphicsWindow interface
>     //
>
>     void grabFocus();
>     void grabFocusIfPointerInWindow();
>     void useCursor(bool cursorOn);
>
>     bool makeCurrentImplementation();
>     void swapBuffersImplementation();
>
>     // note implemented yet...just use dummy implementation to get working.
>     virtual bool valid() const { return true; }
>     virtual bool realizeImplementation() { return true; }
>     virtual bool isRealizedImplementation() const  { return true; }
>     virtual void closeImplementation() {}
>     virtual bool releaseContextImplementation() { return true; }
>
> private:
>     wxCursor _oldCursor;
>
>     DECLARE_EVENT_TABLE()
> };
>
> class MainFrame : public wxFrame
> {
> public:
>     MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
>         const wxSize& size, long style = wxDEFAULT_FRAME_STYLE);
>
>     void SetViewer(osgViewer::CompositeViewer *viewer);
>     void OnIdle(wxIdleEvent& event);
>
> private:
>     osg::ref_ptr<osgViewer::CompositeViewer> _viewer;
>
>     DECLARE_EVENT_TABLE()
> };
>
> /* Define a new application type */
> class wxOsgApp : public wxApp
> {
> public:
>     bool OnInit();
> };
>
> #endif // _WXSIMPLEVIEWERWX_H_
>
>
> _______________________________________________
> osg-users mailing list
> osg-users at lists.openscenegraph.org
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
>



More information about the osg-users mailing list