Line data Source code
1 :
2 : /* Copyright (c) 2008-2009, Cedric Stalder <cedric.stalder@gmail.com>
3 : * 2009-2013, Stefan Eilemann <eile@equalizergraphics.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 "frameBufferObject.h"
20 :
21 : #include <eq/client/gl.h>
22 : #include <eq/fabric/pixelViewport.h>
23 :
24 : #ifdef _WIN32
25 : # define bzero( ptr, size ) memset( ptr, 0, size );
26 : #endif
27 :
28 : namespace eq
29 : {
30 : namespace util
31 : {
32 :
33 13 : FrameBufferObject::FrameBufferObject( const GLEWContext* glewContext,
34 : const GLenum textureTarget )
35 : : _fboID( 0 )
36 : , _depth( textureTarget, glewContext )
37 : , _glewContext( glewContext )
38 13 : , _valid( false )
39 : {
40 13 : LBASSERT( GLEW_EXT_framebuffer_object );
41 13 : _colors.push_back( new Texture( textureTarget, glewContext ));
42 13 : }
43 :
44 26 : FrameBufferObject::~FrameBufferObject()
45 : {
46 13 : exit();
47 26 : for( size_t i = 0; i < _colors.size(); ++i )
48 : {
49 13 : delete _colors[i];
50 13 : _colors[i] = 0;
51 : }
52 13 : }
53 :
54 0 : bool FrameBufferObject::addColorTexture()
55 : {
56 0 : if( _colors.size() >= 16 )
57 : {
58 0 : LBWARN << "Too many color textures, can't add another one" << std::endl;
59 0 : return false;
60 : }
61 :
62 0 : _colors.push_back( new Texture(_colors.front()->getTarget(), _glewContext));
63 0 : _valid = false;
64 0 : return true;
65 : }
66 :
67 20 : Error FrameBufferObject::init( const int32_t width, const int32_t height,
68 : const GLuint colorFormat,
69 : const int32_t depthSize,
70 : const int32_t stencilSize )
71 : {
72 20 : LB_TS_THREAD( _thread );
73 :
74 20 : if( _fboID )
75 7 : return Error( ERROR_FRAMEBUFFER_INITIALIZED );
76 :
77 : // generate and bind the framebuffer
78 13 : glGenFramebuffersEXT( 1, &_fboID );
79 13 : glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID );
80 :
81 : // create and bind textures
82 26 : for( unsigned i = 0; i < _colors.size(); ++i )
83 : {
84 13 : _colors[i]->init( colorFormat, width, height );
85 13 : _colors[i]->bindToFBO( GL_COLOR_ATTACHMENT0 + i, width, height );
86 : }
87 13 : if( stencilSize > 0 && GLEW_EXT_packed_depth_stencil )
88 : {
89 13 : _depth.init( GL_DEPTH24_STENCIL8, width, height );
90 13 : _depth.bindToFBO( GL_DEPTH_STENCIL_ATTACHMENT, width, height );
91 : }
92 0 : else if( depthSize > 0 )
93 : {
94 0 : _depth.init( GL_DEPTH_COMPONENT, width, height );
95 0 : _depth.bindToFBO( GL_DEPTH_ATTACHMENT, width, height );
96 : }
97 :
98 13 : const Error error = _checkStatus();
99 13 : if( error )
100 0 : exit();
101 13 : return error;
102 : }
103 :
104 20 : void FrameBufferObject::exit()
105 : {
106 20 : LB_TS_THREAD( _thread );
107 20 : if( _fboID )
108 : {
109 13 : glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
110 13 : glDeleteFramebuffersEXT( 1, &_fboID );
111 13 : _fboID = 0;
112 : }
113 :
114 40 : for( size_t i = 0; i < _colors.size(); ++i )
115 20 : _colors[i]->flush();
116 20 : _depth.flush();
117 :
118 20 : _valid = false;
119 20 : }
120 :
121 13 : Error FrameBufferObject::_checkStatus()
122 : {
123 13 : _valid = false;
124 :
125 13 : const GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
126 13 : switch( status )
127 : {
128 : case GL_FRAMEBUFFER_COMPLETE_EXT:
129 13 : _valid = true;
130 13 : return Error( ERROR_NONE );
131 :
132 : case 0: // error?!
133 0 : EQ_GL_ERROR( "glCheckFramebufferStatusEXT" );
134 0 : return Error( ERROR_FRAMEBUFFER_STATUS );
135 :
136 : case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
137 0 : return Error( ERROR_FRAMEBUFFER_UNSUPPORTED );
138 :
139 : case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
140 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT );
141 :
142 : case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
143 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_ATTACHMENT );
144 :
145 : case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
146 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_DIMENSIONS );
147 :
148 : case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
149 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_FORMATS );
150 :
151 : case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
152 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER );
153 :
154 : case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
155 0 : return Error( ERROR_FRAMEBUFFER_INCOMPLETE_READ_BUFFER );
156 :
157 : default:
158 0 : LBWARN << "Unhandled frame buffer status 0x" << std::hex
159 0 : << status << std::dec << std::endl;
160 0 : return Error( ERROR_FRAMEBUFFER_STATUS );
161 : }
162 : }
163 :
164 8 : void FrameBufferObject::bind()
165 : {
166 8 : LB_TS_THREAD( _thread );
167 8 : LBASSERT( _fboID );
168 8 : EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID ));
169 8 : }
170 :
171 0 : void FrameBufferObject::unbind()
172 : {
173 0 : EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ));
174 0 : }
175 :
176 0 : Error FrameBufferObject::resize( const int32_t width, const int32_t height )
177 : {
178 0 : LB_TS_THREAD( _thread );
179 0 : LBASSERT( width > 0 && height > 0 );
180 :
181 0 : LBASSERT( !_colors.empty( ));
182 0 : Texture* color = _colors.front();
183 :
184 0 : if( color->getWidth() == width && color->getHeight() == height && _valid )
185 0 : return Error( ERROR_NONE );
186 :
187 0 : for( size_t i = 0; i < _colors.size(); ++i )
188 0 : _colors[i]->resize( width, height );
189 :
190 0 : if ( _depth.isValid( ))
191 0 : _depth.resize( width, height );
192 :
193 0 : return _checkStatus();
194 : }
195 :
196 : }
197 36 : }
|