Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PreviewDifferenceTool.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
22 #ifdef _WIN32
23 #include "wx/msw/wrapwin.h"
24 #endif
25 #include "PreviewDifferenceTool.h"
26 #include "hugin_config.h"
27 #if defined HAVE_EPOXY && HAVE_EPOXY
28 #include <epoxy/gl.h>
29 #else
30 #include <GL/glew.h>
31 #ifdef __WXMAC__
32 #include <OpenGL/gl.h>
33 #else
34 #include <GL/gl.h>
35 #endif
36 #endif
37 #include <wx/platform.h>
38 
39 // This is the number of times to double the result of the difference. It should
40 // be between 0 and 7. Note that with values > 0 no extra colours are used
41 // (infact less are due to clipping), but the difference becomes easier to see.
42 #define DIFFERENCE_DOUBLE 2
43 
45  : Tool(helper)
46 {
47  // rather boring constructor
48 }
49 
52 {
53 #if defined HAVE_EPOXY && HAVE_EPOXY
54  if (epoxy_has_gl_extension("GL_ARB_imaging"))
55  {
56  return true;
57  };
58  if ((glBlendEquation != NULL) && (epoxy_has_gl_extension("GL_EXT_blend_subtract")))
59  {
60  return true;
61  };
62 #else
63  if(GLEW_ARB_imaging)
64  return true;
65  if((glBlendEquation!=NULL) && (GLEW_EXT_blend_subtract))
66  return true;
67 #endif
68  return false;
69 }
70 
72 {
73  over_image = false;
74  // Activate difference tool only if OpenGL extension GL_ARB_imaging is available
75  // cause the extension contains required functions like glBlendEquation
76  // In general this check should be superfluous, due to the fact that the preview frame
77  // must check the OpenGL capabilities and never call this method if differencing is
78  // not supported, but check twice is saver.
80  {
82  }
83 }
84 
86 {
87  std::set<unsigned int> image_set = helper->GetImageNumbersUnderMouse();
88  if (!image_set.empty())
89  {
90  // stop showing the previous one if there was one, if there wasn't, we
91  // need to be able to draw over the preview.
92  if (over_image)
93  {
95  } else {
98  }
99  // The lowest image number is drawn first, since the set is sorted.
100  // Get notifications so we can draw it:
101  image_number = *(image_set.begin());
103  // Redraw the panorama with this image negated from the others.
106  over_image = true;
107  } else {
108  if (over_image)
109  {
110  // We were showing a difference, now there are no images under the
111  // mouse pointer:
112  // Drop notifications, we don't need to do anything extra.
113  over_image = false;
117  // redraw the panorama without the negated image.
120  }
121  }
122 }
123 
124 
126 {
127  // Get the display list used to generate the image
128  unsigned int display_list;
131  tex_m->BindTexture(image_number);
132  // we will use a subtractive blend
133  glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
134  // multiply by the alpha value, so transparent areas appear black.
135  glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
136  glEnable(GL_BLEND);
137  if (tex_m->GetPhotometricCorrect())
138  {
139  // The texture has full photometric correction, we can subtract it once
140  // and be done.
141  glCallList(display_list);
142  } else {
143  // otherwise we have to fake some of the photometric correction to get
144  // good white balance and exposure.
147  float viewer_exposure = 1.0 / pow(2.0,
149  float es = static_cast<float>(viewer_exposure / img->getExposure());
150  float scale[3] = { static_cast<float>(es / img->getWhiteBalanceRed()),
151  es,
152  static_cast<float>(es / img->getWhiteBalanceBlue()) };
153  // now we draw repeatedly until the image has been exposed properly.
154  while (scale[0] > 0.0 && scale[1] > 0.0 && scale[2] > 0.0)
155  {
156  glColor3fv(scale);
157  glCallList(display_list);
158  scale[0] -= 1.0; scale[1] -= 1.0; scale[2] -= 1.0;
159  }
160  glColor3f(1.0, 1.0, 1.0);
161  }
162  glBlendEquation(GL_FUNC_ADD);
163  // To make the difference stand out more, multiply it a few times:
164  tex_m->DisableTexture();
165  glBlendFunc(GL_DST_COLOR, GL_ONE);
166  for (unsigned short int count = 0; count < DIFFERENCE_DOUBLE; count++)
167  {
168  glCallList(display_list);
169  }
170  glEnable(GL_TEXTURE_2D);
171  glDisable(GL_BLEND);
172 }
173 
174 //draw the images below all other images so that the difference is not computed agains something drawn in the background
176 {
177  unsigned int display_list = helper->GetVisualizationStatePtr()->GetMeshDisplayList(image_number);
179 }
180 
181 
183 {
184  return false;
185 }
186 
implementation of huginApp Class
ViewState * GetViewStatePtr()
Definition: ToolHelper.cpp:305
void Activate()
Switch on a tool.
void NotifyMeBeforeDrawing(unsigned int image_nr, Tool *tool)
Definition: ToolHelper.cpp:349
HuginBase::Panorama * GetPanoramaPtr()
Definition: ToolHelper.cpp:310
void DisableTexture(bool maskOnly=false)
bool GetPhotometricCorrect()
PreviewDifferenceTool(ToolHelper *helper)
void ForceRequireRedraw()
Definition: ViewState.cpp:439
void NotifyMe(Event event, Tool *tool)
Definition: ToolHelper.cpp:315
std::set< unsigned int > GetImageNumbersUnderMouse()
Definition: ToolHelper.cpp:281
VisualizationState * GetVisualizationStatePtr()
Definition: ToolHelper.cpp:300
ToolHelper * helper
The PreviewToolHelper that uses the same preview window and panorama as the tool should.
Definition: Tool.h:102
void DoNotNotifyMeBeforeDrawing(unsigned int image_nr, Tool *tool)
Definition: ToolHelper.cpp:397
Definition: Tool.h:42
bool BeforeDrawImageEvent(unsigned int image)
Draw what the tool requires just before a given image is drawn.
float pow(float a, double b)
Definition: utils.h:181
TextureManager * GetTextureManager()
Definition: ViewState.h:104
void ImagesUnderMouseChangedEvent()
Notify when the images directly underneath the mouse pointer have changed.
#define DIFFERENCE_DOUBLE
double getExposure() const
void BeforeDrawImagesEvent()
Draw using OpenGL anything the tool requires underneath the images.
void BindTexture(unsigned int image_number)
void DrawImage(unsigned int image_number, unsigned int display_list)
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
void DoNotNotifyMe(Event event, Tool *tool)
Definition: ToolHelper.cpp:361
HuginBase::SrcPanoImage * GetSrcImage(unsigned int image_nr)
Definition: ViewState.cpp:283
All variables of a source image.
Definition: SrcPanoImage.h:194
unsigned int GetMeshDisplayList(unsigned int image_nr)
Definition: ViewState.cpp:462
static bool CheckOpenGLCanDifference()
check, if graphic card supports the necessary modes for difference tool call this procedure first...
void AfterDrawImagesEvent()
Draw (using OpenGL) images above the others.