root/OpenSceneGraph/trunk/examples/osgviewerWX/osgviewerWX.cpp @ 10778

Revision 10778, 8.4 kB (checked in by robert, 4 years ago)

From J.P. Delport, "simple addition to make the scroll wheel work in the example."

Line 
1// For compilers that support precompilation, includes "wx.h".
2#include "wx/wxprec.h"
3
4#ifdef __BORLANDC__
5#pragma hdrstop
6#endif
7
8#ifndef WX_PRECOMP
9#include "wx/wx.h"
10#endif
11
12// For wxCURSOR_BLANK below, but isn't used a.t.m.
13//#ifdef WIN32
14//#include "wx/msw/wx.rc"
15//#endif
16
17#include "osgviewerWX.h"
18
19
20#include <osgViewer/ViewerEventHandlers>
21#include <osgGA/TrackballManipulator>
22#include <osgDB/ReadFile>
23#include <wx/image.h>
24#include <wx/menu.h>
25
26#include <iostream>
27
28// `Main program' equivalent, creating windows and returning main app frame
29bool wxOsgApp::OnInit()
30{
31    if (argc<2)
32    {
33        std::cout << wxString(argv[0]).mb_str() <<": requires filename argument." << std::endl;
34        return false;
35    }
36
37    int width = 800;
38    int height = 600;
39
40    // Create the main frame window
41
42    MainFrame *frame = new MainFrame(NULL, wxT("wxWidgets OSG Sample"),
43        wxDefaultPosition, wxSize(width, height));
44
45    // create osg canvas
46    //    - initialize
47
48    int *attributes = new int[7];
49    attributes[0] = int(WX_GL_DOUBLEBUFFER);
50    attributes[1] = WX_GL_RGBA;
51    attributes[2] = WX_GL_DEPTH_SIZE;
52    attributes[3] = 8;
53    attributes[4] = WX_GL_STENCIL_SIZE;
54    attributes[5] = 8;
55    attributes[6] = 0;
56
57    OSGCanvas *canvas = new OSGCanvas(frame, wxID_ANY, wxDefaultPosition,
58        wxSize(width, height), wxSUNKEN_BORDER, wxT("osgviewerWX"), attributes);
59
60    GraphicsWindowWX* gw = new GraphicsWindowWX(canvas);
61
62    canvas->SetGraphicsWindow(gw);
63
64    osgViewer::Viewer *viewer = new osgViewer::Viewer;
65    viewer->getCamera()->setGraphicsContext(gw);
66    viewer->getCamera()->setViewport(0,0,width,height);
67    viewer->addEventHandler(new osgViewer::StatsHandler);
68    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
69
70    // load the scene.
71    wxString fname(argv[1]);
72    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(fname.mb_str()));
73    if (!loadedModel)
74    {
75        std::cout << argv[0] <<": No data loaded." << std::endl;
76        return false;
77    }
78
79    viewer->setSceneData(loadedModel.get());
80    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
81    frame->SetViewer(viewer);
82
83    /* Show the frame */
84    frame->Show(true);
85
86    return true;
87}
88
89IMPLEMENT_APP(wxOsgApp)
90
91BEGIN_EVENT_TABLE(MainFrame, wxFrame)
92    EVT_IDLE(MainFrame::OnIdle)
93END_EVENT_TABLE()
94
95/* My frame constructor */
96MainFrame::MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
97    const wxSize& size, long style)
98    : wxFrame(frame, wxID_ANY, title, pos, size, style)
99{
100}
101
102void MainFrame::SetViewer(osgViewer::Viewer *viewer)
103{
104    _viewer = viewer;
105}
106
107void MainFrame::OnIdle(wxIdleEvent &event)
108{
109    _viewer->frame();
110
111    event.RequestMore();
112}
113
114BEGIN_EVENT_TABLE(OSGCanvas, wxGLCanvas)
115    EVT_SIZE                (OSGCanvas::OnSize)
116    EVT_PAINT               (OSGCanvas::OnPaint)
117    EVT_ERASE_BACKGROUND    (OSGCanvas::OnEraseBackground)
118
119    EVT_CHAR                (OSGCanvas::OnChar)
120    EVT_KEY_UP              (OSGCanvas::OnKeyUp)
121
122    EVT_ENTER_WINDOW        (OSGCanvas::OnMouseEnter)
123    EVT_LEFT_DOWN           (OSGCanvas::OnMouseDown)
124    EVT_MIDDLE_DOWN         (OSGCanvas::OnMouseDown)
125    EVT_RIGHT_DOWN          (OSGCanvas::OnMouseDown)
126    EVT_LEFT_UP             (OSGCanvas::OnMouseUp)
127    EVT_MIDDLE_UP           (OSGCanvas::OnMouseUp)
128    EVT_RIGHT_UP            (OSGCanvas::OnMouseUp)
129    EVT_MOTION              (OSGCanvas::OnMouseMotion)
130    EVT_MOUSEWHEEL          (OSGCanvas::OnMouseWheel)
131END_EVENT_TABLE()
132
133OSGCanvas::OSGCanvas(wxWindow *parent, wxWindowID id,
134    const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attributes)
135    : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, attributes)
136{
137    // default cursor to standard
138    _oldCursor = *wxSTANDARD_CURSOR;
139}
140
141OSGCanvas::~OSGCanvas()
142{
143}
144
145void OSGCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
146{
147    /* must always be here */
148    wxPaintDC dc(this);
149}
150
151void OSGCanvas::OnSize(wxSizeEvent& event)
152{
153    // this is also necessary to update the context on some platforms
154    wxGLCanvas::OnSize(event);
155
156    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
157    int width, height;
158    GetClientSize(&width, &height);
159
160    if (_graphics_window.valid())
161    {
162        // update the window dimensions, in case the window has been resized.
163        _graphics_window->getEventQueue()->windowResize(0, 0, width, height);
164        _graphics_window->resized(0,0,width,height);
165    }
166}
167
168void OSGCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
169{
170    /* Do nothing, to avoid flashing on MSW */
171}
172
173void OSGCanvas::OnChar(wxKeyEvent &event)
174{
175#if wxUSE_UNICODE
176    int key = event.GetUnicodeKey();
177#else
178    int key = event.GetKeyCode();
179#endif
180
181    if (_graphics_window.valid())
182        _graphics_window->getEventQueue()->keyPress(key);
183
184    // If this key event is not processed here, we should call
185    // event.Skip() to allow processing to continue.
186}
187
188void OSGCanvas::OnKeyUp(wxKeyEvent &event)
189{
190#if wxUSE_UNICODE
191    int key = event.GetUnicodeKey();
192#else
193    int key = event.GetKeyCode();
194#endif
195
196    if (_graphics_window.valid())
197        _graphics_window->getEventQueue()->keyRelease(key);
198
199    // If this key event is not processed here, we should call
200    // event.Skip() to allow processing to continue.
201}
202
203void OSGCanvas::OnMouseEnter(wxMouseEvent &event)
204{
205    // Set focus to ourselves, so keyboard events get directed to us
206    SetFocus();
207}
208
209void OSGCanvas::OnMouseDown(wxMouseEvent &event)
210{
211    if (_graphics_window.valid())
212    {
213        _graphics_window->getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
214            event.GetButton());
215    }
216}
217
218void OSGCanvas::OnMouseUp(wxMouseEvent &event)
219{
220    if (_graphics_window.valid())
221    {
222        _graphics_window->getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
223            event.GetButton());
224    }
225}
226
227void OSGCanvas::OnMouseMotion(wxMouseEvent &event)
228{
229    if (_graphics_window.valid())
230        _graphics_window->getEventQueue()->mouseMotion(event.GetX(), event.GetY());
231}
232
233void OSGCanvas::OnMouseWheel(wxMouseEvent &event)
234{
235    int delta = event.GetWheelRotation() / event.GetWheelDelta() * event.GetLinesPerAction();
236
237    if (_graphics_window.valid()) {
238        _graphics_window->getEventQueue()->mouseScroll(
239            delta>0 ?
240            osgGA::GUIEventAdapter::SCROLL_UP :
241            osgGA::GUIEventAdapter::SCROLL_DOWN);
242    }
243}
244
245void OSGCanvas::UseCursor(bool value)
246{
247    if (value)
248    {
249        // show the old cursor
250        SetCursor(_oldCursor);
251    }
252    else
253    {
254        // remember the old cursor
255        _oldCursor = GetCursor();
256
257        // hide the cursor
258        //    - can't find a way to do this neatly, so create a 1x1, transparent image
259        wxImage image(1,1);
260        image.SetMask(true);
261        image.SetMaskColour(0, 0, 0);
262        wxCursor cursor(image);
263        SetCursor(cursor);
264
265        // On wxGTK, only works as of version 2.7.0
266        // (http://trac.wxwidgets.org/ticket/2946)
267        // SetCursor( wxStockCursor( wxCURSOR_BLANK ) );
268    }
269}
270
271GraphicsWindowWX::GraphicsWindowWX(OSGCanvas *canvas)
272{
273    _canvas = canvas;
274
275    _traits = new GraphicsContext::Traits;
276
277    wxPoint pos = _canvas->GetPosition();
278    wxSize  size = _canvas->GetSize();
279
280    _traits->x = pos.x;
281    _traits->y = pos.y;
282    _traits->width = size.x;
283    _traits->height = size.y;
284
285    init();
286}
287
288GraphicsWindowWX::~GraphicsWindowWX()
289{
290}
291
292void GraphicsWindowWX::init()
293{
294    if (valid())
295    {
296        setState( new osg::State );
297        getState()->setGraphicsContext(this);
298
299        if (_traits.valid() && _traits->sharedContext)
300        {
301            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
302            incrementContextIDUsageCount( getState()->getContextID() );
303        }
304        else
305        {
306            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
307        }
308    }
309}
310
311void GraphicsWindowWX::grabFocus()
312{
313    // focus the canvas
314    _canvas->SetFocus();
315}
316
317void GraphicsWindowWX::grabFocusIfPointerInWindow()
318{
319    // focus this window, if the pointer is in the window
320    wxPoint pos = wxGetMousePosition();
321    if (wxFindWindowAtPoint(pos) == _canvas)
322        _canvas->SetFocus();
323}
324
325void GraphicsWindowWX::useCursor(bool cursorOn)
326{
327    _canvas->UseCursor(cursorOn);
328}
329
330bool GraphicsWindowWX::makeCurrentImplementation()
331{
332    _canvas->SetCurrent();
333    return true;
334}
335
336void GraphicsWindowWX::swapBuffersImplementation()
337{
338    _canvas->SwapBuffers();
339}
Note: See TracBrowser for help on using the browser.