Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
FilterKernels.hh
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $LastChangedBy$ *
46 * $Date$ *
47 * *
48 \*===========================================================================*/
49 
50 #pragma once
51 
52 
53 #include <ACG/Config/ACGDefines.hh>
54 #include <ACG/Math/GLMatrixT.hh>
55 #include <ACG/GL/gl.hh>
56 
57 #include <QStringList>
58 #include <QImage>
59 #include <vector>
60 
61 
62 namespace ACG
63 {
64 
65 // Forward Declaration
66 class FBO;
67 
68 
69 
70 class ACGDLLEXPORT BaseSeparableFilterKernel
71 {
72 public:
73 
74  /* \brief Create separable filter
75  *
76  * @param _texWidth width of input texture
77  * @param _texHeight height of input texture
78  * @param _internalfmt internal gl format of the texture
79  */
80  BaseSeparableFilterKernel(int _texWidth, int _texHeight, GLenum _internalfmt = GL_RGBA);
81 
83  virtual ~BaseSeparableFilterKernel();
84 
85 
86  /* \brief Execute filter
87  *
88  * Perform the two filter passes.
89  * If a custom fbo and a _tempColorAttachment is provided, the first pass is
90  * rendered into that temporary render texture.
91  * If a custom fbo and a _dstColorAttachment is provided, the second pass is
92  * rendered into that destination render texture.
93  *
94  * If _dstFBO or _tempColorAttachment is invalid, an internal fbo is created as target for the first pass.
95  * If _dstFBO or _dstColorAttachment is invalid, the second pass renders into whatever is currently bound as render target.
96  *
97  * @param _srcTexture 2d input texture
98  * @param _dstFBO custom target fbo (optional)
99  * @param _dstColorAttachment target attachment of the custom target fbo (optional)
100  * @param _tempColorAttachment temporary attachment of the custom fbo, that is different from _dstColorAttachment (optional)
101  * @return true on success, false otherwise
102  */
103  bool execute(GLuint _srcTexture, ACG::FBO* _dstFBO = 0, GLuint _dstColorAttachment = GL_COLOR_ATTACHMENT0, GLuint _tempColorAttachment = 0);
104 
105 
106  /* \brief Resize input texture
107  *
108  * @param _texWidth new input texture width
109  * @param _texHeight new input texture height
110  */
111  void resizeInput(int _texWidth, int _texHeight);
112 
114  int texWidth() const {return texWidth_;}
115 
117  int texHeight() const {return texHeight_;}
118 
120  const ACG::Vec2f& texelSize() const {return texelSize_;}
121 
123  GLenum internalFormat() const {return internalfmt_;}
124 
125 protected:
126 
127  /* \brief Setup shader with uniforms
128  *
129  * @param _pass pass number: 0 or 1
130  * @param _scrTex source texture for pass
131  * @return shader program for screen quad
132  */
133  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex) = 0;
134 
135 
136  /* \brief Update kernel after resizing
137  *
138  */
139  virtual void updateKernel() = 0;
140 
141 private:
142 
143  int texWidth_,
144  texHeight_;
145 
146  GLenum internalfmt_,
147  externalfmt_;
148 
149  // size of a texel in uv space
150  ACG::Vec2f texelSize_;
151 
152  // temp render targets if none supplied by user
153  // attachment0 : target for first axis pass
154  ACG::FBO* tempRT_;
155 };
156 
157 
158 // separable 2d gaussian blur
160 {
161 public:
162 
163  /* \brief Create separable gauss filter
164  *
165  * @param _texWidth width of input texture
166  * @param _texHeight height of input texture
167  * @param _blurRadius radius in pixel coords of the blur kernel
168  * @param _blurSigma blur smoothness, standard deviation of the gaussian function
169  * @param _internalfmt internal gl format of the texture
170  */
171  GaussianBlurFilter(int _texWidth, int _texHeight, int _blurRadius, float _blurSigma = 1.0f, GLenum _internalfmt = GL_RGBA);
172 
174  virtual ~GaussianBlurFilter();
175 
176  /* \brief Change kernel settings
177  *
178  * @param _blurRadius new radius
179  * @param _blurSigma new sigma
180  */
181  void setKernel(int _blurRadius, float _blurSigma);
182 
184  int radius() const {return radius_;}
185 
187  int samples() const {return samples_;}
188 
190  int sigma() const {return sigma_;}
191 
193  const std::vector<ACG::Vec2f>& offsetsX() const {return offsetsX_;}
194 
196  const std::vector<ACG::Vec2f>& offsetsY() const {return offsetsY_;}
197 
199  const std::vector<float>& weights() const {return weights_;}
200 
201 protected:
202 
203  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex);
204 
205  void updateKernel();
206 
207 private:
208 
209  int radius_,
210  samples_;
211 
213  float sigma_;
214 
216  QStringList macros_;
217 
219  std::vector<ACG::Vec2f> offsetsX_;
220  std::vector<ACG::Vec2f> offsetsY_;
221 
223  std::vector<float> weights_;
224 };
225 
226 
227 // bilateral blur: gaussian blur with silhouette preservation
229 {
230 public:
231 
232  /* \brief Create bilateral filter
233  *
234  * @param _texWidth width of input texture
235  * @param _texHeight height of input texture
236  * @param _blurRadius radius in pixel coords of the blur kernel
237  * @param _blurSigmaS blur smoothness in spatial distance (here distance in pixel coords)
238  * @param _blurSigmaR blur smoothness in range distance (here linear view space difference)
239  * @param _internalfmt internal gl format of the texture
240  */
241  BilateralBlurFilter(int _texWidth, int _texHeight, int _blurRadius, float _blurSigmaS = 1.0f, float blurSigmaR = 1.0f, GLenum _internalfmt = GL_RGBA);
242 
244  virtual ~BilateralBlurFilter();
245 
246 
247  /* \brief Set dynamic params before calling execute()
248  *
249  * @param _proj projection matrix
250  * @param _depthTex depthbuffer texture (nonlinear depths)
251  */
252  void setParams(const ACG::GLMatrixf& _proj, GLuint _depthTex)
253  {
254  proj_ = _proj;
255  depthTex_ = _depthTex;
256  }
257 
258 
259  /* \brief Change kernel settings
260  *
261  * @param _blurRadius new radius
262  * @param _blurSigmaS new spatial smoothness
263  * @param _blurSigmaR new range smoothness
264  */
265  void setKernel(int _blurRadius, float _blurSigmaS, float _blurSigmaR);
266 
267 
269  int radius() const {return radius_;}
270 
272  int samples() const {return samples_;}
273 
275  const ACG::Vec2f& sigma() const {return sigma_;}
276 
278  const std::vector<ACG::Vec2f>& offsetsX() const {return offsetsX_;}
279 
281  const std::vector<ACG::Vec2f>& offsetsY() const {return offsetsY_;}
282 
283 protected:
284  virtual GLSL::Program* setupPass(int _pass, GLuint _srcTex);
285 
286  void updateKernel();
287 
288 private:
289 
290  int radius_,
291  samples_;
292 
295 
298 
300  std::vector<ACG::Vec2f> offsetsX_;
301  std::vector<ACG::Vec2f> offsetsY_;
302 
304  std::vector<float> spatialKernel_;
305 
307  QStringList macros_;
308 
309  ACG::GLMatrixf proj_;
310  GLuint depthTex_;
311 };
312 
313 
314 class ACGDLLEXPORT RadialBlurFilter
315 {
316 public:
317 
318  /* \brief Create radial blur filter
319  *
320  * @param _numSamples number of kernel samples
321  */
322  RadialBlurFilter(int _numSamples);
323 
325  virtual ~RadialBlurFilter() {}
326 
327  /* \brief Perform radial blur
328  *
329  * Writes to currently bound render target.
330  * A good intensity range for light to very strong blur is [0.0025, 0.01].
331  *
332  * @param _srcTexture input 2d texture
333  * @param _blurRadius blur radius in uv space
334  * @param _blurIntensity intensity, quadratic distance factor
335  * @param _blurCenter center in uv space
336  */
337  bool execute(GLuint _srcTexture, float _blurRadius = 1.0f, float _blurIntensity = 0.0025f, const ACG::Vec2f& _blurCenter = ACG::Vec2f(0.5f, 0.5f));
338 
339 
340  /* \brief Change kernel settings
341  *
342  * @param _numSamples new sample count
343  */
344  void setKernel(int _numSamples);
345 
347  int samples() const {return samples_;}
348 
349 private:
350 
351  int samples_;
352 
353  QStringList macros_;
354 };
355 
356 
357 class ACGDLLEXPORT PoissonBlurFilter
358 {
359 public:
360 
361  /* \brief Create poisson blur filter
362  *
363  * @param _radius radius of poisson disk
364  * @param _sampleDistance min distance between two samples
365  * @param _numTries number of tries per sample to find the next sample
366  */
367  PoissonBlurFilter(float _radius, float _sampleDistance, int _numTries = 30);
368 
370  virtual ~PoissonBlurFilter();
371 
372  /* \brief Perform poisson blur
373  *
374  * Writes to currently bound render target.
375  *
376  * @param _srcTex input 2d texture
377  * @param _kernelScale kernel radius scaling factor
378  */
379  bool execute(GLuint _srcTex, float _kernelScale = 1.0f);
380 
381 
383  float radius() const {return radius_;}
384 
386  int numSamples() const {return int(samples_.size());}
387 
389  float sampleDistance() const {return sampleDistance_;}
390 
392  int numTries() const {return numTries_;}
393 
395  const std::vector<ACG::Vec2f>& samples() const {return samples_;}
396 
398  void dumpSamples(const char* _filename);
399 
401  void plotSamples(QImage* _image);
402 
403 private:
404 
405  // sampling settings
406  float radius_;
407  float sampleDistance_;
408  int numTries_;
409 
410  // poisson disk
411  std::vector<ACG::Vec2f> samples_;
412 
413  // scaled samples
414  std::vector<ACG::Vec2f> samplesScaled_;
415 
416  // shader macros
417  QStringList macros_;
418 };
419 
420 
421 
422 }
ACG::Vec2f sigma2Rcp_
-1 / (2 * sigma^2)
GLenum internalFormat() const
internal format of the input texture
int radius() const
radius
int numTries() const
number of iterations per sample
int radius() const
radius
int samples() const
number of samples
const ACG::Vec2f & texelSize() const
texel size in uv space
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
int texWidth() const
input texture width
QStringList macros_
shader macros
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
int samples() const
number of samples
float sampleDistance() const
min distance between two samples
const ACG::Vec2f & sigma() const
blur (sigmaS, sigmaR)
QStringList macros_
shader macros
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
virtual ~RadialBlurFilter()
Class destructor.
const std::vector< ACG::Vec2f > & samples() const
disk sample offsets
std::vector< ACG::Vec2f > offsetsX_
filter taps
Definition: FBO.hh:83
float radius() const
radius
const std::vector< float > & weights() const
sample weights
const std::vector< ACG::Vec2f > & offsetsX() const
sample offsets along x direction
ACG::Vec2f sigma_
(sigmaS, sigmaR)
GLSL program class.
Definition: GLSLShader.hh:217
const std::vector< ACG::Vec2f > & offsetsY() const
sample offsets along y direction
std::vector< ACG::Vec2f > offsetsX_
filter taps
std::vector< float > spatialKernel_
precomputed sample -r^2 / (2 * sigma_s^2)
int samples() const
number of samples
int texHeight() const
input texture height
int sigma() const
blur sigma
std::vector< float > weights_
kernel weights
int numSamples() const
number of samples