Main MRPT website > C++ reference for MRPT 1.5.7
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 
12 
17 #include <mrpt/utils/CStringList.h>
18 #include <mrpt/utils/CTimeLogger.h>
19 #include <mrpt/utils/CStream.h>
21 #include <mrpt/opengl/gl_utils.h>
22 
23 #include "opengl_internals.h"
24 
25 using namespace mrpt;
26 using namespace mrpt::poses;
27 using namespace mrpt::opengl;
28 using namespace mrpt::utils;
29 using namespace mrpt::math;
30 using namespace std;
31 
33 using namespace mrpt::utils::metaprogramming;
34 
36 
37 //#define OPENGLVIEWPORT_ENABLE_TIMEPROFILING
38 
39 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
40 mrpt::utils::CTimeLogger glv_timlog;
41 #endif
42 
43 
44 /*--------------------------------------------------------------
45 
46  IMPLEMENTATION OF COpenGLViewport
47 
48  ---------------------------------------------------------------*/
49 
50 /*--------------------------------------------------------------
51  Constructor
52  ---------------------------------------------------------------*/
53 COpenGLViewport::COpenGLViewport( COpenGLScene *parent, const string &name ) :
54  m_camera(),
55  m_parent( parent ),
56  m_isCloned(false),
57  m_isClonedCamera(false),
58  m_clonedViewport(),
59  m_name(name),
60  m_isTransparent(false),
61  m_borderWidth(0),
62  m_view_x(0),
63  m_view_y(0),
64  m_view_width(1),
65  m_view_height(1),
66  m_clip_min(0.1),
67  m_clip_max(10000),
68  m_custom_backgb_color(false),
69  m_background_color(0.6f,0.6f,0.6f),
70  m_isImageView(false),
71  m_imageview_img(),
72  m_objects(),
73  // OpenGL settings:
74  m_OpenGL_enablePolygonNicest(true),
75  m_lights()
76 {
77  // Default: one light from default direction
78  m_lights.push_back( CLight() );
79  m_lights.push_back( CLight() );
80 
81  m_lights[0].setPosition(1,1,1,0);
82  m_lights[0].setDirection(-1,-1,-1);
83 
84  m_lights[1].light_ID = 1;
85  m_lights[1].setPosition(1,2,-1,0);
86  m_lights[1].setDirection(1,2,1);
87 
88  m_lights[1].color_diffuse[0] = 0.3f;
89  m_lights[1].color_diffuse[1] = 0.3f;
90  m_lights[1].color_diffuse[2] = 0.3f;
91 
92  m_lights[1].color_ambient[0] = 0.3f;
93  m_lights[1].color_ambient[1] = 0.3f;
94  m_lights[1].color_ambient[2] = 0.3f;
95 
96 }
97 
98 
99 /*--------------------------------------------------------------
100  Destructor
101  ---------------------------------------------------------------*/
103 {
104  clear();
105 }
106 
107 /*--------------------------------------------------------------
108  setCloneView
109  ---------------------------------------------------------------*/
110 void COpenGLViewport::setCloneView( const string &clonedViewport )
111 {
112  clear();
113  m_isCloned = true;
114  m_clonedViewport = clonedViewport;
115 }
116 
117 /*--------------------------------------------------------------
118  setViewportPosition
119  ---------------------------------------------------------------*/
121  const double x,
122  const double y,
123  const double width,
124  const double height )
125 {
126  MRPT_START
129 
130  m_view_x = x;
131  m_view_y = y;
134 
135  MRPT_END
136 }
137 
138 /*--------------------------------------------------------------
139  getViewportPosition
140  ---------------------------------------------------------------*/
142  double &x,
143  double &y,
144  double &width,
145  double &height )
146 {
147  x = m_view_x;
148  y = m_view_y;
151 }
152 
153 /*--------------------------------------------------------------
154  clear
155  ---------------------------------------------------------------*/
157 {
158  m_objects.clear();
159 }
160 
161 /*--------------------------------------------------------------
162  insert
163  ---------------------------------------------------------------*/
164 void COpenGLViewport::insert( const CRenderizablePtr &newObject )
165 {
166  m_objects.push_back(newObject);
167 }
168 
169 
170 /*---------------------------------------------------------------
171  render
172  ---------------------------------------------------------------*/
173 void COpenGLViewport::render( const int render_width, const int render_height ) const
174 {
175 #if MRPT_HAS_OPENGL_GLUT
176  const CRenderizable *it = NULL; // Declared here for usage in the "catch"
177  try
178  {
179  // Change viewport:
180  // -------------------------------------------
181  const GLint vx = m_view_x>1 ? GLint(m_view_x) : ( m_view_x<0 ? GLint(render_width+m_view_x) : GLint( render_width * m_view_x ) );
182  const GLint vy = m_view_y>1 ? GLint(m_view_y) : ( m_view_y<0 ? GLint(render_height+m_view_y) : GLint( render_height * m_view_y ) );
183 
184  GLint vw;
185  if (m_view_width>1) // >1 -> absolute pixels:
186  vw = GLint(m_view_width);
187  else if (m_view_width<0)
188  { // Negative numbers: Specify the right side coordinates instead of the width:
189  if (m_view_width>=-1)
190  vw = GLint( -render_width * m_view_width - vx +1 );
191  else vw = GLint( -m_view_width - vx + 1 );
192  }
193  else // A factor:
194  {
195  vw = GLint( render_width * m_view_width );
196  }
197 
198 
199  GLint vh;
200  if (m_view_height>1) // >1 -> absolute pixels:
201  vh = GLint(m_view_height);
202  else if (m_view_height<0)
203  { // Negative numbers: Specify the right side coordinates instead of the width:
204  if (m_view_height>=-1)
205  vh = GLint( -render_height * m_view_height - vy + 1);
206  else vh = GLint( -m_view_height - vy +1 );
207  }
208  else // A factor:
209  vh = GLint( render_height * m_view_height );
210 
211  glViewport(vx,vy, vw, vh );
212 
213  // Clear depth&/color buffers:
214  // -------------------------------------------
217 
218  glScissor(vx,vy,vw,vh);
219 
221  if ( !m_isTransparent )
222  { // Clear color & depth buffers:
223  // Save?
224  GLdouble old_colors[4];
226  {
227  glGetDoublev(GL_COLOR_CLEAR_VALUE, old_colors );
229  }
230 
232 
233  // Restore old colors:
235  glClearColor(old_colors[0],old_colors[1],old_colors[2],old_colors[3]);
236  }
237  else
238  { // Clear depth buffer only:
240  }
242 
243  // If we are in "image mode", rendering is much simpler: just set
244  // ortho projection and render the image quad:
245  if (m_isImageView)
246  {
247 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
248  glv_timlog.enter("COpenGLViewport::render imageview");
249 #endif
250  // "Image mode" rendering:
251  // -----------------------------------
252  if (m_imageview_img) // should be ALWAYS true, but just in case!
253  {
254  // Note: The following code is inspired in the implementations:
255  // - libcvd, by Edward Rosten http://www.edwardrosten.com/cvd/
256  // - PTAM, by Klein & Murray http://www.robots.ox.ac.uk/~gk/PTAM/
257 
258  const mrpt::utils::CImage *img = m_imageview_img.pointer();
259 
260  const int img_w = img->getWidth();
261  const int img_h = img->getHeight();
262 
263  if (img_w!=0 && img_h!=0)
264  {
265  // Prepare an ortho projection:
267  glLoadIdentity();
268 
269  // Need to adjust the aspect ratio?
270  const double ratio = vw*img_h/double(vh*img_w);
271  double ortho_w = img_w;
272  double ortho_h = img_h;
273  if (ratio>1)
274  ortho_w *= ratio;
275  else
276  if (ratio!=0) ortho_h /=ratio;
277 
278  glOrtho(
279  -0.5, ortho_h - 0.5,
280  ortho_w - 0.5, -0.5,
281  -1,1);
282 
283  // Prepare raster pos & pixel copy direction in -Y.
284  glRasterPos2f(-0.5f,-0.5f);
285  glPixelZoom(
286  vw / float(ortho_w),
287  -vh / float(ortho_h) );
288 
289  // Prepare image data types:
290  const GLenum img_type = GL_UNSIGNED_BYTE;
291  const int nBytesPerPixel = img->isColor() ? 3 : 1;
292  const bool is_RGB_order = (!::strcmp(img->getChannelsOrder(),"RGB")); // Reverse RGB <-> BGR order?
293  const GLenum img_format = nBytesPerPixel==3 ? (is_RGB_order ? GL_RGB : GL_BGR): GL_LUMINANCE;
294 
295  // Send image data to OpenGL:
296  glPixelStorei(GL_UNPACK_ROW_LENGTH,img->getRowStride()/nBytesPerPixel );
297  glDrawPixels(
298  img_w, img_h,
299  img_format, img_type,
300  img->get_unsafe(0,0)
301  );
304  }
305  }
306  // done.
307 #if defined(OPENGLVIEWPORT_ENABLE_TIMEPROFILING)
308  glv_timlog.leave("COpenGLViewport::render imageview");
309 #endif
310  }
311  else
312  {
313  // Non "image mode" rendering:
314 
315  // Set camera:
316  // -------------------------------------------
318  glLoadIdentity();
319 
320  const CListOpenGLObjects *objectsToRender;
321  COpenGLViewport *viewForGetCamera;
322 
323  if (m_isCloned)
324  { // Clone: render someone's else objects.
325  ASSERT_(m_parent.get()!=NULL);
326 
327  COpenGLViewportPtr view = m_parent->getViewport( m_clonedViewport );
328  if (!view)
329  THROW_EXCEPTION_FMT("Cloned viewport '%s' not found in parent COpenGLScene",m_clonedViewport.c_str());
330 
331  objectsToRender = &view->m_objects;
332  viewForGetCamera = m_isClonedCamera ? view.pointer() : const_cast<COpenGLViewport*>(this);
333  }
334  else
335  { // Normal case: render our own objects:
336  objectsToRender = &m_objects;
337  viewForGetCamera = const_cast<COpenGLViewport*>(this);
338  }
339 
340  // Get camera:
341  // 1st: if there is a CCamera in the scene:
342  CRenderizablePtr cam_ptr = viewForGetCamera->getByClass<CCamera>();
343 
344  CCamera *myCamera=NULL;
345  if (cam_ptr.present())
346  {
347  myCamera = getAs<CCamera>(cam_ptr);
348  }
349 
350  // 2nd: the internal camera of all viewports:
351  if (!myCamera)
352  myCamera = &viewForGetCamera->m_camera;
353 
355 
356 
357  m_lastProjMat.azimuth = DEG2RAD(myCamera->m_azimuthDeg);
358  m_lastProjMat.elev = DEG2RAD(myCamera->m_elevationDeg);
359 
360  const float dis = max(0.01f,myCamera->m_distanceZoom);
361  m_lastProjMat.eye.x = myCamera->m_pointingX + dis * cos(m_lastProjMat.azimuth)*cos(m_lastProjMat.elev);
362  m_lastProjMat.eye.y = myCamera->m_pointingY + dis * sin(m_lastProjMat.azimuth)*cos(m_lastProjMat.elev);
363  m_lastProjMat.eye.z = myCamera->m_pointingZ + dis * sin(m_lastProjMat.elev);
364 
365 
366  if (fabs(fabs(myCamera->m_elevationDeg)-90)>1e-6)
367  {
368  m_lastProjMat.up.x=0;
369  m_lastProjMat.up.y=0;
370  m_lastProjMat.up.z=1;
371  }
372  else
373  {
374  float sgn = myCamera->m_elevationDeg>0 ? 1:-1;
375  m_lastProjMat.up.x = -cos(DEG2RAD(myCamera->m_azimuthDeg))*sgn;
376  m_lastProjMat.up.y = -sin(DEG2RAD(myCamera->m_azimuthDeg))*sgn;
377  m_lastProjMat.up.z = 0;
378  }
379 
380  m_lastProjMat.is_projective = myCamera->m_projectiveModel;
381  m_lastProjMat.FOV = myCamera->m_projectiveFOVdeg;
382  m_lastProjMat.pointing.x = myCamera->m_pointingX;
383  m_lastProjMat.pointing.y = myCamera->m_pointingY;
384  m_lastProjMat.pointing.z = myCamera->m_pointingZ;
385  m_lastProjMat.zoom = myCamera->m_distanceZoom;
386 
387  if (myCamera->m_projectiveModel)
388  {
389  gluPerspective( myCamera->m_projectiveFOVdeg, vw/double(vh),m_clip_min,m_clip_max);
391  }
392  else
393  {
394  const double ratio = vw/double(vh);
395  double Ax = myCamera->m_distanceZoom*0.5;
396  double Ay = myCamera->m_distanceZoom*0.5;
397 
398  if (ratio>1)
399  Ax *= ratio;
400  else
401  {
402  if (ratio!=0) Ay /=ratio;
403  }
404 
405  glOrtho( -Ax,Ax,-Ay,Ay,-0.5*m_clip_max,0.5*m_clip_max);
407  }
408 
409  if (myCamera->is6DOFMode())
410  {
411  // In 6DOFMode eye is set viewing towards the direction of the positive Z axis
412  // Up is set as Y axis
413  mrpt::poses::CPose3D viewDirection,pose,at;
414  viewDirection.z(+1);
415  pose = mrpt::poses::CPose3D(myCamera->getPose());
416  at = pose + viewDirection;
417  gluLookAt(
418  pose.x(),
419  pose.y(),
420  pose.z(),
421  at.x(),
422  at.y(),
423  at.z(),
424  pose.getRotationMatrix()(0,1),
425  pose.getRotationMatrix()(1,1),
426  pose.getRotationMatrix()(2,1)
427  );
429  }else{
430  // This command is common to ortho and perspective:
431  gluLookAt(
440  m_lastProjMat.up.z);
442  }
443 
444  // Optional pre-Render user code:
445  if (hasSubscribers())
446  {
447  mrptEventGLPreRender ev(this);
448  this->publishEvent(ev);
449  }
450 
451 
452  // Global OpenGL settings:
453  // ---------------------------------
456 
457  // Render objects:
458  // -------------------------------------------
460  glLoadIdentity();
461 
463  glDepthFunc(GL_LEQUAL); //GL_LESS
464 
465  // Setup lights
466  // -------------------------------------------
472 
473  for (size_t i=0;i<m_lights.size();i++)
474  m_lights[i].sendToOpenGL();
475 
476  // Render all the objects:
477  // -------------------------------------------
479 
480  } // end of non "image mode" rendering
481 
482 
483  // Finally, draw the border:
484  // --------------------------------
485  if (m_borderWidth>0)
486  {
488  glColor4f(0,0,0,1);
490 
492  glLoadIdentity();
494  glLoadIdentity();
495 
496  glDisable(GL_LIGHTING); // Disable lights when drawing lines
498  glVertex2f(-1,-1);
499  glVertex2f(-1, 1);
500  glVertex2f( 1, 1);
501  glVertex2f( 1,-1);
502  glEnd();
503  glEnable(GL_LIGHTING); // Disable lights when drawing lines
504 
506  }
507 
508  // Optional post-Render user code:
509  if (hasSubscribers())
510  {
511  mrptEventGLPostRender ev(this);
512  this->publishEvent(ev);
513  }
514  }
515  catch(exception &e)
516  {
517  string msg;
518  if (it!=NULL)
519  msg = format("Exception while rendering a class '%s'\n%s", it->GetRuntimeClass()->className, e.what() );
520  else msg = format("Exception while rendering:\n%s", e.what() );
521 
522  THROW_EXCEPTION(msg);
523  }
524  catch(...)
525  {
526  THROW_EXCEPTION("Runtime error!");
527  }
528 #else
529  MRPT_UNUSED_PARAM(render_width); MRPT_UNUSED_PARAM(render_height);
530  THROW_EXCEPTION("The MRPT has been compiled with MRPT_HAS_OPENGL_GLUT=0! OpenGL functions are not implemented");
531 #endif
532 }
533 
534 
535 /*---------------------------------------------------------------
536  Implements the writing to a CStream capability of
537  CSerializable objects
538  ---------------------------------------------------------------*/
540 {
541  if (version)
542  *version = 3;
543  else
544  {
545  // Save data:
546  out << m_camera
548  << m_name
549  << m_isTransparent
550  << m_borderWidth
552 
553  // Added in v1:
555 
556  // Save objects:
557  uint32_t n;
558  n = (uint32_t)m_objects.size();
559  out << n;
560  for (CListOpenGLObjects::const_iterator it=m_objects.begin();it!=m_objects.end();++it)
561  out << **it;
562 
563  // Added in v2: Global OpenGL settings:
565 
566  // Added in v3: Lights
567  out << m_lights;
568 
569  }
570 }
571 
572 /*---------------------------------------------------------------
573  Implements the reading from a CStream capability of
574  CSerializable objects
575  ---------------------------------------------------------------*/
577 {
578  switch(version)
579  {
580  case 0:
581  case 1:
582  case 2:
583  case 3:
584  {
585  // Load data:
586  in >> m_camera
588  >> m_name
589  >> m_isTransparent
590  >> m_borderWidth
592 
593  // in v1:
594  if (version>=1)
595  {
597  }
598  else
599  {
600  m_custom_backgb_color = false;
601  }
602 
603  // Load objects:
604  uint32_t n;
605  in >> n;
606  clear();
607  m_objects.resize(n);
608 
609  for_each(m_objects.begin(), m_objects.end(), ObjectReadFromStream(&in) );
610 
611  // Added in v2: Global OpenGL settings:
612  if (version>=2)
613  {
615  }
616  else {
617  // Defaults
618  }
619 
620  // Added in v3: Lights
621  if (version>=3)
622  in >>m_lights;
623  else
624  {
625  // Default: one light from default direction
626  m_lights.clear();
627  m_lights.push_back( CLight() );
628  }
629 
630  } break;
631  default:
633 
634  };
635 }
636 
637 /*---------------------------------------------------------------
638  getByName
639  ---------------------------------------------------------------*/
640 CRenderizablePtr COpenGLViewport::getByName( const string &str )
641 {
642  for (CListOpenGLObjects::iterator it=m_objects.begin();it!=m_objects.end();++it)
643  {
644  if ((*it)->m_name == str)
645  return *it;
646  else if ( (*it)->GetRuntimeClass() == CLASS_ID_NAMESPACE(CSetOfObjects,opengl))
647  {
648  CRenderizablePtr ret = getAs<CSetOfObjects>(*it)->getByName(str);
649  if (ret.present())
650  return ret;
651  }
652  }
653  return CRenderizablePtr();
654 }
655 
656 /*---------------------------------------------------------------
657  initializeAllTextures
658  ---------------------------------------------------------------*/
660 {
661 #if MRPT_HAS_OPENGL_GLUT
662  for (CListOpenGLObjects::iterator it=m_objects.begin();it!=m_objects.end();++it)
663  {
664  if ( IS_DERIVED(*it, CTexturedObject ))
665  getAs<CTexturedObject>(*it)->loadTextureInOpenGL();
666  else if ( IS_CLASS( *it, CSetOfObjects) )
667  getAs<CSetOfObjects>(*it)->initializeAllTextures();
668  }
669 #endif
670 }
671 
672 /*--------------------------------------------------------------
673  dumpListOfObjects
674  ---------------------------------------------------------------*/
676 {
677  for (CListOpenGLObjects::iterator it=m_objects.begin();it!=m_objects.end();++it)
678  {
679  // Single obj:
680  string s( (*it)->GetRuntimeClass()->className );
681  if ((*it)->m_name.size())
682  s+= string(" (") +(*it)->m_name + string(")");
683  lst.add( s );
684 
685  if ((*it)->GetRuntimeClass() == CLASS_ID_NAMESPACE(CSetOfObjects,mrpt::opengl))
686  {
687  utils::CStringList auxLst;
688 
689  getAs<CSetOfObjects>(*it)->dumpListOfObjects(auxLst);
690 
691  for (size_t i=0;i<auxLst.size();i++)
692  lst.add( string(" ")+auxLst(i) );
693  }
694  }
695 }
696 
697 /*--------------------------------------------------------------
698  removeObject
699  ---------------------------------------------------------------*/
700 void COpenGLViewport::removeObject( const CRenderizablePtr &obj )
701 {
702  for (CListOpenGLObjects::iterator it=m_objects.begin();it!=m_objects.end();++it)
703  if (it->pointer() == obj.pointer())
704  {
705  m_objects.erase(it);
706  return;
707  }
708  else if ( (*it)->GetRuntimeClass()==CLASS_ID_NAMESPACE(CSetOfObjects,opengl) )
709  getAs<CSetOfObjects>(*it)->removeObject(obj);
710 }
711 
712 /*--------------------------------------------------------------
713  setViewportClipDistances
714  ---------------------------------------------------------------*/
715 void COpenGLViewport::setViewportClipDistances(const double clip_min, const double clip_max)
716 {
717  ASSERT_(clip_max>clip_min);
718 
719  m_clip_min = clip_min;
720  m_clip_max = clip_max;
721 }
722 
723 /*--------------------------------------------------------------
724  getViewportClipDistances
725  ---------------------------------------------------------------*/
726 void COpenGLViewport::getViewportClipDistances(double &clip_min, double &clip_max) const
727 {
728  clip_min = m_clip_min;
729  clip_max = m_clip_max;
730 }
731 
732 /*--------------------------------------------------------------
733  get3DRayForPixelCoord
734  ---------------------------------------------------------------*/
736  const double x_coord,
737  const double y_coord,
738  mrpt::math::TLine3D &out_ray,
739  mrpt::poses::CPose3D *out_cameraPose
740  ) const
741 {
743 
744  const double ASPECT = m_lastProjMat.viewport_width / double(m_lastProjMat.viewport_height);
745 
746  // unitary vector between (eye) -> (pointing):
747  TPoint3D pointing_dir;
748  pointing_dir.x = - cos(m_lastProjMat.azimuth)*cos(m_lastProjMat.elev);
749  pointing_dir.y = - sin(m_lastProjMat.azimuth)*cos(m_lastProjMat.elev);
750  pointing_dir.z = - sin(m_lastProjMat.elev);
751 
752  // The camera X vector (in 3D) can be computed from the camera azimuth angle:
753  TPoint3D cam_x_3d;
754  cam_x_3d.x = -sin(m_lastProjMat.azimuth);
755  cam_x_3d.y = cos(m_lastProjMat.azimuth);
756  cam_x_3d.z = 0;
757 
758  // The camera real UP vector (in 3D) is the cross product:
759  // X3d x pointing_dir:
760  TPoint3D cam_up_3d;
761  crossProduct3D(cam_x_3d,pointing_dir, cam_up_3d);
762 
763 
765  {
766  // Ortho projection:
767  // -------------------------------
768  double Ax = m_lastProjMat.zoom*0.5;
769  double Ay = Ax;
770 
771  if (ASPECT>1)
772  Ax *= ASPECT;
773  else {
774  if (ASPECT!=0) Ay /=ASPECT;
775  }
776 
777  const double point_lx = (-0.5 + x_coord/m_lastProjMat.viewport_width)*2*Ax;
778  const double point_ly = -(-0.5 + y_coord/m_lastProjMat.viewport_height)*2*Ay;
779 
780  const TPoint3D ray_origin(
781  m_lastProjMat.eye.x + point_lx * cam_x_3d.x + point_ly * cam_up_3d.x,
782  m_lastProjMat.eye.y + point_lx * cam_x_3d.y + point_ly * cam_up_3d.y,
783  m_lastProjMat.eye.z + point_lx * cam_x_3d.z + point_ly * cam_up_3d.z
784  );
785 
786  out_ray.pBase = ray_origin;
787  out_ray.director[0]=pointing_dir.x;
788  out_ray.director[1]=pointing_dir.y;
789  out_ray.director[2]=pointing_dir.z;
790  }
791  else
792  {
793  // Perspective camera
794  // -------------------------------
795 
796  // JL: This can derived from: http://www.opengl.org/sdk/docs/man/xhtml/gluPerspective.xml
797  // where one arrives to:
798  // tan(FOVx/2) = ASPECT_RATIO * tan(FOVy/2)
799  //
800  const double FOVy = DEG2RAD(m_lastProjMat.FOV);
801  const double FOVx = 2.0*atan(ASPECT*tan(FOVy*0.5));
802 
803  const double ang_horz = (-0.5 + x_coord/m_lastProjMat.viewport_width)* FOVx;
804  const double ang_vert = -(-0.5 + y_coord/m_lastProjMat.viewport_height)* FOVy;
805 
806  const TPoint3D l(tan(ang_horz),tan(ang_vert),1.0); // Point in camera local reference frame
807 
808  const TPoint3D ray_director(
809  l.x * cam_x_3d.x + l.y * cam_up_3d.x + l.z * pointing_dir.x,
810  l.x * cam_x_3d.y + l.y * cam_up_3d.y + l.z * pointing_dir.y,
811  l.x * cam_x_3d.z + l.y * cam_up_3d.z + l.z * pointing_dir.z
812  );
813 
814  // Set out ray:
815  out_ray.pBase = m_lastProjMat.eye;
816  out_ray.director[0]=ray_director.x;
817  out_ray.director[1]=ray_director.y;
818  out_ray.director[2]=ray_director.z;
819 
820  } // end projective
821 
822  // Camera pose:
823  if (out_cameraPose)
824  {
826  M.get_unsafe(0,0) = cam_x_3d.x;
827  M.get_unsafe(1,0) = cam_x_3d.y;
828  M.get_unsafe(2,0) = cam_x_3d.z;
829  M.get_unsafe(3,0) = 0;
830 
831  M.get_unsafe(0,1) = cam_up_3d.x;
832  M.get_unsafe(1,1) = cam_up_3d.y;
833  M.get_unsafe(2,1) = cam_up_3d.z;
834  M.get_unsafe(3,1) = 0;
835 
836  M.get_unsafe(0,2) = pointing_dir.x;
837  M.get_unsafe(1,2) = pointing_dir.y;
838  M.get_unsafe(2,2) = pointing_dir.z;
839  M.get_unsafe(3,2) = 0;
840 
841  M.get_unsafe(0,3) = m_lastProjMat.eye.x;
842  M.get_unsafe(1,3) = m_lastProjMat.eye.y;
843  M.get_unsafe(2,3) = m_lastProjMat.eye.z;
844  M.get_unsafe(3,3) = 1;
845 
846  *out_cameraPose = CPose3D(M);
847  }
848 }
849 
850 MRPT_TODO("Implement a setCurrentCameraFromPose() method")
851 
852 void COpenGLViewport::getCurrentCameraPose( mrpt::poses::CPose3D &out_cameraPose ) const
853 {
855  get3DRayForPixelCoord(0,0,dum, &out_cameraPose);
856 }
857 
858 
859 /** Resets the viewport to a normal 3D viewport \sa setCloneView, setImageView */
861 {
862  // If this was a m_isImageView, remove the quad object:
864  m_imageview_img.clear();
865 
866  m_isCloned=false;
867  m_isClonedCamera=false;
868  m_isImageView=false;
869 }
870 
872 {
874 }
876 {
878 }
879 
881 {
882  // If this is the first time, we have to create the quad object:
885  m_isImageView = true;
886 
887  // Update texture image:
888  mrpt::utils::CImage *my_img = m_imageview_img.pointer();
889 
890  if (!is_fast)
891  *my_img = img;
892  else my_img->copyFastFrom(* const_cast<mrpt::utils::CImage*>(&img));
893 }
894 
895 
896 /** Evaluates the bounding box of this object (including possible children) in the coordinate frame of the object parent. */
898 {
899  bb_min = TPoint3D( std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
900  bb_max = TPoint3D(-std::numeric_limits<double>::max(),-std::numeric_limits<double>::max(),-std::numeric_limits<double>::max() );
901 
902  for (CListOpenGLObjects::const_iterator it=m_objects.begin();it!=m_objects.end();++it)
903  {
904  TPoint3D child_bbmin( std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
905  TPoint3D child_bbmax(-std::numeric_limits<double>::max(),-std::numeric_limits<double>::max(),-std::numeric_limits<double>::max() );
906  (*it)->getBoundingBox(child_bbmin, child_bbmax);
907 
908  keep_min(bb_min.x, child_bbmin.x);
909  keep_min(bb_min.y, child_bbmin.y);
910  keep_min(bb_min.z, child_bbmin.z);
911 
912  keep_max(bb_max.x, child_bbmax.x);
913  keep_max(bb_max.y, child_bbmax.y);
914  keep_max(bb_max.z, child_bbmax.z);
915  }
916 
917 }
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:113
#define GL_BGR
Definition: glew.h:1144
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.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
GLAPI void GLAPIENTRY glMatrixMode(GLenum mode)
double GLdouble
Definition: glew.h:215
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
A base class for all OpenGL objects with loadable textures.
mrpt::utils::CImagePtr m_imageview_img
The image to display, after calling setImageView()
bool m_isTransparent
Whether to clear color buffer.
void removeObject(const CRenderizablePtr &obj)
Removes the given object from the scene (it also deletes the object to free its memory).
A set of object, which are referenced to the coordinates framework established in this object...
Definition: CSetOfObjects.h:32
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:39
#define GL_STENCIL_BUFFER_BIT
Definition: glew.h:257
A class for storing images as grayscale or RGB bitmaps.
Definition: CImage.h:101
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define GL_MODELVIEW
Definition: glew.h:606
#define GL_FRONT_AND_BACK
Definition: glew.h:317
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:167
#define THROW_EXCEPTION(msg)
std::vector< CLight > m_lights
#define THROW_EXCEPTION_FMT(_FORMAT_STRING,...)
GLenum GLsizei n
Definition: glext.h:4618
Scalar * iterator
Definition: eigen_plugins.h:23
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:44
std::deque< CRenderizablePtr > CListOpenGLObjects
A list of objects pointers, automatically managing memory free at destructor, and managing copies cor...
Definition: CRenderizable.h:33
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:298
#define GL_PERSPECTIVE_CORRECTION_HINT
Definition: glew.h:446
const Scalar * const_iterator
Definition: eigen_plugins.h:24
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
Definition: CObservable.h:52
double z
X,Y,Z coordinates.
#define GL_COLOR_MATERIAL
Definition: glew.h:388
mrpt::utils::TColorf m_background_color
used only if m_custom_backgb_color
#define GL_DEPTH_TEST
Definition: glew.h:397
#define GL_SMOOTH
Definition: glew.h:631
mrpt::math::TPoint3D eye
The camera is here.
GLdouble s
Definition: glext.h:3602
GLAPI void GLAPIENTRY glShadeModel(GLenum mode)
#define GL_LIGHTING
Definition: glew.h:381
GLsizei GLsizei GLuint * obj
Definition: glext.h:3902
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:3513
size_t viewport_height
In pixels. This may be smaller than the total render window.
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:616
Each of the possible lights of a 3D scene.
Definition: CLight.h:28
#define MRPT_TODO(x)
bool m_isClonedCamera
Set by setCloneCamera.
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:49
GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params)
#define GL_DEPTH_BUFFER_BIT
Definition: glew.h:255
#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:96
#define GL_COLOR_BUFFER_BIT
Definition: glew.h:261
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:38
void insert(const CRenderizablePtr &newObject)
Insert a new object into the list.
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:439
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:242
virtual const mrpt::utils::TRuntimeClassId * GetRuntimeClass() const
Returns information about the class of an object in runtime.
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:3645
GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode)
GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor)
#define GL_PROJECTION
Definition: glew.h:607
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
An object for reading objects from a stream, intended for being used in STL algorithms.
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
#define GL_RGB
Definition: glew.h:619
A set of utility objects for metaprogramming with STL algorithms.
mrpt::math::TPoint3D up
Up vector of the camera.
TLastProjectiveMatrixInfo m_lastProjMat
Info updated with each "render()" and used in "get3DRayForPixelCoord".
int version
Definition: mrpt_jpeglib.h:898
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:3919
#define GL_LINE_LOOP
Definition: glew.h:270
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:176
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.
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) ...
#define CLASS_ID_NAMESPACE(class_name, namespaceName)
Access to runtime class ID for a defined class name.
Definition: CObject.h:86
unsigned int GLenum
Definition: glew.h:202
#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:477
#define ASSERTDEB_(f)
Defines an assertion mechanism - only when compiled in debug.
static CImagePtr Create()
void clear()
Delete all internal obejcts.
#define GL_NICEST
Definition: glew.h:565
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:171
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:72
void setImageView(const mrpt::utils::CImage &img)
Set this viewport into "image view"-mode, where an image is efficiently drawn (fitting the viewport a...
float elev
Camera elev & azimuth, in radians.
#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:93
An event sent by an mrpt::opengl::COpenGLViewport after calling the scene OpenGL drawing primitives a...
#define GL_SCISSOR_TEST
Definition: glew.h:436
GLAPI void GLAPIENTRY glClear(GLbitfield mask)
GLuint in
Definition: glext.h:6301
The namespace for 3D scene representation and rendering.
GLuint const GLchar * name
Definition: glext.h:3891
This class allows the user to create, load, save, and render 3D scenes using OpenGL primitives...
Definition: COpenGLScene.h:49
#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:41
GLAPI void GLAPIENTRY glEnd(void)
std::string m_clonedViewport
Only if m_isCloned=true.
void get3DRayForPixelCoord(const double x_coord, const double y_coord, mrpt::math::TLine3D &out_ray, mrpt::poses::CPose3D *out_cameraPose=NULL) const
Compute the 3D ray corresponding to a given pixel; this can be used to allow the user to pick and sel...
#define GL_POLYGON_SMOOTH_HINT
Definition: glew.h:449
GLenum GLint GLint y
Definition: glext.h:3516
#define GL_LIGHT_MODEL_TWO_SIDE
Definition: glew.h:383
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 NULL (an empty smart pointer)...
double m_clip_max
The min/max clip depth distances (default: 0.1 - 10000)
int GLint
Definition: glew.h:205
CRenderizablePtr getByName(const std::string &str)
Returns the first object with a given name, or NULL if not found.
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:3516
void getRotationMatrix(mrpt::math::CMatrixDouble33 &ROT) const
Get the 3x3 rotation matrix.
Definition: CPose3D.h:176
Lightweight 3D point.
void OPENGL_IMPEXP renderSetOfObjects(const mrpt::opengl::CListOpenGLObjects &objs)
For each object in the list:
Definition: gl_utils.cpp:33
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
Definition: CCamera.h:31
const char * className
Definition: CObject.h:38
GLenum GLsizei GLsizei height
Definition: glext.h:3523
unsigned __int32 uint32_t
Definition: rptypes.h:49
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:604
double m_view_height
The viewport position [0,1].
#define GL_ACCUM_BUFFER_BIT
Definition: glew.h:256
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.
GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y)
#define GL_LUMINANCE
Definition: glew.h:621
utils::safe_ptr< COpenGLScene > m_parent
The scene that contains this viewport.
#define GL_TRUE
Definition: glew.h:289
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:49
bool m_isCloned
Set by setCloneView.
3D line, represented by a base point and a director vector.
#define GL_FASTEST
Definition: glew.h:564



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019