File: GlobalUtil.cpp

package info (click to toggle)
colmap 3.5-1
  • links: PTS
  • area: main
  • in suites: buster
  • size: 20,564 kB
  • sloc: ansic: 170,595; cpp: 95,339; python: 2,335; makefile: 183; sh: 51
file content (467 lines) | stat: -rwxr-xr-x 15,033 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
////////////////////////////////////////////////////////////////////////////
//	File:		GlobalUtil.cpp
//	Author:		Changchang Wu
//	Description : Global Utility class for SiftGPU
//
//
//
//	Copyright (c) 2007 University of North Carolina at Chapel Hill
//	All Rights Reserved
//
//	Permission to use, copy, modify and distribute this software and its
//	documentation for educational, research and non-profit purposes, without
//	fee, and without a written agreement is hereby granted, provided that the
//	above copyright notice and the following paragraph appear in all copies.
//
//	The University of North Carolina at Chapel Hill make no representations
//	about the suitability of this software for any purpose. It is provided
//	'as is' without express or implied warranty.
//
//	Please send BUG REPORTS to ccwu@cs.unc.edu
//
////////////////////////////////////////////////////////////////////////////
#include <string.h>
#include <iostream>
using std::cout;

#include "GL/glew.h"
#include "GlobalUtil.h"

#if defined(_WIN32)
  #define WIN32_LEAN_AND_MEAN
  #include <windows.h>
#else
  #include <stdio.h>
#endif

#include "LiteWindow.h"

//
int GlobalParam::		_verbose =  1;
int	GlobalParam::       _timingS = 1;  //print out information of each step
int	GlobalParam::       _timingO = 0;  //print out information of each octave
int	GlobalParam::       _timingL = 0;	//print out information of each level
GLuint GlobalParam::	_texTarget = GL_TEXTURE_RECTANGLE_ARB; //only this one is supported
GLuint GlobalParam::	_iTexFormat =GL_RGBA32F_ARB;	//or GL_RGBA16F_ARB
int	GlobalParam::		_debug = 0;		//enable debug code?
int	GlobalParam::		_usePackedTex = 1;//packed implementation
int	GlobalParam::		_UseCUDA = 0;
int GlobalParam::       _UseOpenCL = 0;
int GlobalParam::		_MaxFilterWidth = -1;	//maximum filter width, use when GPU is not good enough
float GlobalParam::     _FilterWidthFactor	= 4.0f;	//the filter size will be _FilterWidthFactor*sigma*2+1
float GlobalParam::     _DescriptorWindowFactor = 3.0f; //descriptor sampling window factor
int GlobalParam::		_SubpixelLocalization = 1; //sub-pixel and sub-scale localization
int	GlobalParam::       _MaxOrientation = 2;	//whether we find multiple orientations for each feature
int	GlobalParam::       _OrientationPack2 = 0;  //use one float to store two orientations
float GlobalParam::		_MaxFeaturePercent = 0.005f;//at most 0.005 of all pixels
int	GlobalParam::		_MaxLevelFeatureNum = 4096; //maximum number of features of a level
int GlobalParam::		_FeatureTexBlock = 4; //feature texture storagte alignment
int	GlobalParam::		_NarrowFeatureTex = 0;

//if _ForceTightPyramid is not 0, pyramid will be reallocated to fit the size of input images.
//otherwise, pyramid can be reused for smaller input images.
int GlobalParam::		_ForceTightPyramid = 0;

//use gpu or cpu to generate feature list ...gpu is a little bit faster
int GlobalParam::		_ListGenGPU =	1;
int	GlobalParam::       _ListGenSkipGPU = 6;  //how many levels are skipped on gpu
int GlobalParam::		_PreProcessOnCPU = 1; //convert rgb 2 intensity on gpu, down sample on GPU

//hardware parameter,   automatically retrieved
int GlobalParam::		_texMaxDim = 3200;	//Maximum working size for SiftGPU, 3200 for packed
int	GlobalParam::		_texMaxDimGL = 4096;        //GPU texture limit
int GlobalParam::       _texMinDim = 16; //
int	GlobalParam::		_MemCapGPU = 0;
int GlobalParam::		_FitMemoryCap = 0;
int	GlobalParam::		_IsNvidia = 0;				//GPU vendor
int GlobalParam::		_KeepShaderLoop = 0;

