MRPT  1.9.9
CWxGLCanvasBase.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "gui-precomp.h" // Precompiled headers
11 
13 #include <mrpt/gui/WxSubsystem.h>
14 #include <mrpt/system/CTicTac.h>
15 
16 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
17 
18 #if MRPT_HAS_OPENGL_GLUT
19 #ifdef _WIN32
20 // Windows:
21 #include <windows.h>
22 #endif
23 
24 #ifdef __APPLE__
25 #include <OpenGL/gl.h>
26 #include <OpenGL/glu.h>
27 #include <GLUT/glut.h>
28 #else
29 #include <GL/gl.h>
30 #include <GL/glu.h>
31 #include <GL/glut.h>
32 #ifdef HAVE_FREEGLUT_EXT_H
33 #include <GL/freeglut_ext.h>
34 #endif
35 #endif
36 
37 #endif
38 
39 #if !wxUSE_GLCANVAS
40 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"
41 #endif
42 
43 using namespace mrpt;
44 using namespace mrpt::gui;
45 using namespace mrpt::opengl;
46 using namespace std;
47 
48 /*----------------------------------------------------------------
49  Implementation of Test-GLCanvas
50 -----------------------------------------------------------------*/
51 
52 void CWxGLCanvasBase::OnWindowCreation(wxWindowCreateEvent& ev)
53 {
54  if (!m_gl_context) m_gl_context = new wxGLContext(this);
55 }
56 
57 void CWxGLCanvasBase::swapBuffers() { SwapBuffers(); }
58 void CWxGLCanvasBase::preRender() { OnPreRender(); }
59 void CWxGLCanvasBase::postRender() { OnPostRender(); }
60 void CWxGLCanvasBase::renderError(const string& err_msg)
61 {
62  OnRenderError(_U(err_msg.c_str()));
63 }
64 
65 void CWxGLCanvasBase::OnMouseDown(wxMouseEvent& event)
66 {
67  setMousePos(event.GetX(), event.GetY());
68  setMouseClicked(true);
69 }
70 void CWxGLCanvasBase::OnMouseUp(wxMouseEvent& /*event*/)
71 {
72  setMouseClicked(false);
73 }
74 
75 void CWxGLCanvasBase::OnMouseMove(wxMouseEvent& event)
76 {
77  bool leftIsDown = event.LeftIsDown();
78 
79  if (leftIsDown || event.RightIsDown())
80  {
81  int X = event.GetX();
82  int Y = event.GetY();
83  updateLastPos(X, Y);
84 
85  // Proxy variables to cache the changes:
86  CamaraParams params = cameraParams();
87 
88  if (leftIsDown)
89  {
90  if (event.ShiftDown())
91  updateZoom(params, X, Y);
92 
93  else if (event.ControlDown())
94  updateRotate(params, X, Y);
95 
96  else
97  updateOrbitCamera(params, X, Y);
98  }
99  else
100  updatePan(params, X, Y);
101 
102  setMousePos(X, Y);
103  setCameraParams(params);
104 
105 #if wxCHECK_VERSION(2, 9, 5)
106  wxTheApp->SafeYieldFor(nullptr, wxEVT_CATEGORY_TIMER);
107 #endif
108  Refresh(false);
109  }
110 
111  // ensure we have the focus so we get keyboard events:
112  this->SetFocus();
113 }
114 
115 void CWxGLCanvasBase::OnMouseWheel(wxMouseEvent& event)
116 {
117  CamaraParams params = cameraParams();
118  updateZoom(params, event.GetWheelRotation());
119  setCameraParams(params);
120 
121  Refresh(false);
122  // ensure we have the focus so we get keyboard events:
123  this->SetFocus();
124 }
125 
126 static int WX_GL_ATTR_LIST[] = {WX_GL_DOUBLEBUFFER, WX_GL_RGBA,
127  WX_GL_DEPTH_SIZE, 24, 0};
128 
129 CWxGLCanvasBase::CWxGLCanvasBase(
130  wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
131  long style, const wxString& name)
132  : CGlCanvasBase(),
133  wxGLCanvas(
134  parent, id, WX_GL_ATTR_LIST, pos, size,
135  style | wxFULL_REPAINT_ON_RESIZE, name)
136 {
137  this->Bind(wxEVT_LEFT_DOWN, &CWxGLCanvasBase::OnMouseDown, this);
138  this->Bind(wxEVT_RIGHT_DOWN, &CWxGLCanvasBase::OnMouseDown, this);
139  this->Bind(wxEVT_LEFT_UP, &CWxGLCanvasBase::OnMouseUp, this);
140  this->Bind(wxEVT_RIGHT_UP, &CWxGLCanvasBase::OnMouseUp, this);
141  this->Bind(wxEVT_MOTION, &CWxGLCanvasBase::OnMouseMove, this);
142  this->Bind(wxEVT_MOUSEWHEEL, &CWxGLCanvasBase::OnMouseWheel, this);
143  this->Bind(wxEVT_CHAR, &CWxGLCanvasBase::OnChar, this);
144  this->Bind(wxEVT_CHAR_HOOK, &CWxGLCanvasBase::OnChar, this);
145  this->Bind(wxEVT_CREATE, &CWxGLCanvasBase::OnWindowCreation, this);
146 
147  this->Bind(wxEVT_SIZE, &CWxGLCanvasBase::OnSize, this);
148  this->Bind(wxEVT_PAINT, &CWxGLCanvasBase::OnPaint, this);
149  this->Bind(
150  wxEVT_ERASE_BACKGROUND, &CWxGLCanvasBase::OnEraseBackground, this);
151  this->Bind(wxEVT_ENTER_WINDOW, &CWxGLCanvasBase::OnEnterWindow, this);
152 
153 // JL: There seems to be a problem in MSW we don't receive this event, but
154 // in GTK we do and at the right moment to avoid an X server crash.
155 #ifdef _WIN32
156  wxWindowCreateEvent dum;
157  OnWindowCreation(dum);
158 #endif
159 }
160 
161 CWxGLCanvasBase::~CWxGLCanvasBase()
162 {
163  if (m_gl_context) delete m_gl_context;
164 }
165 void CWxGLCanvasBase::OnChar(wxKeyEvent& event) { OnCharCustom(event); }
166 void CWxGLCanvasBase::Render()
167 {
168  wxPaintDC dc(this);
169 
170  if (!m_gl_context)
171  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
172  return;
173  }
174  else
175  SetCurrent(*m_gl_context);
176 
177  // Init OpenGL once, but after SetCurrent
178  if (!m_init)
179  {
180  InitGL();
181  m_init = true;
182  }
183 
184  int width, height;
185  GetClientSize(&width, &height);
186  double At = renderCanvas(width, height);
187 
188  OnPostRenderSwapBuffers(At, dc);
189 }
190 
191 void CWxGLCanvasBase::OnEnterWindow(wxMouseEvent& WXUNUSED(event))
192 {
193  SetFocus();
194 }
195 
196 void CWxGLCanvasBase::OnPaint(wxPaintEvent& WXUNUSED(event)) { Render(); }
197 void CWxGLCanvasBase::OnSize(wxSizeEvent& event)
198 {
199  if (!m_parent->IsShown()) return;
200 
201  // set GL viewport (not called by wxGLCanvas::OnSize on all platforms...)
202  int w, h;
203  GetClientSize(&w, &h);
204 
205  if (this->IsShownOnScreen())
206  {
207  if (!m_gl_context)
208  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
209  return;
210  }
211  else
212  SetCurrent(*m_gl_context);
213 
214  resizeViewport(w, h);
215  }
216 }
217 
218 void CWxGLCanvasBase::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
219 {
220  // Do nothing, to avoid flashing.
221 }
222 
223 void CWxGLCanvasBase::InitGL()
224 {
225  if (!m_gl_context)
226  { /*cerr << "[CWxGLCanvasBase::Render] No GL Context!" << endl;*/
227  return;
228  }
229  else
230  SetCurrent(*m_gl_context);
231 
232  static bool GLUT_INIT_DONE = false;
233 
234  if (!GLUT_INIT_DONE)
235  {
236  GLUT_INIT_DONE = true;
237 
238  int argc = 1;
239  char* argv[1] = {nullptr};
240  glutInit(&argc, argv);
241  }
242 }
243 
244 void CWxGLCanvasBase::setCameraPose(const mrpt::poses::CPose3D& camPose)
245 {
246  THROW_EXCEPTION("todo");
247 }
248 
249 #endif // MRPT_HAS_WXWIDGETS
#define _U(x)
Definition: WxSubsystem.h:503
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:41
STL namespace.
GLenum GLsizei width
Definition: glext.h:3531
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:86
GLuint id
Definition: glext.h:3909
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
GLuint const GLchar * name
Definition: glext.h:4054
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:14
GLsizeiptr size
Definition: glext.h:3923
This base class implements a working with opengl::Camera and a OpenGL canvas, and it&#39;s used in gui::C...
Definition: CGlCanvasBase.h:28
GLenum GLsizei GLsizei height
Definition: glext.h:3554
GLenum const GLfloat * params
Definition: glext.h:3534



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020