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" 59 class CMyGLCanvas_DisplayWindow3D :
public mrpt::gui::CWxGLCanvasBase
62 CMyGLCanvas_DisplayWindow3D(
64 const wxPoint& pos = wxDefaultPosition,
65 const wxSize&
size = wxDefaultSize,
long style = 0,
66 const wxString&
name = _T(
"CMyGLCanvas_DisplayWindow3D"));
68 ~CMyGLCanvas_DisplayWindow3D()
override;
78 void render_text_messages_public(
const int w,
const int h)
const 80 render_text_messages(
w, h);
83 THubClass m_text_msgs;
85 void OnCharCustom(wxKeyEvent& event)
override;
86 void OnMouseDown(wxMouseEvent& event);
87 void OnMouseMove(wxMouseEvent& event);
89 void OnPreRender()
override;
90 void OnPostRender()
override;
91 void OnPostRenderSwapBuffers(
double At, wxPaintDC& dc)
override;
93 static void display3D_processKeyEvent(
98 CMyGLCanvas_DisplayWindow3D::CMyGLCanvas_DisplayWindow3D(
100 const wxPoint& pos,
const wxSize&
size,
long style,
const wxString&
name)
101 : CWxGLCanvasBase(parent,
id, pos,
size, style,
name), m_win3D(win3D)
103 this->Bind(wxEVT_CHAR, &CMyGLCanvas_DisplayWindow3D::OnCharCustom,
this);
105 wxEVT_CHAR_HOOK, &CMyGLCanvas_DisplayWindow3D::OnCharCustom,
this);
107 wxEVT_LEFT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown,
this);
109 wxEVT_RIGHT_DOWN, &CMyGLCanvas_DisplayWindow3D::OnMouseDown,
this);
110 this->Bind(wxEVT_MOTION, &CMyGLCanvas_DisplayWindow3D::OnMouseMove,
this);
113 void CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
124 cout <<
"[CDisplayWindow3D] Switching fullscreen...\n";
128 win->ShowFullScreen(!
win->IsFullScreen());
139 const int code = ev.GetKeyCode();
158 void CMyGLCanvas_DisplayWindow3D::OnCharCustom(wxKeyEvent& ev)
160 CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(m_win3D, ev);
163 void CMyGLCanvas_DisplayWindow3D::OnMouseDown(wxMouseEvent& event)
172 event.LeftDown(),
event.RightDown()));
182 void CMyGLCanvas_DisplayWindow3D::OnMouseMove(wxMouseEvent& event)
191 event.LeftDown(),
event.RightDown()));
201 CMyGLCanvas_DisplayWindow3D::~CMyGLCanvas_DisplayWindow3D()
203 getOpenGLSceneRef().reset();
207 void CMyGLCanvas_DisplayWindow3D::OnPreRender()
209 auto& openGLSceneRef = getOpenGLSceneRef();
210 if (openGLSceneRef) openGLSceneRef.reset();
213 if (ptrScene) openGLSceneRef = ptrScene;
216 void CMyGLCanvas_DisplayWindow3D::OnPostRender()
219 getOpenGLSceneRef().reset();
224 this->GetSize(&
w, &h);
226 m_text_msgs.render_text_messages_public(
w, h);
229 void CMyGLCanvas_DisplayWindow3D::OnPostRenderSwapBuffers(
230 double At, wxPaintDC& dc)
251 frame->flipVertical();
253 if (!grabFile.empty())
255 frame->saveToFile(grabFile);
262 std::lock_guard<std::mutex> lock(
271 #endif // Wx + OpenGL 273 #if MRPT_HAS_WXWIDGETS 284 const
std::
string& caption, wxSize initialSize)
285 : m_win3D(win3D), m_mainFrame(parent)
287 #if MRPT_HAS_OPENGL_GLUT 290 parent,
id, caption.c_str(), wxDefaultPosition, initialSize,
291 wxDEFAULT_FRAME_STYLE, _T(
"id"));
298 m_canvas =
new CMyGLCanvas_DisplayWindow3D(
299 win3D,
this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
332 bool allow_close =
true;
342 if (!allow_close)
return;
363 _(
"3D Scene viewer\n Class gui::CDisplayWindow3D\n MRPT C++ library"),
369 #if MRPT_HAS_OPENGL_GLUT 370 CMyGLCanvas_DisplayWindow3D::display3D_processKeyEvent(
m_win3D, ev);
376 #if MRPT_HAS_OPENGL_GLUT 383 m_win3D, event.GetSize().GetWidth(),
384 event.GetSize().GetHeight()));
396 #if MRPT_HAS_OPENGL_GLUT 397 m_canvas->m_text_msgs.clearTextMessages();
402 const double x_frac,
const double y_frac,
const std::string& text,
406 #if MRPT_HAS_OPENGL_GLUT 407 m_canvas->m_text_msgs.addTextMessage(
408 x_frac, y_frac, text,
color, unique_index, font);
413 const double x_frac,
const double y_frac,
const std::string& text,
416 const size_t unique_index,
const double font_spacing,
417 const double font_kerning,
const bool has_shadow,
420 #if MRPT_HAS_OPENGL_GLUT 421 m_canvas->m_text_msgs.addTextMessage(
422 x_frac, y_frac, text,
color, font_name, font_size, font_style,
423 unique_index, font_spacing, font_kerning, has_shadow, shadow_color);
427 #endif // MRPT_HAS_WXWIDGETS 433 const std::string& windowCaption,
unsigned int initialWindowWidth,
434 unsigned int initialWindowHeight)
436 m_lastFullScreen(
mrpt::system::
now())
443 const std::string& windowCaption,
unsigned int initialWindowWidth,
444 unsigned int initialWindowHeight)
446 return std::make_shared<CDisplayWindow3D>(
447 windowCaption, initialWindowWidth, initialWindowHeight);
466 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 469 cerr <<
"[CDisplayWindow3D::setPos] Window closed!: " <<
m_caption 492 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 495 cerr <<
"[CDisplayWindow3D::setPos] Window closed!: " <<
m_caption 518 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 521 cerr <<
"[CDisplayWindow3D::setWindowTitle] Window closed!: " 555 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 576 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 578 if (
win)
win->m_canvas->setElevationDegrees(deg);
586 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 588 if (
win)
win->m_canvas->setUseCameraFromScene(useIt);
599 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 601 if (
win)
win->m_canvas->setAzimuthDegrees(deg);
612 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 616 win->m_canvas->setCameraPointing(
x,
y,
z);
630 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 632 if (
win)
win->m_canvas->setZoomDistance(zoom);
643 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 645 if (
win)
win->m_canvas->setCameraProjective(isProjective);
660 gl_view->getViewportClipDistances(m, M);
661 gl_view->setViewportClipDistances(new_min, M);
674 gl_view->getViewportClipDistances(m, M);
675 gl_view->setViewportClipDistances(m, new_max);
682 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 684 if (
win)
return win->m_canvas->cameraFOV();
691 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 693 if (
win)
win->m_canvas->setCameraFOV(
v);
702 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 704 return win ?
win->m_canvas->getElevationDegrees() : 0;
715 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 717 return win ?
win->m_canvas->getAzimuthDegrees() : 0;
727 float&
x,
float&
y,
float&
z)
const 729 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 733 x =
win->m_canvas->getCameraPointingX();
734 y =
win->m_canvas->getCameraPointingY();
735 z =
win->m_canvas->getCameraPointingZ();
751 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 753 return win ?
win->m_canvas->getZoomDistance() : 0;
764 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 766 return win ?
win->m_canvas->isCameraProjective() :
true;
777 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 779 if (!
win)
return false;
780 win->m_canvas->getLastMousePosition(
x,
y);
798 m_3Dscene->getViewport(
"main")->get3DRayForPixelCoord(
x,
y, ray);
811 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 814 win->m_canvas->SetCursor(
815 *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
887 const double x_frac,
const double y_frac,
const std::string& text,
891 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 904 REQ->vector_x[0] = x_frac;
905 REQ->vector_x[1] = y_frac;
906 REQ->vector_x[2] =
color.R;
907 REQ->vector_x[3] =
color.G;
908 REQ->vector_x[4] =
color.B;
910 REQ->y = int(unique_index);
928 const double x_frac,
const double y_frac,
const std::string& text,
931 const size_t unique_index,
const double font_spacing,
932 const double font_kerning,
const bool draw_shadow,
935 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 945 REQ->plotName = font_name;
947 REQ->vector_x[0] = x_frac;
948 REQ->vector_x[1] = y_frac;
949 REQ->vector_x[2] =
color.R;
950 REQ->vector_x[3] =
color.G;
951 REQ->vector_x[4] =
color.B;
952 REQ->vector_x[5] = font_size;
953 REQ->vector_x[6] = font_spacing;
954 REQ->vector_x[7] = font_kerning;
955 REQ->vector_x[8] = draw_shadow ? 1 : 0;
956 REQ->vector_x[9] = shadow_color.
R;
957 REQ->vector_x[10] = shadow_color.
G;
958 REQ->vector_x[11] = shadow_color.
B;
960 REQ->x = int(font_style);
961 REQ->y = int(unique_index);
986 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 1001 const double ALPHA = 0.99;
1025 view->setImageView(
img);
1033 view->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.
GLAPI void GLAPIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
An event sent by a window upon a mouse click, giving the (x,y) pixel coordinates. ...
std::recursive_mutex m_csAccess3DScene
Critical section for accesing m_3Dscene.
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.
void addTextMessage(const double x_frac, const double y_frac, const std::string &text, const mrpt::img::TColorf &color, const size_t unique_index, const mrpt::opengl::TOpenGLFont font)
#define THROW_EXCEPTION(msg)
#define GL_PACK_ALIGNMENT
mrpt::void_ptr_noncopy m_hwnd
The window handle.
std::string m_caption
The caption of the window.
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.
Keeps a list of text messages which can be rendered to OpenGL contexts by graphic classes...
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()
GLAPI void GLAPIENTRY glReadBuffer(GLenum mode)
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.
GLubyte GLubyte GLubyte GLubyte w
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: ...
~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.
TOpenGLFont
Existing fonts for 2D texts in mrpt::opengl methods.
void setMaxRange(double new_max)
Changes the camera max clip range (z) (used for gluPerspective.
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...
TOpenGLFontStyle
Different style for vectorized font rendering.
bool isOpen()
Returns false if the user has already closed the window.
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
GLsizei const GLchar ** string
mrptKeyModifier keyEventToMrptKeyModifier(const wxKeyEvent &ev)
Extracts the key modifiers from a wxKeyEvent.
volatile mrptKeyModifier m_keyPushedModifier
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)
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::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
#define GL_PACK_ROW_LENGTH
volatile bool m_keyPushed
A RGB color - floats in the range [0,1].
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.
GLuint const GLchar * name
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.
void setMinRange(double new_min)
Changes the camera min clip range (z) (used for gluPerspective).
bool getLastWindowImage(mrpt::img::CImage &out_img) const
Retrieve the last captured image from the window.
void addTextMessage(const double x, const double y, const std::string &text, const mrpt::img::TColorf &color=mrpt::img::TColorf(1.0, 1.0, 1.0), const size_t unique_index=0, const mrpt::opengl::TOpenGLFont font=mrpt::opengl::MRPT_GLUT_BITMAP_TIMES_ROMAN_24)
Add 2D text messages overlapped to the 3D rendered scene.
mrpt::img::CImage::Ptr m_last_captured_img
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
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.
volatile int m_keyPushedCode
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...
GLenum GLsizei GLsizei height
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.
void clearTextMessages()
Clear all text messages created with addTextMessage().
std::mutex m_last_captured_img_cs
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
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.
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.
CMyGLCanvas_DisplayWindow3D * m_canvas
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.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
float getCameraElevationDeg() const
Get camera parameters programmatically.