framework2
193 строки · 6.2 Кб
1/*
2* PostProcessing.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 "PostProcessing.h"
33#include "ofMain.h"
34
35namespace itg
36{
37void PostProcessing::init(unsigned width, unsigned height, bool arb)
38{
39this->width = width;
40this->height = height;
41this->arb = arb;
42
43ofFbo::Settings s;
44
45if (arb)
46{
47s.width = width;
48s.height = height;
49s.textureTarget = GL_TEXTURE_RECTANGLE_ARB;
50}
51else
52{
53s.width = ofNextPow2(width); // Test value: 2048
54s.height = ofNextPow2(height); // Test value: 1024
55s.textureTarget = GL_TEXTURE_2D;
56}
57this->widthFbo = s.width;
58this->heightFbo = s.height;
59
60// no need to use depth for ping pongs
61for (int i = 0; i < 2; ++i)
62{
63pingPong[i].allocate(s);
64}
65
66s.useDepth = true;
67s.depthStencilInternalFormat = GL_DEPTH_COMPONENT24;
68s.depthStencilAsTexture = true;
69raw.allocate(s);
70
71numProcessedPasses = 0;
72currentReadFbo = 0;
73flip = true;
74}
75
76void PostProcessing::begin()
77{
78raw.begin(OF_FBOMODE_NODEFAULTS);
79
80ofMatrixMode(OF_MATRIX_PROJECTION);
81ofPushMatrix();
82
83ofMatrixMode(OF_MATRIX_MODELVIEW);
84ofPushMatrix();
85
86ofViewport(0, 0, ofGetWindowWidth(), ofGetWindowHeight()); // Test values: 1800, 900
87
88glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
89
90ofPushStyle();
91glPushAttrib(GL_ENABLE_BIT);
92}
93
94void PostProcessing::begin(ofCamera& cam)
95{
96// update camera matrices
97
98raw.begin(OF_FBOMODE_NODEFAULTS);
99
100ofViewport(0, 0, ofGetWindowWidth(), ofGetWindowHeight()); // Test values: 1800, 900
101cam.begin();
102
103glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
104
105ofPushStyle();
106glPushAttrib(GL_ENABLE_BIT);
107}
108
109void PostProcessing::end(ofCamera& cam, bool autoDraw)
110{
111glPopAttrib();
112ofPopStyle();
113
114cam.end();
115raw.end();
116
117ofViewport(0, 0, ofGetWidth(), ofGetHeight());
118
119ofPushStyle();
120glPushAttrib(GL_ENABLE_BIT);
121glDisable(GL_LIGHTING);
122ofSetColor(255, 255, 255);
123process();
124if (autoDraw) draw();
125glPopAttrib();
126ofPopStyle();
127}
128
129void PostProcessing::debugDraw()
130{
131raw.getTexture().draw(10, 10, 300, 300);
132raw.getDepthTexture().draw(320, 10, 300, 300);
133pingPong[currentReadFbo].draw(630, 10, 300, 300);
134}
135
136void PostProcessing::draw(float x, float y) const
137{
138draw(x, y, widthFbo, heightFbo); // Test values: 2048, 1024
139}
140
141void PostProcessing::draw(float x, float y, float w, float h) const
142{
143if (flip)
144{
145ofPushMatrix();
146ofTranslate(x, y + h, 0);
147ofScale(1, -1, 1);
148}
149else glTranslatef(x, y, 0);
150if (numProcessedPasses == 0) raw.draw(0, 0, w, h);
151else pingPong[currentReadFbo].draw(0, 0, w, h);
152if (flip) ofPopMatrix();
153}
154
155ofTexture& PostProcessing::getProcessedTextureReference()
156{
157if (numProcessedPasses) return pingPong[currentReadFbo].getTexture();
158else return raw.getTexture();
159}
160
161// need to have depth enabled for some fx
162void PostProcessing::process(ofFbo& raw, bool hasDepthAsTexture)
163{
164numProcessedPasses = 0;
165for (int i = 0; i < passes.size(); ++i)
166{
167if (passes[i]->getEnabled())
168{
169if (arb && !passes[i]->hasArbShader()) ofLogError() << "Arb mode is enabled but pass " << passes[i]->getName() << " does not have an arb shader.";
170else
171{
172if (hasDepthAsTexture)
173{
174if (numProcessedPasses == 0) passes[i]->render(raw, pingPong[1 - currentReadFbo], raw.getDepthTexture());
175else passes[i]->render(pingPong[currentReadFbo], pingPong[1 - currentReadFbo], raw.getDepthTexture());
176}
177else
178{
179if (numProcessedPasses == 0) passes[i]->render(raw, pingPong[1 - currentReadFbo]);
180else passes[i]->render(pingPong[currentReadFbo], pingPong[1 - currentReadFbo]);
181}
182currentReadFbo = 1 - currentReadFbo;
183numProcessedPasses++;
184}
185}
186}
187}
188
189void PostProcessing::process()
190{
191process(raw);
192}
193}
194