Developer Documentation
AntiAliasing.cc
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: 18130 $ *
45  * $Author: moebius $ *
46  * $Date: 2014-02-05 10:41:16 +0100 (Wed, 05 Feb 2014) $ *
47  * *
48 \*===========================================================================*/
49 
50 
51 
52 //=============================================================================
53 //
54 // OpenGL AntiAliasing methods
55 //
56 //=============================================================================
57 
58 
59 //== INCLUDES =================================================================
60 
61 #include <ACG/GL/acg_glew.hh>
62 #include <ACG/GL/AntiAliasing.hh>
63 #include <ACG/ShaderUtils/GLSLShader.hh>
64 #include <ACG/GL/ScreenQuad.hh>
65 
66 #include <ACG/GL/ShaderCache.hh>
67 
68 //== DEFINES ==================================================================
69 
70 // shader files
71 #define MSAA_SCREENQUAD_SHADER "ScreenQuad/screenquad.glsl"
72 #define MSAA_NEAREST_SHADER "MSAA/sample_nearest.glsl"
73 #define MSAA_NEAREST_DEPTH_SHADER "MSAA/sample_nearest_and_depth.glsl"
74 #define MSAA_LINEAR_SHADER "MSAA/sample_linear.glsl"
75 
76 
77 
78 //== NAMESPACES ===============================================================
79 
80 namespace ACG {
81 
82 
83 //== CLASS IMPLEMENTATION =====================================================
84 
85 #ifdef GL_ARB_texture_multisample
86 
87 
88 MSFilterWeights::MSFilterWeights(int _numSamples) : numSamples_(_numSamples) {
89 
90  weights_.resize(_numSamples);
91  float sumWeights = 0.0f;
92 
93  // texel center is at (0.5, 0.5) as specified in
94  // http://www.opengl.org/sdk/docs/man3/xhtml/glGetMultisample.xml
95  Vec2f texelCenter(0.5f, 0.5f);
96 
97  // query sample count of currently bound fbo to avoid error on calling glGetMultisample
98  int fboSamples = 0;
99  glGetIntegerv(GL_SAMPLES, &fboSamples);
100 
101 
102  for (int i = 0; i < _numSamples; ++i) {
103  GLfloat val[2];
104 
105  if (i < fboSamples)
106  glGetMultisamplefv(GL_SAMPLE_POSITION, i, val);
107  else
108  val[0] = val[1] = 0.5f; // maybe output warning here
109 
110  Vec2f samplePosition(val[0], val[1]);
111 
112  // weighting based on distance to texel center
113  float sampleDist = (samplePosition - texelCenter).norm();
114 
115  // samples close to the center are weighted higher than samples farther away
116  weights_[i] = 1.0f - sampleDist;
117 
118  sumWeights += weights_[i];
119  }
120 
121  // normalize weights
122 
123  for (int i = 0; i < _numSamples; ++i)
124  weights_[i] /= sumWeights;
125 }
126 
127 //=============================================================================
128 
129 void MSFilterWeights::asTextureBuffer( TextureBuffer& out ) {
130  if (numSamples_)
131  out.setBufferData(numSamples_ * 4, &weights_[0], GL_R32F, GL_STATIC_DRAW);
132 }
133 
134 //=============================================================================
135 
136 
137 
138 
139 //=============================================================================
140 
141 
142 MSTextureSampler::MSTextureSampler() : shaderNearest_(0), shaderNearestDepth_(0), shaderLinear_(0) {
143 }
144 
145 
146 MSTextureSampler::~MSTextureSampler() {
147  delete shaderNearest_;
148  delete shaderLinear_;
149  delete shaderNearestDepth_;
150 }
151 
152 MSTextureSampler& MSTextureSampler::instance() {
153  static MSTextureSampler singleton;
154  return singleton;
155 }
156 
157 //=============================================================================
158 
159 void MSTextureSampler::init() {
160  if (!shaderNearest_)
161  shaderNearest_ = GLSL::loadProgram(MSAA_SCREENQUAD_SHADER, MSAA_NEAREST_SHADER);
162 
163  if (!shaderNearestDepth_)
164  shaderNearestDepth_ = GLSL::loadProgram(MSAA_SCREENQUAD_SHADER, MSAA_NEAREST_DEPTH_SHADER);
165 
166  if (!shaderLinear_)
167  shaderLinear_ = GLSL::loadProgram(MSAA_SCREENQUAD_SHADER, MSAA_LINEAR_SHADER);
168 }
169 
170 //=============================================================================
171 
172 void MSTextureSampler::filterMSAATexture_Nearest( GLuint _texture, int _samples, const float* _weights /*= 0*/ ) {
173 
174  MSTextureSampler& sampler = instance();
175 
176  // load shader
177  if (!sampler.shaderNearest_)
178  sampler.init();
179 
180  GLSL::Program* shader = sampler.shaderNearest_;
181 
182  if (!shader)
183  return;
184 
185 
186  shader->use();
187 
188  // offset and scale of screenquad
189  shader->setUniform("offset", Vec2f(0.0f, 0.0f));
190  shader->setUniform("size", Vec2f(1.0f, 1.0f));
191 
192  // sample count and filter weights
193  shader->setUniform("numSamples", _samples);
194 
195  // bind multisampled texture to slot 0
196  shader->setUniform("inputTex", 0);
197  glActiveTexture(GL_TEXTURE0);
198  glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _texture);
199 
200  // run texture filter
201  ScreenQuad::draw(shader);
202 
203  shader->disable();
204 }
205 
206 //=============================================================================
207 
208 void MSTextureSampler::filterMSAATexture_Nearest( GLuint _texture, GLuint _depthTexture, int _samples, const float* _weights /*= 0*/ ) {
209 
210  MSTextureSampler& sampler = instance();
211 
212  // load shader
213  if (!sampler.shaderNearestDepth_)
214  sampler.init();
215 
216 // GLSL::Program* shader = sampler.shaderNearestDepth_;
217  GLSL::Program* shader = ACG::ShaderCache::getInstance()->getProgram(MSAA_SCREENQUAD_SHADER, MSAA_NEAREST_DEPTH_SHADER);
218 
219  if (!shader)
220  return;
221 
222 
223  shader->use();
224 
225  // offset and scale of screenquad
226  shader->setUniform("offset", Vec2f(0.0f, 0.0f));
227  shader->setUniform("size", Vec2f(1.0f, 1.0f));
228 
229  // sample count and filter weights
230  shader->setUniform("numSamples", _samples);
231 
232  // bind multisampled depth texture to slot 1
233  shader->setUniform("inputDepthTex", 1);
234  glActiveTexture(GL_TEXTURE1);
235  glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _depthTexture);
236 
237  // bind multisampled texture to slot 0
238  shader->setUniform("inputTex", 0);
239  glActiveTexture(GL_TEXTURE0);
240  glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _texture);
241 
242  // run texture filter
243  ScreenQuad::draw(shader);
244 
245  shader->disable();
246 }
247 
248 //=============================================================================
249 
250 void MSTextureSampler::filterMSAATexture_Linear( GLuint _texture, int _samples, const float* _weights /*= 0*/ ) {
251 
252  MSTextureSampler& sampler = instance();
253 
254  // load shader
255  if (!sampler.shaderLinear_)
256  sampler.init();
257 
258  GLSL::Program* shader = sampler.shaderLinear_;
259 
260  if (!shader)
261  return;
262 
263 
264  shader->use();
265 
266  // offset and scale of screenquad
267  shader->setUniform("offset", Vec2f(0.0f, 0.0f));
268  shader->setUniform("size", Vec2f(1.0f, 1.0f));
269 
270  // sample count and filter weights
271  shader->setUniform("numSamples", _samples);
272 
273  // bind multisampled texture to slot 0
274  shader->setUniform("inputTex", 0);
275  glActiveTexture(GL_TEXTURE0);
276  glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _texture);
277 
278  // run texture filter
279  ScreenQuad::draw(shader);
280 
281  shader->disable();
282 }
283 
284 
285 //=============================================================================
286 
287 
288 
289 #endif // GL_ARB_texture_multisample
290 
291 
292 } // namespace ACG
293 //=============================================================================
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
Definition: ShaderCache.cc:90
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
Definition: GLSLShader.cc:1082
void use()
Enables the program object for using.
Definition: GLSLShader.cc:351
VectorT< float, 2 > Vec2f
Definition: Vector11T.hh:752
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:391
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
Definition: ShaderCache.cc:108
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:361
GLSL program class.
Definition: GLSLShader.hh:217