00001 #ifndef OPENTISSUE_UTILITY_GL_GL_FRAME_BUFFER_OBJECT_H
00002 #define OPENTISSUE_UTILITY_GL_GL_FRAME_BUFFER_OBJECT_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/gl/gl.h>
00013 #include <OpenTissue/gpu/texture/texture_texture2D.h>
00014 #include <OpenTissue/gpu/texture/texture_texture3D.h>
00015 #include <OpenTissue/utility/gl/gl_render_buffer.h>
00016
00017 #include <iostream>
00018
00019 namespace OpenTissue
00020 {
00021
00022 namespace gl
00023 {
00024
00052 class FramebufferObject
00053 {
00054 protected:
00055
00056 GLuint m_fbo_id;
00057 GLuint m_saved_fbo_id;
00058
00059 protected:
00060
00066 static GLuint create_fbo_id()
00067 {
00068 GLuint id = 0;
00069 glGenFramebuffersEXT(1, &id);
00070 return id;
00071 }
00072
00073 public:
00074
00075 FramebufferObject()
00076 : m_fbo_id( create_fbo_id() )
00077 , m_saved_fbo_id(0)
00078 {
00079
00080 guarded_bind();
00081 guarded_unbind();
00082 }
00083
00084 ~FramebufferObject(){ glDeleteFramebuffersEXT(1, &m_fbo_id);}
00085
00086
00087 protected:
00088
00094 void guarded_bind()
00095 {
00096
00097 GLint tmp = 0;
00098 glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &tmp );
00099 m_saved_fbo_id = static_cast<GLuint>(tmp);
00100 if (m_fbo_id != m_saved_fbo_id)
00101 {
00102 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo_id);
00103 }
00104 }
00105
00111 void guarded_unbind()
00112 {
00113
00114 if (m_saved_fbo_id != m_fbo_id)
00115 {
00116 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)m_saved_fbo_id);
00117 }
00118 }
00119
00120 public:
00121
00126 void bind(){ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo_id); }
00127
00145 void attach_texture( GLenum attachment, GLenum texture_target, GLuint texture_id, int mip_level = 0, int z_slice = 0)
00146 {
00147 guarded_bind();
00148 #ifndef NDEBUG
00149 if( get_attached_id(attachment) != texture_id )
00150 {
00151 #endif
00152
00153
00154 if (texture_target == GL_TEXTURE_1D)
00155 {
00156 glFramebufferTexture1DEXT(
00157 GL_FRAMEBUFFER_EXT
00158 , attachment
00159 , GL_TEXTURE_1D
00160 , texture_id
00161 , mip_level
00162 );
00163 }
00164 else if (texture_target == GL_TEXTURE_3D)
00165 {
00166 glFramebufferTexture3DEXT(
00167 GL_FRAMEBUFFER_EXT
00168 , attachment
00169 , GL_TEXTURE_3D
00170 , texture_id
00171 , mip_level
00172 , z_slice
00173 );
00174 }
00175 else
00176 {
00177
00178 glFramebufferTexture2DEXT(
00179 GL_FRAMEBUFFER_EXT
00180 , attachment
00181 , texture_target
00182 , texture_id
00183 , mip_level
00184 );
00185 }
00186 #ifndef NDEBUG
00187 }
00188 #endif
00189 guarded_unbind();
00190 }
00191
00199 void attach_texture(GLenum attachment, OpenTissue::texture::texture2D_pointer texture)
00200 {
00201 attach_texture(attachment, texture->get_texture_target(), texture->get_texture_ID());
00202 }
00203
00211 void attach_texture(GLenum attachment, OpenTissue::texture::texture3D_pointer texture, int z_slice)
00212 {
00213 attach_texture(attachment, texture->get_texture_target(), texture->get_texture_ID(), 0, z_slice);
00214 }
00215
00228 void attach_render_buffer( GLenum attachment, GLuint buffer_id )
00229 {
00230 guarded_bind();
00231 #ifndef NDEBUG
00232 if( get_attached_id(attachment) != buffer_id )
00233 {
00234 #endif
00235 glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, buffer_id);
00236 #ifndef NDEBUG
00237 }
00238 #endif
00239 guarded_unbind();
00240 }
00241
00253 void attach_render_buffer( GLenum attachment, renderbuffer_pointer buffer )
00254 {
00255 attach_render_buffer(attachment, buffer->get_id() );
00256 }
00257
00265 void unattach( GLenum attachment )
00266 {
00267 guarded_bind();
00268 GLenum type = get_attached_type(attachment);
00269 switch(type)
00270 {
00271 case GL_NONE: break;
00272 case GL_RENDERBUFFER_EXT: attach_render_buffer( attachment, 0 ); break;
00273 case GL_TEXTURE: attach_texture( attachment, GL_TEXTURE_2D, 0 ); break;
00274 default: std::cerr << "FramebufferObject::unattach(): Unknown attached resource type" << std::endl;
00275 }
00276 guarded_unbind();
00277 }
00278
00288 #ifndef NDEBUG
00289 bool is_valid( std::ostream& output = std::cerr )
00290 {
00291 guarded_bind();
00292 GLenum status;
00293 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00294 switch(status)
00295 {
00296 case GL_FRAMEBUFFER_COMPLETE_EXT:
00297 break;
00298 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00299 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n";
00300 break;
00301 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00302 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n";
00303 break;
00304
00305
00306
00307
00308
00309
00310 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00311 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n";
00312 break;
00313 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00314 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n";
00315 break;
00316 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00317 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n";
00318 break;
00319 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00320 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n";
00321 break;
00322 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00323 output << "glFrameBufferObject.is_valid():\n\t" << "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n";
00324 break;
00325
00326
00327
00328
00329
00330 default:
00331 output << "glFrameBufferObject.is_valid():\n\t" << "Unknown ERROR\n";
00332 }
00333 guarded_unbind();
00334 return (status==GL_FRAMEBUFFER_COMPLETE_EXT);
00335 }
00336 #else
00337 bool is_valid( std::ostream& ) { return true; }
00338 bool is_valid() { return true; }
00339 #endif
00340
00349 GLenum get_attached_type( GLenum attachment )
00350 {
00351
00352 guarded_bind();
00353 GLint type = 0;
00354 glGetFramebufferAttachmentParameterivEXT(
00355 GL_FRAMEBUFFER_EXT
00356 , attachment
00357 , GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT
00358 , &type
00359 );
00360 guarded_unbind();
00361 return GLenum(type);
00362 }
00363
00373 GLuint get_attached_id( GLenum attachment )
00374 {
00375 guarded_bind();
00376 GLint id = 0;
00377 glGetFramebufferAttachmentParameterivEXT(
00378 GL_FRAMEBUFFER_EXT
00379 , attachment
00380 , GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT
00381 , &id
00382 );
00383 guarded_unbind();
00384 return GLuint(id);
00385 }
00386
00395 GLint get_attached_mip_level( GLenum attachment )
00396 {
00397 guarded_bind();
00398 GLint level = 0;
00399 glGetFramebufferAttachmentParameterivEXT(
00400 GL_FRAMEBUFFER_EXT
00401 , attachment
00402 , GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT
00403 , &level
00404 );
00405 guarded_unbind();
00406 return level;
00407 }
00408
00417 GLint get_attached_cube_face( GLenum attachment )
00418 {
00419 guarded_bind();
00420 GLint level = 0;
00421 glGetFramebufferAttachmentParameterivEXT(
00422 GL_FRAMEBUFFER_EXT
00423 , attachment
00424 , GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT
00425 , &level
00426 );
00427 guarded_unbind();
00428 return level;
00429 }
00430
00439 GLint get_attached_Z_slice( GLenum attachment )
00440 {
00441 guarded_bind();
00442 GLint slice = 0;
00443 glGetFramebufferAttachmentParameterivEXT(
00444 GL_FRAMEBUFFER_EXT
00445 , attachment
00446 , GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT
00447 , &slice
00448 );
00449 guarded_unbind();
00450 return slice;
00451 }
00452
00453 public:
00454
00462 static GLint get_max_color_attachments()
00463 {
00464 GLint max_attach = 0;
00465 glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &max_attach );
00466 return max_attach;
00467 }
00468
00474 static void disable(){ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); }
00475
00476 };
00477
00478
00479
00489 inline bool is_framebuffer_object_supported()
00490 {
00491
00492
00493 if (glewIsSupported("GL_EXT_framebuffer_object"))
00494 {
00495 return true;
00496 }
00497 return false;
00498 }
00499
00500 }
00501
00502 }
00503
00504
00505 #endif
00506