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


<<inline: Moved to 2nd screen.jpg>>

<<inline: Before moved.jpg>>

// 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@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to