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&param)
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&param)
347 {
348     s_bag->SelectInitialSmoothingFilter(octave_min, param);
349 }
350