12 #include <mrpt/config.h>    21 #if MRPT_HAS_OPENGL_GLUT    28 #include <GLUT/glut.h>    29 #include <OpenGL/gl.h>    30 #include <OpenGL/glu.h>    35 #ifdef HAVE_FREEGLUT_EXT_H    36 #include <GL/freeglut_ext.h>    48 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT    51 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets"    58 class CMyGLCanvas_DisplayWindow3D : 
public mrpt::gui::CWxGLCanvasBase
    61     CMyGLCanvas_DisplayWindow3D(
    63         const wxPoint& pos = wxDefaultPosition,
    64         const wxSize& 
size = wxDefaultSize, 
long style = 0,
    65         const wxString& name = _T(
"CMyGLCanvas_DisplayWindow3D"));
    67     ~CMyGLCanvas_DisplayWindow3D() 
override;
    71     void OnCharCustom(wxKeyEvent& event) 
override;
    72     void OnMouseDown(wxMouseEvent& event);
    73     void OnMouseMove(wxMouseEvent& event);
    75     void OnPreRender() 
override;
    76     void OnPostRender() 
override;
    77     void OnPostRenderSwapBuffers(
double At, wxPaintDC& dc) 
override;
    79     static void display3D_processKeyEvent(
    84 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
    86     const wxPoint& pos, 
const wxSize& 
size, 
long style, 
const wxString& name)
    87     : CWxGLCanvasBase(parent, id, pos, 
size, style, name), m_win3D(win3D)
    89     this->Bind(wxEVT_CHAR, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, 
this);
    91         wxEVT_CHAR_HOOK, &CMyGLCanvas_DisplayWindow3D::OnCharCustom, 
this);
    93         wxEVT_LEFT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, 
this);
    95         wxEVT_RIGHT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown, 
this);
    96     this->Bind(wxEVT_MOTION, &CMyGLCanvas_DisplayWindow3D::OnMouseMove, 
this);
    99 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
   110                 cout << 
"[CDisplayWindow3D] Switching fullscreen...\n";
   114                     win->ShowFullScreen(!
win->IsFullScreen());
   125         const int code = ev.GetKeyCode();
   144 void CMyGLCanvas_DisplayWindow3D::OnCharCustom(wxKeyEvent& ev)
   146     CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
   149 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
   158                 event.LeftDown(), 
event.RightDown()));
   168 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
   177                 event.LeftDown(), 
event.RightDown()));
   187 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
   190     if (getOpenGLSceneRef()) getOpenGLSceneRef()->unloadShaders();
   193     auto& scene = getOpenGLSceneRef();
   194     if (scene) scene->freeOpenGLResources();
   197 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
   199     auto& openGLSceneRef = getOpenGLSceneRef();
   200     if (openGLSceneRef) openGLSceneRef.reset();
   203     if (ptrScene) openGLSceneRef = ptrScene;
   206 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
   211 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(
   212     double At, wxPaintDC& dc)
   228         glPixelStorei(GL_PACK_ALIGNMENT, 1);
   229         glPixelStorei(GL_PACK_ROW_LENGTH, 0);
   231         glReadBuffer(GL_FRONT);
   232         glReadPixels(0, 0, w, h, GL_BGR_EXT, GL_UNSIGNED_BYTE, (*frame)(0, 0));
   233         frame->flipVertical();
   235         if (!grabFile.empty())
   237             frame->saveToFile(grabFile);
   244                 std::lock_guard<std::mutex> lock(
   253 #endif  // Wx + OpenGL   255 #if MRPT_HAS_WXWIDGETS   266     const 
std::
string& caption, wxSize initialSize)
   267     : m_win3D(win3D), m_mainFrame(parent)
   269 #if MRPT_HAS_OPENGL_GLUT   272         parent, 
id, caption.c_str(), wxDefaultPosition, initialSize,
   273         wxDEFAULT_FRAME_STYLE, _T(
"id"));
   280     m_canvas = 