//you can't change the following 2 values
//all other versions of code are now dropped
int GlobalParam::       _DescriptorPPR = 8;
int	GlobalParam::		_DescriptorPPT = 16;

//whether orientation/descriptor is supported by hardware
int GlobalParam::		_SupportNVFloat = 0;
int GlobalParam::       _SupportTextureRG = 0;
int	GlobalParam::		_UseDynamicIndexing = 0;
int GlobalParam::		_FullSupported = 1;

//when SiftGPUEX is not used, display VBO generation is skipped
int GlobalParam::		_UseSiftGPUEX = 0;
int GlobalParam::		_InitPyramidWidth=0;
int GlobalParam::		_InitPyramidHeight=0;
int	GlobalParam::		_octave_min_default=0;
int	GlobalParam::		_octave_num_default=-1;


//////////////////////////////////////////////////////////////////
int	GlobalParam::		_GoodOpenGL = -1;      //indicates OpenGl initialization status
int	GlobalParam::		_FixedOrientation = 0; //upright
int	GlobalParam::		_LoweOrigin = 0;       //(0, 0) to be at the top-left corner.
int	GlobalParam::       _NormalizedSIFT = 1;   //normalize descriptor
int GlobalParam::       _BinarySIFT = 0;       //saving binary format
int	GlobalParam::		_ExitAfterSIFT = 0;    //exif after saving result
int	GlobalParam::		_KeepExtremumSign = 0; // if 1, scales of dog-minimum will be multiplied by -1
///
int GlobalParam::       _KeyPointListForceLevel0 = 0;
int GlobalParam::		_DarknessAdaption = 0;
int	GlobalParam::		_ProcessOBO = 0;
int GlobalParam::       _TruncateMethod = 0;
int	GlobalParam::		_PreciseBorder = 1;

// parameter changing for better matching with Lowe's SIFT
float GlobalParam::		_OrientationWindowFactor = 2.0f;	// 1.0(-v292), 2(v293-),
float GlobalParam::		_OrientationGaussianFactor = 1.5f;	// 4.5(-v292), 1.5(v293-)
float GlobalParam::     _MulitiOrientationThreshold = 0.8f;
///
int GlobalParam::       _FeatureCountThreshold = -1;

///////////////////////////////////////////////
int	GlobalParam::			_WindowInitX = -1;
int GlobalParam::			_WindowInitY = -1;
int GlobalParam::           _DeviceIndex = 0;
const char * GlobalParam::	_WindowDisplay = NULL;



/////////////////
////
ClockTimer GlobalUtil::	_globalTimer;


#ifdef _DEBUG
void GlobalUtil::CheckErrorsGL(const char* location)
{
	GLuint errnum;
	const char *errstr;
	while (errnum = glGetError())
	{
		errstr = (const char *)(gluErrorString(errnum));
		if(errstr) {
			std::cerr << errstr;
		}
		else {
			std::cerr  << "Error " << errnum;
		}

		if(location) std::cerr  << " at " << location;
		std::cerr  << "\n";
	}
	return;
}

#endif

void GlobalUtil::CleanupOpenGL()
{
	glActiveTexture(GL_TEXTURE0);
}

void GlobalUtil::SetDeviceParam(int argc, char** argv)
{
    if(GlobalParam::_GoodOpenGL!= -1) return;

    #define CHAR1_TO_INT(x)         ((x >= 'A' && x <= 'Z') ? x + 32 : x)
    #define CHAR2_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR1_TO_INT(str[i+1]) << 8) : 0)
    #define CHAR3_TO_INT(str, i)    (str[i] ? CHAR1_TO_INT(str[i]) + (CHAR2_TO_INT(str, i + 1) << 8) : 0)
    #define STRING_TO_INT(str)      (CHAR1_TO_INT(str[0]) +  (CHAR3_TO_INT(str, 1) << 8))

	char* arg, * opt;
	for(int i = 0; i< argc; i++)
	{
		arg = argv[i];
		if(arg == NULL || arg[0] != '-')continue;
		opt = arg+1;

        ////////////////////////////////
        switch( STRING_TO_INT(opt))
        {
        case 'w' + ('i' << 8) + ('n' << 16) + ('p' << 24):
            if(_GoodOpenGL != 2 && i + 1 < argc)
            {
                int x =0, y=0;
                if(sscanf(argv[++i], "%dx%d", &x, &y) == 2)
                {
                    GlobalParam::_WindowInitX = x;
                    GlobalParam::_WindowInitY = y;
                }
            }
            break;
        case 'd' + ('i' << 8) + ('s' << 16) + ('p' << 24):
            if(_GoodOpenGL != 2 && i + 1 < argc)
            {
                GlobalParam::_WindowDisplay = argv[++i];
            }
            break;
        case 'c' + ('u' << 8) + ('d' << 16) + ('a' << 24):
            if(i + 1 < argc)
            {
               int device =  0;
               scanf(argv[++i], "%d", &device) ;
               GlobalParam::_DeviceIndex = device;
            }
            break;
        default:
            break;
        }
    }
}

