I have just re-implemented my wxWindows implementation of osgViewer to use
osgViewer::Viewer instead of the old SimpleViewer. The code is very heavily
based on the osgviewerWX example (as was the old version!).

 

I have come across two problems. 1. I cannot get the TrackballManipilator to
work. 2. I get an assert on program exit because the view is being deleted
whilst the window is hidden.

 

Looking at 1. - I can see in the debugger that it appears that trackball
code is correctly handling all the mouse events but main scene view matrix
is not being updated. I have got somewhat lost trying to track the sequence
of events by which this should happen. Can anyone give me any guidance on
this? I am suspicious of the fact that requestRedraw and
requestContinuousUpdate are empty implementations., but this may be a red
herring(a false conclusion).

 

As far as 2. goes it is a feature of my app the it can exit whilst the popup
3d window is hidden, it used to work with the simpleViewer based code.
However I suspect I need to do more clean up now?  Any comments?

 

I have attached my source files.

 

Roger

 

#pragma once

#include "osg/node"
#include "osgViewer/Viewer"
#include "wx/glcanvas.h"

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 CWxOsgViewer : public wxFrame
{
public:
        CWxOsgViewer(wxWindow *pParent, long lStyle = wxDEFAULT_FRAME_STYLE);
        ~CWxOsgViewer(void);
        void SetRootNode(osg::Node *pNode);

protected:
        void OnIdle(wxIdleEvent& event);
        DECLARE_EVENT_TABLE()
        osg::ref_ptr<osgViewer::Viewer> m_p3dViewer;
        osg::ref_ptr<osg::Node> m_pRootNode;
};
// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif

#include "WxOsgViewer.h"
#include "osgViewer/ViewerEventHandlers"
#include "osgGA/TrackballManipulator"


BEGIN_EVENT_TABLE(CWxOsgViewer, wxFrame)
EVT_IDLE(CWxOsgViewer::OnIdle)
END_EVENT_TABLE()


CWxOsgViewer::CWxOsgViewer(wxWindow *pParent, long lStyle) : wxFrame(pParent, 
wxID_ANY, _("Triangulation Results"), wxDefaultPosition, wxSize(600, 400), 
lStyle)
{
        GraphicsWindowWX *pGraphicsWindow = new GraphicsWindowWX(this);
        m_p3dViewer = new osgViewer::Viewer;
        wxPoint ActualPosition = pGraphicsWindow->GetPosition();
        wxSize ActualSize = pGraphicsWindow->GetSize();

        m_p3dViewer->getCamera()->setGraphicsContext(pGraphicsWindow);
        m_p3dViewer->getCamera()->setViewport(ActualPosition.x, 
ActualPosition.y, ActualSize.x, ActualSize.y);
        m_p3dViewer->addEventHandler(new osgViewer::StatsHandler);
        m_p3dViewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);

        m_p3dViewer->setSceneData(new osg::Node);
    m_p3dViewer->setCameraManipulator(new osgGA::TrackballManipulator);
}

CWxOsgViewer::~CWxOsgViewer(void)
{
}

void CWxOsgViewer::SetRootNode(osg::Node *pNode)
{
        m_p3dViewer->setSceneData(pNode);
}


void CWxOsgViewer::OnIdle(wxIdleEvent& event)
{
        if (IsShown()) // If another app window is using the idle loop we will 
contine to get
                                        // idle events even if the window is 
hidden
                m_p3dViewer->frame();
}

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)
{
        wxPoint ActualPosition = GetPosition();
        wxSize ActualSize = GetSize();
    // default cursor to standard
    _oldCursor = *wxSTANDARD_CURSOR;
    _traits = new GraphicsContext::Traits;
    _traits->x = ActualPosition.x;
    _traits->y = ActualPosition.y;
    _traits->width = ActualSize.x;
    _traits->height = ActualSize.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 wxUSE_UNICODE
    int key = event.GetUnicodeKey();
#else
    int key = event.GetKeyCode();
#endif
    getEventQueue()->keyPress(key);

        wxLogDebug(wxT("Key down"));

    // propagate event
    event.Skip();
}

void GraphicsWindowWX::OnKeyUp(wxKeyEvent &event)
{
#if wxUSE_UNICODE
    int key = event.GetUnicodeKey();
#else
    int key = event.GetKeyCode();
#endif
    getEventQueue()->keyRelease(key);

        wxLogDebug(wxT("Key up"));
    // 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();
}

_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to