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