Project

General

Profile

Statistics
| Branch: | Revision:

root / rgbdslam / external / siftgpu / src / SiftGPU / GlobalUtil.cpp @ 9240aaa3

History | View | Annotate | Download (14.4 KB)

1 9240aaa3 Alex
////////////////////////////////////////////////////////////////////////////
2
//        File:                GlobalUtil.cpp
3
//        Author:                Changchang Wu
4
//        Description : Global Utility class for SiftGPU
5
//
6
//
7
//
8
//        Copyright (c) 2007 University of North Carolina at Chapel Hill
9
//        All Rights Reserved
10
//
11
//        Permission to use, copy, modify and distribute this software and its
12
//        documentation for educational, research and non-profit purposes, without
13
//        fee, and without a written agreement is hereby granted, provided that the
14
//        above copyright notice and the following paragraph appear in all copies.
15
//        
16
//        The University of North Carolina at Chapel Hill make no representations
17
//        about the suitability of this software for any purpose. It is provided
18
//        'as is' without express or implied warranty. 
19
//
20
//        Please send BUG REPORTS to ccwu@cs.unc.edu
21
//
22
////////////////////////////////////////////////////////////////////////////
23
#include <string.h>
24
#include <iostream>
25
using std::cout;
26
27
#include "GL/glew.h"
28
#include "GlobalUtil.h"
29
30
//for windows, the default timing uses timeGetTime, you can define TIMING_BY_CLOCK to use clock()
31
//for other os, the default timing uses gettimeofday, you can define TIMING_BY_CLOCK to use clock()
32
33
34
#if defined(_WIN32)
35
        #if defined(TIMING_BY_CLOCK)
36
                #include <time.h>
37
        #else
38
            #define WIN32_LEAN_AND_MEAN
39
            #include <windows.h>
40
                #include <mmsystem.h>
41
        #endif
42
#else
43
        #if defined(TIMING_BY_CLOCK)
44
                #include <time.h>
45
        #else
46
                #include <sys/time.h>
47
        #endif
