Main MRPT website > C++ reference for MRPT 1.9.9
CGlCanvasBase.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-2017, 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 #include <mrpt/gui/CGlCanvasBase.h>
12 #include <mrpt/utils/CTicTac.h>
13 
14 using namespace mrpt;
15 using namespace mrpt::utils;
16 using namespace mrpt::gui;
17 using namespace mrpt::opengl;
18 using namespace std;
19 
20 float CGlCanvasBase::SENSIBILITY_DEG_PER_PIXEL = 0.1f;
21 
22 #if MRPT_HAS_OPENGL_GLUT
23 #ifdef MRPT_OS_WINDOWS
24 // Windows:
25 #include <windows.h>
26 #endif
27 
28 #ifdef MRPT_OS_APPLE
29 #include <OpenGL/gl.h>
30 #include <OpenGL/glu.h>
31 #include <GLUT/glut.h>
32 #else
33 #include <GL/gl.h>
34 #include <GL/glu.h>
35 #include <GL/glut.h>
36 #ifdef HAVE_FREEGLUT_EXT_H
37 #include <GL/freeglut_ext.h>
38 #endif
39 #endif
40 
41 void CGlCanvasBase::setMinimumZoom(float zoom) { m_minZoom = zoom; }
42 void CGlCanvasBase::setMaximumZoom(float zoom) { m_maxZoom = zoom; }
43 void CGlCanvasBase::setMousePos(int x, int y)
44 {
45  m_mouseClickX = x;
46  m_mouseClickY = y;
47 }
48 
49 void CGlCanvasBase::setMouseClicked(bool is) { mouseClicked = is; }
50 void CGlCanvasBase::updateZoom(CamaraParams& params, int x, int y) const
51 {
52  float zoom = params.cameraZoomDistance * exp(0.01 * (y - m_mouseClickY));
53  if (zoom <= m_minZoom || (m_maxZoom != -1.0f && m_maxZoom <= zoom)) return;
54  params.cameraZoomDistance = zoom;
55  if (params.cameraZoomDistance < 0.01) params.cameraZoomDistance = 0.01f;
56 
57  float Az = -0.05 * (x - m_mouseClickX);
58  float D = 0.001 * params.cameraZoomDistance;
59  params.cameraPointingZ += D * Az;
60 }
61 
62 void CGlCanvasBase::updateZoom(CamaraParams& params, float delta) const
63 {
64  float zoom = params.cameraZoomDistance * (1 - 0.03f * (delta / 120.0f));
65  if (zoom <= m_minZoom || (m_maxZoom != -1.0f && m_maxZoom <= zoom)) return;
66 
67  params.cameraZoomDistance = zoom;
68 }
69 
70 void CGlCanvasBase::updateRotate(CamaraParams& params, int x, int y) const
71 {
72  const float dis = max(0.01f, (params.cameraZoomDistance));
73  float eye_x = params.cameraPointingX +
74  dis * cos(DEG2RAD(params.cameraAzimuthDeg)) *
75  cos(DEG2RAD(params.cameraElevationDeg));
76  float eye_y = params.cameraPointingY +
77  dis * sin(DEG2RAD(params.cameraAzimuthDeg)) *
78  cos(DEG2RAD(params.cameraElevationDeg));
79  float eye_z =
80  params.cameraPointingZ + dis * sin(DEG2RAD(params.cameraElevationDeg));
81 
82  // Orbit camera:
83  float A_AzimuthDeg = -SENSIBILITY_DEG_PER_PIXEL * (x - m_mouseClickX);
84  params.cameraAzimuthDeg += A_AzimuthDeg;
85 
86  float A_ElevationDeg = SENSIBILITY_DEG_PER_PIXEL * (y - m_mouseClickY);
87  params.setElevationDeg(params.cameraElevationDeg + A_ElevationDeg);
88 
89  // Move cameraPointing pos:
90  params.cameraPointingX = eye_x -
91  dis * cos(DEG2RAD(params.cameraAzimuthDeg)) *
92  cos(DEG2RAD(params.cameraElevationDeg));
93  params.cameraPointingY = eye_y -
94  dis * sin(DEG2RAD(params.cameraAzimuthDeg)) *
95  cos(DEG2RAD(params.cameraElevationDeg));
96  params.cameraPointingZ =
97  eye_z - dis * sin(DEG2RAD(params.cameraElevationDeg));
98 }
99 
100 void CGlCanvasBase::updateOrbitCamera(CamaraParams& params, int x, int y) const
101 {
102  params.cameraAzimuthDeg -= 0.2 * (x - m_mouseClickX);
103  params.setElevationDeg(
104  params.cameraElevationDeg + 0.2 * (y - m_mouseClickY));
105 }
106 
107 void CGlCanvasBase::updateLastPos(int x, int y)
108 {
109  m_mouseLastX = x;
110  m_mouseLastY = y;
111 }
112 
113 void CGlCanvasBase::resizeViewport(int w, int h)
114 {
115  if (w == -1 || h == -1) return;
116 
117  glViewport(0, 0, (GLint)w, (GLint)h);
118 }
119 
120 void CGlCanvasBase::clearColors()
121 {
122  glClearColor(clearColorR, clearColorG, clearColorB, clearColorA);
123 }
124 
125 void CGlCanvasBase::updatePan(CamaraParams& params, int x, int y) const
126 {
127  float Ay = -(x - m_mouseClickX);
128  float Ax = -(y - m_mouseClickY);
129  float D = 0.001 * params.cameraZoomDistance;
130  params.cameraPointingX += D * (Ax * cos(DEG2RAD(params.cameraAzimuthDeg)) -
131  Ay * sin(DEG2RAD(params.cameraAzimuthDeg)));
132  params.cameraPointingY += D * (Ax * sin(DEG2RAD(params.cameraAzimuthDeg)) +
133  Ay * cos(DEG2RAD(params.cameraAzimuthDeg)));
134 }
135 
136 CGlCanvasBase::CamaraParams CGlCanvasBase::cameraParams() const
137 {
138  return m_cameraParams;
139 }
140 
141 const CGlCanvasBase::CamaraParams& CGlCanvasBase::getRefCameraParams() const
142 {
143  return m_cameraParams;
144 }
145 
146 void CGlCanvasBase::setCameraParams(const CGlCanvasBase::CamaraParams& params)
147 {
148  m_cameraParams = params;
149 }
150 
151 float CGlCanvasBase::getZoomDistance() const
152 {
153  return m_cameraParams.cameraZoomDistance;
154 }
155 
156 void CGlCanvasBase::setZoomDistance(float zoom)
157 {
158  m_cameraParams.cameraZoomDistance = zoom;
159 }
160 
161 CCamera& CGlCanvasBase::updateCameraParams(CCamera& cam) const
162 {
163  cam.setPointingAt(
164  m_cameraParams.cameraPointingX, m_cameraParams.cameraPointingY,
165  m_cameraParams.cameraPointingZ);
166  cam.setZoomDistance(m_cameraParams.cameraZoomDistance);
167  cam.setAzimuthDegrees(m_cameraParams.cameraAzimuthDeg);
168  cam.setElevationDegrees(m_cameraParams.cameraElevationDeg);
169  cam.setProjectiveModel(m_cameraParams.cameraIsProjective);
170  cam.setProjectiveFOVdeg(m_cameraParams.cameraFOV);
171 
172  return cam;
173 }
174 
175 void CGlCanvasBase::setUseCameraFromScene(bool is) { useCameraFromScene = is; }
176 bool CGlCanvasBase::getUseCameraFromScene() const { return useCameraFromScene; }
177 void CGlCanvasBase::setAzimuthDegrees(float ang)
178 {
179  m_cameraParams.cameraAzimuthDeg = ang;
180 }
181 
182 void CGlCanvasBase::setElevationDegrees(float ang)
183 {
184  m_cameraParams.cameraElevationDeg = ang;
185 }
186 
187 float CGlCanvasBase::getAzimuthDegrees() const
188 {
189  return m_cameraParams.cameraAzimuthDeg;
190 }
191 
192 float CGlCanvasBase::getElevationDegrees() const
193 {
194  return m_cameraParams.cameraElevationDeg;
195 }
196 
197 void CGlCanvasBase::setCameraProjective(bool is)
198 {
199  m_cameraParams.cameraIsProjective = is;
200 }
201 
202 bool CGlCanvasBase::isCameraProjective() const
203 {
204  return m_cameraParams.cameraIsProjective;
205 }
206 
207 void CGlCanvasBase::setCameraFOV(float FOV) { m_cameraParams.cameraFOV = FOV; }
208 float CGlCanvasBase::cameraFOV() const { return m_cameraParams.cameraFOV; }
209 void CGlCanvasBase::setClearColors(float r, float g, float b, float a)
210 {
211  clearColorR = r;
212  clearColorG = g;
213  clearColorB = b;
214  clearColorA = a;
215 }
216 
217 float CGlCanvasBase::getClearColorR() const { return clearColorR; }
218 float CGlCanvasBase::getClearColorG() const { return clearColorG; }
219 float CGlCanvasBase::getClearColorB() const { return clearColorB; }
220 float CGlCanvasBase::getClearColorA() const { return clearColorA; }
221 void CGlCanvasBase::setOpenGLSceneRef(COpenGLScene::Ptr scene)
222 {
223  m_openGLScene = scene;
224 }
225 
226 void CGlCanvasBase::setCameraPointing(float pointX, float pointY, float pointZ)
227 {
228  m_cameraParams.cameraPointingX = pointX;
229  m_cameraParams.cameraPointingY = pointY;
230  m_cameraParams.cameraPointingZ = pointZ;
231 }
232 
233 float CGlCanvasBase::getCameraPointingX() const
234 {
235  return m_cameraParams.cameraPointingX;
236 }
237 
238 float CGlCanvasBase::getCameraPointingY() const
239 {
240  return m_cameraParams.cameraPointingY;
241 }
242 
243 float CGlCanvasBase::getCameraPointingZ() const
244 {
245  return m_cameraParams.cameraPointingZ;
246 }
247 
248 double CGlCanvasBase::renderCanvas(int width, int height)
249 {
250  CTicTac tictac;
251  double At = 0.1;
252 
253  try
254  {
255  // Call PreRender user code:
256  preRender();
257 
259 
260  // Set static configs:
264 
265  // PART 1a: Set the viewport
266  // --------------------------------------
267  resizeViewport((GLsizei)width, (GLsizei)height);
268 
269  // Set the background color:
270  clearColors();
271 
272  if (m_openGLScene)
273  {
274  // Set the camera params in the scene:
275  if (!useCameraFromScene)
276  {
277  COpenGLViewport::Ptr view = m_openGLScene->getViewport("main");
278  if (!view)
279  {
281  "Fatal error: there is no 'main' viewport in the 3D "
282  "scene!");
283  }
284 
285  mrpt::opengl::CCamera& cam = view->getCamera();
286  updateCameraParams(cam);
287  }
288 
289  // PART 2: Set the MODELVIEW matrix
290  // --------------------------------------
292  glLoadIdentity();
293 
294  tictac.Tic();
295 
296  // PART 3: Draw primitives:
297  // --------------------------------------
298  m_openGLScene->render();
299 
300  } // end if "m_openGLScene!=nullptr"
301 
302  postRender();
303 
304  // Flush & swap buffers to disply new image:
305  glFlush();
306  swapBuffers();
307 
308  At = tictac.Tac();
309 
310  glPopAttrib();
311  }
312  catch (std::exception& e)
313  {
314  glPopAttrib();
315  const std::string err_msg =
316  std::string("[CWxGLCanvasBase::Render] Exception!: ") +
317  std::string(e.what());
318  std::cerr << err_msg;
319  renderError(err_msg);
320  }
321  catch (...)
322  {
323  glPopAttrib();
324  std::cerr << "Runtime error!" << std::endl;
325  }
326 
327  return At;
328 }
329 
330 void CGlCanvasBase::CamaraParams::setElevationDeg(float deg)
331 {
332  cameraElevationDeg = deg;
333 
334  if (cameraElevationDeg < -90.0f)
335  cameraElevationDeg = -90.0f;
336  else if (cameraElevationDeg > 90.0f)
337  cameraElevationDeg = 90.0f;
338 }
339 #endif
GLAPI void GLAPIENTRY glFlush(void)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::shared_ptr< COpenGLViewport > Ptr
GLAPI void GLAPIENTRY glMatrixMode(GLenum mode)
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define GL_MODELVIEW
Definition: glew.h:610
#define THROW_EXCEPTION(msg)
void setProjectiveModel(bool v=true)
Enable/Disable projective mode (vs.
Definition: CCamera.h:79
STL namespace.
#define GL_DEPTH_TEST
Definition: glew.h:401
GLAPI void GLAPIENTRY glPopAttrib(void)
void Tic()
Starts the stopwatch.
Definition: CTicTac.cpp:82
GLAPI void GLAPIENTRY glLoadIdentity(void)
GLenum GLsizei width
Definition: glext.h:3531
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:4178
void setZoomDistance(float z)
Definition: CCamera.h:72
void setAzimuthDegrees(float ang)
Definition: CCamera.h:76
This class implements a high-performance stopwatch.
Definition: CTicTac.h:23
GLubyte g
Definition: glext.h:6279
void setProjectiveFOVdeg(float ang)
Field-of-View in degs, only when projectiveModel=true (default=30 deg).
Definition: CCamera.h:95
GLubyte GLubyte b
Definition: glext.h:6279
double DEG2RAD(const double x)
Degrees to radians.
Definition: bits.h:96
GLsizei const GLchar ** string
Definition: glext.h:4101
#define GL_ALPHA_TEST
Definition: glew.h:426
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
void setElevationDegrees(float ang)
Definition: CCamera.h:77
GLdouble GLdouble GLdouble r
Definition: glext.h:3705
GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask)
std::shared_ptr< COpenGLScene > Ptr
Definition: COpenGLScene.h:62
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
double Tac()
Stops the stopwatch.
Definition: CTicTac.cpp:97
GLenum GLint GLint y
Definition: glext.h:3538
#define GL_ALL_ATTRIB_BITS
Definition: glew.h:271
Classes for creating GUI windows for 2D and 3D visualization.
Definition: about_box.h:16
int GLint
Definition: glew.h:209
GLenum GLint x
Definition: glext.h:3538
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:30
GLenum GLsizei GLsizei height
Definition: glext.h:3554
GLubyte GLubyte GLubyte a
Definition: glext.h:6279
GLenum const GLfloat * params
Definition: glext.h:3534
#define GL_TEXTURE_2D
Definition: glew.h:7238
int GLsizei
Definition: glew.h:210
void setPointingAt(float x, float y, float z)
Definition: CCamera.h:50



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019