Line data Source code
1 :
2 : /* Copyright (c) 2009-2013, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2009, Sarah Amsellem <sarah.amsellem@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "accum.h"
20 : #include "accumBufferObject.h"
21 :
22 : #include <eq/gl.h>
23 :
24 : namespace eq
25 : {
26 : namespace util
27 : {
28 : namespace detail
29 : {
30 : class Accum
31 : {
32 : public:
33 0 : explicit Accum(const GLEWContext* const gl)
34 0 : : glewContext(gl)
35 : , abo(0)
36 : , numSteps(0)
37 0 : , totalSteps(0)
38 : {
39 0 : LBASSERT(glewContext);
40 0 : }
41 :
42 : const GLEWContext* const glewContext;
43 : PixelViewport pvp;
44 :
45 : AccumBufferObject* abo;
46 : uint32_t numSteps;
47 : uint32_t totalSteps;
48 : };
49 : }
50 :
51 0 : Accum::Accum(const GLEWContext* const glewContext)
52 0 : : _impl(new detail::Accum(glewContext))
53 : {
54 0 : }
55 :
56 0 : Accum::~Accum()
57 : {
58 0 : this->exit();
59 0 : delete _impl;
60 0 : }
61 :
62 0 : bool Accum::init(const PixelViewport& pvp, GLuint textureFormat)
63 : {
64 0 : if (usesFBO())
65 : {
66 0 : _impl->abo = new AccumBufferObject(_impl->glewContext);
67 0 : if (!_impl->abo->init(pvp, textureFormat))
68 : {
69 0 : delete _impl->abo;
70 0 : _impl->abo = 0;
71 0 : return false;
72 : }
73 : }
74 :
75 0 : if (_impl->totalSteps == 0)
76 0 : _impl->totalSteps = getMaxSteps();
77 :
78 0 : _impl->pvp = pvp;
79 0 : return (_impl->totalSteps > 0);
80 : }
81 :
82 0 : void Accum::exit()
83 : {
84 0 : clear();
85 :
86 0 : if (_impl->abo)
87 0 : _impl->abo->exit();
88 :
89 0 : delete _impl->abo;
90 0 : _impl->abo = 0;
91 0 : }
92 :
93 0 : void Accum::clear()
94 : {
95 0 : _impl->numSteps = 0;
96 0 : }
97 :
98 0 : bool Accum::resize(const int width, const int height)
99 : {
100 0 : return resize(PixelViewport(0, 0, width, height));
101 : }
102 :
103 0 : bool Accum::resize(const PixelViewport& pvp)
104 : {
105 0 : if (_impl->pvp == pvp)
106 0 : return false;
107 :
108 0 : _impl->pvp = pvp;
109 0 : if (usesFBO())
110 0 : return _impl->abo->resize(pvp);
111 0 : return true;
112 : }
113 :
114 0 : void Accum::accum()
115 : {
116 0 : LBASSERT(_impl->numSteps < _impl->totalSteps);
117 :
118 0 : if (_impl->abo)
119 : {
120 0 : if (_impl->numSteps == 0)
121 0 : _impl->abo->load(1.0f);
122 : else
123 0 : _impl->abo->accum(1.0f);
124 : }
125 : else
126 : {
127 : // This is the only working implementation on MacOS found at the moment.
128 : // glAccum function seems to be implemented differently.
129 0 : if (_impl->numSteps == 0)
130 : #ifdef Darwin
131 : glAccum(GL_LOAD, 1.0f / _impl->totalSteps);
132 : #else
133 0 : glAccum(GL_LOAD, 1.0f);
134 : #endif
135 : else
136 : #ifdef Darwin
137 : glAccum(GL_ACCUM, 1.0f / _impl->totalSteps);
138 : #else
139 0 : glAccum(GL_ACCUM, 1.0f);
140 : #endif
141 : }
142 :
143 0 : ++_impl->numSteps;
144 0 : }
145 :
146 0 : void Accum::display()
147 : {
148 0 : LBASSERT(_impl->numSteps <= _impl->totalSteps);
149 :
150 0 : if (_impl->abo)
151 0 : _impl->abo->display(1.0f / _impl->numSteps);
152 : else
153 : {
154 : #ifdef Darwin
155 : const float factor = float(_impl->totalSteps) / _impl->numSteps;
156 : #else
157 0 : const float factor = 1.0f / _impl->numSteps;
158 : #endif
159 0 : glAccum(GL_RETURN, factor);
160 : }
161 0 : }
162 :
163 0 : uint32_t Accum::getMaxSteps() const
164 : {
165 0 : if (usesFBO())
166 0 : return 256;
167 :
168 : GLint accumBits;
169 0 : glGetIntegerv(GL_ACCUM_RED_BITS, &accumBits);
170 0 : return accumBits >= 16 ? 256 : 0;
171 : }
172 :
173 0 : uint32_t Accum::getNumSteps() const
174 : {
175 0 : return _impl->numSteps;
176 : }
177 :
178 0 : void Accum::setTotalSteps(uint32_t totalSteps)
179 : {
180 0 : _impl->totalSteps = totalSteps;
181 0 : }
182 :
183 0 : uint32_t Accum::getTotalSteps()
184 : {
185 0 : return _impl->totalSteps;
186 : }
187 :
188 0 : bool Accum::usesFBO() const
189 : {
190 0 : return usesFBO(glewGetContext());
191 : }
192 :
193 0 : const GLEWContext* Accum::glewGetContext() const
194 : {
195 0 : return _impl->glewContext;
196 : }
197 :
198 : #define glewGetContext() glewContext
199 :
200 : #ifdef Darwin
201 : bool Accum::usesFBO(const GLEWContext*)
202 : {
203 : return false;
204 : }
205 : #else
206 0 : bool Accum::usesFBO(const GLEWContext* glewContext)
207 : {
208 0 : return (GLEW_EXT_framebuffer_object &&
209 0 : (GLEW_VERSION_3_0 || GLEW_ARB_texture_float));
210 : }
211 : #endif
212 :
213 : #undef glewGetContext
214 : }
215 30 : }
|