TextureManager.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00023 /* a TextureManager sets up openGL textures for each of the input images in a
00024  * panorama. It scales images down so they should fit in graphics memory.
00025  */
00026 
00027 /* Texture sizes must be powers of two. The texture sizes are the biggest size
00028  * that does not scale up the input image, or the biggest size supported by the
00029  * hardware, whichever is smaller. However, not all of the texture is defined
00030  * at any time, so the memory consumption is limited.
00031  * The textures are mipmapped, i.e. they use progressivly smaller versions.
00032  * The mipmaps are defined in a range from the smallest 1*1 pixel version to
00033  * the largest mipmap that doesn't go over the texture space budget. OpenGL
00034  * uses mip level 0 to be the original image, and log2(max(width, height)) + 1
00035  * to be the smallest 1 by 1 pixel image. We use this convention too.
00036  */
00037 
00038 #ifndef _TextureManager_h
00039 #define _TextureManager_h
00040 
00041 #include <string>
00042 #include <map>
00043 #include <boost/version.hpp>
00044 #if BOOST_VERSION>=105400
00045 #include <boost/signals2/trackable.hpp>
00046 namespace boostSignal=boost::signals2;
00047 #else
00048 #include <boost/signals/trackable.hpp>
00049 namespace boostSignal=boost::signals;
00050 #endif
00051 #include <huginapp/ImageCache.h>
00052 #include "PT/Panorama.h"
00053 
00054 //class GLViewer;
00055 class ViewState;
00056 
00057 class TextureManager
00058 {
00059 public:
00060     TextureManager(PT::Panorama *pano, ViewState *view);
00061     virtual ~TextureManager();
00062     // selct the texture for the requested image in opengl
00063     void DrawImage(unsigned int image_number, unsigned int display_list);
00064     // react to the images & fields of view changing. We can update the
00065     // textures here.
00066     void CheckUpdate();
00067     // change the OpenGL state for rendering the textures.
00068     void Begin();
00069     void End();
00070     // set to true if we are doing photmetric correction
00071     void SetPhotometricCorrect(bool state);
00072     // return true if we are doing photometric correction.
00073     bool GetPhotometricCorrect() {return photometric_correct;}
00074     // get the OpneGL texture name for a given image
00075     unsigned int GetTextureName(unsigned int image_number);
00076     // binds the texture for a given image
00077     void BindTexture(unsigned int image_number);
00078     // disables the image textures
00079     void DisableTexture(bool maskOnly=false);
00080 
00081 protected:
00082     PT::Panorama  * m_pano;
00083     ViewState *view_state;
00084     float viewer_exposure;
00085     // remove textures for deleted images.
00086     void CleanTextures();
00087     class TextureInfo
00088         // If the TextureInfo is deleted while the image is loading, we want to
00089         // avoid a segfault when the image loaded event happens. So we let the
00090         // signal react to destruction of a TextureInfo.
00091         : public boostSignal::trackable
00092     {
00093     public:
00094         TextureInfo(ViewState *new_view_state);
00095         // specify log2(width) and log2(height) for the new texture's size.
00096         // this is the size of mip level 0, which may or may not be defined.
00097         TextureInfo(ViewState *new_view_state, unsigned int width_p, unsigned int height_p);
00098         ~TextureInfo();
00099         // width and height are the size of the texture. This can be different
00100         // to the image size, we have to scale to powers of two. The texture
00101         // size is the biggest we can use for the image without scaling up
00102         // (unless the hardware doesn't support textures that big)
00103         // we generally have only lower mip levels defined though.
00104         unsigned int width, height;
00105         // log base 2 of the above, cached.
00106         unsigned int width_p, height_p;
00107         // min_lod is the most detailed mipmap level defined
00108         int min_lod;
00109         
00110         void DefineLevels(int min, int max,
00111                           bool photometric_correct,
00112                           const HuginBase::PanoramaOptions &dest_img,
00113                           const HuginBase::SrcPanoImage &state);
00114         void DefineMaskTexture(const HuginBase::SrcPanoImage &srcImg);
00115         void UpdateMask(const HuginBase::SrcPanoImage &srcImg);
00116         void SetMaxLevel(int level);
00117         void Bind();
00118         void BindImageTexture();
00119         void BindMaskTexture();
00120         unsigned int GetNumber() {return num;};
00121         // if the image has a mask, we want to use alpha blending to draw it.
00122         bool GetUseAlpha() {return has_mask;};
00123         bool GetHasActiveMasks() {return has_active_masks;};
00124     private:
00125         unsigned int num;     // the openGL texture name
00126         unsigned int numMask; // the openGL texture name for the mask
00127         bool has_mask; // this is the alpha channel
00128         bool has_active_masks; // has active masks
00129         ViewState *m_viewState;
00131         HuginBase::ImageCache::RequestPtr m_imageRequest;
00132         // this binds a new texture in openGL and sets the various parameters
00133         // we need for it.
00134         void CreateTexture();
00135         void SetParameters();
00136     };
00137     
00138     // A TextureKey uniquely identifies a texture. It contains the filename
00139     // of the image and the photometric correction properties used to make it.
00140     class TextureKey
00141     {
00142     public:
00143         TextureKey();
00144         TextureKey(HuginBase::SrcPanoImage * source, bool *photometric_correct_ptr);
00145             
00146         // TODO all of this lot should probably be made read only
00147         std::string filename;
00148         double exposure, white_balance_red, white_balance_blue;
00149         std::vector<float> EMoR_params;
00150         std::vector<double> radial_vig_corr_coeff;
00151         hugin_utils::FDiff2D radial_vig_corr_center_shift;
00152         int vig_corr_mode;
00153         HuginBase::SrcPanoImage::ResponseType response_type;
00154         std::vector<double> radial_distortion_red;
00155         std::vector<double> radial_distortion_blue;
00156         double gamma;
00157         std::string masks;
00158                 
00159         // when stored in the textures map, this should be set to something that
00160         // always indicates if photometric correction comparisons should be made
00161         bool *photometric_correct;
00162         // we need to specify our own comparison function as the photometric
00163         // correction parameters do not need to be compared when we are not
00164         // using photometric correction.
00165         const bool operator==(const TextureKey comp) const;
00166         // we need to be able to order the keys
00167         const bool operator<(const TextureKey comp) const;
00168     private:
00169         void SetOptions(HuginBase::SrcPanoImage *source);
00170     };
00171     // we map filenames to TexturesInfos, so we can keep track of
00172     // images' textures when the numbers change.
00173     std::map<TextureKey, TextureInfo> textures;
00174     // Our pixel budget for all textures.
00175     unsigned int GetMaxTotalTexels();
00176     // this is the maximum size a single texture is supported on the hardware.
00177     unsigned int GetMaxTextureSizePower(); 
00178     float texel_density;          // multiply by angles to get optimal size.
00179     bool photometric_correct;
00180 };
00181 
00182 #endif
00183    

Generated on 26 Oct 2014 for Hugintrunk by  doxygen 1.4.7