root / tbeta / Windows / apps / tbeta app / Configapp / src / Filters / ImageFilter.cpp @ 3

View | Annotate | Download (6.4 KB)

1
#include "ImageFilter.h"
2
#include <stdio.h>
3
#include "tinyxml.h"
4
#include "ofUtils.h"
5
6
//helper functon, should go somewhere else
7
void getFrameBufferForTexture(GLuint* fbo, GLuint* tex, int sizeX, int sizeY){
8
    GLenum status;
9
10
    //allocate ouput buffer on GPU using FBO
11
    glEnable(GL_TEXTURE_2D);
12
    glGenTextures(1, tex);
13
    glBindTexture(GL_TEXTURE_2D, *tex);
14
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
15
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8,  sizeX, sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
16
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
17
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
18
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
19
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
20
    //glGenerateMipmapEXT(GL_TEXTURE_2D);
21
22
    glBindTexture(GL_TEXTURE_2D, 0);
23
24
    //generate fbo
25
    glGenFramebuffersEXT(1, fbo);
26
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, *fbo);
27
28
    //attach texture to fbo
29
    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, *tex, 0);
30
31
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
32
33
    status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
34
    printf("Frame buffer status: %d\n", status);
35
}
36
37
38
39
40
41
42
ImageFilter::ImageFilter(const char* fname, int sx, int sy){
43
//read the filter description file and creates a filter based on the shaders and parameters given in that file
44
//allocates output buffer/texture
45
46
        res_x = sx; res_y = sy;
47
        useGeometryShader =false;
48
        //this->shader = shaderProg;
49
        glGenTextures(1, &output_texture );
50
        getFrameBufferForTexture(&output_buffer, &output_texture, res_x, res_y);
51
        this->parseXML(fname);
52
53
}
54
55
56
void ImageFilter::parseXML(const char* fname){
57
        //load filter description file
58
        printf("Loading Filter...\n");
59
60
61
        //load and parse xml filter description file
62
        TiXmlDocument doc(ofToDataPath(fname).c_str());
63
        if (!doc.LoadFile()) printf("error loading filter description file");
64
65
66
        //get the name of the filter
67
        TiXmlElement* root_node = doc.RootElement();
68
69
        this->name = root_node->Attribute("name");
70
71
        printf("Filter Name:%s\n", this->name);
72
73
74
        //get the  shader source file names
75
        TiXmlElement* node = root_node;
76
77
        node = root_node->FirstChildElement("VertexShader");
78
        const char* vertSrc = node ? node->GetText() : NULL;
79
80
        node = root_node->FirstChildElement("GeometryShader");
81
        const char* geomSrc = node ? node->GetText() : NULL;
82
        if (geomSrc != NULL){ //We are using a geometry shader
83
                this->useGeometryShader = true;
84
        }
85
86
        node = root_node->FirstChildElement("FragmentShader");
87
        const char* fragSrc = node ? node->GetText() : NULL;
88
89
    this->shader = new ShaderProgram(vertSrc, geomSrc, ofToDataPath(fragSrc).c_str());
90
91
92
        //get parameters
93
        //TODO: add type handling
94
        while( (node = (TiXmlElement*)node->NextSibling("Parameter")) ){
95
                const char* name = node->Attribute("name");
96
                float type = atof(node->Attribute("type"));
97
                float min = atof(node->Attribute("min"));
98
                float max = atof(node->Attribute("max"));
99
                float val = atof(node->GetText());
100
101
102
                parameters["size_cx"] = new FilterParameter("size_cx", (float)res_x, 0, 0, 0 );
103
                parameters["size_cy"] = new FilterParameter("size_cy", (float)res_y, 0, 0, 0 );
104
                parameters[std::string(name)] = new FilterParameter(name, val, min, max, (int)type );
105
        }
106
}
107
108
109
//applies the filter to a GL texture.
110
//
111
//saves opengl states, and binds this filter's output buffer (render to texture)
112
//sets up ortho projection for drawing just the texture using teh filters shaders
113
//parameters are set as uniforms for the shaders
114
GLuint ImageFilter::apply(GLuint inputTexture, GLuint inputTexture2){
115
116
        glPushAttrib(GL_VIEWPORT_BIT);
117
    glPushAttrib(GL_ENABLE_BIT);
118
119
    glMatrixMode(GL_MODELVIEW);
120
    glPushMatrix();
121
    glMatrixMode(GL_PROJECTION);
122
    glPushMatrix();
123
124
    //render to the fbo using the shader
125
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, output_buffer);
126
127
    glClearColor(0.0,1.0,0.0,1.0);