new CMyGLCanvas_DisplayWindow3D(
   281         win3D, 
this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
   310     bool allow_close = 
true;
   320     if (!allow_close) 
return;  
   341         _(
"3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),
   347 #if MRPT_HAS_OPENGL_GLUT   348     CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
m_win3D, ev);
   354 #if MRPT_HAS_OPENGL_GLUT   361                 m_win3D, event.GetSize().GetWidth(),
   362                 event.GetSize().GetHeight()));
   372 #endif  // MRPT_HAS_WXWIDGETS   378     const std::string& windowCaption, 
unsigned int initialWindowWidth,
   379     unsigned int initialWindowHeight)
   380     : 
CBaseGUIWindow(static_cast<void*>(this), 300, 399, windowCaption),
   381       m_lastFullScreen(
mrpt::system::
now())
   388     const std::string& windowCaption, 
unsigned int initialWindowWidth,
   389     unsigned int initialWindowHeight)
   391     return std::make_shared<CDisplayWindow3D>(
   392         windowCaption, initialWindowWidth, initialWindowHeight);
   407             << 
"[~CDisplayWindow3D] Warning: Timeout acquiring mutex lock.\n";
   414     [[maybe_unused]] 
unsigned int width, [[maybe_unused]] 
unsigned int height)
   416 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   419         cerr << 
"[CDisplayWindow3D::setPos] Window closed!: " << 
m_caption   439 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   442         cerr << 
"[CDisplayWindow3D::setPos] Window closed!: " << 
m_caption   462 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   465         cerr << 
"[CDisplayWindow3D::setWindowTitle] Window closed!: "   489 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   510 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   512     if (
win) 
win->m_canvas->setElevationDegrees(deg);
   518 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   520     if (
win) 
win->m_canvas->setUseCameraFromScene(useIt);
   529 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   531     if (
win) 
win->m_canvas->setAzimuthDegrees(deg);
   539     [[maybe_unused]] 
float x, [[maybe_unused]] 
float y,
   540     [[maybe_unused]] 
float z)
   542 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   546         win->m_canvas->setCameraPointing(x, y, z);
   556 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   558     if (
win) 
win->m_canvas->setZoomDistance(zoom);
   567 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   569     if (
win) 
win->m_canvas->setCameraProjective(isProjective);
   582             gl_view->getViewportClipDistances(m, M);
   583             gl_view->setViewportClipDistances(new_min, M);
   596             gl_view->getViewportClipDistances(m, M);
   597             gl_view->setViewportClipDistances(m, new_max);
   604 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   606     if (
win) 
return win->m_canvas->cameraFOV();
   613 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   615     if (
win) 
win->m_canvas->setCameraFOV(v);
   624 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   626     return win ? 
win->m_canvas->getElevationDegrees() : 0;
   637 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   639     return win ? 
win->m_canvas->getAzimuthDegrees() : 0;
   649     [[maybe_unused]] 
float& x, [[maybe_unused]] 
float& y,
   650     [[maybe_unused]] 
float& z)
 const   652 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   656         x = 
win->m_canvas->getCameraPointingX();
   657         y = 
win->m_canvas->getCameraPointingY();
   658         z = 
win->m_canvas->getCameraPointingZ();
   670 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   672     return win ? 
win->m_canvas->getZoomDistance() : 0;
   683 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   685     return win ? 
win->m_canvas->isCameraProjective() : 
true;
   695     [[maybe_unused]] 
