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

Revision 7938, 6.5 kB (checked in by robert, 7 years ago)

From Paul Melis, "Here is an updated osgviewerWX example to bring it more in line with the
other GUI toolkit examples. It now takes a model file as command-line
argument (complaining if there isn't one), and its startup window size
is now actually applied (it used to be too small). I tested this with a
unicode-build of wxWidgets, as that is the recommended build type on
Linux with GTK. I'm pretty sure this version of the example will work
for the ANSI build as well, but I have no way of testing."

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#include "osgviewerWX.h"
13
14
15#include <osgViewer/ViewerEventHandlers>
16#include <osgGA/TrackballManipulator>
17#include <osgDB/ReadFile>
18#include <wx/image.h>
19#include <wx/menu.h>
20
21// `Main program' equivalent, creating windows and returning main app frame
22bool wxOsgApp::OnInit()
23{
24    if (argc<2)
25    {
26        std::cout << wxString(argv[0]).mb_str() <<": requires filename argument." << std::endl;
27        return false;
28    }
29
30    int width = 800;
31    int height = 600;
32
33    // Create the main frame window
34
35    MainFrame *frame = new MainFrame(NULL, wxT("wxWidgets OSG Sample"),
36        wxDefaultPosition, wxSize(width, height));
37
38    // create osg canvas
39    //    - initialize
40
41    int *attributes = new int[6];
42    attributes[0] = int(WX_GL_DOUBLEBUFFER);
43    attributes[1] = WX_GL_RGBA;
44    attributes[2] = WX_GL_DEPTH_SIZE;
45    attributes[3] = 8;
46    attributes[4] = WX_GL_STENCIL_SIZE;
47    attributes[5] = 8;
48
49    GraphicsWindowWX* gw = new GraphicsWindowWX(frame, wxID_ANY, wxDefaultPosition,
50                                                wxSize(width, height), wxSUNKEN_BORDER, wxT("osgviewerWX"), attributes);
51
52    osgViewer::Viewer *viewer = new osgViewer::Viewer;
53    viewer->getCamera()->setGraphicsContext(gw);
54    viewer->getCamera()->setViewport(0,0,width,height);
55    viewer->addEventHandler(new osgViewer::StatsHandler);
56    viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
57
58    // load the scene.
59    wxString fname(argv[1]);
60    osg::ref_ptr<osg::Node> loadedModel = osgDB::readNodeFile(std::string(fname.mb_str()));
61    if (!loadedModel)
62    {
63        std::cout << argv[0] <<": No data loaded." << std::endl;
64        return false;
65    }
66
67    viewer->setSceneData(loadedModel.get());
68    viewer->setCameraManipulator(new osgGA::TrackballManipulator);
69
70    frame->SetViewer(viewer);
71
72    /* Show the frame */
73    frame->Show(true);
74
75    return true;
76}
77
78IMPLEMENT_APP(wxOsgApp)
79
80BEGIN_EVENT_TABLE(MainFrame, wxFrame)
81    EVT_IDLE(MainFrame::OnIdle)
82END_EVENT_TABLE()
83
84/* My frame constructor */
85MainFrame::MainFrame(wxFrame *frame, const wxString& title, const wxPoint& pos,
86    const wxSize& size, long style)
87    : wxFrame(frame, wxID_ANY, title, pos, size, style)
88{
89}
90
91void MainFrame::SetViewer(osgViewer::Viewer *viewer)
92{
93    _viewer = viewer;
94}
95
96void MainFrame::OnIdle(wxIdleEvent &event)
97{
98    _viewer->frame();
99
100    event.RequestMore();
101}
102
103BEGIN_EVENT_TABLE(GraphicsWindowWX, wxGLCanvas)
104    EVT_SIZE            (GraphicsWindowWX::OnSize            )
105    EVT_PAINT            (GraphicsWindowWX::OnPaint            )
106    EVT_ERASE_BACKGROUND(GraphicsWindowWX::OnEraseBackground)
107    EVT_KEY_DOWN        (GraphicsWindowWX::OnKeyDown        )
108    EVT_KEY_UP            (GraphicsWindowWX::OnKeyUp            )
109    EVT_MOUSE_EVENTS    (GraphicsWindowWX::OnMouse            )
110END_EVENT_TABLE()
111
112GraphicsWindowWX::GraphicsWindowWX(wxWindow *parent, wxWindowID id,
113    const wxPoint& pos, const wxSize& size, long style, const wxString& name, int *attributes)
114    : wxGLCanvas(parent, id, pos, size, style|wxFULL_REPAINT_ON_RESIZE, name, attributes)
115{
116    // default cursor to standard
117    _oldCursor = *wxSTANDARD_CURSOR;
118
119    _traits = new GraphicsContext::Traits;
120    _traits->x = pos.x;
121    _traits->y = pos.y;
122    _traits->width = size.x;
123    _traits->height = size.y;
124
125    init();
126
127}
128
129void GraphicsWindowWX::init()
130{
131    if (valid())
132    {
133        setState( new osg::State );
134        getState()->setGraphicsContext(this);
135
136        if (_traits.valid() && _traits->sharedContext)
137        {
138            getState()->setContextID( _traits->sharedContext->getState()->getContextID() );
139            incrementContextIDUsageCount( getState()->getContextID() );
140        }
141        else
142        {
143            getState()->setContextID( osg::GraphicsContext::createNewContextID() );
144        }
145    }
146}
147
148GraphicsWindowWX::~GraphicsWindowWX()
149{
150}
151
152void GraphicsWindowWX::OnPaint( wxPaintEvent& WXUNUSED(event) )
153{
154    /* must always be here */
155    wxPaintDC dc(this);
156}
157
158void GraphicsWindowWX::OnSize(wxSizeEvent& event)
159{
160    // this is also necessary to update the context on some platforms
161    wxGLCanvas::OnSize(event);
162
163    // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
164    int width, height;
165    GetClientSize(&width, &height);
166
167    // update the window dimensions, in case the window has been resized.
168    getEventQueue()->windowResize(0, 0, width, height);
169    resized(0,0,width,height);
170}
171
172void GraphicsWindowWX::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
173{
174    /* Do nothing, to avoid flashing on MSW */
175}
176
177void GraphicsWindowWX::OnKeyDown(wxKeyEvent &event)
178{
179#if wxUSE_UNICODE
180    int key = event.GetUnicodeKey();
181#else
182    int key = event.GetKeyCode();
183#endif
184    getEventQueue()->keyPress(key);
185
186    // propagate event
187    event.Skip();
188}
189
190void GraphicsWindowWX::OnKeyUp(wxKeyEvent &event)
191{
192#if wxUSE_UNICODE
193    int key = event.GetUnicodeKey();
194#else
195    int key = event.GetKeyCode();
196#endif
197    getEventQueue()->keyRelease(key);
198
199    // propagate event
200    event.Skip();
201}
202
203void GraphicsWindowWX::OnMouse(wxMouseEvent& event)
204{
205    if (event.ButtonDown()) {
206        int button = event.GetButton();
207        getEventQueue()->mouseButtonPress(event.GetX(), event.GetY(), button);
208    }
209    else if (event.ButtonUp()) {
210        int button = event.GetButton();
211        getEventQueue()->mouseButtonRelease(event.GetX(), event.GetY(), button);
212    }
213    else if (event.Dragging()) {
214        getEventQueue()->mouseMotion(event.GetX(), event.GetY());
215    }
216}
217
218void GraphicsWindowWX::grabFocus()
219{
220    // focus this window
221    SetFocus();
222}
223
224void GraphicsWindowWX::grabFocusIfPointerInWindow()
225{
226    // focus this window, if the pointer is in the window
227    wxPoint pos = wxGetMousePosition();
228    if (this == wxFindWindowAtPoint(pos)) {
229        SetFocus();
230    }
231}
232
233void GraphicsWindowWX::useCursor(bool cursorOn)
234{
235    if (cursorOn) {
236
237        // show the old cursor
238        SetCursor(_oldCursor);
239    }
240    else {
241
242        // remember the old cursor
243        _oldCursor = GetCursor();
244
245        // hide the cursor
246        //    - can't find a way to do this neatly, so create a 1x1, transparent image
247        wxImage image(1,1);
248        image.SetMask(true);
249        image.SetMaskColour(0, 0, 0);
250        wxCursor cursor(image);
251        SetCursor(cursor);
252    }
253}
254
255bool GraphicsWindowWX::makeCurrentImplementation()
256{
257    SetCurrent();
258    return true;
259}
260
261void GraphicsWindowWX::swapBuffersImplementation()
262{
263    SwapBuffers();
264}
Note: See TracBrowser for help on using the browser.