128
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
129
    glViewport(0,0,res_x, res_y);
130
131
    glMatrixMode(GL_PROJECTION);
132
    glLoadIdentity();
133
    glOrtho(-1, 1.0, -1, 1.0, -1, 1.0);
134
    glMatrixMode(GL_MODELVIEW);
135
    glLoadIdentity();
136
137
        glEnable(GL_TEXTURE_2D);
138
    glBindTexture(GL_TEXTURE_2D, inputTexture);
139
140
141
142
    this->shader->enable();
143
144
    //set the parameters for the filters
145
        for(std::map<std::string, FilterParameter*>::const_iterator it = parameters.begin(); it != parameters.end(); ++it){
146
                    const char* test = it->first.c_str();
147
                float test2 = it->second->value;
148
                        this->shader->setUniform1f(it->first.c_str(), it->second->value);
149
        }
150
151
        if (inputTexture2 !=0){
152
                this->shader->setUniform1i("tex2", 1);
153
        }
154
155
156
        //use geometry shader threads to process image blocks
157
        if(useGeometryShader){
158
                        //send n number of threads
159
                int numThreads = (int) parameters["threads"]->value;
160
                        glBegin(GL_POINTS);
161
162
                //glVertex2d(3,3);
163
                int i=0;
164
                for(i=0; i<numThreads; i++){
165
                                float x = (float)((i/numThreads ) / (float)numThreads -0.5f) * 2.0f;
166
                                float y = (float)((i%numThreads ) / (float)numThreads  -0.5f)* 2.0f;
167
                                glVertex2d(x,y);
168
                }
169
                        glEnd();
170
        }else{
171
172
                //draw full screen quad with input texture aplied
173
                glActiveTexture(GL_TEXTURE0);
174
                glEnable(GL_TEXTURE_2D);
175
        glBindTexture(GL_TEXTURE_2D, inputTexture);
176
                glActiveTexture(GL_TEXTURE1);
177
                glEnable(GL_TEXTURE_2D);
178
        glBindTexture(GL_TEXTURE_2D, inputTexture2);
179
180
                this->shader->enable();
181
        glBegin(GL_QUADS);
182
        glColor3d(1.0, 0.0, 0.0);
183
        glTexCoord2f(0, 0); glVertex3f(-1, -1, 0);
184
        glTexCoord2f(1, 0); glVertex3f(1, -1, 0);
185
        glTexCoord2f(1, 1); glVertex3f(1, 1, 0);
186
        glTexCoord2f(0, 1); glVertex3f(-1, 1, 0);
187
        glEnd();
188
        }
189
190
191
192
        this->shader->disable();
193
194
        glPopMatrix();
195
        glMatrixMode(GL_PROJECTION);
196
        glPopMatrix();
197
        glPopAttrib();
198
        glPopAttrib();
199
200
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);  //should maybe have a stack
201
202
        glActiveTexture(GL_TEXTURE1);
203
        glBindTexture(GL_TEXTURE_2D,0);
204
        glActiveTexture(GL_TEXTURE0);
205
        glBindTexture(GL_TEXTURE_2D,0);
206
207
208
        return output_texture;
209
210
211
};
212
213
214
215
216
217
218
void ImageFilter::drawOutputTexture(float x,float y, float w, float h){
219
        glEnable(GL_TEXTURE_2D);
220
        glBindTexture(GL_TEXTURE_2D, this->output_texture);
221
        glPushMatrix();
222
        glBegin( GL_QUADS );
223
                glTexCoord2f(0,0);                        glVertex3i(x, y,0);
224
                glTexCoord2f(1,0);                        glVertex3i(x+w, y,0);
225
                glTexCoord2f(1,1);                        glVertex3i(x+w, y+h,0);
226
                glTexCoord2f(0,1);                        glVertex3i(x, y+h,0);
227
        glEnd();
228
        glPopMatrix();
229
}
230
231
232
233
234
//destructor
235
ImageFilter::~ImageFilter()
236
{
237
}