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