Line data Source code
1 : /* Copyright (c) 2009-2013, Stefan Eilemann <eile@equalizergraphics.com>
2 : * 2009, Sarah Amsellem <sarah.amsellem@gmail.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #include "accumBufferObject.h"
19 :
20 : #include <eq/gl.h>
21 :
22 : namespace eq
23 : {
24 : namespace util
25 : {
26 0 : AccumBufferObject::AccumBufferObject(const GLEWContext* glewContext)
27 : : FrameBufferObject(glewContext)
28 : , _texture(0)
29 : , _pvp(0, 0, 0, 0)
30 0 : , _previousFBO(0)
31 : {
32 0 : }
33 :
34 0 : AccumBufferObject::~AccumBufferObject()
35 : {
36 0 : exit();
37 0 : }
38 :
39 0 : bool AccumBufferObject::init(const PixelViewport& pvp,
40 : const GLuint textureFormat)
41 : {
42 0 : _pvp = pvp;
43 0 : _texture = new Texture(GL_TEXTURE_RECTANGLE_ARB, glewGetContext());
44 0 : _texture->init(textureFormat, pvp.w, pvp.h);
45 :
46 0 : const Error error = FrameBufferObject::init(pvp.w, pvp.h, GL_RGBA32F, 0, 0);
47 0 : if (error)
48 : {
49 0 : LBDEBUG << "FrameBufferObject init failed: " << error << std::endl;
50 0 : exit();
51 0 : return false;
52 : }
53 :
54 0 : unbind();
55 0 : return true;
56 : }
57 :
58 0 : void AccumBufferObject::exit()
59 : {
60 0 : if (_texture)
61 0 : _texture->flush();
62 :
63 0 : delete _texture;
64 0 : _texture = 0;
65 :
66 0 : FrameBufferObject::exit();
67 0 : }
68 :
69 0 : void AccumBufferObject::load(const GLfloat value)
70 : {
71 0 : EQ_GL_ERROR("before AccumBufferObject::load");
72 0 : _texture->copyFromFrameBuffer(_texture->getInternalFormat(), _pvp);
73 :
74 0 : const PixelViewport pvp(0, 0, getWidth(), getHeight());
75 0 : _setup(pvp);
76 0 : _drawQuadWithTexture(_texture, pvp, value);
77 0 : _reset();
78 :
79 0 : EQ_GL_ERROR("after AccumBufferObject::load");
80 :
81 : #if 0
82 : static a_int32_t i;
83 : std::ostringstream os;
84 : os << "abo" << ++i;
85 : getColorTextures()[0]->writeRGB( os.str( ));
86 :
87 : os << "tex";
88 : _texture->writeRGB( os.str( ));
89 : #endif
90 0 : }
91 :
92 0 : void AccumBufferObject::accum(const GLfloat value)
93 : {
94 0 : _texture->copyFromFrameBuffer(_texture->getInternalFormat(), _pvp);
95 :
96 0 : const PixelViewport pvp(0, 0, getWidth(), getHeight());
97 0 : _setup(pvp);
98 0 : EQ_GL_CALL(glEnable(GL_BLEND));
99 0 : EQ_GL_CALL(glBlendFunc(GL_ONE, GL_ONE));
100 :
101 0 : _drawQuadWithTexture(_texture, pvp, value);
102 :
103 0 : EQ_GL_CALL(glBlendFunc(GL_ONE, GL_ZERO));
104 0 : EQ_GL_CALL(glDisable(GL_BLEND));
105 0 : _reset();
106 0 : }
107 :
108 0 : void AccumBufferObject::display(const GLfloat value)
109 : {
110 0 : _drawQuadWithTexture(getColorTextures()[0], _pvp, value);
111 0 : }
112 :
113 0 : bool AccumBufferObject::resize(const PixelViewport& pvp)
114 : {
115 0 : if (_pvp == pvp)
116 0 : return false;
117 :
118 0 : _pvp = pvp;
119 0 : return FrameBufferObject::resize(pvp.w, pvp.h);
120 : }
121 :
122 0 : void AccumBufferObject::_setup(const PixelViewport& pvp)
123 : {
124 0 : EQ_GL_CALL(glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &_previousFBO));
125 0 : bind();
126 0 : EQ_GL_CALL(
127 : glPushAttrib(GL_SCISSOR_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT));
128 0 : EQ_GL_CALL(glMatrixMode(GL_PROJECTION));
129 0 : EQ_GL_CALL(glPushMatrix());
130 0 : EQ_GL_CALL(glLoadIdentity());
131 0 : EQ_GL_CALL(glOrtho(0, pvp.w, 0, pvp.h, -1, 1));
132 0 : EQ_GL_CALL(glScissor(0, 0, pvp.w, pvp.h));
133 0 : EQ_GL_CALL(glViewport(0, 0, pvp.w, pvp.h));
134 0 : }
135 :
136 0 : void AccumBufferObject::_reset()
137 : {
138 0 : EQ_GL_CALL(glMatrixMode(GL_PROJECTION));
139 0 : EQ_GL_CALL(glPopMatrix());
140 0 : EQ_GL_CALL(glPopAttrib());
141 0 : EQ_GL_CALL(glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, _previousFBO));
142 0 : }
143 :
144 0 : void AccumBufferObject::_drawQuadWithTexture(Texture* texture,
145 : const PixelViewport& pvp,
146 : const GLfloat value)
147 : {
148 0 : texture->bind();
149 :
150 0 : EQ_GL_CALL(glDepthMask(false));
151 0 : EQ_GL_CALL(glDisable(GL_LIGHTING));
152 0 : EQ_GL_CALL(glEnable(GL_TEXTURE_RECTANGLE_ARB));
153 0 : EQ_GL_CALL(glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE));
154 0 : texture->applyWrap();
155 0 : texture->applyZoomFilter(FILTER_NEAREST);
156 :
157 0 : EQ_GL_CALL(glColor4f(value, value, value, value));
158 :
159 0 : const float startX = static_cast<float>(pvp.x);
160 0 : const float endX = static_cast<float>(pvp.x + pvp.w);
161 0 : const float startY = static_cast<float>(pvp.y);
162 0 : const float endY = static_cast<float>(pvp.y + pvp.h);
163 :
164 0 : glBegin(GL_QUADS);
165 0 : glTexCoord2f(0.0f, 0.0f);
166 0 : glVertex3f(startX, startY, 0.0f);
167 :
168 0 : glTexCoord2f(static_cast<float>(pvp.w), 0.0f);
169 0 : glVertex3f(endX, startY, 0.0f);
170 :
171 0 : glTexCoord2f(static_cast<float>(pvp.w), static_cast<float>(pvp.h));
172 0 : glVertex3f(endX, endY, 0.0f);
173 :
174 0 : glTexCoord2f(0.0f, static_cast<float>(pvp.h));
175 0 : glVertex3f(startX, endY, 0.0f);
176 0 : glEnd();
177 :
178 : // restore state
179 0 : EQ_GL_CALL(glDisable(GL_TEXTURE_RECTANGLE_ARB));
180 0 : EQ_GL_CALL(glDepthMask(true));
181 0 : }
182 : }
183 30 : }
|