PICCANTE  0.4
The hottest HDR imaging library!
buffer_op.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_BUFFER_OP_HPP
19 #define PIC_UTIL_GL_BUFFER_OP_HPP
20 
21 #include "../../base.hpp"
22 
23 #include "../../util/array.hpp"
24 
25 #include "../../util/string.hpp"
26 #include "../../util/gl/quad.hpp"
27 #include "../../util/gl/fbo.hpp"
28 
29 namespace pic {
30 
35 {
36 protected:
37 
38  //FBO
39  Fbo *fbo;
40 
41  //Quad
43 
44  //Shaders
46  GLenum target;
47 
48  std::string op;
49  float c0[4], c1[4];
51 
55  void initShaders();
56 
57 public:
58 
60 
68  BufferOpGL(std::string op, bool bTexelFetch, float *c0, float *c1);
69 
75  void update(const float *c0, const float *c1);
76 
82  void update(float c0, float c1);
83 
92  void Process(GLuint tex0, GLuint tex1, GLuint texOut, int width, int height);
93 
94 };
95 
96 PIC_INLINE BufferOpGL::BufferOpGL(std::string op, bool bTexelFetch = false, float *c0 = NULL, float *c1 = NULL)
97 {
98  fbo = NULL;
99 
100  quad = NULL;
101 
102  target = GL_TEXTURE_2D;
103 
104  if(c0 != NULL) {
105  memcpy(this->c0, c0, 4 * sizeof(float));
106  } else {
107  Arrayf::assign(1.0f, this->c0, 4);
108  }
109 
110  if(c1 != NULL) {
111  memcpy(this->c1, c1, 4 * sizeof(float));
112  } else {
113  Arrayf::assign(1.0f, this->c1, 4);
114  }
115 
116  this->op = op;
117  this->bTexelFetch = bTexelFetch;
118 
119  if(bTexelFetch) {
121  quad = new QuadGL(false);
122  } else {
124  quad = new QuadGL(true);
125  }
126 
127  initShaders();
128 }
129 
131 {
132  std::string strOp = "vec4 ret = ";
133  strOp.append(op);
134  strOp.append(";\n");
135  int counter;
136 
137  //I0x
138  counter = countSubString(strOp, "I0x");
139 
140  if(counter == 1) {
141  size_t I_found = strOp.find("I0x");
142 
143  if(I_found != std::string::npos) {
144  if(bTexelFetch) {
145  strOp.replace(I_found, 3, "texelFetch(u_tex_0, coords, 0).xxxx");
146  } else {
147  strOp.replace(I_found, 3, "texture(u_tex_0, coords).xxxx");
148  }
149  }
150 
151  } else {
152  if(counter > 1) {
153  if(bTexelFetch) {
154  strOp = "vec4 tmp0x = texelFetch(u_tex_0, coords, 0);\n" + strOp;
155  } else {
156  strOp = "vec4 tmp0x = texture(u_tex_0, coords);\n" + strOp;
157  }
158  strOp = stdStringRepAll(strOp, "I0x", "tmp0x");
159  }
160  }
161 
162  //I1x
163  counter = countSubString(strOp, "I1x");
164 
165  if(counter == 1) {
166  size_t I_found = strOp.find("I1x");
167 
168  if(I_found != std::string::npos) {
169  if(bTexelFetch) {
170  strOp.replace(I_found, 3, "texelFetch(u_tex_1, coords, 0).xxxx");
171  } else {
172  strOp.replace(I_found, 3, "texture(u_tex_1, coords).xxxx");
173  }
174  }
175 
176  } else {
177  if(counter > 1) {
178  if(bTexelFetch) {
179  strOp = "vec4 tmp1x = texelFetch(u_tex_1, coords, 0);\n" + strOp;
180  } else {
181  strOp = "vec4 tmp1x = texture(u_tex_1, coords);\n" + strOp;
182  }
183  strOp = stdStringRepAll(strOp, "I1x", "tmp1x");
184  }
185  }
186 
187  //I0
188  counter = countSubString(strOp, "I0");
189 
190  if(counter == 1) {
191  size_t I_found = strOp.find("I0");
192 
193  if(I_found != std::string::npos) {
194  if(bTexelFetch) {
195  strOp.replace(I_found, 2, "texelFetch(u_tex_0, coords, 0)");
196  } else {
197  strOp.replace(I_found, 2, "texture(u_tex_0, coords)");
198  }
199  }
200  } else {
201  if(counter > 1) {
202  if(bTexelFetch) {
203  strOp = "vec4 tmp0 = texelFetch(u_tex_0, coords, 0);\n" + strOp;
204  } else {
205  strOp = "vec4 tmp0 = texture(u_tex_0, coords);\n" + strOp;
206  }
207 
208  strOp = stdStringRepAll(strOp, "I0", "tmp0");
209  }
210  }
211 
212  //I1
213  counter = countSubString(strOp, "I1");
214 
215  if(counter == 1) {
216  size_t I_found = strOp.find("I1");
217 
218  if(I_found != std::string::npos) {
219  if(bTexelFetch) {
220  strOp.replace(I_found, 2, "texelFetch(u_tex_1, coords, 0)");
221  } else {
222  strOp.replace(I_found, 2, "texture(u_tex_1, coords)");
223  }
224  }
225  } else {
226  if(counter > 1) {
227  if(bTexelFetch) {
228  strOp = "vec4 tmp1 = texelFetch(u_tex_1, coords, 0);\n" + strOp;
229  } else {
230  strOp = "vec4 tmp1 = texture(u_tex_1, coords);\n" + strOp;
231  }
232 
233  strOp = stdStringRepAll(strOp, "I1", "tmp1");
234  }
235  }
236 
237  //C1 and C2
238  strOp = stdStringRepAll(strOp, "C0", "u_val_0");
239  strOp = stdStringRepAll(strOp, "C1", "u_val_1");
240 
242  (
243  uniform sampler2D u_tex_0; \n
244  uniform sampler2D u_tex_1; \n
245  uniform vec4 u_val_0; \n
246  uniform vec4 u_val_1; \n
247  in vec2 v_tex_coord; \n
248  out vec4 f_color; \n
249  \n
250  void main(void) { \n
251  _COORDINATES_FOR_FETCHING_ \n
252  _PROCESSING_OPERATOR_ \n
253  f_color = ret; \n
254  }
255  );
256 
257  if(bTexelFetch) {
258  size_t processing_found = fragment_source.find("_COORDINATES_FOR_FETCHING_");
259  fragment_source.replace(processing_found, 27,
260  "ivec2 coords = ivec2(gl_FragCoord.xy);\n");
261  } else {
262  size_t processing_found = fragment_source.find("_COORDINATES_FOR_FETCHING_");
263  fragment_source.replace(processing_found, 27,
264  "vec2 coords = v_tex_coord.xy;\n");
265  }
266 
267  size_t processing_found = fragment_source.find("_PROCESSING_OPERATOR_");
268  fragment_source.replace(processing_found, 21, strOp);
269 
271 
272 #ifdef PIC_DEBUG
273  technique.printLog("BufferOp");
274 #endif
275 
276  technique.bind();
277  technique.setAttributeIndex("a_position", 0);
278 
279  if(!bTexelFetch) {
280  technique.setAttributeIndex("a_tex_coord", 1);
281  }
282 
284  technique.link();
285  technique.unbind();
286 
287  technique.bind();
288  technique.setUniform1i("u_tex_0", 0);
289  technique.setUniform1i("u_tex_1", 1);
290  technique.setUniform4fv("u_val_0", c0);
291  technique.setUniform4fv("u_val_1", c1);
292  technique.unbind();
293 }
294 
295 PIC_INLINE void BufferOpGL::update(const float *c0, const float *c1 = NULL)
296 {
297  if(c0 != NULL) {
298  memcpy(this->c0, c0, sizeof(float) * 4);
299  }
300 
301  if(c1 != NULL) {
302  memcpy(this->c1, c1, sizeof(float) * 4);
303  }
304 
305  technique.bind();
306  technique.setUniform1i("u_tex_0", 0);
307  technique.setUniform1i("u_tex_1", 1);
308  technique.setUniform4fv("u_val_0", this->c0);
309  technique.setUniform4fv("u_val_1", this->c1);
310  technique.unbind();
311 }
312 
313 PIC_INLINE void BufferOpGL::update(float c0 = 0.0f, float c1 = 0.0f)
314 {
315  Arrayf::assign(c0, this->c0, 4);
316  Arrayf::assign(c1, this->c1, 4);
317 
318  technique.bind();
319  technique.setUniform1i("u_tex_0", 0);
320  technique.setUniform1i("u_tex_1", 1);
321  technique.setUniform4fv("u_val_0", this->c0);
322  technique.setUniform4fv("u_val_1", this->c1);
323  technique.unbind();
324 }
325 
326 PIC_INLINE void BufferOpGL::Process(GLuint tex0, GLuint tex1, GLuint texOut, int width, int height)
327 {
328  if(texOut == 0) {
329  #ifdef PIC_DEBUG
330  printf("BufferOpGL::Process: the output texture, texOut, is empty.\n");
331  #endif
332  return;
333  }
334 
335  if(fbo == NULL) {
336  fbo = new Fbo();
337  }
338 
339  fbo->create(width, height, 1, false, texOut);
340 
341  //Rendering
342  fbo->bind();
343  glViewport(0, 0, (GLsizei)width, (GLsizei)height);
344 
345  //Shaders
346  technique.bind();
347 
348  //Textures
349  glActiveTexture(GL_TEXTURE0);
350  glBindTexture(GL_TEXTURE_2D, tex0);
351 
352  glActiveTexture(GL_TEXTURE1);
353  glBindTexture(GL_TEXTURE_2D, tex1);
354 
355  quad->Render();
356 
357  //Fbo
358  fbo->unbind();
359 
360  //Shaders
361  technique.unbind();
362 
363  //Textures
364  glActiveTexture(GL_TEXTURE1);
365  glBindTexture(GL_TEXTURE_2D, 0);
366 
367  glActiveTexture(GL_TEXTURE0);
368  glBindTexture(GL_TEXTURE_2D, 0);
369 }
370 
371 } // end namespace pic
372 
373 #endif /* PIC_UTIL_GL_BUFFER_OP_HPP */
QuadGL * quad
Definition: buffer_op.hpp:42
static std::string getVertexProgramWithTexCoordinates()
getVertexProgramWithTexCoordinates creates a simple vertex program with texture coordinates as input...
Definition: quad.hpp:253
std::string op
Definition: buffer_op.hpp:48
The BufferOpGL class.
Definition: buffer_op.hpp:34
The Fbo class.
Definition: display.hpp:32
void unbind()
unbind
void Process(GLuint tex0, GLuint tex1, GLuint texOut, int width, int height)
Process.
int countSubString(std::string str, std::string subStr)
countSubString counts how many subStr are in str.
Definition: string.hpp:240
void setOutputFragmentShaderIndex(const char *fragment_output_color_name, unsigned int index)
setOutputFragmentShaderIndex
Definition: technique.hpp:215
BufferOpGL(std::string op, bool bTexelFetch, float *c0, float *c1)
BufferOpGL.
void unbind()
unbind
Definition: technique.hpp:197
void link()
link
Definition: technique.hpp:205
The Fbo class.
Definition: fbo.hpp:32
std::string vertex_source
Definition: buffer_op.hpp:59
#define MAKE_STRING(input_string)
void initShaders()
initShaders
bool init(std::string version_number, std::string vertex_shader_source, std::string fragment_shader_source)
Definition: technique.hpp:67
void update(const float *c0, const float *c1)
update
The TechniqueGL class.
Definition: technique.hpp:31
bool bTexelFetch
Definition: buffer_op.hpp:50
TechniqueGL technique
Definition: buffer_op.hpp:45
static std::string getVertexProgramV3()
getVertexProgramV3 creates a simple vertex program.
Definition: quad.hpp:216
The QuadGL class.
Definition: quad.hpp:30
Fbo * fbo
Definition: buffer_op.hpp:39
void setUniform4fv(const char *name_uniform, const float *value)
setUniform4
Definition: technique.hpp:343
void printLog(std::string name)
printLog
Definition: technique.hpp:176
std::string fragment_source
Definition: buffer_op.hpp:59
#define PIC_INLINE
Definition: base.hpp:33
bool create(int width, int height, bool bDepth)
create
void setAttributeIndex(const char *attribute_name, unsigned int index)
setAttributeIndex
Definition: technique.hpp:225
void Render()
Render draws a quad on screen.
Definition: quad.hpp:140
std::string stdStringRepAll(std::string str, std::string strSub, std::string strRep)
stdStringRepAll replaces all strSub in str with strRep.
Definition: string.hpp:79
GLenum target
Definition: buffer_op.hpp:46
float c1[4]
Definition: buffer_op.hpp:49
Definition: bilateral_separation.hpp:25
static T * assign(T *data, int size, T *ret)
assign
Definition: array.hpp:464
The QuadGL class.
Definition: display.hpp:30
std::string geometry_source
Definition: buffer_op.hpp:59
void setUniform1i(const char *name_uniform, int value0)
SetUniform.
Definition: technique.hpp:236
void bind()
bind
void bind()
bind
Definition: technique.hpp:189
float c0[4]
Definition: buffer_op.hpp:49