Developer Documentation
Loading...
Searching...
No Matches
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
71namespace ACG {
72
73
74//== CLASS IMPLEMENTATION =====================================================
75
76#ifdef MSFILTERWEIGHTS
77
78
79MSFilterWeights::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//=============================================================================
119void 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
131MSTextureSampler::MSTextureSampler() : shaderNearest_(0), shaderNearestDepth_(0), shaderLinear_(0) {
132}
133
134
135MSTextureSampler::~MSTextureSampler() {
136 delete shaderNearest_;
137 delete shaderLinear_;
138 delete shaderNearestDepth_;
139}
140
141MSTextureSampler& MSTextureSampler::instance() {
142 static MSTextureSampler singleton;
143 return singleton;
144}
145
146//=============================================================================
147
148void 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
161void 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
197void 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
239void 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//=============================================================================
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
GLSL program class.
void disable()
Resets to standard rendering pipeline.
void use()
Enables the program object for using.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
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)