Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GLViewer.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
23 #include "panoinc_WX.h"
24 #include "base_wx/wxutils.h"
25 
26 #include "panoinc.h"
27 #include "hugin_config.h"
28 #if defined HAVE_EPOXY && HAVE_EPOXY
29 #include <epoxy/gl.h>
30 #ifdef __WXMSW__
31 #include <epoxy/wgl.h>
32 #endif
33 #else
34 #include <GL/glew.h>
35 #endif
36 #include <base_wx/platform.h>
37 #include <wx/settings.h>
38 #include <wx/dcclient.h>
39 #include <wx/event.h>
40 
41 #include "GLViewer.h"
42 #include "GLRenderer.h"
43 #include "TextureManager.h"
44 #include "MeshManager.h"
45 #include "ToolHelper.h"
46 #include "GLPreviewFrame.h"
47 #include "hugin/huginApp.h"
48 
49 #if !defined HAVE_EPOXY || !HAVE_EPOXY
51 #endif
54 
56  wxWindow* parent,
57  HuginBase::Panorama &pano,
58  int args[],
59  GLPreviewFrame *frame_in,
60  wxGLContext * shared_context
61  ) :
62  wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize,
63  0, wxT("GLPreviewCanvas"), wxNullPalette)
64 {
65  /* create OpenGL context... */
66  m_glContext = new wxGLContext(this, shared_context);
67 
68  m_renderer = 0;
70 
71  m_pano = &pano;
72 
73  frame = frame_in;
74 
76 
77  started_creation = false;
78  redrawing = false;
79  m_toolsInitialized = false;
80 
81  active = true;
82  // bind event handler
83  Bind(wxEVT_PAINT, &GLViewer::RedrawE, this);
84  Bind(wxEVT_SIZE, &GLViewer::Resized, this);
85  Bind(wxEVT_ERASE_BACKGROUND, &GLViewer::OnEraseBackground, this);
86  Bind(wxEVT_MOTION, &GLViewer::MouseMotion, this);
87  Bind(wxEVT_ENTER_WINDOW, &GLViewer::MouseEnter, this);
88  Bind(wxEVT_LEAVE_WINDOW, &GLViewer::MouseLeave, this);
89  Bind(wxEVT_MOUSEWHEEL, &GLViewer::MouseWheel, this);
90  Bind(wxEVT_LEFT_DOWN, &GLViewer::MouseButtons, this);
91  Bind(wxEVT_LEFT_UP, &GLViewer::MouseButtons, this);
92  Bind(wxEVT_LEFT_DCLICK, &GLViewer::MouseButtons, this);
93  Bind(wxEVT_RIGHT_DOWN, &GLViewer::MouseButtons, this);
94  Bind(wxEVT_RIGHT_UP, &GLViewer::MouseButtons, this);
95  Bind(wxEVT_RIGHT_DCLICK, &GLViewer::MouseButtons, this);
96  Bind(wxEVT_MIDDLE_DOWN, &GLViewer::MouseButtons, this);
97  Bind(wxEVT_MIDDLE_UP, &GLViewer::MouseButtons, this);
98  Bind(wxEVT_MIDDLE_DCLICK, &GLViewer::MouseButtons, this);
99  Bind(wxEVT_KEY_DOWN, &GLViewer::KeyDown, this);
100  Bind(wxEVT_KEY_UP, &GLViewer::KeyUp, this);
101 }
102 
104 {
105  if (m_renderer)
106  {
107  delete m_tool_helper;
108  delete m_renderer;
109  delete m_visualization_state;
110  // because m_view_state is a static member variable we need to check
111  // if other class has already deleted it
113  if (m_view_state_observer == 0)
114  {
115  delete m_view_state;
116  m_view_state=NULL;
117  }
118  }
119  delete m_glContext;
120 }
121 
123 {
124  // set the context
125  DEBUG_INFO("Setting rendering context...");
126  Show();
127  m_glContext->SetCurrent(*this);
128  DEBUG_INFO("...got a rendering context.");
129  if (!started_creation)
130  {
131  // It appears we are setting up for the first time.
132  started_creation = true;
133 
134 #if defined HAVE_EPOXY && HAVE_EPOXY
135  // check the openGL capabilities.
136  if (!(epoxy_gl_version() > 11 && epoxy_has_gl_extension("GL_ARB_multitexture")))
137  {
138  started_creation = false;
139  wxConfigBase::Get()->Write(wxT("DisableOpenGL"), 1l);
140  wxConfigBase::Get()->Flush();
141  DEBUG_ERROR("Sorry, OpenGL 1.1 + GL_ARB_multitexture extension required.");
142  frame->Close();
143  wxMessageBox(_("Sorry, the fast preview window requires a system which supports OpenGL version 1.1 with the GL_ARB_multitexture extension.\nThe fast preview cannot be opened.\n\nHugin has been configured to start without fast preview.\nPlease restart Hugin."), _("Error"), wxOK | wxICON_ERROR);
144  return;
145  }
146 #else
147  if (!initialised_glew)
148  {
149  // initialise the glew library, if not done it before.
150  GLenum error_state = glewInit();
151  initialised_glew = true;
152  if (error_state != GLEW_OK)
153  {
154  // glewInit failed
155  started_creation=false;
156  DEBUG_ERROR("Error initialising GLEW: "
157  << glewGetErrorString(error_state) << ".");
158  frame->Close();
159  wxMessageBox(_("Error initializing GLEW\nFast preview window can not be opened."),_("Error"), wxOK | wxICON_ERROR);
160  return;
161  }
162  }
163  // check the openGL capabilities.
164  if (!(GLEW_VERSION_1_1 && GLEW_ARB_multitexture))
165  {
166  started_creation=false;
167  wxConfigBase::Get()->Write(wxT("DisableOpenGL"), 1l);
168  wxConfigBase::Get()->Flush();
169  DEBUG_ERROR("Sorry, OpenGL 1.1 + GL_ARB_multitexture extension required.");
170  frame->Close();
171  wxMessageBox(_("Sorry, the fast preview window requires a system which supports OpenGL version 1.1 with the GL_ARB_multitexture extension.\nThe fast preview cannot be opened.\n\nHugin has been configured to start without fast preview.\nPlease restart Hugin."),_("Error"), wxOK | wxICON_ERROR);
172  return;
173  }
174 #endif
175 
176  setUp();
177 #ifdef __WXGTK__
178  if(this==frame->getPreview())
179  {
180  frame->getOverview()->setUp();
181  }
182  else
183  {
184  frame->getPreview()->setUp();
185  };
186 #endif
187  }
188 }
189 
191 {
192  DEBUG_DEBUG("Preview Setup");
193  if (m_toolsInitialized)
194  {
195  return;
196  };
197  m_toolsInitialized = true;
198  // we need something to store the state of the view and control updates
199  if (!m_view_state)
200  {
201  GLint countMultiTexture;
202  glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&countMultiTexture);
203  m_view_state = new ViewState(m_pano, countMultiTexture>1);
204  }
207  //Start the tools going:
209  m_tool_helper = static_cast<ToolHelper*>(helper);
210  frame->MakePreviewTools(helper);
211  // now make a renderer
215 }
216 
218 {
219  if (m_renderer)
220  {
222  {
224  delete panosphere_m_renderer;
226  }
227  else
228  {
229  delete plane_m_tool_helper;
230  delete plane_m_renderer;
232  };
233  };
234 }
235 
237 {
238  DEBUG_DEBUG("Overview Setup");
239  if (m_toolsInitialized)
240  {
241  return;
242  };
243  m_toolsInitialized = true;
244  // we need something to store the state of the view and control updates
245  if (!m_view_state)
246  {
247  GLint countMultiTexture;
248  glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&countMultiTexture);
249  m_view_state = new ViewState(m_pano, countMultiTexture>1);
250  }
252 
255 
257 
258  //Start the tools going:
261 
264 
265  // now make a renderer
272 
273  switch(mode) {
274  case PANOSPHERE_OUTSIDE:
275  case PANOSPHERE_INSIDE:
280  break;
281  case PLANE:
285  break;
286  }
287 }
288 
290 {
292  Refresh();
293 }
294 
295 void GLViewer::SetLayoutMode(bool state)
296 {
298  Refresh();
299 }
300 
301 void GLViewer::SetLayoutScale(double scale)
302 {
304  Refresh();
305 }
306 
308 {
311  Refresh();
312 }
313 
314 void GLOverview::SetLayoutScale(double scale)
315 {
318  Refresh();
319 }
320 
321 
322 void GLViewer::RedrawE(wxPaintEvent& e)
323 {
324  if (!IsActive()) {
325  return;
326  }
327 
328  //TODO: CanResize specific to a viewer?
329  DEBUG_DEBUG("REDRAW_E");
330  if(!IsShown()) return;
331  // don't redraw during a redraw.
332  if (!(frame->CanResize())) {
333  DEBUG_DEBUG("RESIZE IN REDRAW");
335  return;
336  }
337 
338  if (!redrawing)
339  {
340  DEBUG_DEBUG("REDRAW_E IN");
341  redrawing = true;
342  SetUpContext();
343  Redraw();
344  redrawing = false;
345  }
346  DEBUG_DEBUG("END OF REDRAW_E");
347 }
348 
349 void GLViewer::RefreshWrapper(void * obj)
350 {
351  DEBUG_DEBUG("REFRESH WRAPPER");
352  GLViewer* self = static_cast<GLViewer*>(obj);
353  self->Refresh();
354 }
355 
356 void GLViewer::Resized(wxSizeEvent& e)
357 {
358 
359  if (!IsActive()) {
360  return;
361  }
362 
363  DEBUG_DEBUG("RESIZED_OUT");
364 
365  if (frame->CanResize()) {
366  DEBUG_DEBUG("RESIZED_IN");
367  if(!IsShown()) return;
368  // if we have a render at this point, tell it the new size.
369  DEBUG_DEBUG("RESIZED_IN_SHOWN");
370  if (m_renderer)
371  {
372  DEBUG_DEBUG("RESIZED_IN_RENDERER");
373  wxSize clientSize = GetClientSize();
374 #if defined __WXGTK3__ || defined __WXOSX__
375  m_scale = GetContentScaleFactor();
376  clientSize *= m_scale;
377 #endif
378  SetUpContext();
379  offset = m_renderer->Resize(clientSize.GetWidth(), clientSize.GetHeight());
380  Redraw();
381  };
382  }
383 }
384 
386 {
387  // get the renderer to redraw the OpenGL stuff
388  if(!m_renderer) return;
389  // don't redraw if we are in middle of a pending change of the panorama object
390  if(m_pano->hasPendingChanges()) return;
391  DEBUG_INFO("Rendering.");
392 
393  // we should use the window background colour outside the panorama
394  // FIXME shouldn't this work on textured backrounds?
395 #if defined __WXMAC__
396  wxColour col(128,128,128);
397 #else
398  wxColour col = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE);
399 #endif
400  m_renderer->SetBackground(col.Red(), col.Green(), col.Blue());
402  {
403  // resize the viewport in case the panorama dimensions have changed.
404  wxSize clientSize = GetClientSize();
405 #if defined __WXGTK3__ || defined __WXOSX__
406  m_scale = GetContentScaleFactor();
407  clientSize *= m_scale;
408 #endif
409  offset = m_renderer->Resize(clientSize.GetWidth(), clientSize.GetHeight());
410  }
412  m_renderer->Redraw();
413  glFlush();
414  SwapBuffers();
415  // tell the view state we did all the updates and redrew.
417  DEBUG_INFO("Finished Rendering.");
418 }
419 
420 void GLViewer::OnEraseBackground(wxEraseEvent& e)
421 {
422  // Do nothing, to avoid flashing on MSW
423 }
424 
425 void GLViewer::MouseMotion(wxMouseEvent& e)
426 {
427  if(m_renderer)
429  hugin_utils::roundi(e.m_y * m_scale - offset.y), e);
430 }
431 
432 void GLViewer::MouseEnter(wxMouseEvent & e)
433 {
434  if(m_renderer)
436  hugin_utils::roundi(e.m_y * m_scale - offset.y), e);
437 }
438 
439 void GLViewer::MouseLeave(wxMouseEvent & e)
440 {
441  if(m_renderer)
443 }
444 
445 void GLViewer::MouseButtons(wxMouseEvent& e)
446 {
447  if(m_renderer) {
448  //disregard non button events
449  if (e.IsButton()) {
451  }
452  }
453 #ifdef __WXMSW__
454  //use normal mouse button processing of GLCanvas
455  //otherwise the mouse wheel is not working
456  e.Skip();
457 #endif
458 }
459 
460 void GLViewer::MouseWheel(wxMouseEvent& e)
461 {
462  if(m_renderer) {
464  }
465 }
466 
467 
468 void GLViewer::KeyDown(wxKeyEvent& e)
469 {
470  if(m_renderer)
471  m_tool_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), true);
472 }
473 
474 void GLViewer::KeyUp(wxKeyEvent& e)
475 {
476  if(m_renderer)
477  m_tool_helper->KeypressEvent(e.GetKeyCode(), e.GetModifiers(), false);
478 }
479 
481 {
483 }
484 
486 {
487  this->m_background_color = col;
488  if(m_renderer)
490 }
491 
493 {
494  this->mode = mode;
495  if (panosphere_m_renderer != 0 && plane_m_renderer != 0) {
496  switch(mode) {
497  case PANOSPHERE_OUTSIDE:
498  case PANOSPHERE_INSIDE:
503  break;
504  case PLANE:
508  break;
509  }
510  this->Refresh();
511  }
512 }
513 
514 
#define DEBUG_INFO(msg)
Definition: utils.h:69
static size_t m_view_state_observer
Definition: GLViewer.h:73
void MouseButtons(wxMouseEvent &e)
Definition: GLViewer.cpp:445
implementation of huginApp Class
void MouseWheelEvent(wxMouseEvent &e)
Definition: ToolHelper.cpp:156
void MouseLeave(wxMouseEvent &e)
Definition: GLViewer.cpp:439
The OpenGL preview frame.
void setUp()
Definition: GLViewer.cpp:236
void KeyDown(wxKeyEvent &e)
Definition: GLViewer.cpp:468
int roundi(T x)
Definition: hugin_math.h:73
wxColour GetPreviewBackgroundColor()
GLPreviewFrame * frame
Definition: GLViewer.h:103
PanosphereOverviewVisualizationState * panosphere_m_visualization_state
Definition: GLViewer.h:157
virtual void SetLayoutScale(double scale)
Definition: GLViewer.cpp:301
virtual vigra::Diff2D Resize(int width, int height)=0
Resize the viewport because the window&#39;s dimensions have changed.
void SetPhotometricCorrect(bool state)
Definition: GLViewer.cpp:289
PlaneOverviewToolHelper * plane_m_tool_helper
Definition: GLViewer.h:162
subclass for the preview canvas
Definition: GLRenderer.h:84
void setInsideView(bool insideView)
Definition: ViewState.cpp:586
void Resized(wxSizeEvent &e)
Definition: GLViewer.cpp:356
void MarkToolsDirty()
Definition: GLViewer.cpp:480
void setUp()
Definition: GLViewer.cpp:190
HuginBase::Panorama * m_pano
Definition: GLViewer.h:95
void SetLayoutScale(double scale)
void MouseMotion(wxMouseEvent &e)
Definition: GLViewer.cpp:425
include file for the hugin project
bool redrawing
Definition: GLViewer.h:99
wxGLContext * m_glContext
Definition: GLViewer.h:94
void KeyUp(wxKeyEvent &e)
Definition: GLViewer.cpp:474
static void RefreshWrapper(void *obj)
Definition: GLViewer.cpp:349
virtual void Redraw()=0
GLPlaneOverviewRenderer * plane_m_renderer
Definition: GLViewer.h:163
static bool initialised_glew
Definition: GLViewer.h:100
virtual void setUp()=0
void OnEraseBackground(wxEraseEvent &e)
Definition: GLViewer.cpp:420
void SetPhotometricCorrect(bool state)
void SetMode(OverviewMode mode)
Definition: GLViewer.cpp:492
Model for a panorama.
Definition: Panorama.h:152
void MouseEnter(int x, int y, wxMouseEvent &e)
Definition: ToolHelper.cpp:248
PlaneOverviewVisualizationState * plane_m_visualization_state
Definition: GLViewer.h:161
void MakePreviewTools(PreviewToolHelper *helper)
GLViewer(wxWindow *parent, HuginBase::Panorama &pano, int args[], GLPreviewFrame *frame, wxGLContext *shared_context=NULL)
Definition: GLViewer.cpp:55
MeshManager * GetMeshManager()
Definition: ViewState.h:207
subclass for the plane overview mode
Definition: GLRenderer.h:118
void MouseEnter(wxMouseEvent &e)
Definition: GLViewer.cpp:432
bool started_creation
Definition: GLViewer.h:99
TextureManager * GetTextureManager()
Definition: ViewState.h:104
void MouseButtonEvent(wxMouseEvent &e)
Definition: ToolHelper.cpp:148
const bool hasPendingChanges() const
return if the panorama class has pending changes normally all controls listen to panoramaChanges noti...
Definition: Panorama.cpp:1563
virtual void SetLayoutMode(bool state)
Definition: GLViewer.cpp:295
void MakePanosphereOverviewTools(PanosphereOverviewToolHelper *helper)
bool IsActive()
Definition: GLViewer.h:76
VisualizationState * m_visualization_state
Definition: GLViewer.h:71
#define DEBUG_ERROR(msg)
Definition: utils.h:76
void KeypressEvent(int keycode, int modifiers, bool pressed)
Definition: ToolHelper.cpp:165
bool RequireRecalculateViewport()
Definition: ViewState.cpp:415
void MakePlaneOverviewTools(PlaneOverviewToolHelper *helper)
PanosphereOverviewToolHelper * panosphere_m_tool_helper
Definition: GLViewer.h:158
subclass for the panosphere overview mode
Definition: GLRenderer.h:101
virtual void SetLayoutScale(double scale)
Definition: GLViewer.cpp:314
GLRenderer * m_renderer
Definition: GLViewer.h:93
virtual ~GLViewer()
Definition: GLViewer.cpp:103
double m_scale
Definition: GLViewer.h:102
include file for the hugin project
virtual void SetLayoutMode(bool state)
Definition: GLViewer.cpp:307
void SetBackground(unsigned char red, unsigned char green, unsigned char blue)
Definition: GLRenderer.cpp:60
void Redraw()
Definition: GLViewer.cpp:385
bool m_toolsInitialized
Definition: GLViewer.h:99
static const double scale_diff
scale factor to be used for the layout mode TODO: test this for more scenarios
Definition: MeshManager.h:178
GLOverview * getOverview()
void MouseLeave()
Definition: ToolHelper.cpp:263
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
virtual void MouseMoved(int x, int y, wxMouseEvent &e)
Definition: ToolHelper.cpp:75
void SetViewerBackground(wxColour col)
Definition: GLViewer.cpp:485
GLPanosphereOverviewRenderer * panosphere_m_renderer
Definition: GLViewer.h:159
bool active
Definition: GLViewer.h:105
void SetPreviewBackgroundColor(const wxColour c)
sets the preview background color
Definition: GLRenderer.cpp:55
ToolHelper * m_tool_helper
Definition: GLViewer.h:92
void SetLayoutMode(bool state)
Turn layout mode on or off.
GLPreview * getPreview()
static ViewState * m_view_state
Definition: GLViewer.h:72
void RedrawE(wxPaintEvent &e)
Definition: GLViewer.cpp:322
void SetUpContext()
Definition: GLViewer.cpp:122
wxColour m_background_color
Definition: GLViewer.h:107
void MouseWheel(wxMouseEvent &e)
Definition: GLViewer.cpp:460
A wxWidget to display the fast preview.
Definition: GLViewer.h:51
OverviewMode mode
Definition: GLViewer.h:155
vigra::Diff2D offset
Definition: GLViewer.h:101
void MarkDirty()
Definition: ToolHelper.cpp:203