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 :
27 0 : AccumBufferObject::AccumBufferObject( const GLEWContext* glewContext )
28 : : FrameBufferObject( glewContext )
29 : , _texture( 0 )
30 : , _pvp( 0, 0, 0, 0 )
31 0 : , _previousFBO( 0 )
32 : {
33 0 : }
34 :
35 0 : AccumBufferObject::~AccumBufferObject()
36 : {
37 0 : exit();
38 0 : }
39 :
40 0 : bool AccumBufferObject::init( const PixelViewport& pvp,
41 : const GLuint textureFormat )
42 : {
43 0 : _pvp = pvp;
44 0 : _texture = new Texture( GL_TEXTURE_RECTANGLE_ARB, glewGetContext( ));
45 0 : _texture->init( textureFormat, pvp.w, pvp.h );
46 :
47 : const Error error = FrameBufferObject::init( pvp.w, pvp.h,
48 0 : GL_RGBA32F, 0, 0 );
49 0 : if( error )
50 : {
51 0 : LBDEBUG << "FrameBufferObject init failed: " << error << std::endl;
52 0 : exit();
53 0 : return false;
54 : }
55 :
56 0 : unbind();
57 0 : return true;
58 : }
59 :
60 0 : void AccumBufferObject::exit()
61 : {
62 0 : if( _texture )
63 0 : _texture->flush();
64 :
65 0 : delete _texture;
66 0 : _texture = 0;
67 :
68 0 : FrameBufferObject::exit();
69 0 : }
70 :
71 0 : void AccumBufferObject::load( const GLfloat value )
72 : {
73 0 : EQ_GL_ERROR( "before AccumBufferObject::load" );
74 0 : _texture->copyFromFrameBuffer( _texture->getInternalFormat(), _pvp );
75 :
76 0 : const PixelViewport pvp( 0, 0, getWidth(), getHeight( ));
77 0 : _setup( pvp );
78 0 : _drawQuadWithTexture( _texture, pvp, value );
79 0 : _reset();
80 :
81 0 : EQ_GL_ERROR( "after AccumBufferObject::load" );
82 :
83 : #if 0
84 : static a_int32_t i;
85 : std::ostringstream os;
86 : os << "abo" << ++i;
87 : getColorTextures()[0]->writeRGB( os.str( ));
88 :
89 : os << "tex";
90 : _texture->writeRGB( os.str( ));
91 : #endif
92 0 : }
93 :
94 0 : void AccumBufferObject::accum( const GLfloat value )
95 : {
96 0 : _texture->copyFromFrameBuffer( _texture->getInternalFormat(), _pvp );
97 :
98 0 : const PixelViewport pvp( 0, 0, getWidth(), getHeight( ));
99 0 : _setup( pvp );
100 0 : EQ_GL_CALL( glEnable( GL_BLEND ));
101 0 : EQ_GL_CALL( glBlendFunc( GL_ONE, GL_ONE ));
102 :
103 0 : _drawQuadWithTexture( _texture, pvp, value );
104 :
105 0 : EQ_GL_CALL( glBlendFunc( GL_ONE, GL_ZERO ));
106 0 : EQ_GL_CALL( glDisable( GL_BLEND ));
107 0 : _reset();
108 0 : }
109 :
110 0 : void AccumBufferObject::display( const GLfloat value )
111 : {
112 0 : _drawQuadWithTexture( getColorTextures()[0], _pvp, value );
113 0 : }
114 :
115 0 : bool AccumBufferObject::resize( const PixelViewport& pvp )
116 : {
117 0 : if( _pvp == pvp )
118 0 : return false;
119 :
120 0 : _pvp = pvp;
121 0 : return FrameBufferObject::resize( pvp.w, pvp.h );
122 : }
123 :
124 0 : void AccumBufferObject::_setup( const PixelViewport& pvp )
125 : {
126 0 : EQ_GL_CALL( glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &_previousFBO ));
127 0 : bind();
128 0 : EQ_GL_CALL( glPushAttrib( GL_SCISSOR_BIT | GL_VIEWPORT_BIT |
129 : GL_TRANSFORM_BIT ));
130 0 : EQ_GL_CALL( glMatrixMode(GL_PROJECTION));
131 0 : EQ_GL_CALL( glPushMatrix());
132 0 : EQ_GL_CALL( glLoadIdentity());
133 0 : EQ_GL_CALL( glOrtho(0, pvp.w, 0, pvp.h, -1, 1));
134 0 : EQ_GL_CALL( glScissor(0, 0, pvp.w, pvp.h));
135 0 : EQ_GL_CALL( glViewport(0, 0, pvp.w, pvp.h));
136 0 : }
137 :
138 0 : void AccumBufferObject::_reset()
139 : {
140 0 : EQ_GL_CALL( glMatrixMode(GL_PROJECTION));
141 0 : EQ_GL_CALL( glPopMatrix());
142 0 : EQ_GL_CALL( glPopAttrib());
143 0 : EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _previousFBO ));
144 0 : }
145 :
146 0 : void AccumBufferObject::_drawQuadWithTexture( Texture* texture,
147 : const PixelViewport& pvp,
148 : const GLfloat value )
149 : {
150 0 : texture->bind();
151 :
152 0 : EQ_GL_CALL( glDepthMask( false ));
153 0 : EQ_GL_CALL( glDisable( GL_LIGHTING ));
154 0 : EQ_GL_CALL( glEnable( GL_TEXTURE_RECTANGLE_ARB ));
155 0 : EQ_GL_CALL( glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ));
156 0 : texture->applyWrap();
157 0 : texture->applyZoomFilter( FILTER_NEAREST );
158 :
159 0 : EQ_GL_CALL( glColor4f( value, value, value, value ));
160 :
161 0 : const float startX = static_cast< float >( pvp.x );
162 0 : const float endX = static_cast< float >( pvp.x + pvp.w );
163 0 : const float startY = static_cast< float >( pvp.y );
164 0 : const float endY = static_cast< float >( pvp.y + pvp.h );
165 :
166 0 : glBegin( GL_QUADS );
167 0 : glTexCoord2f( 0.0f, 0.0f );
168 0 : glVertex3f( startX, startY, 0.0f );
169 :
170 0 : glTexCoord2f( static_cast< float >( pvp.w ), 0.0f );
171 0 : glVertex3f( endX, startY, 0.0f );
172 :
173 0 : glTexCoord2f( static_cast<float>( pvp.w ), static_cast<float>( pvp.h ));
174 0 : glVertex3f( endX, endY, 0.0f );
175 :
176 0 : glTexCoord2f( 0.0f, static_cast< float >( pvp.h ));
177 0 : glVertex3f( startX, endY, 0.0f );
178 0 : glEnd();
179 :
180 : // restore state
181 0 : EQ_GL_CALL( glDisable( GL_TEXTURE_RECTANGLE_ARB ));
182 0 : EQ_GL_CALL( glDepthMask( true ));
183 0 : }
184 :
185 : }
186 42 : }
|