1 ////////////////////////////////////////////////////////////////////////////
2 // File: ShaderMan.cpp
3 // Author: Changchang Wu
4 // Description : implementation of the ShaderMan class.
5 // A Shader Manager that calls different implementation of shaders
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
24
25 #include "GL/glew.h"
26 #include <vector>
27 #include <iostream>
28 #include <stdlib.h>
29 #include <math.h>
30 using std::vector;
31 using std::ostream;
32 using std::endl;
33
34
35 #include "ProgramGLSL.h"
36 #include "GlobalUtil.h"
37 #include "GLTexImage.h"
38 #include "SiftGPU.h"
39 #include "ShaderMan.h"
40
41 ///
42 ShaderBag * ShaderMan::s_bag = NULL;
43
44 //////////////////////////////////////////////////////////////////////
45 // Construction/Destruction
46 //////////////////////////////////////////////////////////////////////
47
InitShaderMan(SiftParam & param)48 void ShaderMan::InitShaderMan(SiftParam¶m)
49 {
50 if(s_bag) return;
51
52 if(GlobalUtil::_usePackedTex ) s_bag = new ShaderBagPKSL;
53 else s_bag =new ShaderBagGLSL;
54
55 GlobalUtil::StartTimer("Load Programs");
56 s_bag->LoadFixedShaders();
57 s_bag->LoadDynamicShaders(param);
58 if(GlobalUtil::_UseSiftGPUEX) s_bag->LoadDisplayShaders();
59 GlobalUtil::StopTimer();
60
61 GlobalUtil::CheckErrorsGL("InitShaderMan");
62 }
63
64
DestroyShaders()65 void ShaderMan::DestroyShaders()
66 {
67 if(s_bag) delete s_bag;
68 s_bag = NULL;
69 }
70
UnloadProgram()71 void ShaderMan::UnloadProgram()
72 {
73 if(s_bag) s_bag->UnloadProgram();
74 }
75
FilterImage(FilterProgram * filter,GLTexImage * dst,GLTexImage * src,GLTexImage * tmp)76 void ShaderMan::FilterImage(FilterProgram* filter, GLTexImage *dst, GLTexImage *src, GLTexImage*tmp)
77 {
78 if(filter == NULL) return;
79
80 //////////////////////////////
81 src->FillMargin(filter->_size, 0);
82
83 //output parameter
84 if(tmp) tmp->AttachToFBO(0);
85 else dst->AttachToFBO(0);
86
87
88 //input parameter
89 src->BindTex();
90 dst->FitTexViewPort();
91
92 //horizontal filter
93 filter->s_shader_h->UseProgram();
94 dst->DrawQuad();
95
96 //parameters
97 if(tmp)
98 {
99 // fill margin for out-of-boundary lookup
100 tmp->DetachFBO(0);
101 tmp->AttachToFBO(0);
102 tmp->FillMargin(0, filter->_size);
103 tmp->DetachFBO(0);
104 dst->AttachToFBO(0);
105 tmp->BindTex();
106 }
107 else
108 {
109 glFinish();
110 // fill margin for out-of-boundary lookup
111 dst->FillMargin(0, filter->_size);
112 dst->BindTex();
113 }
114
115 //vertical filter
116 filter->s_shader_v->UseProgram();
117 dst->DrawQuad();
118
119
120 //clean up
121 dst->UnbindTex();
122 dst->DetachFBO(0);
123
124 //
125 ShaderMan::UnloadProgram();
126 }
127
128
FilterInitialImage(GLTexImage * tex,GLTexImage * buf)129 void ShaderMan::FilterInitialImage(GLTexImage* tex, GLTexImage* buf)
130 {
131 if(s_bag->f_gaussian_skip0) FilterImage(s_bag->f_gaussian_skip0, tex, tex, buf);
132 }
133
FilterSampledImage(GLTexImage * tex,GLTexImage * buf)134 void ShaderMan::FilterSampledImage(GLTexImage* tex, GLTexImage* buf)
135 {
136 if(s_bag->f_gaussian_skip1) FilterImage(s_bag->f_gaussian_skip1, tex, tex, buf);
137 }
138
TextureCopy(GLTexImage * dst,GLTexImage * src)139 void ShaderMan::TextureCopy(GLTexImage*dst, GLTexImage*src)
140 {
141
142 dst->AttachToFBO(0);
143
144 src->BindTex();
145
146 dst->FitTexViewPort();
147
148 dst->DrawQuad();
149
150 dst->UnbindTex();
151 // ShaderMan::UnloadProgram();
152 dst->DetachFBO(0);
153 return;
154 }
TextureDownSample(GLTexImage * dst,GLTexImage * src,int scale)155 void ShaderMan::TextureDownSample(GLTexImage *dst, GLTexImage *src, int scale)
156 {
157 //output parameter
158
159 dst->AttachToFBO(0);
160
161 //input parameter
162 src->BindTex();
163
164 //
165 dst->FitTexViewPort();
166
167 s_bag->s_sampling->UseProgram();
168
169 dst->DrawQuadDS(scale);
170 src->UnbindTex();
171
172 UnloadProgram();
173
174 dst->DetachFBO(0);
175 }
176
TextureUpSample(GLTexImage * dst,GLTexImage * src,int scale)177 void ShaderMan::TextureUpSample(GLTexImage *dst, GLTexImage *src, int scale)
178 {
179
180 //output parameter
181 dst->AttachToFBO(0);
182 //input parameter
183 src->BindTex();
184
185 dst->FitTexViewPort();
186
187 GlobalUtil::SetTextureParameterUS();
188
189 if(GlobalUtil::_usePackedTex)
190 {
191 s_bag->s_sampling->UseProgram();
192 }
193
194 dst->DrawQuadUS(scale);
195 src->UnbindTex();
196
197 UnloadProgram();
198
199 dst->DetachFBO(0);
200
201 GlobalUtil::SetTextureParameter();
202 }
203
204
205
UseShaderDisplayGaussian()206 void ShaderMan::UseShaderDisplayGaussian()
207 {
208 if(s_bag && s_bag->s_display_gaussian) s_bag->s_display_gaussian->UseProgram();
209 }
210
UseShaderDisplayDOG()211 void ShaderMan::UseShaderDisplayDOG()
212 {
213 if(s_bag && s_bag->s_display_dog) s_bag->s_display_dog->UseProgram();
214 }
215
216
217
UseShaderRGB2Gray()218 void ShaderMan::UseShaderRGB2Gray()
219 {
220 if(s_bag && s_bag->s_gray)s_bag->s_gray->UseProgram();
221 }
222
223
UseShaderDisplayGrad()224 void ShaderMan::UseShaderDisplayGrad()
225 {
226 if(s_bag && s_bag->s_display_grad) s_bag->s_display_grad->UseProgram();
227 }
228
229
UseShaderDisplayKeypoints()230 void ShaderMan::UseShaderDisplayKeypoints()
231 {
232 if(s_bag && s_bag->s_display_keys) s_bag->s_display_keys->UseProgram();
233 }
234
235
236
237
238
UseShaderGradientPass(int texP)239 void ShaderMan::UseShaderGradientPass(int texP)
240 {
241 s_bag->s_grad_pass->UseProgram();
242 s_bag->SetGradPassParam(texP);
243 }
244
245
UseShaderKeypoint(int texU,int texD)246 void ShaderMan::UseShaderKeypoint(int texU, int texD)
247 {
248 s_bag->s_keypoint->UseProgram();
249 s_bag->SetDogTexParam(texU, texD);
250 }
251
252
253
UseShaderGenListInit(int w,int h,int tight)254 void ShaderMan::UseShaderGenListInit(int w, int h, int tight)
255 {
256 if(tight)
257 {
258 s_bag->s_genlist_init_tight->UseProgram();
259 }else
260 {
261 s_bag->s_genlist_init_ex->UseProgram();
262 s_bag->SetGenListInitParam(w, h);
263 }
264 }
265
UseShaderGenListHisto()266 void ShaderMan::UseShaderGenListHisto()
267 {
268 s_bag->s_genlist_histo->UseProgram();
269
270 }
271
272
273
274
UseShaderGenListStart(float fw,int tex0)275 void ShaderMan::UseShaderGenListStart(float fw, int tex0)
276 {
277 s_bag->s_genlist_start->UseProgram();
278 s_bag->SetGenListStartParam(fw, tex0);
279 }
280
UseShaderGenListStep(int tex,int tex0)281 void ShaderMan::UseShaderGenListStep(int tex, int tex0)
282 {
283 s_bag->s_genlist_step->UseProgram();
284 s_bag->SetGenListStepParam( tex, tex0);
285 }
286
UseShaderGenListEnd(int ktex)287 void ShaderMan::UseShaderGenListEnd(int ktex)
288 {
289 s_bag->s_genlist_end->UseProgram();
290 s_bag->SetGenListEndParam(ktex);
291 }
292
UseShaderDebug()293 void ShaderMan::UseShaderDebug()
294 {
295 if(s_bag->s_debug) s_bag->s_debug->UseProgram();
296 }
297
UseShaderZeroPass()298 void ShaderMan::UseShaderZeroPass()
299 {
300 if(s_bag->s_zero_pass) s_bag->s_zero_pass->UseProgram();
301 }
302
UseShaderGenVBO(float width,float fwidth,float size)303 void ShaderMan::UseShaderGenVBO( float width, float fwidth, float size)
304 {
305 s_bag->s_vertex_list->UseProgram();
306 s_bag->SetGenVBOParam(width, fwidth, size);
307 }
UseShaderMarginCopy(int xmax,int ymax)308 void ShaderMan::UseShaderMarginCopy(int xmax, int ymax)
309 {
310 s_bag->s_margin_copy->UseProgram();
311 s_bag->SetMarginCopyParam(xmax, ymax);
312
313 }
UseShaderCopyKeypoint()314 void ShaderMan::UseShaderCopyKeypoint()
315 {
316 s_bag->s_copy_key->UseProgram();
317 }
318
UseShaderSimpleOrientation(int oTex,float sigma,float sigma_step)319 void ShaderMan::UseShaderSimpleOrientation(int oTex, float sigma, float sigma_step)
320 {
321 s_bag->s_orientation->UseProgram();
322 s_bag->SetSimpleOrientationInput(oTex, sigma, sigma_step);
323 }
324
325
326
UseShaderOrientation(int gtex,int width,int height,float sigma,int auxtex,float step,int keypoint_list)327 void ShaderMan::UseShaderOrientation(int gtex, int width, int height, float sigma, int auxtex, float step, int keypoint_list)
328 {
329 s_bag->s_orientation->UseProgram();
330
331 //changes in v345.
332 //set sigma to 0 to identify keypoit list mode
333 //set sigma to negative to identify fixed_orientation
334 if(keypoint_list) sigma = 0.0f;
335 else if(GlobalUtil::_FixedOrientation) sigma = - sigma;
336
337 s_bag->SetFeatureOrientationParam(gtex, width, height, sigma, auxtex, step);
338 }
339
UseShaderDescriptor(int gtex,int otex,int dwidth,int fwidth,int width,int height,float sigma)340 void ShaderMan::UseShaderDescriptor(int gtex, int otex, int dwidth, int fwidth, int width, int height, float sigma)
341 {
342 s_bag->s_descriptor_fp->UseProgram();
343 s_bag->SetFeatureDescirptorParam(gtex, otex, (float)dwidth, (float)fwidth, (float)width, (float)height, sigma);
344 }
345
SelectInitialSmoothingFilter(int octave_min,SiftParam & param)346 void ShaderMan::SelectInitialSmoothingFilter(int octave_min, SiftParam¶m)
347 {
348 s_bag->SelectInitialSmoothingFilter(octave_min, param);
349 }
350