PreviewDifferenceTool.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00022 #include "PreviewDifferenceTool.h"
00023 #include <config.h>
00024 #include <GL/glew.h>
00025 #include <wx/platform.h>
00026 #ifdef __WXMAC__
00027 #include <OpenGL/gl.h>
00028 #else
00029 #include <GL/gl.h>
00030 #endif
00031 
00032 // This is the number of times to double the result of the difference. It should
00033 // be between 0 and 7. Note that with  values > 0 no extra colours are used
00034 // (infact less are due to clipping), but the difference becomes easier to see.
00035 #define DIFFERENCE_DOUBLE 2
00036 
00037 PreviewDifferenceTool::PreviewDifferenceTool(ToolHelper *helper)
00038     : Tool(helper)
00039 {
00040     // rather boring constructor
00041 }
00042 
00044 bool PreviewDifferenceTool::CheckOpenGLCanDifference()
00045 {
00046     if(GLEW_ARB_imaging)
00047         return true;
00048     if((glBlendEquation!=NULL) && (GLEW_EXT_blend_subtract))
00049         return true;
00050     return false;
00051 }
00052 
00053 void PreviewDifferenceTool::Activate()
00054 {
00055     over_image = false;
00056     // Activate difference tool only if OpenGL extension GL_ARB_imaging is available
00057     // cause the extension contains required functions like glBlendEquation
00058     // In general this check should be superfluous, due to the fact that the preview frame
00059     // must check the OpenGL capabilities and never call this method if differencing is
00060     // not supported, but check twice is saver.
00061     if (CheckOpenGLCanDifference())
00062     {
00063         helper->NotifyMe(PreviewToolHelper::IMAGES_UNDER_MOUSE_CHANGE, this);
00064     }
00065 }
00066 
00067 void PreviewDifferenceTool::ImagesUnderMouseChangedEvent()
00068 {
00069     std::set<unsigned int> image_set = helper->GetImageNumbersUnderMouse();
00070     if (!image_set.empty())
00071     {
00072         // stop showing the previous one if there was one, if there wasn't, we
00073         // need to be able to draw over the preview.
00074         if (over_image)
00075         {
00076             helper->DoNotNotifyMeBeforeDrawing(image_number, this);
00077         } else {
00078             helper->NotifyMe(PreviewToolHelper::DRAW_OVER_IMAGES, this);
00079             helper->NotifyMe(PreviewToolHelper::DRAW_UNDER_IMAGES, this);
00080         }
00081         // The lowest image number is drawn first, since the set is sorted.
00082         // Get notifications so we can draw it:
00083         image_number = *(image_set.begin());
00084         helper->NotifyMeBeforeDrawing(image_number, this);
00085         // Redraw the panorama with this image negated from the others.
00086         helper->GetVisualizationStatePtr()->ForceRequireRedraw();
00087         helper->GetVisualizationStatePtr()->Redraw();
00088         over_image = true;
00089     } else {
00090         if (over_image)
00091         {
00092             // We were showing a difference, now there are no images under the
00093             // mouse pointer:
00094             // Drop notifications, we don't need to do anything extra.
00095             over_image = false;
00096             helper->DoNotNotifyMe(PreviewToolHelper::DRAW_OVER_IMAGES, this);
00097             helper->DoNotNotifyMe(PreviewToolHelper::DRAW_UNDER_IMAGES, this);
00098             helper->DoNotNotifyMeBeforeDrawing(image_number, this);
00099             // redraw the panorama without the negated image.
00100             helper->GetVisualizationStatePtr()->ForceRequireRedraw();
00101             helper->GetVisualizationStatePtr()->Redraw();
00102         }
00103     }
00104 }
00105 
00106 
00107 void PreviewDifferenceTool::AfterDrawImagesEvent()
00108 {
00109     // Get the display list used to generate the image
00110     unsigned int display_list;
00111         display_list = helper->GetVisualizationStatePtr()->GetMeshDisplayList(image_number);    
00112     TextureManager *tex_m = helper->GetViewStatePtr()->GetTextureManager();
00113     tex_m->BindTexture(image_number);
00114     // we will use a subtractive blend
00115     glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
00116     // multiply by the alpha value, so transparent areas appear black.
00117     glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
00118     glEnable(GL_BLEND);
00119     if (tex_m->GetPhotometricCorrect())
00120     {
00121         // The texture has full photometric correction, we can subtract it once
00122         // and be done.
00123         glCallList(display_list);
00124     } else {
00125         // otherwise we have to fake some of the photometric correction to get
00126         // good white balance and exposure.
00127         HuginBase::SrcPanoImage *img;
00128         img = helper->GetViewStatePtr()->GetSrcImage(image_number);
00129         float viewer_exposure = 1.0 / pow(2.0,
00130                     helper->GetPanoramaPtr()->getOptions().outputExposureValue);
00131         float es = static_cast<float>(viewer_exposure / img->getExposure());
00132         float scale[3] = { static_cast<float>(es / img->getWhiteBalanceRed()),
00133                           es,
00134                           static_cast<float>(es / img->getWhiteBalanceBlue()) };
00135         // now we draw repeatedly until the image has been exposed properly.
00136         while (scale[0] > 0.0 && scale[1] > 0.0 && scale[2] > 0.0)
00137         {
00138             glColor3fv(scale);
00139             glCallList(display_list);
00140             scale[0] -= 1.0; scale[1] -= 1.0; scale[2] -= 1.0;
00141         }
00142         glColor3f(1.0, 1.0, 1.0);
00143     }
00144     glBlendEquation(GL_FUNC_ADD);
00145     // To make the difference stand out more, multiply it a few times:
00146     tex_m->DisableTexture();
00147     glBlendFunc(GL_DST_COLOR, GL_ONE);
00148     for (unsigned short int count = 0; count < DIFFERENCE_DOUBLE; count++)
00149     {
00150         glCallList(display_list);
00151     }
00152     glEnable(GL_TEXTURE_2D);
00153     glDisable(GL_BLEND);
00154 }
00155 
00156 //draw the images below all other images so that the difference is not computed agains something drawn in the background
00157 void PreviewDifferenceTool::BeforeDrawImagesEvent()
00158 {
00159     unsigned int display_list = helper->GetVisualizationStatePtr()->GetMeshDisplayList(image_number);    
00160     helper->GetViewStatePtr()->GetTextureManager()->DrawImage(image_number, display_list);
00161 }
00162 
00163 
00164 bool PreviewDifferenceTool::BeforeDrawImageEvent(unsigned int image)
00165 {
00166     return false;
00167 }
00168 

Generated on 27 Jun 2016 for Hugintrunk by  doxygen 1.4.7