int& x, [[maybe_unused]] 
int& y)
 const   697 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   699     if (!
win) 
return false;
   700     win->m_canvas->getLastMousePosition(x, y);
   716         m_3Dscene->getViewport(
"main")->get3DRayForPixelCoord(x, y, ray);
   728 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT   731     win->m_canvas->SetCursor(
   732         *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
   800     const double ALPHA = 0.99;
   821     m_3Dscene->getViewport(
"main")->setImageView(img);
   827     m_3Dscene->getViewport(
"main")->setImageView(std::move(img));
 An event sent by a window upon resize. 
 
bool getLastMousePosition(int &x, int &y) const override
Gets the last x,y pixel coordinates of the mouse. 
 
float getCameraAzimuthDeg() const
Get camera parameters programmatically. 
 
bool getLastMousePositionRay(mrpt::math::TLine3D &ray) const
Gets the 3D ray for the direction line of the pixel where the mouse cursor is at. ...
 
static void pushPendingWxRequest(TRequestToWxMainThread *data)
Thread-safe method to insert a new pending request (The memory must be dinamically allocated with "ne...
 
An event sent by a CDisplayWindow3D window when an image is saved after enabling this feature with CD...
 
void OnMenuAbout(wxCommandEvent &event)
 
void unlockAccess3DScene()
Unlocks the access to the internal 3D scene. 
 
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
 
std::atomic_int m_keyPushedCode
 
void OnClose(wxCloseEvent &event)
 
mrpt::gui::CDisplayWindow3D * source3D
Only one of source* can be non-nullptr, indicating the class that generated the request. 
 
mrpt::img::CImage::Ptr getLastWindowImagePtr() const
Retrieve the last captured image from the window, as a smart pointer. 
 
The data structure for each inter-thread request: 
 
CDisplayWindow3DLocker(CDisplayWindow3D &win, mrpt::opengl::COpenGLScene::Ptr &out_scene_ptr)
Acquires the lock of the 3D scene of the referenced window, and returns a copy of the smart pointer t...
 
bool isCapturingImgs() const
 
void setWindowTitle(const std::string &str) override
Changes the window title. 
 
#define THROW_EXCEPTION(msg)
 
mrpt::void_ptr_noncopy m_hwnd
The window handle. 
 
std::string std::string format(std::string_view fmt, ARGS &&... args)
 
std::string m_caption
The caption of the window. 
 
size_t size(const MATRIXLIKE &m, const int dim)
 
mrpt::opengl::COpenGLScene::Ptr & get3DSceneAndLock()
Gets a reference to the smart shared pointer that holds the internal scene (carefuly read introductio...
 
void grabImagesStart(const std::string &grab_imgs_prefix=std::string("video_"))
Start to save rendered images to disk. 
 
static int notifyWindowCreation()
Atomically increments the number of windows created with the main frame as parent. 
 
void resize(unsigned int width, unsigned int height) override
Resizes the window, stretching the image to fit into the display area. 
 
void setCameraPointingToPoint(float x, float y, float z)
Changes the camera parameters programmatically. 
 
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime. 
 
void OnMenuClose(wxCommandEvent &event)
 
static wxBitmap getMRPTDefaultIcon()
 
~CDisplayWindow3DLocker()
 
void setMaxRange(float new_max)
Changes the camera max clip range (z) (used for gluPerspective. 
 
CDisplayWindow3D * m_win3D
 
static CDisplayWindow3D::Ptr Create(const std::string &windowCaption, unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Class factory returning a smart pointer. 
 
void internal_emitGrabImageEvent(const std::string &fil)
called by CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers 
 
void setCameraProjective(bool isProjective)
Sets the camera as projective, or orthogonal. 
 
float getCameraZoom() const
Get camera parameters programmatically. 
 
void OnResize(wxSizeEvent &event)
 
An event sent by a window upon when it's about to be closed, either manually by the user or programma...
 
An event sent by a window when the mouse is moved over it. 
 
void OnChar(wxKeyEvent &event)
 
void notifyChildWindowDestruction()
Called by wx main thread to set m_hwnd to NULL. 
 
mrpt::opengl::COpenGLViewport::Ptr getDefaultViewport()
A short cut for getting the "main" viewport of the scene object, it is equivalent to: ...
 
void setMinRange(float new_min)
Changes the camera min clip range (z) (used for gluPerspective). 
 
~C3DWindowDialog() override
 
This base provides a set of functions for maths stuff. 
 
void getCameraPointingToPoint(float &x, float &y, float &z) const
Get camera parameters programmatically. 
 
void setPos(int x, int y) override
Changes the position of the window on the screen. 
 
~CDisplayWindow3D() override
Destructor. 
 
std::string grabImageGetNextFile()
Increments by one the image counter and return the next image file name (Users normally don't want to...
 
bool isOpen()
Returns false if the user has already closed the window. 
 
std::atomic< mrptKeyModifier > m_keyPushedModifier
 
A pair (x,y) of pixel coordinates (integer resolution). 
 
unsigned int m_grab_imgs_idx
 
std::string m_grab_imgs_prefix
 
An event sent by a window upon a char pressed by the user. 
 
mrpt::gui::CDisplayWindow3D::Ptr win
 
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent. 
 
void forceRepaint()
Repaints the window. 
 
void setImageView(const mrpt::img::CImage &img)
Set the "main" viewport into "image view"-mode, where an image is efficiently drawn (fitting the view...
 
float getFOV() const
Return the camera field of view (in degrees) (used for gluPerspective) 
 
std::recursive_timed_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene. 
 
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries. 
 
mrpt::system::TTimeStamp m_lastFullScreen
 
This class implements the GUI thread required for the wxWidgets-based GUI. 
 
void grabImagesStop()
Stops image grabbing started by grabImagesStart. 
 
std::atomic_bool m_keyPushed
 
bool isCameraProjective() const
Sets the camera as projective, or orthogonal. 
 
bool hasSubscribers() const
Can be called by a derived class before preparing an event for publishing with publishEvent to determ...
 
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...
 
void setCameraZoom(float zoom)
Changes the camera parameters programmatically. 
 
The namespace for 3D scene representation and rendering. 
 
void setCursorCross(bool cursorIsCross) override
Set cursor style to default (cursorIsCross=false) or to a cross (cursorIsCross=true) ...
 
void destroyWxWindow()
Must be called by child classes in their destructors. 
 
bool getLastWindowImage(mrpt::img::CImage &out_img) const
Retrieve the last captured image from the window. 
 
mrpt::img::CImage::Ptr m_last_captured_img
 
Classes for creating GUI windows for 2D and 3D visualization. 
 
void createWxWindow(unsigned int initialWidth, unsigned int initialHeight)
Must be called by child classes just within the constructor. 
 
void captureImagesStop()
Stop image grabbing. 
 
CDisplayWindow3D(const std::string &windowCaption=std::string(), unsigned int initialWindowWidth=400, unsigned int initialWindowHeight=300)
Constructor. 
 
double timeDifference(const mrpt::system::TTimeStamp t_first, const mrpt::system::TTimeStamp t_later)
Returns the time difference from t1 to t2 (positive if t2 is posterior to t1), in seconds...
 
void internal_setRenderingFPS(double FPS)
Set the rendering FPS (users don't call this, the method is for internal MRPT objects only) ...
 
std::promise< void > m_windowDestroyed
This semaphore will be signaled when the wx window is destroyed. 
 
std::mutex m_last_captured_img_cs
 
mrpt::opengl::COpenGLScene::Ptr m_3Dscene
Internal OpenGL object (see general discussion in about usage of this object) 
 
The base class for GUI window classes based on wxWidgets. 
 
void setFOV(float v)
Changes the camera field of view (in degrees) (used for gluPerspective). 
 
static int notifyWindowDestruction()
Atomically decrements the number of windows created with the main frame as parent. 
 
void setCameraAzimuthDeg(float deg)
Changes the camera parameters programmatically. 
 
A class for storing images as grayscale or RGB bitmaps. 
 
void setCameraElevationDeg(float deg)
Changes the camera parameters programmatically. 
 
void useCameraFromScene(bool useIt=true)
If set to true (default = false), the mouse-based scene navigation will be disabled and the camera po...
 
A graphical user interface (GUI) for efficiently rendering 3D scenes in real-time. 
 
void captureImagesStart()
Enables the grabbing of CImage objects from screenshots of the window. 
 
3D line, represented by a base point and a director vector. 
 
float getCameraElevationDeg() const
Get camera parameters programmatically.