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