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 | } |