17 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT 25 float CMyGLCanvasBase::SENSIBILITY_DEG_PER_PIXEL = 0.1f;
27 #if MRPT_HAS_OPENGL_GLUT 28 #ifdef MRPT_OS_WINDOWS 34 #include <OpenGL/gl.h> 35 #include <OpenGL/glu.h> 36 #include <GLUT/glut.h> 41 #ifdef HAVE_FREEGLUT_EXT_H 42 #include <GL/freeglut_ext.h> 49 #error "OpenGL required: set wxUSE_GLCANVAS to 1 and rebuild wxWidgets" 56 BEGIN_EVENT_TABLE(CMyGLCanvasBase, wxGLCanvas)
57 EVT_SIZE(CMyGLCanvasBase::OnSize)
58 EVT_PAINT(CMyGLCanvasBase::OnPaint)
59 EVT_ERASE_BACKGROUND(CMyGLCanvasBase::OnEraseBackground)
60 EVT_ENTER_WINDOW( CMyGLCanvasBase::OnEnterWindow )
61 EVT_WINDOW_CREATE( CMyGLCanvasBase::OnWindowCreation )
64 void CMyGLCanvasBase::OnWindowCreation(wxWindowCreateEvent &ev)
66 if (!m_gl_context) m_gl_context=
new wxGLContext(
this);
69 void CMyGLCanvasBase::OnMouseDown(wxMouseEvent& event)
71 mouseClickX =
event.GetX();
72 mouseClickY =
event.GetY();
75 void CMyGLCanvasBase::OnMouseUp(wxMouseEvent& event)
80 void CMyGLCanvasBase::OnMouseMove(wxMouseEvent& event)
82 int X = m_mouseLastX =
event.GetX();
83 int Y = m_mouseLastY =
event.GetY();
86 float cameraPointingX = this->cameraPointingX;
87 float cameraPointingY = this->cameraPointingY;
88 float cameraPointingZ = this->cameraPointingZ;
89 float cameraZoomDistance = this->cameraZoomDistance;
90 float cameraElevationDeg = this->cameraElevationDeg;
91 float cameraAzimuthDeg = this->cameraAzimuthDeg;
93 if (event.LeftIsDown() )
95 if ( event.ShiftDown() )
98 cameraZoomDistance *= exp(0.01*(Y - mouseClickY));
99 if (cameraZoomDistance<0.01) cameraZoomDistance = 0.01f;
101 float Az = -0.05*(X - mouseClickX);
102 float D = 0.001*cameraZoomDistance;
103 cameraPointingZ += D*Az;
106 if (event.ControlDown())
109 const float dis = max(0.01f,(cameraZoomDistance));
110 float eye_x = cameraPointingX + dis * cos(
DEG2RAD(cameraAzimuthDeg))*cos(
DEG2RAD(cameraElevationDeg));
111 float eye_y = cameraPointingY + dis * sin(
DEG2RAD(cameraAzimuthDeg))*cos(
DEG2RAD(cameraElevationDeg));
112 float eye_z = cameraPointingZ + dis * sin(
DEG2RAD(cameraElevationDeg));
114 float A_AzimuthDeg = -SENSIBILITY_DEG_PER_PIXEL*(X - mouseClickX);
115 float A_ElevationDeg = SENSIBILITY_DEG_PER_PIXEL*(Y - mouseClickY);
118 cameraAzimuthDeg += A_AzimuthDeg;
119 cameraElevationDeg += A_ElevationDeg;
120 if (cameraElevationDeg<-90) cameraElevationDeg = -90;
121 if (cameraElevationDeg>90) cameraElevationDeg = 90;
124 cameraPointingX = eye_x - dis * cos(
DEG2RAD(cameraAzimuthDeg))*cos(
DEG2RAD(cameraElevationDeg));
125 cameraPointingY = eye_y - dis * sin(
DEG2RAD(cameraAzimuthDeg))*cos(
DEG2RAD(cameraElevationDeg));
126 cameraPointingZ = eye_z - dis * sin(
DEG2RAD(cameraElevationDeg));
131 cameraAzimuthDeg -= 0.2*(X - mouseClickX);
132 cameraElevationDeg += 0.2*(Y - mouseClickY);
133 if (cameraElevationDeg<-90) cameraElevationDeg = -90;
134 if (cameraElevationDeg>90) cameraElevationDeg = 90;
141 OnUserManuallyMovesCamera(cameraPointingX, cameraPointingY, cameraPointingZ, cameraZoomDistance, cameraElevationDeg, cameraAzimuthDeg);
143 #if wxCHECK_VERSION(2,9,5) 144 wxTheApp->SafeYieldFor(NULL,wxEVT_CATEGORY_TIMER);
150 if ( event.RightIsDown() )
152 float Ay = -(X - mouseClickX);
153 float Ax = -(Y - mouseClickY);
154 float D = 0.001*cameraZoomDistance;
155 cameraPointingX += D*(Ax*cos(
DEG2RAD(cameraAzimuthDeg)) - Ay*sin(
DEG2RAD(cameraAzimuthDeg)));
156 cameraPointingY += D*(Ax*sin(
DEG2RAD(cameraAzimuthDeg)) + Ay*cos(
DEG2RAD(cameraAzimuthDeg)));
162 OnUserManuallyMovesCamera(cameraPointingX, cameraPointingY, cameraPointingZ, cameraZoomDistance, cameraElevationDeg, cameraAzimuthDeg);
164 #if wxCHECK_VERSION(2,9,5) 165 wxTheApp->SafeYieldFor(NULL,wxEVT_CATEGORY_TIMER);
174 void CMyGLCanvasBase::OnMouseWheel(wxMouseEvent& event)
176 float cameraZoomDistance = this->cameraZoomDistance;
178 cameraZoomDistance *= 1 - 0.03f*(
event.GetWheelRotation()/120.0f);
181 OnUserManuallyMovesCamera(cameraPointingX, cameraPointingY, cameraPointingZ, cameraZoomDistance, cameraElevationDeg, cameraAzimuthDeg);
188 static int WX_GL_ATTR_LIST[] = { WX_GL_DOUBLEBUFFER, WX_GL_RGBA, WX_GL_DEPTH_SIZE, 24, 0 };
190 CMyGLCanvasBase::CMyGLCanvasBase(wxWindow *parent, wxWindowID
id,
const wxPoint& pos,
const wxSize&
size,
long style,
const wxString&
name) :
191 wxGLCanvas(parent,
id, WX_GL_ATTR_LIST, pos,
size, style|wxFULL_REPAINT_ON_RESIZE ,
name ),
194 m_mouseLastX(0),m_mouseLastY(0)
196 m_openGLScene = COpenGLScene::Create();
200 mouseClicked =
false;
207 cameraIsProjective =
true;
209 useCameraFromScene =
false;
211 cameraZoomDistance = 40;
213 cameraElevationDeg = 45;
214 cameraAzimuthDeg = 45;
221 Connect(wxID_ANY,wxEVT_LEFT_DOWN,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseDown);
222 Connect(wxID_ANY,wxEVT_RIGHT_DOWN,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseDown);
223 Connect(wxID_ANY,wxEVT_LEFT_UP,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseUp);
224 Connect(wxID_ANY,wxEVT_RIGHT_UP,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseUp);
225 Connect(wxID_ANY,wxEVT_MOTION,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseMove);
226 Connect(wxID_ANY,wxEVT_MOUSEWHEEL,(wxObjectEventFunction)&CMyGLCanvasBase::OnMouseWheel);
228 Connect(wxID_ANY,wxEVT_CHAR,(wxObjectEventFunction)&CMyGLCanvasBase::OnChar);
229 Connect(wxID_ANY,wxEVT_CHAR_HOOK,(wxObjectEventFunction)&CMyGLCanvasBase::OnChar);
231 Connect(wxEVT_CREATE,(wxObjectEventFunction)&CMyGLCanvasBase::OnWindowCreation);
236 wxWindowCreateEvent dum;
237 OnWindowCreation(dum);
242 CMyGLCanvasBase::~CMyGLCanvasBase()
244 m_openGLScene.clear_unique();
248 void CMyGLCanvasBase::OnChar( wxKeyEvent& event )
253 void CMyGLCanvasBase::Render()
260 if (!m_gl_context) {
return; }
261 else SetCurrent(*m_gl_context);
300 if (!useCameraFromScene)
302 COpenGLViewportPtr view= m_openGLScene->getViewport(
"main");
305 THROW_EXCEPTION(
"Fatal error: there is no 'main' viewport in the 3D scene!");
309 cam.
setPointingAt( cameraPointingX, cameraPointingY, cameraPointingZ );
326 m_openGLScene->render();
340 catch (std::exception &e)
344 std::cerr << err_msg;
345 OnRenderError(
_U(err_msg.c_str()) );
350 std::cerr <<
"Runtime error!" << std::endl;
353 OnPostRenderSwapBuffers( At, dc );
357 void CMyGLCanvasBase::OnEnterWindow( wxMouseEvent& WXUNUSED(event) )
362 void CMyGLCanvasBase::OnPaint( wxPaintEvent& WXUNUSED(event) )
367 void CMyGLCanvasBase::OnSize(wxSizeEvent& event)
369 if (!m_parent->IsShown())
return;
373 GetClientSize(&
w, &h);
375 if (this->IsShownOnScreen())
377 if (!m_gl_context) {
return; }
378 else SetCurrent(*m_gl_context);
384 void CMyGLCanvasBase::OnEraseBackground(wxEraseEvent& WXUNUSED(event))
389 void CMyGLCanvasBase::InitGL()
391 if (!m_gl_context) {
return; }
392 else SetCurrent(*m_gl_context);
394 static bool GLUT_INIT_DONE =
false;
398 GLUT_INIT_DONE =
true;
401 char *argv[1] = { NULL };
402 glutInit( &argc, argv );
411 #endif // MRPT_HAS_WXWIDGETS GLAPI void GLAPIENTRY glFlush(void)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLAPI void GLAPIENTRY glMatrixMode(GLenum mode)
GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
void setProjectiveModel(bool v=true)
Enable/Disable projective mode (vs. orthogonal)
GLAPI void GLAPIENTRY glPopAttrib(void)
void Tic()
Starts the stopwatch.
GLAPI void GLAPIENTRY glLoadIdentity(void)
GLubyte GLubyte GLubyte GLubyte w
void setZoomDistance(float z)
void setAzimuthDegrees(float ang)
void delete_safe(T *&ptr)
Calls "delete" to free an object only if the pointer is not NULL, then set the pointer to NULL...
This class implements a high-performance stopwatch.
void setProjectiveFOVdeg(float ang)
Field-of-View in degs, only when projectiveModel=true (default=30 deg).
double DEG2RAD(const double x)
Degrees to radians.
GLsizei const GLchar ** string
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
void setElevationDegrees(float ang)
GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask)
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
The namespace for 3D scene representation and rendering.
GLuint const GLchar * name
double Tac()
Stops the stopwatch.
#define GL_ALL_ATTRIB_BITS
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
Classes for creating GUI windows for 2D and 3D visualization.
A camera: if added to a scene, the viewpoint defined by this camera will be used instead of the camer...
GLenum GLsizei GLsizei height
void setPointingAt(float x, float y, float z)