framework2

Форк
0
155 строк · 5.7 Кб
1
/*
2
 *  ConvolutionPass.cpp
3
 *
4
 *  Copyright (c) 2012, Neil Mendoza, http://www.neilmendoza.com
5
 *  All rights reserved. 
6
 *  
7
 *  Redistribution and use in source and binary forms, with or without 
8
 *  modification, are permitted provided that the following conditions are met: 
9
 *  
10
 *  * Redistributions of source code must retain the above copyright notice, 
11
 *    this list of conditions and the following disclaimer. 
12
 *  * Redistributions in binary form must reproduce the above copyright 
13
 *    notice, this list of conditions and the following disclaimer in the 
14
 *    documentation and/or other materials provided with the distribution. 
15
 *  * Neither the name of Neil Mendoza nor the names of its contributors may be used 
16
 *    to endorse or promote products derived from this software without 
17
 *    specific prior written permission. 
18
 *  
19
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20
 *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21
 *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
22
 *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
23
 *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
24
 *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
25
 *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
26
 *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
27
 *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
28
 *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
29
 *  POSSIBILITY OF SUCH DAMAGE. 
30
 *
31
 */
32
#include "ConvolutionPass.h"
33
#include "ofMain.h"
34

35
namespace itg
36
{
37
    ConvolutionPass::ConvolutionPass(const ofVec2f& aspect, bool arb, const ofVec2f& imageIncrement, float sigma, unsigned kernelSize) :
38
        imageIncrement(imageIncrement), RenderPass(aspect, arb, "convolution")
39
    {
40
        string vertShaderSrc = STRINGIFY(
41
            uniform vec2 imageIncrement;
42
            uniform vec2 resolution;
43
                                         
44
            varying vec2 vUv;
45
            varying vec2 scaledImageIncrement;
46
            
47
            void main()
48
            {
49
                gl_TexCoord[0] = gl_MultiTexCoord0;
50
                scaledImageIncrement = imageIncrement * resolution;
51
                vUv = gl_TexCoord[0].st - ( ( KERNEL_SIZE - 1.0 ) / 2.0 ) * scaledImageIncrement;
52
                gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
53
            }
54
        );
55
        
56
        string fragShaderSrc = STRINGIFY(
57
            uniform float kernel[KERNEL_SIZE];
58
            uniform SAMPLER_TYPE readTex;
59
            uniform vec2 imageIncrement;
60
            
61
            varying vec2 vUv;
62
            varying vec2 scaledImageIncrement;
63
                                         
64
            void main()
65
            {
66
            
67
                vec2 imageCoord = vUv;
68
                vec4 sum = vec4( 0.0, 0.0, 0.0, 0.0 );
69
                
70
                for( int i = 0; i < KERNEL_SIZE; i++ )
71
                {
72
                    sum += TEXTURE_FN( readTex, imageCoord ) * kernel[ i ];
73
                    imageCoord += scaledImageIncrement;
74
                }
75
                
76
                gl_FragColor = sum;
77
            }
78
        );
79
        
80
        ostringstream oss;
81
        oss << "#version 120\n#define KERNEL_SIZE " << kernelSize << ".0" << endl << vertShaderSrc;
82
        shader.setupShaderFromSource(GL_VERTEX_SHADER, oss.str());
83
        
84
        oss.str("");
85
        oss << "#version 120\n#define KERNEL_SIZE " << kernelSize << endl;
86
        if (arb)
87
        {
88
            oss << "#define SAMPLER_TYPE sampler2DRect" << endl;
89
            oss << "#define TEXTURE_FN texture2DRect" << endl;
90
        }
91
        else
92
        {
93
            oss << "#define SAMPLER_TYPE sampler2D" << endl;
94
            oss << "#define TEXTURE_FN texture2D" << endl;
95
        }
96
        oss << fragShaderSrc;
97
        shader.setupShaderFromSource(GL_FRAGMENT_SHADER, oss.str());
98
        shader.linkProgram();
99
        
100
        // build kernel
101
        buildKernel(sigma);
102
    }
103
    
104
    // We lop off the sqrt(2 * pi) * sigma term, since we're going to normalize anyway.
105
    float ConvolutionPass::gauss(float x, float sigma)
106
    {
107
        return expf( -( x * x ) / ( 2.0 * sigma * sigma ) );
108
    }
109

110
    void ConvolutionPass::render(ofFbo& readFbo, ofFbo& writeFbo)
111
    {
112
        writeFbo.begin();
113
        
114
        ofClear(0, 0, 0, 255);
115
        
116
        shader.begin();
117
        
118
        shader.setUniformTexture("readTex", readFbo, 0);
119
        shader.setUniform2f("imageIncrement", imageIncrement.x, imageIncrement.y);
120
        shader.setUniform1fv("kernel", kernel.data(), kernel.size());
121
        if (arb) shader.setUniform2f("resolution", readFbo.getWidth(), readFbo.getHeight());
122
        else shader.setUniform2f("resolution", 1.f, 1.f);
123
        
124
        if (arb) texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight(), readFbo.getWidth(), readFbo.getHeight());
125
        else texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
126
        
127
        shader.end();
128
        writeFbo.end();
129
    }
130
    
131
    void ConvolutionPass::buildKernel(float sigma)
132
    {
133
        unsigned kernelSize = 2 * ceil( sigma * 3.0 ) + 1;
134
        
135
        if (kernelSize > MAX_KERNEL_SIZE) kernelSize = MAX_KERNEL_SIZE;
136
        
137
        kernel.clear();
138
        kernel.reserve(kernelSize);
139
        
140
        float halfWidth = ( kernelSize - 1 ) * 0.5;
141
        
142
        float sum = 0.0;
143
        for (unsigned i = 0; i < kernelSize; ++i )
144
        {
145
            kernel.push_back(gauss(i - halfWidth, sigma));
146
            sum += kernel.back();
147
        }
148
        
149
        // normalize the kernel
150
        for (unsigned i = 0; i < kernelSize; ++i )
151
        {
152
            kernel[ i ] /= sum;
153
        }
154
    }
155
}

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.