2007-05-11 17:07:00 +08:00
|
|
|
// 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
|
|
|
|
|
2007-06-02 06:41:11 +08:00
|
|
|
#include "osgviewerWX.h"
|
2007-06-02 23:31:21 +08:00
|
|
|
|
|
|
|
|
2007-06-07 00:23:20 +08:00
|
|
|
#include <osgViewer/ViewerEventHandlers>
|
2007-05-11 17:07:00 +08:00
|
|
|
#include <osgGA/TrackballManipulator>
|
|
|
|
#include <osgDB/ReadFile>
|
|
|
|
#include <wx/image.h>
|
|
|
|
#include <wx/menu.h>
|
|
|
|
|
2008-03-14 22:35:15 +08:00
|
|
|
#include <iostream>
|
|
|
|
|
2007-05-11 17:07:00 +08:00
|
|
|
// `Main program' equivalent, creating windows and returning main app frame
|
|
|
|
bool wxOsgApp::OnInit()
|
|
|
|
{
|
2008-03-14 00:22:07 +08:00
|
|
|
if (argc<2)
|
|
|
|
{
|
|
|
|
std::cout << wxString(argv[0]).mb_str() <<": requires filename argument." << std::endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int width = 800;
|
|
|
|
int height = 600;
|
|
|
|
|
2007-05-11 17:07:00 +08:00
|
|
|
// Create the main frame window
|
2008-03-14 00:22:07 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
MainFrame *frame = new MainFrame(NULL, wxT("wxWidgets OSG Sample"),
|
2008-03-14 00:22:07 +08:00
|
|
|
wxDefaultPosition, wxSize(width, height));
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// create osg canvas
|
|
|
|
// - initialize
|
2007-06-02 23:31:21 +08:00
|
|
|
|
2007-08-27 21:33:58 +08:00
|
|
|
int *attributes = new int[6];
|
|
|
|
attributes[0] = int(WX_GL_DOUBLEBUFFER);
|
|
|
|
attributes[1] = WX_GL_RGBA;
|
|
|
|
attributes[2] = WX_GL_DEPTH_SIZE;
|
|
|
|
attributes[3] = 8;
|
|
|
|
attributes[4] = WX_GL_STENCIL_SIZE;
|
|
|
|
attributes[5] = 8;
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-08-27 21:33:58 +08:00
|
|
|
GraphicsWindowWX* gw = new GraphicsWindowWX(frame, wxID_ANY, wxDefaultPosition,
|
|
|
|
wxSize(width, height), wxSUNKEN_BORDER, wxT("osgviewerWX"), attributes);
|
2008-03-14 00:22:07 +08:00
|
|
|
|
2007-06-02 23:31:21 +08:00
|
|
|
osgViewer::Viewer *viewer = new osgViewer::Viewer;
|
|
|
|
viewer->getCamera()->setGraphicsContext(gw);
|
|
|
|
viewer->getCamera()->setViewport(0,0,width,height);
|
|
|
|
viewer->addEventHandler(new osgViewer::StatsHandler);
|
|
|
|
viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// load the scene.
|
2008-03-14 00:22:07 +08:00
|
|
|
wxString fname(argv[1]);
|
|
|
|
osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(fname.mb_str()));
|
2007-05-21 20:28:25 +08:00
|
|
|
if (!loadedModel)
|
|
|
|
{
|
2008-03-14 00:22:07 +08:00
|
|
|
std::cout << argv[0] <<": No data loaded." << std::endl;
|
2007-05-21 20:28:25 +08:00
|
|
|
return false;
|
|
|
|
}
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-06-02 23:31:21 +08:00
|
|
|
viewer->setSceneData(loadedModel.get());
|
|
|
|
viewer->setCameraManipulator(new osgGA::TrackballManipulator);
|
|
|
|
frame->SetViewer(viewer);
|
2007-05-11 17:07:00 +08:00
|
|
|
|
|
|
|
/* Show the frame */
|
2007-05-21 20:28:25 +08:00
|
|
|
frame->Show(true);
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
return true;
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
IMPLEMENT_APP(wxOsgApp)
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(MainFrame, wxFrame)
|
2007-05-21 20:28:25 +08:00
|
|
|
EVT_IDLE(MainFrame::OnIdle)
|
2007-05-11 17:07:00 +08:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
/* My frame constructor */
|
|
|
|
MainFrame::MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
|
2007-05-21 20:28:25 +08:00
|
|
|
const wxSize& size, long style)
|
|
|
|
: wxFrame(frame, wxID_ANY, title, pos, size, style)
|
2007-05-11 17:07:00 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2007-06-02 23:31:21 +08:00
|
|
|
void MainFrame::SetViewer(osgViewer::Viewer *viewer)
|
2007-05-11 17:07:00 +08:00
|
|
|
{
|
2007-06-02 23:31:21 +08:00
|
|
|
_viewer = viewer;
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void MainFrame::OnIdle(wxIdleEvent &event)
|
|
|
|
{
|
2007-06-02 23:31:21 +08:00
|
|
|
_viewer->frame();
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
event.RequestMore();
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
BEGIN_EVENT_TABLE(GraphicsWindowWX, wxGLCanvas)
|
2008-05-27 05:09:54 +08:00
|
|
|
EVT_SIZE (GraphicsWindowWX::OnSize)
|
|
|
|
EVT_PAINT (GraphicsWindowWX::OnPaint)
|
|
|
|
EVT_ERASE_BACKGROUND (GraphicsWindowWX::OnEraseBackground)
|
|
|
|
|
|
|
|
EVT_CHAR (GraphicsWindowWX::OnChar)
|
|
|
|
EVT_KEY_UP (GraphicsWindowWX::OnKeyUp)
|
|
|
|
|
|
|
|
EVT_ENTER_WINDOW (GraphicsWindowWX::OnMouseEnter)
|
|
|
|
EVT_LEFT_DOWN (GraphicsWindowWX::OnMouseDown)
|
|
|
|
EVT_MIDDLE_DOWN (GraphicsWindowWX::OnMouseDown)
|
|
|
|
EVT_RIGHT_DOWN (GraphicsWindowWX::OnMouseDown)
|
|
|
|
EVT_LEFT_UP (GraphicsWindowWX::OnMouseUp)
|
|
|
|
EVT_MIDDLE_UP (GraphicsWindowWX::OnMouseUp)
|
|
|
|
EVT_RIGHT_UP (GraphicsWindowWX::OnMouseUp)
|
|
|
|
EVT_MOTION (GraphicsWindowWX::OnMouseMotion)
|
2007-05-11 17:07:00 +08:00
|
|
|
END_EVENT_TABLE()
|
|
|
|
|
|
|
|
GraphicsWindowWX::GraphicsWindowWX(wxWindow *parent, wxWindowID id,
|
2007-08-27 21:33:58 +08:00
|
|
|
const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attributes)
|
|
|
|
: wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, attributes)
|
2007-05-11 17:07:00 +08:00
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
// default cursor to standard
|
|
|
|
_oldCursor = *wxSTANDARD_CURSOR;
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-06-02 23:31:21 +08:00
|
|
|
_traits = new GraphicsContext::Traits;
|
|
|
|
_traits->x = pos.x;
|
|
|
|
_traits->y = pos.y;
|
|
|
|
_traits->width = size.x;
|
|
|
|
_traits->height = size.y;
|
|
|
|
|
|
|
|
init();
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-06-02 23:31:21 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::init()
|
|
|
|
{
|
|
|
|
if (valid())
|
|
|
|
{
|
|
|
|
setState( new osg::State );
|
|
|
|
getState()->setGraphicsContext(this);
|
|
|
|
|
|
|
|
if (_traits.valid() && _traits->sharedContext)
|
|
|
|
{
|
|
|
|
getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
|
2007-08-24 17:42:11 +08:00
|
|
|
incrementContextIDUsageCount( getState()->getContextID() );
|
2007-06-02 23:31:21 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
getState()->setContextID( osg::GraphicsContext::createNewContextID() );
|
|
|
|
}
|
|
|
|
}
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
GraphicsWindowWX::~GraphicsWindowWX()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnPaint( wxPaintEvent& WXUNUSED(event) )
|
|
|
|
{
|
|
|
|
/* must always be here */
|
2007-05-21 20:28:25 +08:00
|
|
|
wxPaintDC dc(this);
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnSize(wxSizeEvent& event)
|
|
|
|
{
|
|
|
|
// this is also necessary to update the context on some platforms
|
2007-05-21 20:28:25 +08:00
|
|
|
wxGLCanvas::OnSize(event);
|
2007-05-11 17:07:00 +08:00
|
|
|
|
|
|
|
// set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
|
2007-05-21 20:28:25 +08:00
|
|
|
int width, height;
|
|
|
|
GetClientSize(&width, &height);
|
2007-08-24 17:42:11 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// update the window dimensions, in case the window has been resized.
|
|
|
|
getEventQueue()->windowResize(0, 0, width, height);
|
2007-06-02 23:31:21 +08:00
|
|
|
resized(0,0,width,height);
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
/* Do nothing, to avoid flashing on MSW */
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
2008-05-27 05:09:54 +08:00
|
|
|
void GraphicsWindowWX::OnChar(wxKeyEvent &event)
|
2007-05-11 17:07:00 +08:00
|
|
|
{
|
2007-08-24 17:42:11 +08:00
|
|
|
#if wxUSE_UNICODE
|
2007-06-02 23:31:21 +08:00
|
|
|
int key = event.GetUnicodeKey();
|
|
|
|
#else
|
2007-05-21 20:28:25 +08:00
|
|
|
int key = event.GetKeyCode();
|
2007-06-02 23:31:21 +08:00
|
|
|
#endif
|
2007-08-24 17:42:11 +08:00
|
|
|
getEventQueue()->keyPress(key);
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2008-05-27 05:09:54 +08:00
|
|
|
// If this key event is not processed here, we should call
|
|
|
|
// event.Skip() to allow processing to continue.
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnKeyUp(wxKeyEvent &event)
|
|
|
|
{
|
2007-08-24 17:42:11 +08:00
|
|
|
#if wxUSE_UNICODE
|
2007-06-02 23:31:21 +08:00
|
|
|
int key = event.GetUnicodeKey();
|
|
|
|
#else
|
2007-05-21 20:28:25 +08:00
|
|
|
int key = event.GetKeyCode();
|
2007-06-02 23:31:21 +08:00
|
|
|
#endif
|
2007-08-24 17:42:11 +08:00
|
|
|
getEventQueue()->keyRelease(key);
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2008-05-27 05:09:54 +08:00
|
|
|
// If this key event is not processed here, we should call
|
|
|
|
// event.Skip() to allow processing to continue.
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
2008-05-27 05:09:54 +08:00
|
|
|
void GraphicsWindowWX::OnMouseEnter(wxMouseEvent &event)
|
2007-05-11 17:07:00 +08:00
|
|
|
{
|
2008-05-27 05:09:54 +08:00
|
|
|
// Set focus to ourselves, so keyboard events get directed to us
|
|
|
|
SetFocus();
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnMouseDown(wxMouseEvent &event)
|
|
|
|
{
|
|
|
|
getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
|
|
|
|
event.GetButton());
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
2008-05-27 05:09:54 +08:00
|
|
|
void GraphicsWindowWX::OnMouseUp(wxMouseEvent &event)
|
|
|
|
{
|
|
|
|
getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
|
|
|
|
event.GetButton());
|
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::OnMouseMotion(wxMouseEvent &event)
|
|
|
|
{
|
|
|
|
getEventQueue()->mouseMotion(event.GetX(), event.GetY());
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-05-11 17:07:00 +08:00
|
|
|
void GraphicsWindowWX::grabFocus()
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
// focus this window
|
|
|
|
SetFocus();
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::grabFocusIfPointerInWindow()
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
// focus this window, if the pointer is in the window
|
|
|
|
wxPoint pos = wxGetMousePosition();
|
|
|
|
if (this == wxFindWindowAtPoint(pos)) {
|
|
|
|
SetFocus();
|
|
|
|
}
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::useCursor(bool cursorOn)
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
if (cursorOn) {
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// show the old cursor
|
|
|
|
SetCursor(_oldCursor);
|
|
|
|
}
|
|
|
|
else {
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// remember the old cursor
|
|
|
|
_oldCursor = GetCursor();
|
2007-05-11 17:07:00 +08:00
|
|
|
|
2007-05-21 20:28:25 +08:00
|
|
|
// 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);
|
|
|
|
}
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GraphicsWindowWX::makeCurrentImplementation()
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
SetCurrent();
|
|
|
|
return true;
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GraphicsWindowWX::swapBuffersImplementation()
|
|
|
|
{
|
2007-05-21 20:28:25 +08:00
|
|
|
SwapBuffers();
|
2007-05-11 17:07:00 +08:00
|
|
|
}
|