48
#include <stdio.h>
49
#endif
50
51
#include "LiteWindow.h"
52
53
//
54
int GlobalParam::                _verbose =  1;   
55
int        GlobalParam::       _timingS = 1;  //print out information of each step
56
int        GlobalParam::       _timingO = 0;  //print out information of each octave
57
int        GlobalParam::       _timingL = 0;        //print out information of each level
58
GLuint GlobalParam::        _texTarget = GL_TEXTURE_RECTANGLE_ARB; //only this one is supported
59
GLuint GlobalParam::        _iTexFormat =GL_RGBA32F_ARB;        //or GL_RGBA16F_ARB
60
int        GlobalParam::                _debug = 0;                //enable debug code?
61
int        GlobalParam::                _usePackedTex = 1;//packed implementation
62
int GlobalParam::                _BetaFilter = 0;
63
int        GlobalParam::                _UseCUDA = 0;
64
int GlobalParam::       _UseOpenCL = 0;
65
int GlobalParam::                _MaxFilterWidth = -1;        //maximum filter width, use when GPU is not good enough
66
float GlobalParam::     _FilterWidthFactor        = 4.0f;        //the filter size will be _FilterWidthFactor*sigma*2+1
67
float GlobalParam::     _DescriptorWindowFactor = 3.0f; //descriptor sampling window factor
68
int GlobalParam::                _SubpixelLocalization = 1; //sub-pixel and sub-scale localization         
69
int        GlobalParam::       _MaxOrientation = 2;        //whether we find multiple orientations for each feature 
70
int        GlobalParam::       _OrientationPack2 = 0;  //use one float to store two orientations
71
float GlobalParam::                _MaxFeaturePercent = 0.005f;//at most 0.005 of all pixels
72
int        GlobalParam::                _MaxLevelFeatureNum = 4096; //maximum number of features of a level
73
int GlobalParam::                _FeatureTexBlock = 4; //feature texture storagte alignment
74
int        GlobalParam::                _NarrowFeatureTex = 0; 
75
76
//if _ForceTightPyramid is not 0, pyramid will be reallocated to fit the size of input images.
77
//otherwise, pyramid can be reused for smaller input images. 
78
int GlobalParam::                _ForceTightPyramid = 0;
79
80
//use gpu or cpu to generate feature list ...gpu is a little bit faster
81
int GlobalParam::                _ListGenGPU =        1;        
82
int        GlobalParam::       _ListGenSkipGPU = 6;  //how many levels are skipped on gpu
83
int GlobalParam::                _PreProcessOnCPU = 1; //convert rgb 2 intensity on gpu, down sample on GPU
84
85
//hardware parameter,   automatically retrieved
86
int GlobalParam::                _texMaxDim = 3200;        //Maximum working size for SiftGPU, 3200 for packed
87
int        GlobalParam::                _texMaxDimGL = 4096;        //GPU texture limit
88
int GlobalParam::       _texMinDim = 16; //
89
int        GlobalParam::                _IsNvidia = 0;                                //GPU vendor
90
91
//you can't change the following 2 values
92
//all other versions of code are now dropped
93
int GlobalParam::       _DescriptorPPR = 8;
94
int        GlobalParam::                _DescriptorPPT = 16;
95
96
//whether orientation/descriptor is supported by hardware
97
int GlobalParam::                _SupportNVFloat = 0;
98
int GlobalParam::       _SupportTextureRG = 0;
99
int        GlobalParam::                _UseDynamicIndexing = 0; 
100
int GlobalParam::                _FullSupported = 1;
101
102
//when SiftGPUEX is not used, display VBO generation is skipped
103
int GlobalParam::                _UseSiftGPUEX = 0;
104
int GlobalParam::                _InitPyramidWidth=0;
105
int GlobalParam::                _InitPyramidHeight=0;
106
int        GlobalParam::                _octave_min_default=0;
107
int        GlobalParam::                _octave_num_default=-1;
108
109
110
//////////////////////////////////////////////////////////////////
111
int        GlobalParam::                _GoodOpenGL = -1;      //indicates OpenGl initialization status
112
int        GlobalParam::                _FixedOrientation = 0; //upright
113
int        GlobalParam::                _LoweOrigin = 0;       //(0, 0) to be at the top-left corner.
114
int        GlobalParam::       _NormalizedSIFT = 1;   //normalize descriptor
115
int GlobalParam::       _BinarySIFT = 0;       //saving binary format
116
int        GlobalParam::                _ExitAfterSIFT = 0;    //exif after saving result
117
int        GlobalParam::                _KeepExtremumSign = 0; // if 1, scales of dog-minimum will be multiplied by -1
118
///
119
int GlobalParam::       _KeyPointListForceLevel0 = 0;
120
int        GlobalParam::                _ProcessOBO = 0;
121
int GlobalParam::       _TruncateMethod = 0;
122
int        GlobalParam::                _PreciseBorder = 1;
123
124
// parameter changing for better matching with Lowe's SIFT
125
float GlobalParam::                _OrientationWindowFactor = 2.0f;        // 1.0(-v292), 2(v293-), 
126
float GlobalParam::                _OrientationGaussianFactor = 1.5f;        // 4.5(-v292), 1.5(v293-)
127
float GlobalParam::     _MulitiOrientationThreshold = 0.8f;
128
///
129
int GlobalParam::       _FeatureCountThreshold = -1;
130
131
///////////////////////////////////////////////
132
int        GlobalParam::                        _WindowInitX = -1;
133
int GlobalParam::                        _WindowInitY = -1;
134
int GlobalParam::           _DeviceIndex = 0; 
135
const char * GlobalParam::        _WindowDisplay = NULL;
136
137
138
139
/////////////////
140
////
141
ClockTimer GlobalUtil::        _globalTimer;
142
143
144
#ifdef _DEBUG
145
void GlobalUtil::CheckErrorsGL(const char* location)
146
{
147
        GLuint errnum;
148
        const char *errstr;
149
        while (errnum = glGetError()) 
150
        {
151
                errstr = (const char *)(gluErrorString(errnum));
152
                if(errstr) {
153
                        std::cerr << errstr; 
154
                }
155
                else {
156
                        std::cerr  << "Error " << errnum;
157
                }
158
                
159
                if(location) std::cerr  << " at " << location;                
160
                std::cerr  << "\n";
161
        }
162
        return;
163
}
164
165
#endif
166
167
void GlobalUtil::CleanupOpenGL()
168
{
169
        glActiveTexture(GL_TEXTURE0);
170
}
171
172
void GlobalUtil::SetDeviceParam(int argc, char** argv)
173
{
174
    if(GlobalParam::_GoodOpenGL!= -1) return;
175
176
    #define CHAR1_TO_INT(x)         ((x >= 'A' && x <= 'Z') ? x + 32 : x)
177
    #define CHAR2_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0)  
178
    #define CHAR3_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0)
179
    #define STRING_TO_INT(str)      (CHAR1_TO_INT(str[0]) +  (CHAR3_TO_INT(str, 1) << 8))
180
181
        char* arg, * opt;
182
        for(int i = 0; i< argc; i++)
183
        {
184
                arg = argv[i];
185
                if(arg == NULL || arg[0] != '-')continue;
186
                opt = arg+1;
187
 
188
        ////////////////////////////////
189
        switch( STRING_TO_INT(opt))
190
        {
191
        case 'w' + ('i' << 8) + ('n' << 16) + ('p' << 24): 
192
            if(_GoodOpenGL != 2 && i + 1 < argc)
193
            {
194
                int x =0, y=0;
195
                if(sscanf(argv[++i], "%dx%d", &x, &y) == 2)
196
                {
197
                    GlobalParam::_WindowInitX = x;
198
                    GlobalParam::_WindowInitY = y;
199
                }  
200
            }
201
            break;  
202
        case 'd' + ('i' << 8) + ('s' << 16) + ('p' << 24):
203
            if(_GoodOpenGL != 2 && i + 1 < argc)
204
            {
205
                GlobalParam::_WindowDisplay = argv[++i];
206
            }
207
            break;   
208
        case 'c' + ('u' << 8) + ('d' << 16) + ('a' << 24):
209
            if(i + 1 < argc)
210
            {
211
               int device =  0; 
212
               scanf(argv[++i], "%d", &device) ;
213
               GlobalParam::_DeviceIndex = device;
214
            }
215
            break;  
216
        default:
217
            break;
218
        }                
219
    }
220
}
221
222
void GlobalUtil::SetTextureParameter()
223
{
224
225
        glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
226
        glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
227
        glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
228
        glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
229
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
230
}
231
232
//if image need to be up sampled ..use this one
233
234
void GlobalUtil::SetTextureParameterUS()
235
{
236
237
        glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
238
        glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 
239
        glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
240
        glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
241
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
242
}
243
244
245
void GlobalUtil::FitViewPort(int width, int height)
246
{
247
        GLint port[4];
248
        glGetIntegerv(GL_VIEWPORT, port);
249
        if(port[2] !=width || port[3] !=height)
250
        {
251
                glViewport(0, 0, width, height);      
252
                glMatrixMode(GL_PROJECTION);    
253
                glLoadIdentity();               
254
                glOrtho(0, width, 0, height,  0, 1);                
255
                glMatrixMode(GL_MODELVIEW);     
256
                glLoadIdentity();  
257
        }
258
}
259
260
261
bool GlobalUtil::CheckFramebufferStatus() {
262
    GLenum status;
263
    status=(GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
264
    switch(status) {
265
        case GL_FRAMEBUFFER_COMPLETE_EXT:
266
            return true;
267
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
268
            std::cerr<<("Framebuffer incomplete,incomplete attachment\n");
269
            return false;
270
        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
271
            std::cerr<<("Unsupported framebuffer format\n");
272
            return false;
273
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
274
            std::cerr<<("Framebuffer incomplete,missing attachment\n");
275
            return false;
276
        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
277
            std::cerr<<("Framebuffer incomplete,attached images must have same dimensions\n");
278
            return false;
279
        case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
280
             std::cerr<<("Framebuffer incomplete,attached images must have same format\n");
281
            return false;
282
        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
283
            std::cerr<<("Framebuffer incomplete,missing draw buffer\n");
284
            return false;
285
        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
286
            std::cerr<<("Framebuffer incomplete,missing read buffer\n");
287
            return false;
288
    }
289
        return false;
290
}
291
292
293
int ClockTimer::ClockMS()
294
{
295
#if defined(TIMING_BY_CLOCK)
296
        return clock() * 1000 / CLOCKS_PER_SEC;
297
#elif defined(_WIN32)
298
        static int    started = 0;
299
        static int        tstart;
300
        if(started == 0)
301
        {
302
                tstart = timeGetTime();
303
                started = 1;
304
                return 0;
305
        }else
306
        {
307
                return timeGetTime() - tstart;
308
        }
309
#else
310
        static int    started = 0;
311
        static struct timeval tstart;
312
        if(started == 0) 
313
        {
314
                gettimeofday(&tstart, NULL);
315
                started = 1;
316
                return 0;
317
        }else
318
        {        
319
                struct timeval now;
320
                gettimeofday(&now, NULL) ;
321
                return (now.tv_usec - tstart.tv_usec + (now.tv_sec - tstart.tv_sec) * 1000000)/1000;
322
        }
323
#endif
324
}
325
326
double ClockTimer::CLOCK()
327
{
328
        return ClockMS() * 0.001;
329
}
330
331
void ClockTimer::InitHighResolution()
332
{
333
#if defined(_WIN32) 
334
        timeBeginPeriod(1);
335
#endif
336
}
337
338
void ClockTimer::StartTimer(const char* event, int verb)
339
{        
340
        strcpy(_current_event, event);
341
        _time_start = ClockMS();
342
        if(verb && GlobalUtil::_verbose)
343
        {
344
                std::cout<<"\n["<<_current_event<<"]:\tbegin ...\n";
345
        }
346
} 
347
348
void ClockTimer::StopTimer(int verb)
349
{
350
        _time_stop = ClockMS();
351
        if(verb && GlobalUtil::_verbose)
352
        {
353
                std::cout<<"["<<_current_event<<"]:\t"<<GetElapsedTime()<<"\n";
354
        }
355
}
356
357
float ClockTimer::GetElapsedTime()
358
{
359
        return (_time_stop - _time_start)  * 0.001f;
360
}
361
362
void GlobalUtil::SetGLParam()
363
{
364
    if(GlobalUtil::_UseCUDA) return;
365
    else if(GlobalUtil::_UseOpenCL) return;
366
        glEnable(GlobalUtil::_texTarget);
367
        glActiveTexture(GL_TEXTURE0);
368
}
369
370
void GlobalUtil::InitGLParam(int NotTargetGL)
371
{
372
    //IF the OpenGL context passed the check
373
    if(GlobalUtil::_GoodOpenGL == 2) return;
374
    //IF the OpenGl context failed the check
375
    if(GlobalUtil::_GoodOpenGL == 0) return; 
376
    //IF se use CUDA or OpenCL
377
    if(NotTargetGL && !GlobalUtil::_UseSiftGPUEX)
378
    {
379
        GlobalUtil::_GoodOpenGL = 1;
380
    }else
381
    {
382
        //first time in this function
383
            glewInit();
384
385
            GlobalUtil::_GoodOpenGL = 2;
386
387
            const char * vendor = (const char * )glGetString(GL_VENDOR);
388
            if(vendor)
389
            {
390
                    GlobalUtil::_IsNvidia  = (strstr(vendor, "NVIDIA") !=NULL ? 1 : 0);
391
                    if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << "\n";
392
            }
393
            if(GlobalUtil::_IsNvidia == 0 )GlobalUtil::_UseCUDA = 0;
394
395
            if (glewGetExtension("GL_ARB_fragment_shader")    != GL_TRUE ||
396
                    glewGetExtension("GL_ARB_shader_objects")       != GL_TRUE ||
397
                    glewGetExtension("GL_ARB_shading_language_100") != GL_TRUE)
398
            {
399
                    std::cerr << "Shader not supported by your hardware!\n";
400
                    GlobalUtil::_GoodOpenGL = 0;
401
            }
402
403
            if (glewGetExtension("GL_EXT_framebuffer_object") != GL_TRUE) 
404
            {
405
                    std::cerr << "Framebuffer object not supported!\n";
406
                    GlobalUtil::_GoodOpenGL = 0;
407
            }
408
409
            if(glewGetExtension("GL_ARB_texture_rectangle")==GL_TRUE)
410
            {
411
                GLint value;
412
                    GlobalUtil::_texTarget =  GL_TEXTURE_RECTANGLE_ARB;
413
                    glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &value);
414
                    GlobalUtil::_texMaxDimGL = value; 
415
                    if(GlobalUtil::_verbose) std::cout << "TEXTURE:\t" << GlobalUtil::_texMaxDimGL << "\n";
416
417
                    if(GlobalUtil::_texMaxDim == 0 || GlobalUtil::_texMaxDim > GlobalUtil::_texMaxDimGL)
418
                    {
419
                            GlobalUtil::_texMaxDim = GlobalUtil::_texMaxDimGL; 
420
                    }
421
                    glEnable(GlobalUtil::_texTarget);
422
            }else
423
            {
424
                    std::cerr << "GL_ARB_texture_rectangle not supported!\n";
425
                    GlobalUtil::_GoodOpenGL = 0;
426
            }
427
428
            GlobalUtil::_SupportNVFloat = glewGetExtension("GL_NV_float_buffer");
429
            GlobalUtil::_SupportTextureRG = glewGetExtension("GL_ARB_texture_rg");
430
431
432
            glShadeModel(GL_FLAT);
433
            glPolygonMode(GL_FRONT, GL_FILL);
434
435
            GlobalUtil::SetTextureParameter();
436
    }
437
}
438
439
int GlobalUtil::CreateWindowEZ(LiteWindow* window)
440
{
441
        if(window == NULL) return 0;
442
    if(!window->IsValid())window->Create(_WindowInitX, _WindowInitY, _WindowDisplay);
443
    if(window->IsValid()) 
444
    {
445
        window->MakeCurrent();
446
        return 1;
447
    }
448
    else  
449
    {
450
        std::cerr << "Unable to create OpenGL Context!\n";
451
                std::cerr << "For nVidia cards, you can try change to CUDA mode in this case\n";
452
        return 0;
453
    }
454
}
455
456
int GlobalUtil::CreateWindowEZ()
457
{
458
        static LiteWindow window;
459
    return CreateWindowEZ(&window);
460
}
461
462
int CreateLiteWindow(LiteWindow* window)
463
{
464
    return GlobalUtil::CreateWindowEZ(window);
465
}