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

Revision 13130, 8.5 kB (checked in by robert, 15 hours ago)

Fixed rendering of Popups

  • Property svn:eol-style set to native
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[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    if (!_viewer->isRealized())
110        return;
111
112    _viewer->frame();
113
114    event.RequestMore();
115}
116
117BEGIN_EVENT_TABLE(OSGCanvas, wxGLCanvas)
118    EVT_SIZE                (OSGCanvas::OnSize)
119    EVT_PAINT               (OSGCanvas::OnPaint)
120    EVT_ERASE_BACKGROUND    (OSGCanvas::OnEraseBackground)
121
122    EVT_CHAR                (OSGCanvas::OnChar)
123    EVT_KEY_UP              (OSGCanvas::OnKeyUp)
124
125    EVT_ENTER_WINDOW        (OSGCanvas::OnMouseEnter)
126    EVT_LEFT_DOWN           (OSGCanvas::OnMouseDown)
127    EVT_MIDDLE_DOWN         (OSGCanvas::OnMouseDown)
128    EVT_RIGHT_DOWN          (OSGCanvas::OnMouseDown)
129    EVT_LEFT_UP             (OSGCanvas::OnMouseUp)
130    EVT_MIDDLE_UP           (OSGCanvas::OnMouseUp)
131    EVT_RIGHT_UP            (OSGCanvas::OnMouseUp)
132    EVT_MOTION              (OSGCanvas::OnMouseMotion)
133    EVT_MOUSEWHEEL          (OSGCanvas::OnMouseWheel)
134END_EVENT_TABLE()
135
136OSGCanvas::OSGCanvas(wxWindow *parent, wxWindowID id,
137    const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attributes)
138    : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, attributes)
139{
140    // default cursor to standard
141    _oldCursor = *wxSTANDARD_CURSOR;
142}
143
144OSGCanvas::~OSGCanvas()
145{
146}
147
148void OSGCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
149{
150    /* must always be here */
151    wxPaintDC dc(this);
152}
153
154void OSGCanvas::OnSize(wxSizeEvent& event)
155{
156    // this is also necessary to update the context on some platforms
157    wxGLCanvas::OnSize(event);
158
159    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
160    int width, height;
161    GetClientSize(&width, &height);
162
163    if (_graphics_window.valid())
164    {
165        // update the window dimensions, in case the window has been resized.
166        _graphics_window->getEventQueue()->windowResize(0, 0, width, height);
167        _graphics_window->resized(0,0,width,height);
168    }
169}
170
171void OSGCanvas::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
172{
173    /* Do nothing, to avoid flashing on MSW */
174}
175
176void OSGCanvas::OnChar(wxKeyEvent &event)
177{
178#if wxUSE_UNICODE
179    int key = event.GetUnicodeKey();
180#else
181    int key = event.GetKeyCode();
182#endif
183
184    if (_graphics_window.valid())
185        _graphics_window->getEventQueue()->keyPress(key);
186
187    // If this key event is not processed here, we should call
188    // event.Skip() to allow processing to continue.
189}
190
191void OSGCanvas::OnKeyUp(wxKeyEvent &event)
192{
193#if wxUSE_UNICODE
194    int key = event.GetUnicodeKey();
195#else
196    int key = event.GetKeyCode();
197#endif
198
199    if (_graphics_window.valid())
200        _graphics_window->getEventQueue()->keyRelease(key);
201
202    // If this key event is not processed here, we should call
203    // event.Skip() to allow processing to continue.
204}
205
206void OSGCanvas::OnMouseEnter(wxMouseEvent &event)
207{
208    // Set focus to ourselves, so keyboard events get directed to us
209    SetFocus();
210}
211
212void OSGCanvas::OnMouseDown(wxMouseEvent &event)
213{
214    if (_graphics_window.valid())
215    {
216        _graphics_window->getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(),
217            event.GetButton());
218    }
219}
220
221void OSGCanvas::OnMouseUp(wxMouseEvent &event)
222{
223    if (_graphics_window.valid())
224    {
225        _graphics_window->getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(),
226            event.GetButton());
227    }
228}
229
230void OSGCanvas::OnMouseMotion(wxMouseEvent &event)
231{
232    if (_graphics_window.valid())
233        _graphics_window->getEventQueue()->mouseMotion(event.GetX(), event.GetY());
234}
235
236void OSGCanvas::OnMouseWheel(wxMouseEvent &event)
237{
238    int delta = event.GetWheelRotation() / event.GetWheelDelta() * event.GetLinesPerAction();
239
240    if (_graphics_window.valid()) {
241        _graphics_window->getEventQueue()->mouseScroll(
242            delta>0 ?
243            osgGA::GUIEventAdapter::SCROLL_UP :
244            osgGA::GUIEventAdapter::SCROLL_DOWN);
245    }
246}
247
248void OSGCanvas::UseCursor(bool value)
249{
250    if (value)
251    {
252        // show the old cursor
253        SetCursor(_oldCursor);
254    }
255    else
256    {
257        // remember the old cursor
258        _oldCursor = GetCursor();
259
260        // hide the cursor
261        //    - can't find a way to do this neatly, so create a 1x1, transparent image
262        wxImage image(1,1);
263        image.SetMask(true);
264        image.SetMaskColour(0, 0, 0);
265        wxCursor cursor(image);
266        SetCursor(cursor);
267
268        // On wxGTK, only works as of version 2.7.0
269        // (http://trac.wxwidgets.org/ticket/2946)
270        // SetCursor( wxStockCursor( wxCURSOR_BLANK ) );
271    }
272}
273
274GraphicsWindowWX::GraphicsWindowWX(OSGCanvas *canvas)
275{
276    _canvas = canvas;
277
278    _traits = new GraphicsContext::Traits;
279
280    wxPoint pos = _canvas->GetPosition();
281    wxSize  size = _canvas->GetSize();
282
283    _traits->x = pos.x;
284    _traits->y = pos.y;
285    _traits->width = size.x;
286    _traits->height = size.y;
287
288    init();
289}
290
291GraphicsWindowWX::~GraphicsWindowWX()
292{
293}
294
295void GraphicsWindowWX::init()
296{
297    if (valid())
298    {
299        setState( new osg::State );
300        getState()->setGraphicsContext(this);
301
302        if (_traits.valid() && _traits->sharedContext.valid())
303        {
304            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
305            incrementContextIDUsageCount( getState()->getContextID() );
306        }
307        else
308        {
309            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
310        }
311    }
312}
313
314void GraphicsWindowWX::grabFocus()
315{
316    // focus the canvas
317    _canvas->SetFocus();
318}
319
320void GraphicsWindowWX::grabFocusIfPointerInWindow()
321{
322    // focus this window, if the pointer is in the window
323    wxPoint pos = wxGetMousePosition();
324    if (wxFindWindowAtPoint(pos) == _canvas)
325        _canvas->SetFocus();
326}
327
328void GraphicsWindowWX::useCursor(bool cursorOn)
329{
330    _canvas->UseCursor(cursorOn);
331}
332
333bool GraphicsWindowWX::makeCurrentImplementation()
334{
335    _canvas->SetCurrent();
336    return true;
337}
338
339void GraphicsWindowWX::swapBuffersImplementation()
340{
341    _canvas->SwapBuffers();
342}
Note: See TracBrowser for help on using the browser.