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 "accumBufferObject.h"
20 : #include "accum.h"
21 :
22 : #include <eq/client/gl.h>
23 :
24 : namespace eq
25 : {
26 : namespace util
27 : {
28 : namespace detail
29 : {
30 : class Accum
31 : {
32 : public:
33 0 : Accum( const GLEWContext* const gl )
34 : : 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 : 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 :
171 0 : return accumBits >= 16 ? 256 : 0;
172 : }
173 :
174 0 : uint32_t Accum::getNumSteps() const
175 : {
176 0 : return _impl->numSteps;
177 : }
178 :
179 0 : void Accum::setTotalSteps( uint32_t totalSteps )
180 : {
181 0 : _impl->totalSteps = totalSteps;
182 0 : }
183 :
184 0 : uint32_t Accum::getTotalSteps()
185 : {
186 0 : return _impl->totalSteps;
187 : }
188 :
189 0 : bool Accum::usesFBO() const
190 : {
191 0 : return usesFBO( glewGetContext( ));
192 : }
193 :
194 :
195 0 : const GLEWContext* Accum::glewGetContext() const
196 : {
197 0 : return _impl->glewContext;
198 : }
199 :
200 : #define glewGetContext() glewContext
201 :
202 : #ifdef Darwin
203 : bool Accum::usesFBO( const GLEWContext* )
204 : {
205 : return false;
206 : }
207 : #else
208 0 : bool Accum::usesFBO( const GLEWContext* glewContext )
209 : {
210 0 : return ( GLEW_EXT_framebuffer_object &&
211 0 : ( GLEW_VERSION_3_0 || GLEW_ARB_texture_float ));
212 : }
213 : #endif
214 :
215 : #undef glewGetContext
216 :
217 : }
218 36 : }
219 :
|