GlobalUtil.cpp
Go to the documentation of this file.
00001 
00002 //      File:           GlobalUtil.cpp
00003 //      Author:         Changchang Wu
00004 //      Description : Global Utility class for SiftGPU
00005 //
00006 //
00007 //
00008 //      Copyright (c) 2007 University of North Carolina at Chapel Hill
00009 //      All Rights Reserved
00010 //
00011 //      Permission to use, copy, modify and distribute this software and its
00012 //      documentation for educational, research and non-profit purposes, without
00013 //      fee, and without a written agreement is hereby granted, provided that the
00014 //      above copyright notice and the following paragraph appear in all copies.
00015 //      
00016 //      The University of North Carolina at Chapel Hill make no representations
00017 //      about the suitability of this software for any purpose. It is provided
00018 //      'as is' without express or implied warranty. 
00019 //
00020 //      Please send BUG REPORTS to ccwu@cs.unc.edu
00021 //
00023 #include <string.h>
00024 #include <iostream>
00025 using std::cout;
00026 
00027 #include "GL/glew.h"
00028 #include "GlobalUtil.h"
00029 
00030 //for windows, the default timing uses timeGetTime, you can define TIMING_BY_CLOCK to use clock()
00031 //for other os, the timing uses gettimeofday
00032 
00033 
00034 #if defined(_WIN32)
00035         #if defined(TIMING_BY_CLOCK)
00036                 #include <time.h>
00037         #else
00038             #define WIN32_LEAN_AND_MEAN
00039             #include <windows.h>
00040                 #include <mmsystem.h>
00041         #endif
00042 #else
00043         #include <sys/time.h>
00044         #include <stdio.h>
00045 #endif
00046 
00047 #include "LiteWindow.h"
00048 
00049 //
00050 int GlobalParam::		_verbose =  1;   
00051 int     GlobalParam::       _timingS = 1;  //print out information of each step
00052 int     GlobalParam::       _timingO = 0;  //print out information of each octave
00053 int     GlobalParam::       _timingL = 0;       //print out information of each level
00054 GLuint GlobalParam::	_texTarget = GL_TEXTURE_RECTANGLE_ARB; //only this one is supported
00055 GLuint GlobalParam::	_iTexFormat =GL_RGBA32F_ARB;       //or GL_RGBA16F_ARB
00056 int     GlobalParam::		_debug = 0;              //enable debug code?
00057 int     GlobalParam::		_usePackedTex = 1;//packed implementation
00058 int     GlobalParam::		_UseCUDA = 0;
00059 int GlobalParam::       _UseOpenCL = 0;
00060 int GlobalParam::		_MaxFilterWidth = -1;        //maximum filter width, use when GPU is not good enough
00061 float GlobalParam::     _FilterWidthFactor      = 4.0f; //the filter size will be _FilterWidthFactor*sigma*2+1
00062 float GlobalParam::     _DescriptorWindowFactor = 3.0f; //descriptor sampling window factor
00063 int GlobalParam::		_SubpixelLocalization = 1; //sub-pixel and sub-scale localization    
00064 int     GlobalParam::       _MaxOrientation = 2;        //whether we find multiple orientations for each feature 
00065 int     GlobalParam::       _OrientationPack2 = 0;  //use one float to store two orientations
00066 float GlobalParam::		_MaxFeaturePercent = 0.005f;//at most 0.005 of all pixels
00067 int     GlobalParam::		_MaxLevelFeatureNum = 4096; //maximum number of features of a level
00068 int GlobalParam::		_FeatureTexBlock = 4; //feature texture storagte alignment
00069 int     GlobalParam::		_NarrowFeatureTex = 0; 
00070 
00071 //if _ForceTightPyramid is not 0, pyramid will be reallocated to fit the size of input images.
00072 //otherwise, pyramid can be reused for smaller input images. 
00073 int GlobalParam::		_ForceTightPyramid = 0;
00074 
00075 //use gpu or cpu to generate feature list ...gpu is a little bit faster
00076 int GlobalParam::		_ListGenGPU =        1;      
00077 int     GlobalParam::       _ListGenSkipGPU = 6;  //how many levels are skipped on gpu
00078 int GlobalParam::		_PreProcessOnCPU = 1; //convert rgb 2 intensity on gpu, down sample on GPU
00079 
00080 //hardware parameter,   automatically retrieved
00081 int GlobalParam::		_texMaxDim = 3200;   //Maximum working size for SiftGPU, 3200 for packed
00082 int     GlobalParam::		_texMaxDimGL = 4096;        //GPU texture limit
00083 int GlobalParam::       _texMinDim = 16; //
00084 int     GlobalParam::		_MemCapGPU = 0;
00085 int GlobalParam::		_FitMemoryCap = 0;
00086 int     GlobalParam::		_IsNvidia = 0;                           //GPU vendor
00087 int GlobalParam::		_KeepShaderLoop = 0;
00088 
00089 //you can't change the following 2 values
00090 //all other versions of code are now dropped
00091 int GlobalParam::       _DescriptorPPR = 8;
00092 int     GlobalParam::		_DescriptorPPT = 16;
00093 
00094 //whether orientation/descriptor is supported by hardware
00095 int GlobalParam::		_SupportNVFloat = 0;
00096 int GlobalParam::       _SupportTextureRG = 0;
00097 int     GlobalParam::		_UseDynamicIndexing = 0; 
00098 int GlobalParam::		_FullSupported = 1;
00099 
00100 //when SiftGPUEX is not used, display VBO generation is skipped
00101 int GlobalParam::		_UseSiftGPUEX = 0;
00102 int GlobalParam::		_InitPyramidWidth=0;
00103 int GlobalParam::		_InitPyramidHeight=0;
00104 int     GlobalParam::		_octave_min_default=0;
00105 int     GlobalParam::		_octave_num_default=-1;
00106 
00107 
00109 int     GlobalParam::		_GoodOpenGL = -1;      //indicates OpenGl initialization status
00110 int     GlobalParam::		_FixedOrientation = 0; //upright
00111 int     GlobalParam::		_LoweOrigin = 0;       //(0, 0) to be at the top-left corner.
00112 int     GlobalParam::       _NormalizedSIFT = 1;   //normalize descriptor
00113 int GlobalParam::       _BinarySIFT = 0;       //saving binary format
00114 int     GlobalParam::		_ExitAfterSIFT = 0;    //exif after saving result
00115 int     GlobalParam::		_KeepExtremumSign = 0; // if 1, scales of dog-minimum will be multiplied by -1
00117 int GlobalParam::       _KeyPointListForceLevel0 = 0;
00118 int GlobalParam::		_DarknessAdaption = 0;
00119 int     GlobalParam::		_ProcessOBO = 0;
00120 int GlobalParam::       _TruncateMethod = 0;
00121 int     GlobalParam::		_PreciseBorder = 1;
00122 
00123 // parameter changing for better matching with Lowe's SIFT
00124 float GlobalParam::		_OrientationWindowFactor = 2.0f;   // 1.0(-v292), 2(v293-), 
00125 float GlobalParam::		_OrientationGaussianFactor = 1.5f; // 4.5(-v292), 1.5(v293-)
00126 float GlobalParam::     _MulitiOrientationThreshold = 0.8f;
00128 int GlobalParam::       _FeatureCountThreshold = -1;
00129 
00131 int     GlobalParam::			_WindowInitX = -1;
00132 int GlobalParam::			_WindowInitY = -1;
00133 int GlobalParam::           _DeviceIndex = 0; 
00134 const char * GlobalParam::	_WindowDisplay = NULL;
00135 
00136 
00137 
00140 ClockTimer GlobalUtil::	_globalTimer;
00141 
00142 
00143 #ifdef _DEBUG
00144 void GlobalUtil::CheckErrorsGL(const char* location)
00145 {
00146         GLuint errnum;
00147         const char *errstr;
00148         while (errnum = glGetError()) 
00149         {
00150                 errstr = (const char *)(gluErrorString(errnum));
00151                 if(errstr) {
00152                         std::cerr << errstr; 
00153                 }
00154                 else {
00155                         std::cerr  << "Error " << errnum;
00156                 }
00157                 
00158                 if(location) std::cerr  << " at " << location;          
00159                 std::cerr  << "\n";
00160         }
00161         return;
00162 }
00163 
00164 #endif
00165 
00166 void GlobalUtil::CleanupOpenGL()
00167 {
00168         glActiveTexture(GL_TEXTURE0);
00169 }
00170 
00171 void GlobalUtil::SetDeviceParam(int argc, char** argv)
00172 {
00173     if(GlobalParam::_GoodOpenGL!= -1) return;
00174 
00175     #define CHAR1_TO_INT(x)         ((x >= 'A' && x <= 'Z') ? x + 32 : x)
00176     #define CHAR2_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0)  
00177     #define CHAR3_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0)
00178     #define STRING_TO_INT(str)      (CHAR1_TO_INT(str[0]) +  (CHAR3_TO_INT(str, 1) << 8))
00179 
00180         char* arg, * opt;
00181         for(int i = 0; i< argc; i++)
00182         {
00183                 arg = argv[i];
00184                 if(arg == NULL || arg[0] != '-')continue;
00185                 opt = arg+1;
00186  
00188         switch( STRING_TO_INT(opt))
00189         {
00190         case 'w' + ('i' << 8) + ('n' << 16) + ('p' << 24): 
00191             if(_GoodOpenGL != 2 && i + 1 < argc)
00192             {
00193                 int x =0, y=0;
00194                 if(sscanf(argv[++i], "%dx%d", &x, &y) == 2)
00195                 {
00196                     GlobalParam::_WindowInitX = x;
00197                     GlobalParam::_WindowInitY = y;
00198                 }  
00199             }
00200             break;  
00201         case 'd' + ('i' << 8) + ('s' << 16) + ('p' << 24):
00202             if(_GoodOpenGL != 2 && i + 1 < argc)
00203             {
00204                 GlobalParam::_WindowDisplay = argv[++i];
00205             }
00206             break;   
00207         case 'c' + ('u' << 8) + ('d' << 16) + ('a' << 24):
00208             if(i + 1 < argc)
00209             {
00210                int device =  0; 
00211                scanf(argv[++i], "%d", &device) ;
00212                GlobalParam::_DeviceIndex = device;
00213             }
00214             break;  
00215         default:
00216             break;
00217         }               
00218     }
00219 }
00220 
00221 void GlobalUtil::SetTextureParameter()
00222 {
00223 
00224         glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
00225         glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
00226         glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
00227         glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
00228         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00229 }
00230 
00231 //if image need to be up sampled ..use this one
00232 
00233 void GlobalUtil::SetTextureParameterUS()
00234 {
00235 
00236         glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
00237         glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
00238         glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
00239         glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
00240         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
00241 }
00242 
00243 
00244 void GlobalUtil::FitViewPort(int width, int height)
00245 {
00246         GLint port[4];
00247         glGetIntegerv(GL_VIEWPORT, port);
00248         if(port[2] !=width || port[3] !=height)
00249         {
00250                 glViewport(0, 0, width, height);      
00251                 glMatrixMode(GL_PROJECTION);    
00252                 glLoadIdentity();               
00253                 glOrtho(0, width, 0, height,  0, 1);            
00254                 glMatrixMode(GL_MODELVIEW);     
00255                 glLoadIdentity();  
00256         }
00257 }
00258 
00259 
00260 bool GlobalUtil::CheckFramebufferStatus() {
00261     GLenum status;
00262     status=(GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00263     switch(status) {
00264         case GL_FRAMEBUFFER_COMPLETE_EXT:
00265             return true;
00266         case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00267             std::cerr<<("Framebuffer incomplete,incomplete attachment\n");
00268             return false;
00269         case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00270             std::cerr<<("Unsupported framebuffer format\n");
00271             return false;
00272         case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00273             std::cerr<<("Framebuffer incomplete,missing attachment\n");
00274             return false;
00275         case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00276             std::cerr<<("Framebuffer incomplete,attached images must have same dimensions\n");
00277             return false;
00278         case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00279              std::cerr<<("Framebuffer incomplete,attached images must have same format\n");
00280             return false;
00281         case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00282             std::cerr<<("Framebuffer incomplete,missing draw buffer\n");
00283             return false;
00284         case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00285             std::cerr<<("Framebuffer incomplete,missing read buffer\n");
00286             return false;
00287     }
00288         return false;
00289 }
00290 
00291 
00292 int ClockTimer::ClockMS()
00293 {
00294 #if defined(_WIN32)
00295         #if defined(TIMING_BY_CLOCK)
00296                 return clock() * 1000 / CLOCKS_PER_SEC;
00297         #else
00298                 static int    started = 0;
00299                 static int      tstart;
00300                 if(started == 0)
00301                 {
00302                         tstart = timeGetTime();
00303                         started = 1;
00304                         return 0;
00305                 }else
00306                 {
00307                         return timeGetTime() - tstart;
00308                 }
00309         #endif
00310 #else
00311         static int    started = 0;
00312         static struct timeval tstart;
00313         if(started == 0) 
00314         {
00315                 gettimeofday(&tstart, NULL);
00316                 started = 1;
00317                 return 0;
00318         }else
00319         {       
00320                 struct timeval now;
00321                 gettimeofday(&now, NULL) ;
00322                 return (now.tv_usec - tstart.tv_usec + (now.tv_sec - tstart.tv_sec) * 1000000)/1000;
00323         }
00324 #endif
00325 }
00326 
00327 double ClockTimer::CLOCK()
00328 {
00329         return ClockMS() * 0.001;
00330 }
00331 
00332 void ClockTimer::InitHighResolution()
00333 {
00334 #if defined(_WIN32) 
00335         timeBeginPeriod(1);
00336 #endif
00337 }
00338 
00339 void ClockTimer::StartTimer(const char* event, int verb)
00340 {       
00341         strcpy(_current_event, event);
00342         _time_start = ClockMS();
00343         if(verb && GlobalUtil::_verbose)
00344         {
00345                 std::cout<<"\n["<<_current_event<<"]:\tbegin ...\n";
00346         }
00347 } 
00348 
00349 void ClockTimer::StopTimer(int verb)
00350 {
00351         _time_stop = ClockMS();
00352         if(verb && GlobalUtil::_verbose)
00353         {
00354                 std::cout<<"["<<_current_event<<"]:\t"<<GetElapsedTime()<<"\n";
00355         }
00356 }
00357 
00358 float ClockTimer::GetElapsedTime()
00359 {
00360         return (_time_stop - _time_start)  * 0.001f;
00361 }
00362 
00363 void GlobalUtil::SetGLParam()
00364 {
00365     if(GlobalUtil::_UseCUDA) return;
00366     else if(GlobalUtil::_UseOpenCL) return;
00367         glEnable(GlobalUtil::_texTarget);
00368         glActiveTexture(GL_TEXTURE0);
00369 }
00370 
00371 void GlobalUtil::InitGLParam(int NotTargetGL)
00372 {
00373     //IF the OpenGL context passed the check
00374     if(GlobalUtil::_GoodOpenGL == 2) return;
00375     //IF the OpenGl context failed the check
00376     if(GlobalUtil::_GoodOpenGL == 0) return; 
00377     //IF se use CUDA or OpenCL
00378     if(NotTargetGL && !GlobalUtil::_UseSiftGPUEX)
00379     {
00380         GlobalUtil::_GoodOpenGL = 1;
00381     }else
00382     {
00383         //first time in this function
00384         glewInit();
00385 
00386             GlobalUtil::_GoodOpenGL = 2;
00387 
00388             const char * vendor = (const char * )glGetString(GL_VENDOR);
00389             if(vendor)
00390             {
00391                     GlobalUtil::_IsNvidia  = (strstr(vendor, "NVIDIA") !=NULL ? 1 : 0);
00392 
00393                         // Let nVidia compiler to take care of the unrolling.
00394                         if (GlobalUtil::_IsNvidia)              GlobalUtil::_KeepShaderLoop = 1;
00395 
00396 #ifndef WIN32
00397                         else if(!strstr(vendor, "ATI") )
00398                         {
00399                                 // For non-nVidia non-ATI cards...simply assume it is Mesa
00400                                 // Keep the original shader loop, because some of the unrolled
00401                                 // loopes are too large, and it may take too much time to compile
00402                                 GlobalUtil::_KeepShaderLoop = 1;
00403                         }
00404 #endif
00405 
00406                         if(GlobalUtil::_IsNvidia && glewGetExtension("GL_NVX_gpu_memory_info"))
00407                         {
00408                                 glGetIntegerv(0x9049/*GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX*/, &_MemCapGPU);
00409                                 _MemCapGPU /= (1024); 
00410                           if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << ' ' <<_MemCapGPU << "MB\n";
00411                         }else if(strstr(vendor, "ATI") && glewGetExtension("GL_ATI_meminfo"))
00412                         {
00413                                 int info[4];    glGetIntegerv(0x87FC/*GL_TEXTURE_FREE_MEMORY_ATI*/, info);
00414                                 _MemCapGPU = info[0] / (1024);
00415                             if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << ' ' <<_MemCapGPU << "MB\n";
00416                         }else
00417                         {
00418                                 if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << "\n";
00419                         }
00420 
00421             }
00422             if(GlobalUtil::_IsNvidia == 0 )GlobalUtil::_UseCUDA = 0;
00423 
00424             if (glewGetExtension("GL_ARB_fragment_shader")    != GL_TRUE ||
00425                     glewGetExtension("GL_ARB_shader_objects")       != GL_TRUE ||
00426                     glewGetExtension("GL_ARB_shading_language_100") != GL_TRUE)
00427             {
00428                     std::cerr << "Shader not supported by your hardware!\n";
00429                     GlobalUtil::_GoodOpenGL = 0;
00430             }
00431 
00432             if (glewGetExtension("GL_EXT_framebuffer_object") != GL_TRUE) 
00433             {
00434                     std::cerr << "Framebuffer object not supported!\n";
00435                     GlobalUtil::_GoodOpenGL = 0;
00436             }
00437 
00438             if(glewGetExtension("GL_ARB_texture_rectangle")==GL_TRUE)
00439             {
00440                 GLint value;
00441                     GlobalUtil::_texTarget =  GL_TEXTURE_RECTANGLE_ARB;
00442                     glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &value);
00443                     GlobalUtil::_texMaxDimGL = value; 
00444                     if(GlobalUtil::_verbose) std::cout << "TEXTURE:\t" << GlobalUtil::_texMaxDimGL << "\n";
00445 
00446                     if(GlobalUtil::_texMaxDim == 0 || GlobalUtil::_texMaxDim > GlobalUtil::_texMaxDimGL)
00447                     {
00448                             GlobalUtil::_texMaxDim = GlobalUtil::_texMaxDimGL; 
00449                     }
00450                     glEnable(GlobalUtil::_texTarget);
00451             }else
00452             {
00453                     std::cerr << "GL_ARB_texture_rectangle not supported!\n";
00454                     GlobalUtil::_GoodOpenGL = 0;
00455             }
00456 
00457             GlobalUtil::_SupportNVFloat = glewGetExtension("GL_NV_float_buffer");
00458             GlobalUtil::_SupportTextureRG = glewGetExtension("GL_ARB_texture_rg");
00459 
00460 
00461             glShadeModel(GL_FLAT);
00462             glPolygonMode(GL_FRONT, GL_FILL);
00463 
00464             GlobalUtil::SetTextureParameter();
00465 
00466     }
00467 }
00468 
00469 void GlobalUtil::SelectDisplay()
00470 {
00471 #ifdef WIN32
00472         if(_WindowDisplay == NULL) return;
00473 
00474         HDC hdc = CreateDC(_WindowDisplay, _WindowDisplay, NULL, NULL);
00475         _WindowDisplay = NULL;
00476         if(hdc == NULL) 
00477         {
00478                 std::cout << "ERROR: invalid dispaly specified\n";
00479                 return;
00480         }
00481 
00482         PIXELFORMATDESCRIPTOR pfd = 
00483         {
00484                 sizeof(PIXELFORMATDESCRIPTOR),1,                             
00485                 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,               
00486                 PFD_TYPE_RGBA,24,0, 0, 0, 0, 0, 0,0,0,0,0, 0, 0, 0,16,0,0,                          
00487                 PFD_MAIN_PLANE,0,0, 0, 0                     
00488         };
00489         ChoosePixelFormat(hdc, &pfd);
00490 #endif
00491 }
00492 
00493 int GlobalUtil::CreateWindowEZ(LiteWindow* window)
00494 {
00495         if(window == NULL) return 0;
00496     if(!window->IsValid())window->Create(_WindowInitX, _WindowInitY, _WindowDisplay);
00497     if(window->IsValid()) 
00498     {
00499         window->MakeCurrent();
00500         std::cout << std::endl << "OPENGL context created successfully!" << std::endl << std::endl;
00501         return 1;
00502     }
00503     else  
00504     {
00505         std::cerr << "Unable to create OpenGL Context!\n";
00506                 std::cerr << "For nVidia cards, you can try change to CUDA mode in this case\n";
00507         return 0;
00508     }
00509 }
00510 
00511 int GlobalUtil::CreateWindowEZ()
00512 {
00513         static LiteWindow window;
00514     return CreateWindowEZ(&window);
00515 }
00516 
00517 int CreateLiteWindow(LiteWindow* window)
00518 {
00519     return GlobalUtil::CreateWindowEZ(window);
00520 }


siftgpu
Author(s): Changchang Wu
autogenerated on Wed Aug 26 2015 15:24:06