Main MRPT website > C++ reference for MRPT 1.9.9
COpenGLViewport.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 "opengl-precomp.h" // Precompiled header
11 
16 #include <mrpt/utils/CStringList.h>
17 #include <mrpt/utils/CTimeLogger.h>
18 #include <mrpt/utils/CStream.h>
20 #include <mrpt/opengl/gl_utils.h>
21 
22 #include "opengl_internals.h"
23 
24 using namespace mrpt;
25 using namespace mrpt::poses;
26 using namespace mrpt::opengl;
27 using namespace mrpt::utils;
28 using namespace mrpt::math;
29 using namespace std;
30 
32 using namespace mrpt::utils::metaprogramming;
33 
35 
36 //#define OPENGLVIEWPORT_ENABLE_TIMEPROFILING
37 
38 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
39 mrpt::utils::CTimeLogger glv_timlog;
40 #endif
41 
42 /*--------------------------------------------------------------
43 
44  IMPLEMENTATION OF COpenGLViewport
45 
46  ---------------------------------------------------------------*/
47 
48 /*--------------------------------------------------------------
49  Constructor
50  ---------------------------------------------------------------*/
51 COpenGLViewport::COpenGLViewport(COpenGLScene* parent, const string& name)
52  : m_camera(),
53  m_parent(parent),
54  m_isCloned(false),
55  m_isClonedCamera(false),
56  m_clonedViewport(),
57  m_name(name),
58  m_isTransparent(false),
59  m_borderWidth(0),
60  m_view_x(0),
61  m_view_y(0),
62  m_view_width(1),
63  m_view_height(1),
64  m_clip_min(0.1),
65  m_clip_max(10000),
66  m_custom_backgb_color(false),
67  m_background_color(0.6f, 0.6f, 0.6f),
68  m_isImageView(false),
69  m_imageview_img(),
70  m_objects(),
71  // OpenGL settings:
72  m_OpenGL_enablePolygonNicest(true),
73  m_lights()
74 {
75  // Default: one light from default direction
76  m_lights.push_back(CLight());
77  m_lights.push_back(CLight());
78 
79  m_lights[0].setPosition(1, 1, 1, 0);
80  m_lights[0].setDirection(-1, -1, -1);
81 
82  m_lights[1].light_ID = 1;
83  m_lights[1].setPosition(1, 2, -1, 0);
84  m_lights[1].setDirection(1, 2, 1);
85 
86  m_lights[1].color_diffuse[0] = 0.3f;
87  m_lights[1].color_diffuse[1] = 0.3f;
88  m_lights[1].color_diffuse[2] = 0.3f;
89 
90  m_lights[1].color_ambient[0] = 0.3f;
91  m_lights[1].color_ambient[1] = 0.3f;
92  m_lights[1].color_ambient[2] = 0.3f;
93 }
94 
95 /*--------------------------------------------------------------
96  Destructor
97  ---------------------------------------------------------------*/
99 /*--------------------------------------------------------------
100  setCloneView
101  ---------------------------------------------------------------*/
102 void COpenGLViewport::setCloneView(const string& clonedViewport)
103 {
104  clear();
105  m_isCloned = true;
106  m_clonedViewport = clonedViewport;
107 }
108 
109 /*--------------------------------------------------------------
110  setViewportPosition
111  ---------------------------------------------------------------*/
113  const double x, const double y, const double width, const double height)
114 {
115  MRPT_START
116  ASSERT_(m_view_width > 0)
118 
119  m_view_x = x;
120  m_view_y = y;
123 
124  MRPT_END
125 }
126 
127 /*--------------------------------------------------------------
128  getViewportPosition
129  ---------------------------------------------------------------*/
131  double& x, double& y, double& width, double& height)
132 {
133  x = m_view_x;
134  y = m_view_y;
137 }
138 
139 /*--------------------------------------------------------------
140  clear
141  ---------------------------------------------------------------*/
143 /*--------------------------------------------------------------
144  insert
145  ---------------------------------------------------------------*/
147 {
148  m_objects.push_back(newObject);
149 }
150 
151 /*---------------------------------------------------------------
152  render
153  ---------------------------------------------------------------*/
155  const int render_width, const int render_height) const
156 {
157 #if MRPT_HAS_OPENGL_GLUT
158  const CRenderizable* it =
159  nullptr; // Declared here for usage in the "catch"
160  try
161  {
162  // Change viewport:
163  // -------------------------------------------
164  const GLint vx = m_view_x > 1
165  ? GLint(m_view_x)
166  : (m_view_x < 0 ? GLint(render_width + m_view_x)
167  : GLint(render_width * m_view_x));
168  const GLint vy = m_view_y > 1
169  ? GLint(m_view_y)
170  : (m_view_y < 0 ? GLint(render_height + m_view_y)
171  : GLint(render_height * m_view_y));
172 
173  GLint vw;
174  if (m_view_width > 1) // >1 -> absolute pixels:
175  vw = GLint(m_view_width);
176  else if (m_view_width < 0)
177  { // Negative numbers: Specify the right side coordinates instead of
178  // the width:
179  if (m_view_width >= -1)
180  vw = GLint(-render_width * m_view_width - vx + 1);
181  else
182  vw = GLint(-m_view_width - vx + 1);
183  }
184  else // A factor:
185  {
186  vw = GLint(render_width * m_view_width);
187  }
188 
189  GLint vh;
190  if (m_view_height > 1) // >1 -> absolute pixels:
191  vh = GLint(m_view_height);
192  else if (m_view_height < 0)
193  { // Negative numbers: Specify the right side coordinates instead of
194  // the width:
195  if (m_view_height >= -1)
196  vh = GLint(-render_height * m_view_height - vy + 1);
197  else
198  vh = GLint(-m_view_height - vy + 1);
199  }
200  else // A factor:
201  vh = GLint(render_height * m_view_height);
202 
203  glViewport(vx, vy, vw, vh);
204 
205  // Clear depth&/color buffers:
206  // -------------------------------------------
209 
210  glScissor(vx, vy, vw, vh);
211 
213  if (!m_isTransparent)
214  { // Clear color & depth buffers:
215  // Save?
216  GLdouble old_colors[4];
218  {
219  glGetDoublev(GL_COLOR_CLEAR_VALUE, old_colors);
220  glClearColor(
223  }
224 
225  glClear(
228 
229  // Restore old colors:
231  glClearColor(
232  old_colors[0], old_colors[1], old_colors[2], old_colors[3]);
233  }
234  else
235  { // Clear depth buffer only:
237  }
239 
240  // If we are in "image mode", rendering is much simpler: just set
241  // ortho projection and render the image quad:
242  if (m_isImageView)
243  {
244 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
245  glv_timlog.enter("COpenGLViewport::render imageview");
246 #endif
247  // "Image mode" rendering:
248  // -----------------------------------
249  if (m_imageview_img) // should be ALWAYS true, but just in case!
250  {
251  // Note: The following code is inspired in the implementations:
252  // - libcvd, by Edward Rosten http://www.edwardrosten.com/cvd/
253  // - PTAM, by Klein & Murray
254  // http://www.robots.ox.ac.uk/~gk/PTAM/
255 
256  const mrpt::utils::CImage* img = m_imageview_img.get();
257 
258  const int img_w = img->getWidth();
259  const int img_h = img->getHeight();
260 
261  if (img_w != 0 && img_h != 0)
262  {
263  // Prepare an ortho projection:
265  glLoadIdentity();
266 
267  // Need to adjust the aspect ratio?
268  const double ratio = vw * img_h / double(vh * img_w);
269  double ortho_w = img_w;
270  double ortho_h = img_h;
271  if (ratio > 1)
272  ortho_w *= ratio;
273  else if (ratio != 0)
274  ortho_h /= ratio;
275 
276  glOrtho(-0.5, ortho_h - 0.5, ortho_w - 0.5, -0.5, -1, 1);
277 
278  // Prepare raster pos & pixel copy direction in -Y.
279  glRasterPos2f(-0.5f, -0.5f);
280  glPixelZoom(vw / float(ortho_w), -vh / float(ortho_h));
281 
282  // Prepare image data types:
283  const GLenum img_type = GL_UNSIGNED_BYTE;
284  const int nBytesPerPixel = img->isColor() ? 3 : 1;
285  const bool is_RGB_order =
286  (!::strcmp(
287  img->getChannelsOrder(),
288  "RGB")); // Reverse RGB <-> BGR order?
289  const GLenum img_format =
290  nBytesPerPixel == 3 ? (is_RGB_order ? GL_RGB : GL_BGR)
291  : GL_LUMINANCE;
292 
293  // Send image data to OpenGL:
296  img->getRowStride() / nBytesPerPixel);
297  glDrawPixels(
298  img_w, img_h, img_format, img_type,
299  img->get_unsafe(0, 0));
300  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Reset
302  }
303  }
304 // done.
305 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
306  glv_timlog.leave("COpenGLViewport::render imageview");
307 #endif
308  }
309  else
310  {
311  // Non "image mode" rendering:
312 
313  // Set camera:
314  // -------------------------------------------
316  glLoadIdentity();
317 
318  const CListOpenGLObjects* objectsToRender;
319  COpenGLViewport* viewForGetCamera;
320 
321  if (m_isCloned)
322  { // Clone: render someone's else objects.
323  ASSERT_(m_parent.get() != nullptr);
324 
325  COpenGLViewport::Ptr view =
326  m_parent->getViewport(m_clonedViewport);
327  if (!view)
329  "Cloned viewport '%s' not found in parent COpenGLScene",
330  m_clonedViewport.c_str());
331 
332  objectsToRender = &view->m_objects;
333  viewForGetCamera = m_isClonedCamera
334  ? view.get()
335  : const_cast<COpenGLViewport*>(this);
336  }
337  else
338  { // Normal case: render our own objects:
339  objectsToRender = &m_objects;
340  viewForGetCamera = const_cast<COpenGLViewport*>(this);
341  }
342 
343  // Get camera:
344  // 1st: if there is a CCamera in the scene:
345  CRenderizable::Ptr cam_ptr =
346  viewForGetCamera->getByClass<CCamera>();
347 
348  CCamera* myCamera = nullptr;
349  if (cam_ptr)
350  {
351  myCamera = getAs<CCamera>(cam_ptr);
352  }
353 
354  // 2nd: the internal camera of all viewports:
355  if (!myCamera) myCamera = &viewForGetCamera->m_camera;
356 
358 
359  m_lastProjMat.azimuth = DEG2RAD(myCamera->m_azimuthDeg);
360  m_lastProjMat.elev = DEG2RAD(myCamera->m_elevationDeg);
361 
362  const float dis = max(0.01f, myCamera->m_distanceZoom);
364  myCamera->m_pointingX +
365  dis * cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
367  myCamera->m_pointingY +
368  dis * sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
370  myCamera->m_pointingZ + dis * sin(m_lastProjMat.elev);
371 
372  if (fabs(fabs(myCamera->m_elevationDeg) - 90) > 1e-6)
373  {
374  m_lastProjMat.up.x = 0;
375  m_lastProjMat.up.y = 0;
376  m_lastProjMat.up.z = 1;
377  }
378  else
379  {
380  float sgn = myCamera->m_elevationDeg > 0 ? 1 : -1;
381  m_lastProjMat.up.x =
382  -cos(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
383  m_lastProjMat.up.y =
384  -sin(DEG2RAD(myCamera->m_azimuthDeg)) * sgn;
385  m_lastProjMat.up.z = 0;
386  }
387 
388  m_lastProjMat.is_projective = myCamera->m_projectiveModel;
389  m_lastProjMat.FOV = myCamera->m_projectiveFOVdeg;
390  m_lastProjMat.pointing.x = myCamera->m_pointingX;
391  m_lastProjMat.pointing.y = myCamera->m_pointingY;
392  m_lastProjMat.pointing.z = myCamera->m_pointingZ;
393  m_lastProjMat.zoom = myCamera->m_distanceZoom;
394 
395  if (myCamera->m_projectiveModel)
396  {
397  gluPerspective(
398  myCamera->m_projectiveFOVdeg, vw / double(vh), m_clip_min,
399  m_clip_max);
401  }
402  else
403  {
404  const double ratio = vw / double(vh);
405  double Ax = myCamera->m_distanceZoom * 0.5;
406  double Ay = myCamera->m_distanceZoom * 0.5;
407 
408  if (ratio > 1)
409  Ax *= ratio;
410  else
411  {
412  if (ratio != 0) Ay /= ratio;
413  }
414 
415  glOrtho(-Ax, Ax, -Ay, Ay, -0.5 * m_clip_max, 0.5 * m_clip_max);
417  }
418 
419  if (myCamera->is6DOFMode())
420  {
421  // In 6DOFMode eye is set viewing towards the direction of the
422  // positive Z axis
423  // Up is set as Y axis
424  mrpt::poses::CPose3D viewDirection, pose, at;
425  viewDirection.z(+1);
426  pose = mrpt::poses::CPose3D(myCamera->getPose());
427  at = pose + viewDirection;
428  gluLookAt(
429  pose.x(), pose.y(), pose.z(), at.x(), at.y(), at.z(),
430  pose.getRotationMatrix()(0, 1),
431  pose.getRotationMatrix()(1, 1),
432  pose.getRotationMatrix()(2, 1));
434  }
435  else
436  {
437  // This command is common to ortho and perspective:
438  gluLookAt(
444  }
445 
446  // Optional pre-Render user code:
447  if (hasSubscribers())
448  {
449  mrptEventGLPreRender ev(this);
450  this->publishEvent(ev);
451  }
452 
453  // Global OpenGL settings:
454  // ---------------------------------
455  glHint(
459 
460  // Render objects:
461  // -------------------------------------------
463  glLoadIdentity();
464 
466  glDepthFunc(GL_LEQUAL); // GL_LESS
467 
468  // Setup lights
469  // -------------------------------------------
475 
476  for (size_t i = 0; i < m_lights.size(); i++)
477  m_lights[i].sendToOpenGL();
478 
479  // Render all the objects:
480  // -------------------------------------------
482 
483  } // end of non "image mode" rendering
484 
485  // Finally, draw the border:
486  // --------------------------------
487  if (m_borderWidth > 0)
488  {
490  glColor4f(0, 0, 0, 1);
492 
494  glLoadIdentity();
496  glLoadIdentity();
497 
498  glDisable(GL_LIGHTING); // Disable lights when drawing lines
500  glVertex2f(-1, -1);
501  glVertex2f(-1, 1);
502  glVertex2f(1, 1);
503  glVertex2f(1, -1);
504  glEnd();
505  glEnable(GL_LIGHTING); // Disable lights when drawing lines
506 
508  }
509 
510  // Optional post-Render user code:
511  if (hasSubscribers())
512  {
513  mrptEventGLPostRender ev(this);
514  this->publishEvent(ev);
515  }
516  }
517  catch (exception& e)
518  {
519  string msg;
520  if (it != nullptr)
521  msg = format(
522  "Exception while rendering a class '%s'\n%s",
523  it->GetRuntimeClass()->className, e.what());
524  else
525  msg = format("Exception while rendering:\n%s", e.what());
526 
527  THROW_EXCEPTION(msg);
528  }
529  catch (...)
530  {
531  THROW_EXCEPTION("Runtime error!");
532  }
533 #else
534  MRPT_UNUSED_PARAM(render_width);
535  MRPT_UNUSED_PARAM(render_height);
537  "The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL "
538  "functions are not implemented");
539 #endif
540 }
541 
542 /*---------------------------------------------------------------
543  Implements the writing to a CStream capability of
544  CSerializable objects
545  ---------------------------------------------------------------*/
547  mrpt::utils::CStream& out, int* version) const
548 {
549  if (version)
550  *version = 3;
551  else
552  {
553  // Save data:
557 
558  // Added in v1:
562 
563  // Save objects:
564  uint32_t n;
565  n = (uint32_t)m_objects.size();
566  out << n;
568  it != m_objects.end(); ++it)
569  out << **it;
570 
571  // Added in v2: Global OpenGL settings:
573 
574  // Added in v3: Lights
575  out << m_lights;
576  }
577 }
578 
579 /*---------------------------------------------------------------
580  Implements the reading from a CStream capability of
581  CSerializable objects
582  ---------------------------------------------------------------*/
584 {
585  switch (version)
586  {
587  case 0:
588  case 1:
589  case 2:
590  case 3:
591  {
592  // Load data:
597 
598  // in v1:
599  if (version >= 1)
600  {
604  }
605  else
606  {
607  m_custom_backgb_color = false;
608  }
609 
610  // Load objects:
611  uint32_t n;
612  in >> n;
613  clear();
614  m_objects.resize(n);
615 
616  for_each(
617  m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in));
618 
619  // Added in v2: Global OpenGL settings:
620  if (version >= 2)
621  {
623  }
624  else
625  {
626  // Defaults
627  }
628 
629  // Added in v3: Lights
630  if (version >= 3)
631  in >> m_lights;
632  else
633  {
634  // Default: one light from default direction
635  m_lights.clear();
636  m_lights.push_back(CLight());
637  }
638  }
639  break;
640  default:
642  };
643 }
644 
645 /*---------------------------------------------------------------
646  getByName
647  ---------------------------------------------------------------*/
649 {
650  for (CListOpenGLObjects::iterator it = m_objects.begin();
651  it != m_objects.end(); ++it)
652  {
653  if ((*it)->m_name == str)
654  return *it;
655  else if (
656  (*it)->GetRuntimeClass() ==
658  {
659  CRenderizable::Ptr ret = getAs<CSetOfObjects>(*it)->getByName(str);
660  if (ret) return ret;
661  }
662  }
663  return CRenderizable::Ptr();
664 }
665 
666 /*---------------------------------------------------------------
667  initializeAllTextures
668  ---------------------------------------------------------------*/
670 {
671 #if MRPT_HAS_OPENGL_GLUT
672  for (CListOpenGLObjects::iterator it = m_objects.begin();
673  it != m_objects.end(); ++it)
674  {
675  if (IS_DERIVED(*it, CTexturedObject))
676  getAs<CTexturedObject>(*it)->loadTextureInOpenGL();
677  else if (IS_CLASS(*it, CSetOfObjects))
678  getAs<CSetOfObjects>(*it)->initializeAllTextures();
679  }
680 #endif
681 }
682 
683 /*--------------------------------------------------------------
684  dumpListOfObjects
685  ---------------------------------------------------------------*/
687 {
688  for (CListOpenGLObjects::iterator it = m_objects.begin();
689  it != m_objects.end(); ++it)
690  {
691  // Single obj:
692  string s((*it)->GetRuntimeClass()->className);
693  if ((*it)->m_name.size())
694  s += string(" (") + (*it)->m_name + string(")");
695  lst.add(s);
696 
697  if ((*it)->GetRuntimeClass() ==
699  {
700  utils::CStringList auxLst;
701 
702  getAs<CSetOfObjects>(*it)->dumpListOfObjects(auxLst);
703 
704  for (size_t i = 0; i < auxLst.size(); i++)
705  lst.add(string(" ") + auxLst(i));
706  }
707  }
708 }
709 
710 /*--------------------------------------------------------------
711  removeObject
712  ---------------------------------------------------------------*/
714 {
715  for (CListOpenGLObjects::iterator it = m_objects.begin();
716  it != m_objects.end(); ++it)
717  if (*it == obj)
718  {
719  m_objects.erase(it);
720  return;
721  }
722  else if (
723  (*it)->GetRuntimeClass() ==
725  getAs<CSetOfObjects>(*it)->removeObject(obj);
726 }
727 
728 /*--------------------------------------------------------------
729  setViewportClipDistances
730  ---------------------------------------------------------------*/
732  const double clip_min, const double clip_max)
733 {
734  ASSERT_(clip_max > clip_min);
735 
736  m_clip_min = clip_min;
737  m_clip_max = clip_max;
738 }
739 
740 /*--------------------------------------------------------------
741  getViewportClipDistances
742  ---------------------------------------------------------------*/
744  double& clip_min, double& clip_max) const
745 {
746  clip_min = m_clip_min;
747  clip_max = m_clip_max;
748 }
749 
750 /*--------------------------------------------------------------
751  get3DRayForPixelCoord
752  ---------------------------------------------------------------*/
754  const double x_coord, const double y_coord, mrpt::math::TLine3D& out_ray,
755  mrpt::poses::CPose3D* out_cameraPose) const
756 {
757  ASSERTDEB_(
759 
760  const double ASPECT =
762 
763  // unitary vector between (eye) -> (pointing):
764  TPoint3D pointing_dir;
765  pointing_dir.x = -cos(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
766  pointing_dir.y = -sin(m_lastProjMat.azimuth) * cos(m_lastProjMat.elev);
767  pointing_dir.z = -sin(m_lastProjMat.elev);
768 
769  // The camera X vector (in 3D) can be computed from the camera azimuth
770  // angle:
771  TPoint3D cam_x_3d;
772  cam_x_3d.x = -sin(m_lastProjMat.azimuth);
773  cam_x_3d.y = cos(m_lastProjMat.azimuth);
774  cam_x_3d.z = 0;
775 
776  // The camera real UP vector (in 3D) is the cross product:
777  // X3d x pointing_dir:
778  TPoint3D cam_up_3d;
779  crossProduct3D(cam_x_3d, pointing_dir, cam_up_3d);
780 
782  {
783  // Ortho projection:
784  // -------------------------------
785  double Ax = m_lastProjMat.zoom * 0.5;
786  double Ay = Ax;
787 
788  if (ASPECT > 1)
789  Ax *= ASPECT;
790  else
791  {
792  if (ASPECT != 0) Ay /= ASPECT;
793  }
794 
795  const double point_lx =
796  (-0.5 + x_coord / m_lastProjMat.viewport_width) * 2 * Ax;
797  const double point_ly =
798  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * 2 * Ay;
799 
800  const TPoint3D ray_origin(
801  m_lastProjMat.eye.x + point_lx * cam_x_3d.x +
802  point_ly * cam_up_3d.x,
803  m_lastProjMat.eye.y + point_lx * cam_x_3d.y +
804  point_ly * cam_up_3d.y,
805  m_lastProjMat.eye.z + point_lx * cam_x_3d.z +
806  point_ly * cam_up_3d.z);
807 
808  out_ray.pBase = ray_origin;
809  out_ray.director[0] = pointing_dir.x;
810  out_ray.director[1] = pointing_dir.y;
811  out_ray.director[2] = pointing_dir.z;
812  }
813  else
814  {
815  // Perspective camera
816  // -------------------------------
817 
818  // JL: This can derived from:
819  // http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
820  // where one arrives to:
821  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
822  //
823  const double FOVy = DEG2RAD(m_lastProjMat.FOV);
824  const double FOVx = 2.0 * atan(ASPECT * tan(FOVy * 0.5));
825 
826  const double ang_horz =
827  (-0.5 + x_coord / m_lastProjMat.viewport_width) * FOVx;
828  const double ang_vert =
829  -(-0.5 + y_coord / m_lastProjMat.viewport_height) * FOVy;
830 
831  const TPoint3D l(
832  tan(ang_horz), tan(ang_vert),
833  1.0); // Point in camera local reference frame
834 
835  const TPoint3D ray_director(
836  l.x * cam_x_3d.x + l.y * cam_up_3d.x + l.z * pointing_dir.x,
837  l.x * cam_x_3d.y + l.y * cam_up_3d.y + l.z * pointing_dir.y,
838  l.x * cam_x_3d.z + l.y * cam_up_3d.z + l.z * pointing_dir.z);
839 
840  // Set out ray:
841  out_ray.pBase = m_lastProjMat.eye;
842  out_ray.director[0] = ray_director.x;
843  out_ray.director[1] = ray_director.y;
844  out_ray.director[2] = ray_director.z;
845 
846  } // end projective
847 
848  // Camera pose:
849  if (out_cameraPose)
850  {
852  M.get_unsafe(0, 0) = cam_x_3d.x;
853  M.get_unsafe(1, 0) = cam_x_3d.y;
854  M.get_unsafe(2, 0) = cam_x_3d.z;
855  M.get_unsafe(3, 0) = 0;
856 
857  M.get_unsafe(0, 1) = cam_up_3d.x;
858  M.get_unsafe(1, 1) = cam_up_3d.y;
859  M.get_unsafe(2, 1) = cam_up_3d.z;
860  M.get_unsafe(3, 1) = 0;
861 
862  M.get_unsafe(0, 2) = pointing_dir.x;
863  M.get_unsafe(1, 2) = pointing_dir.y;
864  M.get_unsafe(2, 2) = pointing_dir.z;
865  M.get_unsafe(3, 2) = 0;
866 
867  M.get_unsafe(0, 3) = m_lastProjMat.eye.x;
868  M.get_unsafe(1, 3) = m_lastProjMat.eye.y;
869  M.get_unsafe(2, 3) = m_lastProjMat.eye.z;
870  M.get_unsafe(3, 3) = 1;
871 
872  *out_cameraPose = CPose3D(M);
873  }
874 }
875 
876 MRPT_TODO("Implement a setCurrentCameraFromPose() method")
877 
878 void COpenGLViewport::getCurrentCameraPose(
879  mrpt::poses::CPose3D& out_cameraPose) const
880 {
882  get3DRayForPixelCoord(0, 0, dum, &out_cameraPose);
883 }
884 
885 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView
886  */
888 {
889  // If this was a m_isImageView, remove the quad object:
891 
892  m_isCloned = false;
893  m_isClonedCamera = false;
894  m_isImageView = false;
895 }
896 
898 {
900 }
902 {
904 }
905 
907  const mrpt::utils::CImage& img, bool is_fast)
908 {
909  // If this is the first time, we have to create the quad object:
911  m_imageview_img = mrpt::make_aligned_shared<mrpt::utils::CImage>();
912  m_isImageView = true;
913 
914  // Update texture image:
915  mrpt::utils::CImage* my_img = m_imageview_img.get();
916 
917  if (!is_fast)
918  *my_img = img;
919  else
920  my_img->copyFastFrom(*const_cast<mrpt::utils::CImage*>(&img));
921 }
922 
923 /** Evaluates the bounding box of this object (including possible children) in
924  * the coordinate frame of the object parent. */
926  mrpt::math::TPoint3D& bb_min, mrpt::math::TPoint3D& bb_max) const
927 {
928  bb_min = TPoint3D(
929  std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
930  std::numeric_limits<double>::max());
931  bb_max = TPoint3D(
932  -std::numeric_limits<double>::max(),
933  -std::numeric_limits<double>::max(),
934  -std::numeric_limits<double>::max());
935 
937  it != m_objects.end(); ++it)
938  {
939  TPoint3D child_bbmin(
940  std::numeric_limits<double>::max(),
941  std::numeric_limits<double>::max(),
942  std::numeric_limits<double>::max());
943  TPoint3D child_bbmax(
944  -std::numeric_limits<double>::max(),
945  -std::numeric_limits<double>::max(),
946  -std::numeric_limits<double>::max());
947  (*it)->getBoundingBox(child_bbmin, child_bbmax);
948 
949  keep_min(bb_min.x, child_bbmin.x);
950  keep_min(bb_min.y, child_bbmin.y);
951  keep_min(bb_min.z, child_bbmin.z);
952 
953  keep_max(bb_max.x, child_bbmax.x);
954  keep_max(bb_max.y, child_bbmax.y);
955  keep_max(bb_max.z, child_bbmax.z);
956  }
957 }
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
#define GL_BGR
Definition: glew.h:1239
opengl::CListOpenGLObjects m_objects
The list of objects that comprise the 3D scene.
void dumpListOfObjects(mrpt::utils::CStringList &lst)
Retrieves a list of all objects in text form.
CRenderizable::Ptr getByName(const std::string &str)
Returns the first object with a given name, or nullptr if not found.
void get3DRayForPixelCoord(const double x_coord, const double y_coord, mrpt::math::TLine3D &out_ray, mrpt::poses::CPose3D *out_cameraPose=nullptr) const
Compute the 3D ray corresponding to a given pixel; this can be used to allow the user to pick and sel...
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)
double GLdouble
Definition: glew.h:219
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
A base class for all OpenGL objects with loadable textures.
bool m_isTransparent
Whether to clear color buffer.
A set of object, which are referenced to the coordinates framework established in this object...
Definition: CSetOfObjects.h:30
GLAPI void GLAPIENTRY glEnable(GLenum cap)
uint32_t m_borderWidth
Default=0, the border around the viewport.
void setCloneView(const std::string &clonedViewport)
Set this viewport as a clone of some other viewport, given its name - as a side effect, current list of internal OpenGL objects is cleared.
The virtual base class which provides a unified interface for all persistent objects in MRPT...
Definition: CSerializable.h:44
#define GL_STENCIL_BUFFER_BIT
Definition: glew.h:261
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:118
float azimuth
Camera elev & azimuth, in radians.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define GL_MODELVIEW
Definition: glew.h:610
#define GL_FRONT_AND_BACK
Definition: glew.h:321
std::deque< CRenderizable::Ptr > CListOpenGLObjects
A list of objects pointers, automatically managing memory free at destructor, and managing copies cor...
void copyFastFrom(CImage &o)
Moves an image from another object, erasing the origin image in the process (this is much faster than...
Definition: CImage.cpp:173
#define THROW_EXCEPTION(msg)
std::vector< CLight > m_lights
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLenum GLsizei n
Definition: glext.h:5074
Scalar * iterator
Definition: eigen_plugins.h:26
void setImageView_fast(mrpt::utils::CImage &img)
Just like setImageView but moves the internal image memory instead of making a copy, so it&#39;s faster but empties the input image.
void getViewportClipDistances(double &clip_min, double &clip_max) const
Get the current min/max clip depth distances of the rendering frustum (default: 0.1 - 10000)
The base class of 3D objects that can be directly rendered through OpenGL.
Definition: CRenderizable.h:43
std::shared_ptr< CRenderizable > Ptr
Definition: CRenderizable.h:45
void setViewportClipDistances(const double clip_min, const double clip_max)
Set the min/max clip depth distances of the rendering frustum (default: 0.1 - 10000) ...
TPoint3D pBase
Base point.
STL namespace.
#define GL_UNSIGNED_BYTE
Definition: glew.h:302
#define GL_PERSPECTIVE_CORRECTION_HINT
Definition: glew.h:450
const Scalar * const_iterator
Definition: eigen_plugins.h:27
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:57
#define GL_COLOR_MATERIAL
Definition: glew.h:392
mrpt::utils::TColorf m_background_color
used only if m_custom_backgb_color
#define GL_DEPTH_TEST
Definition: glew.h:401
#define GL_SMOOTH
Definition: glew.h:635
mrpt::math::TPoint3D eye
The camera is here.
GLdouble s
Definition: glext.h:3676
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
#define GL_LIGHTING
Definition: glew.h:385
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
A viewport within a COpenGLScene, containing a set of OpenGL objects to render.
GLAPI void GLAPIENTRY glLoadIdentity(void)
GLenum GLsizei width
Definition: glext.h:3531
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
Definition: geometry.h:811
Each of the possible lights of a 3D scene.
Definition: CLight.h:32
#define MRPT_TODO(x)
bool m_isClonedCamera
Set by setCloneCamera.
double m_clip_min
The min/max clip depth distances (default: 0.1 - 10000)
void publishEvent(const mrptEvent &e) const
Called when you want this object to emit an event to all the observers currently subscribed to this o...
Definition: CObservable.cpp:47
GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params)
#define GL_DEPTH_BUFFER_BIT
Definition: glew.h:259
#define IS_DERIVED(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is an i...
Definition: CObject.h:109
#define GL_COLOR_BUFFER_BIT
Definition: glew.h:265
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
A class for storing a list of text lines.
Definition: CStringList.h:32
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
bool m_isImageView
Set by setImageView.
#define GL_COLOR_CLEAR_VALUE
Definition: glew.h:443
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
GLAPI void GLAPIENTRY glDepthFunc(GLenum func)
#define MRPT_END
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
#define GL_LEQUAL
Definition: glew.h:246
void render(const int render_width, const int render_height) const
Render the objects in this viewport (called from COpenGLScene only)
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
GLint GLvoid * img
Definition: glext.h:3763
GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode)
GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
void removeObject(const CRenderizable::Ptr &obj)
Removes the given object from the scene (it also deletes the object to free its memory).
#define GL_PROJECTION
Definition: glew.h:611
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:19
An object for reading objects from a stream, intended for being used in STL algorithms.
#define GL_RGB
Definition: glew.h:623
A set of utility objects for metaprogramming with STL algorithms.
double x
X,Y,Z coordinates.
mrpt::math::TPoint3D up
Up vector of the camera.
TLastProjectiveMatrixInfo m_lastProjMat
Info updated with each "render()" and used in "get3DRayForPixelCoord".
void setNormalMode()
Resets the viewport to a normal 3D viewport.
GLAPI void GLAPIENTRY glBegin(GLenum mode)
#define DEG2RAD
GLsizei const GLchar ** string
Definition: glext.h:4101
#define GL_LINE_LOOP
Definition: glew.h:274
GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode)
void keep_max(T &var, const K test_val)
If the second argument is above the first one, set the first argument to this higher value...
Definition: bits.h:227
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
size_t size() const
Returns the number of text lines in the list.
virtual ~COpenGLViewport()
Destructor: clears all objects.
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const override
Returns information about the class of an object in runtime.
mrpt::math::TPoint3D pointing
The camera points to here.
double director[3]
Director vector.
void initializeAllTextures()
Initializes all textures in the scene (See opengl::CTexturedPlane::loadTextureInOpenGL) ...
mrpt::utils::CImage::Ptr m_imageview_img
The image to display, after calling setImageView()
#define CLASS_ID_NAMESPACE(class_name, namespaceName)
Definition: CObject.h:88
unsigned int GLenum
Definition: glew.h:206
#define MRPT_START
GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param)
static void checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
#define GL_UNPACK_ROW_LENGTH
Definition: glew.h:481
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
void clear()
Delete all internal obejcts.
#define GL_NICEST
Definition: glew.h:569
An event sent by an mrpt::opengl::COpenGLViewport just after clearing the viewport and setting the GL...
void keep_min(T &var, const K test_val)
If the second argument is below the first one, set the first argument to this lower value...
Definition: bits.h:220
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
void setImageView(const mrpt::utils::CImage &img)
Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport a...
#define IS_CLASS(ptrObj, class_name)
Evaluates to true if the given pointer to an object (derived from mrpt::utils::CSerializable) is of t...
Definition: CObject.h:103
An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives a...
#define GL_SCISSOR_TEST
Definition: glew.h:440
GLAPI void GLAPIENTRY glClear(GLbitfield mask)
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
GLuint in
Definition: glext.h:7274
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
GLuint const GLchar * name
Definition: glext.h:4054
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:60
#define ASSERT_(f)
A versatile "profiler" that logs the time spent within each pair of calls to enter(X)-leave(X), among other stats.
Definition: CTimeLogger.h:45
GLAPI void GLAPIENTRY glEnd(void)
std::string m_clonedViewport
Only if m_isCloned=true.
#define GL_POLYGON_SMOOTH_HINT
Definition: glew.h:453
GLenum GLint GLint y
Definition: glext.h:3538
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: glew.h:387
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
T::Ptr getByClass(const size_t &ith=0) const
Returns the i&#39;th object of a given class (or of a descendant class), or nullptr (an empty smart point...
int GLint
Definition: glew.h:209
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
GLAPI void GLAPIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)
void internal_setImageView_fast(const mrpt::utils::CImage &img, bool is_fast)
GLenum GLint x
Definition: glext.h:3538
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:237
Lightweight 3D point.
void renderSetOfObjects(const mrpt::opengl::CListOpenGLObjects &objs)
For each object in the list:
Definition: gl_utils.cpp:32
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:30
const char * className
Definition: CObject.h:34
GLenum GLsizei GLsizei height
Definition: glext.h:3554
unsigned __int32 uint32_t
Definition: rptypes.h:47
GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y)
GLAPI void GLAPIENTRY glDisable(GLenum cap)
void setViewportPosition(const double x, const double y, const double width, const double height)
Change the viewport position and dimension on the rendering window.
#define GL_AMBIENT_AND_DIFFUSE
Definition: glew.h:608
#define GL_ACCUM_BUFFER_BIT
Definition: glew.h:260
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
void getViewportPosition(double &x, double &y, double &width, double &height)
Get the current viewport position and dimension on the rendering window.
void insert(const CRenderizable::Ptr &newObject)
Insert a new object into the list.
double m_view_x
The viewport position [0,1].
GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y)
#define GL_LUMINANCE
Definition: glew.h:625
utils::safe_ptr< COpenGLScene > m_parent
The scene that contains this viewport.
#define GL_TRUE
Definition: glew.h:293
opengl::CCamera m_camera
The camera associated to the viewport.
std::string m_name
The viewport&#39;s name.
void add(const std::string &str)
Appends a new string at the end of the string list.
Definition: CStringList.cpp:43
bool m_isCloned
Set by setCloneView.
3D line, represented by a base point and a director vector.
#define GL_FASTEST
Definition: glew.h:568



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