PICCANTE  0.4
The hottest HDR imaging library!
redux.hpp
Go to the documentation of this file.
1 /*
2 
3 PICCANTE
4 The hottest HDR imaging library!
5 http://vcg.isti.cnr.it/piccante
6 
7 Copyright (C) 2014
8 Visual Computing Laboratory - ISTI CNR
9 http://vcg.isti.cnr.it
10 First author: Francesco Banterle
11 
12 This Source Code Form is subject to the terms of the Mozilla Public
13 License, v. 2.0. If a copy of the MPL was not distributed with this
14 file, You can obtain one at http://mozilla.org/MPL/2.0/.
15 
16 */
17 
18 #ifndef PIC_UTIL_GL_REDUX_HPP
19 #define PIC_UTIL_GL_REDUX_HPP
20 
21 #include "base.hpp"
22 
23 #include "util/gl/technique.hpp"
24 #include "util/gl/fbo.hpp"
25 #include "util/gl/quad.hpp"
26 
27 namespace pic {
28 
32 class ReduxGL
33 {
34 protected:
35  //FBO
36  Fbo *fbo;
37 
38  //quad
40 
42  int counter;
43 
44  //shaders
47 
48  std::string reduxOperation;
49 
53  void initShaders();
54 
55 public:
60  ReduxGL(std::string reduxOperation, bool bDomainTransform);
61 
62  ~ReduxGL();
63 
73  GLuint Process(GLuint texIn, int width, int height, int channels, GLuint texOut);
74 
84  GLuint Redux(GLuint texIn, int width, int height, int channels, std::vector<GLuint> &stack)
85  {
86  if(stack.empty() || (texIn == 0)) {
87  return 0;
88  }
89 
90  GLuint texFlt = texIn;
91 
92  for(unsigned int i = 0; i < stack.size(); i++) {
93  counter = (bDomainTransform && (i == 0)) ? 1 : 0;
94 
95  width = divideByTwoWithEvenDividend(width);
96  height = divideByTwoWithEvenDividend(height);
97 
98  Process(texFlt, width, height, channels, stack[i]);
99  texFlt = stack[i];
100  }
101 
102  return texFlt;
103  }
104 
109  static ReduxGL *createMean()
110  {
111  ReduxGL *filter = new
112  ReduxGL("color = (color00 + color10 + color01 + color11) / 4.0;", false);
113  return filter;
114  }
115 
120  static ReduxGL *createSum()
121  {
122  ReduxGL *filter = new
123  ReduxGL("color = color00 + color10 + color01 + color11;", false);
124  return filter;
125  }
126 
132  {
133  ReduxGL *filter = new
134  ReduxGL("color = (color00 + color10 + color01 + color11) / 4.0;", true);
135  return filter;
136  }
137 
142  static ReduxGL *createMin()
143  {
144  ReduxGL *filter = new
145  ReduxGL("color = min(color00, color10);\n "
146  "color = min(color, color01);\n "
147  "color = min(color, color11);\n", false);
148  return filter;
149  }
150 
155  static ReduxGL *createMax()
156  {
157  ReduxGL *filter = new
158  ReduxGL("color = max(color00, color10);\n "
159  "color = max(color, color01);\n "
160  "color = max(color, color11);\n", false);
161  return filter;
162  }
163 
169  {
170  ReduxGL *filter = new
171  ReduxGL("vec4 maxVal = vec4(1e-6); "
172  "if(color00.x>0.0f) color = color00; "
173  "if(color01.x>0.0f) color = min(color,color01); "
174  "if(color10.x>0.0f) color = min(color,color10); "
175  "if(color11.x>0.0f) color = min(color,color11);\n", false);
176  return filter;
177  }
178 
184  {
185  ReduxGL *filter = new
186  ReduxGL("vec4 sum = color00 + color01 + color10 + color11; "
187  "color = sum.x < 0.5? vec4(0.0) : sum; "
188  "color = ((sum.x > 0.5) && (sum.x < 3.5))? vec4(10.0) : color; "
189  "color = ((sum.x > 3.5) && (sum.x < 4.5))? vec4(1.0) : color; "
190  "color = sum.x > 4.5 ? vec4(10.0) : color;\n", false);
191  return filter;
192  }
193 
199  static int divideByTwoWithEvenDividend(int x)
200  {
201  if((x % 2) != 0) {
202  x++;
203  }
204 
205  return (x >> 1);
206  }
207 
216  static void allocateReduxData(int width, int height, int channels,
217  std::vector<GLuint> &stack, int minSize = 2)
218  {
219  int checkSize = divideByTwoWithEvenDividend(MIN(width, height));
220 
221  stack.clear();
222 
223  if(minSize < 2) {
224  minSize = 2;
225  }
226 
227  while(checkSize >= minSize) {
228  width = divideByTwoWithEvenDividend(width);
229  height = divideByTwoWithEvenDividend(height);
230 
231  stack.push_back(generateTexture2DGL(width, height, channels));
232 
233  checkSize = MIN(width, height);
234  }
235  }
236 
237 };
238 
239 PIC_INLINE ReduxGL::ReduxGL(std::string reduxOperation, bool bDomainTransform)
240 {
241  fbo = NULL;
242 
243  quad = NULL;
244 
245  this->counter = 0;
246  this->bDomainTransform = bDomainTransform;
247 
248  quad = new QuadGL(false);
249 
250  //get a vertex program for screen aligned quad
252 
253  this->reduxOperation = reduxOperation;
254  initShaders();
255 }
256 
258 {
259  if(quad != NULL) {
260  delete quad;
261  quad = NULL;
262  }
263 
264  if(fbo != NULL) {
265  delete fbo;
266  fbo = NULL;
267  }
268 }
269 
271 {
273  (
274  uniform sampler2D u_tex; \n
275  out vec4 f_color; \n
276 
277  void main(void) {
278  \n
279  ivec2 texSize = textureSize(u_tex, 0);
280  ivec2 coords = ivec2(gl_FragCoord.xy) * 2;
281  \n
282  vec4 color00 = texelFetch(u_tex, coords ,0);
283  \n
284  vec4 color10 = texelFetch(u_tex, coords + ivec2(1, 0), 0);
285  \n
286  vec4 color01 = texelFetch(u_tex, coords + ivec2(0, 1), 0);
287  \n
288  vec4 color11 = texelFetch(u_tex, coords + ivec2(1, 1), 0);
289  \n
290  vec4 color;
291  \n
292  ___REDUX_OPERATION___ \n
293  f_color = vec4(color.xyz, 1.0);
294  \n
295  }
296  );
297 // f_color = ((texSize - coords) == ivec2(0, 0)) ? color00 : color;
298 
300 
301  size_t processing_found = fragment_source.find("___REDUX_OPERATION___");
302  fragment_source.replace(processing_found, 21, reduxOperation);
303 
304  techinques[0].initStandard("330", vertex_source, fragment_source, "ReduxGL");
305 
306  techinques[0].bind();
307  techinques[0].setUniform1i("u_tex", 0);
308  techinques[0].unbind();
309 
310  if(bDomainTransform) {
311  size_t processing_found = fragment_source_domain_transform.find("___REDUX_OPERATION___");
312  std::string domain_transform = "float eps = 1e-6; "
313  "color00 = log(color00 + eps); "
314  "color01 = log(color01 + eps); "
315  "color10 = log(color10 + eps) ; "
316  "color11 = log(color11 + eps);";
317  domain_transform += reduxOperation;
318  fragment_source_domain_transform.replace(processing_found, 21, domain_transform);
319 
321 
322  techinques[1].bind();
323  techinques[1].setUniform1i("u_tex", 0);
324  techinques[1].unbind();
325  }
326 }
327 
328 PIC_INLINE GLuint ReduxGL::Process(GLuint texIn, int width, int height, int channels, GLuint texOut)
329 {
330  if(texIn == 0) {
331  return texOut;
332  }
333 
334  if(texOut == 0) {
335  texOut = generateTexture2DGL(width, height, channels);
336  }
337 
338  if(width < 1 || height < 1) {
339  return texOut;
340  }
341 
342  //check the fbo
343  if(fbo == NULL) {
344  fbo = new Fbo();
345  }
346 
347  fbo->create(width, height, 1, false, texOut);
348 
349  //bind the fbo
350  fbo->bind();
351  glViewport(0, 0, (GLsizei)width, (GLsizei)height);
352 
353  //bind shaders
355 
356  //bind textures
357  glActiveTexture(GL_TEXTURE0);
358  glBindTexture(GL_TEXTURE_2D, texIn);
359 
360  //render an aligned quad
361  quad->Render();
362 
363  //unbind the fbo
364  fbo->unbind();
365 
366  //unbind shaders
368 
369  //unbind textures
370  glActiveTexture(GL_TEXTURE0);
371  glBindTexture(GL_TEXTURE_2D, 0);
372 
373  return texOut;
374 }
375 
376 } // end namespace pic
377 
378 #endif /* PIC_UTIL_GL_REDUX_HPP */
379 
static ReduxGL * createSum()
createSum
Definition: redux.hpp:120
int counter
Definition: redux.hpp:42
void unbind()
unbind
static ReduxGL * createLogMean()
createLogMean
Definition: redux.hpp:131
std::string fragment_source_domain_transform
Definition: redux.hpp:45
void unbind()
unbind
Definition: technique.hpp:197
static ReduxGL * createMean()
createMean
Definition: redux.hpp:109
The Fbo class.
Definition: fbo.hpp:32
#define MAKE_STRING(input_string)
bool initStandard(std::string version_number, std::string vertex_shader_source, std::string fragment_shader_source, std::string name)
initStandard
Definition: technique.hpp:114
The TechniqueGL class.
Definition: technique.hpp:31
static std::string getVertexProgramV3()
getVertexProgramV3 creates a simple vertex program.
Definition: quad.hpp:216
PIC_INLINE GLuint generateTexture2DGL(int width, int height, int channels, float *data=NULL, bool mipmap=false)
generateTexture2DGL
Definition: buffer_allocation.hpp:37
The QuadGL class.
Definition: quad.hpp:30
GLuint Redux(GLuint texIn, int width, int height, int channels, std::vector< GLuint > &stack)
Redux.
Definition: redux.hpp:84
TechniqueGL techinques[2]
Definition: redux.hpp:46
QuadGL * quad
Definition: redux.hpp:39
std::string reduxOperation
Definition: redux.hpp:48
static ReduxGL * createMax()
createMax
Definition: redux.hpp:155
bool bDomainTransform
Definition: redux.hpp:41
The ReduxGL class.
Definition: redux.hpp:32
ReduxGL(std::string reduxOperation, bool bDomainTransform)
ReduxGL.
static int divideByTwoWithEvenDividend(int x)
divideByTwoWithEvenDividend if x is even it computes x / 2 otherwise (x + 1) / 2. ...
Definition: redux.hpp:199
std::string geometry_source
Definition: redux.hpp:45
static ReduxGL * createMin()
createMin
Definition: redux.hpp:142
#define PIC_INLINE
Definition: base.hpp:33
GLuint Process(GLuint texIn, int width, int height, int channels, GLuint texOut)
Process.
bool create(int width, int height, bool bDepth)
create
#define MIN(a, b)
Definition: math.hpp:69
void Render()
Render draws a quad on screen.
Definition: quad.hpp:140
static ReduxGL * createMinPos()
createMinPos
Definition: redux.hpp:168
void initShaders()
initShaders
Definition: bilateral_separation.hpp:25
static ReduxGL * createCheck()
createCheck
Definition: redux.hpp:183
std::string vertex_source
Definition: redux.hpp:45
Fbo * fbo
Definition: redux.hpp:36
void setUniform1i(const char *name_uniform, int value0)
SetUniform.
Definition: technique.hpp:236
void bind()
bind
static void allocateReduxData(int width, int height, int channels, std::vector< GLuint > &stack, int minSize=2)
allocateReduxData allocates a pyramid for computing the Redux operator.
Definition: redux.hpp:216
std::string fragment_source
Definition: redux.hpp:45
void bind()
bind
Definition: technique.hpp:189