void GlobalUtil::SetTextureParameter()
{

	glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}

//if image need to be up sampled ..use this one

void GlobalUtil::SetTextureParameterUS()
{

	glTexParameteri (_texTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
	glTexParameteri (_texTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	glTexParameteri(_texTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(_texTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}


void GlobalUtil::FitViewPort(int width, int height)
{
	GLint port[4];
	glGetIntegerv(GL_VIEWPORT, port);
	if(port[2] !=width || port[3] !=height)
	{
		glViewport(0, 0, width, height);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		glOrtho(0, width, 0, height,  0, 1);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
	}
}


bool GlobalUtil::CheckFramebufferStatus() {
    GLenum status;
    status=(GLenum)glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
    switch(status) {
        case GL_FRAMEBUFFER_COMPLETE_EXT:
            return true;
        case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
            std::cerr<<("Framebuffer incomplete,incomplete attachment\n");
            return false;
        case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
            std::cerr<<("Unsupported framebuffer format\n");
            return false;
        case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
            std::cerr<<("Framebuffer incomplete,missing attachment\n");
            return false;
        case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
            std::cerr<<("Framebuffer incomplete,attached images must have same dimensions\n");
            return false;
        case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
             std::cerr<<("Framebuffer incomplete,attached images must have same format\n");
            return false;
        case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
            std::cerr<<("Framebuffer incomplete,missing draw buffer\n");
            return false;
        case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
            std::cerr<<("Framebuffer incomplete,missing read buffer\n");
            return false;
    }
	return false;
}


int ClockTimer::ClockMS()
{
	return 0;
}

double ClockTimer::CLOCK()
{
	return 0;
}

void ClockTimer::InitHighResolution()
{
}

void ClockTimer::StartTimer(const char* event, int verb)
{

}

void ClockTimer::StopTimer(int verb)
{

}

float ClockTimer::GetElapsedTime()
{
	return 0;
}

void GlobalUtil::SetGLParam()
{
    if(GlobalUtil::_UseCUDA) return;
    else if(GlobalUtil::_UseOpenCL) return;
	glEnable(GlobalUtil::_texTarget);
	glActiveTexture(GL_TEXTURE0);
}

void GlobalUtil::InitGLParam(int NotTargetGL)
{
    //IF the OpenGL context passed the check
    if(GlobalUtil::_GoodOpenGL == 2) return;
    //IF the OpenGl context failed the check
    if(GlobalUtil::_GoodOpenGL == 0) return;
    //IF se use CUDA or OpenCL
    if(NotTargetGL && !GlobalUtil::_UseSiftGPUEX)
    {
        GlobalUtil::_GoodOpenGL = 1;
    }else
    {
        //first time in this function
        glewInit();

	    GlobalUtil::_GoodOpenGL = 2;

	    const char * vendor = (const char * )glGetString(GL_VENDOR);
	    if(vendor)
	    {
		    GlobalUtil::_IsNvidia  = (strstr(vendor, "NVIDIA") !=NULL ? 1 : 0);

			// Let nVidia compiler to take care of the unrolling.
			if (GlobalUtil::_IsNvidia) 		GlobalUtil::_KeepShaderLoop = 1;

#ifndef WIN32
			else if(!strstr(vendor, "ATI") )
			{
				// For non-nVidia non-ATI cards...simply assume it is Mesa
				// Keep the original shader loop, because some of the unrolled
				// loopes are too large, and it may take too much time to compile
				GlobalUtil::_KeepShaderLoop = 1;
			}
#endif

			if(GlobalUtil::_IsNvidia && glewGetExtension("GL_NVX_gpu_memory_info"))
			{
				glGetIntegerv(0x9049/*GL_GPU_MEM_INFO_CURRENT_AVAILABLE_MEM_NVX*/, &_MemCapGPU);
				_MemCapGPU /= (1024);
			  if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << ' ' <<_MemCapGPU << "MB\n";
			}else if(strstr(vendor, "ATI") && glewGetExtension("GL_ATI_meminfo"))
			{
				int info[4]; 	glGetIntegerv(0x87FC/*GL_TEXTURE_FREE_MEMORY_ATI*/, info);
				_MemCapGPU = info[0] / (1024);
			    if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << ' ' <<_MemCapGPU << "MB\n";
			}else
			{
				if(GlobalUtil::_verbose) std::cout << "[GPU VENDOR]:\t" << vendor << "\n";
			}

	    }
	    if(GlobalUtil::_IsNvidia == 0 )GlobalUtil::_UseCUDA = 0;

	    if (glewGetExtension("GL_ARB_fragment_shader")    != GL_TRUE ||
		    glewGetExtension("GL_ARB_shader_objects")       != GL_TRUE ||
		    glewGetExtension("GL_ARB_shading_language_100") != GL_TRUE)
	    {
		    std::cerr << "Shader not supported by your hardware!\n";
		    GlobalUtil::_GoodOpenGL = 0;
	    }

	    if (glewGetExtension("GL_EXT_framebuffer_object") != GL_TRUE)
	    {
		    std::cerr << "Framebuffer object not supported!\n";
		    GlobalUtil::_GoodOpenGL = 0;
	    }

	    if(glewGetExtension("GL_ARB_texture_rectangle")==GL_TRUE)
	    {
	        GLint value;
		    GlobalUtil::_texTarget =  GL_TEXTURE_RECTANGLE_ARB;
		    glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT, &value);
		    GlobalUtil::_texMaxDimGL = value;
		    if(GlobalUtil::_verbose) std::cout << "TEXTURE:\t" << GlobalUtil::_texMaxDimGL << "\n";

		    if(GlobalUtil::_texMaxDim == 0 || GlobalUtil::_texMaxDim > GlobalUtil::_texMaxDimGL)
		    {
			    GlobalUtil::_texMaxDim = GlobalUtil::_texMaxDimGL;
		    }
		    glEnable(GlobalUtil::_texTarget);
	    }else
	    {
		    std::cerr << "GL_ARB_texture_rectangle not supported!\n";
		    GlobalUtil::_GoodOpenGL = 0;
	    }

	    GlobalUtil::_SupportNVFloat = glewGetExtension("GL_NV_float_buffer");
	    GlobalUtil::_SupportTextureRG = glewGetExtension("GL_ARB_texture_rg");


	    glShadeModel(GL_FLAT);
	    glPolygonMode(GL_FRONT, GL_FILL);

	    GlobalUtil::SetTextureParameter();

    }
}

void GlobalUtil::SelectDisplay()
{
#ifdef WIN32
	if(_WindowDisplay == NULL) return;

	HDC hdc = CreateDC(_WindowDisplay, _WindowDisplay, NULL, NULL);
	_WindowDisplay = NULL;
	if(hdc == NULL)
	{
		std::cout << "ERROR: invalid dispaly specified\n";
		return;
	}

	PIXELFORMATDESCRIPTOR pfd =
	{
		sizeof(PIXELFORMATDESCRIPTOR),1,
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
		PFD_TYPE_RGBA,24,0, 0, 0, 0, 0, 0,0,0,0,0, 0, 0, 0,16,0,0,
		PFD_MAIN_PLANE,0,0, 0, 0
	};
	ChoosePixelFormat(hdc, &pfd);
#endif
}

int GlobalUtil::CreateWindowEZ(LiteWindow* window)
{
	if(window == NULL) return 0;
    if(!window->IsValid())window->Create(_WindowInitX, _WindowInitY, _WindowDisplay);
    if(window->IsValid())
    {
        window->MakeCurrent();
        return 1;
    }
    else
    {
        std::cerr << "Unable to create OpenGL Context!\n";
		std::cerr << "For nVidia cards, you can try change to CUDA mode in this case\n";
        return 0;
    }
}

int GlobalUtil::CreateWindowEZ()
{
	static LiteWindow window;
    return CreateWindowEZ(&window);
}

int CreateLiteWindow(LiteWindow* window)
{
    return GlobalUtil::CreateWindowEZ(window);
}