50 #include <ACG/GL/acg_glew.hh> 54 #include "GLFormatInfo.hh" 64 FBO::RenderTexture::RenderTexture()
65 : id(0), target(0), internalFormat(0), format(0), gltype(0),
66 dim(0,0,0), wrapMode(0), minFilter(0), magFilter(0), owner(false)
72 : fbo_(0), depthbuffer_(0), stencilbuffer_(0), width_(0), height_(0), samples_(0), fixedsamplelocation_(GL_TRUE), prevFbo_(0), prevDrawBuffer_(GL_NONE)
96 std::cerr <<
"Framebuffer object not supported! " << std::endl;
103 glGenFramebuffers( 1, &
fbo_ );
115 glDeleteFramebuffers( 1, &
fbo_ );
125 for (AttachmentList::iterator it = attachments_.begin(); it != attachments_.end(); ++it)
126 if (it->second.id && it->second.owner)
127 glDeleteTextures(1, &it->second.id);
135 #ifdef GL_VERSION_3_2 140 glFramebufferTexture( GL_FRAMEBUFFER_EXT, _attachment, _texture, _level );
160 if (prevTex.owner && prevTex.id)
161 glDeleteTextures(1, &prevTex.id);
164 attachments_[_attachment] = intID;
166 std::cerr <<
"error: FBO::attachTexture unsupported - update glew headers and rebuild" << std::endl;
180 glFramebufferTexture2D( GL_FRAMEBUFFER_EXT, _attachment, _target, _texture, 0 );
194 intID.target = _target;
198 if (prevTex.owner && prevTex.id)
199 glDeleteTextures(1, &prevTex.id);
202 attachments_[_attachment] = intID;
207 void FBO::attachTexture2D( GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode , GLint _minFilter , GLint _magFilter )
211 glGenTextures(1, &texID);
213 #ifdef GL_ARB_texture_multisample 214 GLenum target =
samples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
216 GLenum target = GL_TEXTURE_2D;
217 #endif // GL_ARB_texture_multisample 224 if (_minFilter != GL_NEAREST || _magFilter != GL_NEAREST)
226 std::cerr <<
"ACG::FBO - Multisampled texture must be filtered with GL_NEAREST!" << std::endl;
228 _minFilter = _magFilter = GL_NEAREST;
235 intID.internalFormat = _internalFmt;
236 intID.format = _format;
238 intID.target = target;
240 intID.wrapMode = _wrapMode;
241 intID.minFilter = _minFilter;
242 intID.magFilter = _magFilter;
247 glBindTexture(target, texID);
250 #ifdef GL_ARB_texture_multisample 253 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
254 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
255 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
256 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
257 glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, intID.gltype, 0);
262 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
263 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
264 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
265 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
266 glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, intID.gltype, 0);
267 #endif // GL_ARB_texture_multisample 275 glBindTexture(target, 0);
281 attachments_[_attachment] = intID;
286 void FBO::attachTexture3D( GLenum _attachment, GLsizei _width, GLsizei _height, GLsizei _depth, GLuint _internalFmt, GLenum _format, GLint _wrapMode , GLint _minFilter , GLint _magFilter )
290 glGenTextures(1, &texID);
292 GLenum target = GL_TEXTURE_3D;
297 intID.internalFormat = _internalFmt;
298 intID.format = _format;
300 intID.target = target;
301 intID.dim =
ACG::Vec3i(_width, _height, _depth);
302 intID.wrapMode = _wrapMode;
303 intID.minFilter = _minFilter;
304 intID.magFilter = _magFilter;
309 glBindTexture(target, texID);
311 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
312 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
313 glTexParameteri(target, GL_TEXTURE_WRAP_R, _wrapMode);
314 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
315 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
316 glTexImage3D(target, 0, _internalFmt, _width, _height, _depth, 0, _format, GL_FLOAT, 0);
323 glBindTexture(target, 0);
329 attachments_[_attachment] = intID;
336 attachTexture2D(GL_DEPTH_ATTACHMENT, _width, _height, _internalFmt, _format, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST);
343 attachTexture2D(GL_STENCIL_ATTACHMENT_EXT, _width, _height, GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST);
359 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
depthbuffer_);
362 #ifdef GL_ARB_texture_multisample 363 glRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT,
samples_, GL_DEPTH_COMPONENT, _width, _height);
365 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, _width, _height);
370 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
395 #ifdef GL_ARB_texture_multisample 396 glRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT,
samples_, GL_STENCIL_INDEX, _width, _height);
398 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, _width, _height);
403 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
stencilbuffer_);
430 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
depthbuffer_);
433 #ifdef GL_ARB_texture_multisample 434 glRenderbufferStorageMultisample(GL_RENDERBUFFER_EXT,
samples_, GL_DEPTH_STENCIL, _width, _height);
436 glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL, _width, _height);
442 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
443 glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
461 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&
prevFbo_);
462 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&prevDrawBuffer_);
495 status = ( GLenum ) glCheckFramebufferStatus( GL_FRAMEBUFFER_EXT );
499 case GL_FRAMEBUFFER_COMPLETE_EXT:
502 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
503 std::cout <<
" Framebuffer incomplete attachment\n";
505 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
506 std::cout <<
"Unsupported framebuffer format\n";
508 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
509 std::cout <<
"Framebuffer incomplete, missing attachment\n";
511 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
512 std::cout <<
"Framebuffer incomplete, attached images must have same dimensions\n";
514 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
515 std::cout <<
"Framebuffer incomplete, attached images must have same format\n";
517 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
518 std::cout <<
"Framebuffer incomplete, missing draw buffer\n";
520 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
521 std::cout <<
"Framebuffer incomplete, missing read buffer\n";
524 std::cout <<
"Framebuffer incomplete, attached images must have same multisample count\n";
527 std::cout <<
"Unhandled case\n";
531 return ( status == GL_FRAMEBUFFER_COMPLETE_EXT );
538 return attachments_[_attachment].id;
545 return attachments_[_attachment].internalFormat;
550 void FBO::resize( GLsizei _width, GLsizei _height,
bool _forceResize )
552 if (_width !=
width_ ||_height != height_ || _forceResize)
559 glDeleteFramebuffers(1, &
fbo_);
560 glGenFramebuffers(1, &
fbo_);
564 temp.swap(attachments_);
567 for (AttachmentList::iterator it = temp.begin(); it != temp.end(); ++it)
574 glDeleteTextures(1, &rt->id);
579 #ifdef GL_ARB_texture_multisample 580 case GL_TEXTURE_2D_MULTISAMPLE:
582 attachTexture2D(it->first, _width, _height, rt->internalFormat, rt->format, rt->wrapMode, rt->minFilter, rt->magFilter);
586 attachTexture3D(it->first, _width, _height, rt->dim[2], rt->internalFormat, rt->format, rt->wrapMode, rt->minFilter, rt->magFilter);
590 std::cout <<
"FBO::resize - unknown resize target " << rt->target << std::endl;
617 static GLint maxSamples = -1;
619 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
621 if (_samples >= maxSamples) _samples = maxSamples - 1;
628 int safeSampleCount = 1;
630 while (safeSampleCount < _samples)
631 safeSampleCount <<= 1;
633 while (safeSampleCount >= maxSamples)
634 safeSampleCount >>= 1;
636 _samples = safeSampleCount;
639 recreateTextures = recreateTextures || (
samples_ != _samples);
647 if (recreateTextures)
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
GLuint depthbuffer_
depthbuffer
GLuint fbo_
handle of frame buffer object
Namespace providing different geometric functions concerning angles.
void addDepthStencilBuffer(GLuint _width, GLuint _height)
add a packed depth24_stencil8 renderbuffer
void unbind()
unbind fbo, go to normal rendering mode
void attachTexture2D(GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode=GL_CLAMP_TO_EDGE, GLint _minFilter=GL_NEAREST, GLint _magFilter=GL_NEAREST)
function to attach a texture to fbo
GLuint getFboID()
return opengl id
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
void attachTexture2DStencil(GLsizei _width, GLsizei _height)
function to attach a stencil-buffer texture to fbo (texformat = GL_STENCIL_INDEX8) ...
VectorT< signed int, 3 > Vec3i
void del()
delete fbo and all internally created render textures
void addStencilBuffer(GLuint _width, GLuint _height)
function to add a stencil renderbuffer to the fbo
GLsizei width_
width and height of render textures
GLuint prevFbo_
handle of previously bound fbo
void init()
function to generate the framebuffer object
void attachTexture2DDepth(GLsizei _width, GLsizei _height, GLuint _internalFmt=GL_DEPTH_COMPONENT32, GLenum _format=GL_DEPTH_COMPONENT)
function to attach a depth-buffer texture to fbo (using GL_DEPTH_ATTACHMENT)
bool openGLVersion(const int _major, const int _minor, bool _verbose)
bool bind()
bind the fbo and sets it as rendertarget
GLboolean fixedsamplelocation_
enable fixed sample location if multisampling
GLuint getInternalFormat(GLenum _attachment)
return internal texture format of attachment
void attachTexture(GLenum _attachment, GLuint _texture, GLuint _level=0)
attach a texture of arbitrary dimension (requires OpenGL 3.2)
void attachTexture3D(GLenum _attachment, GLsizei _width, GLsizei _height, GLsizei _depth, GLuint _internalFmt, GLenum _format, GLint _wrapMode=GL_CLAMP, GLint _minFilter=GL_NEAREST, GLint _magFilter=GL_NEAREST)
bool checkExtensionSupported(const std::string &_extension)
bool checkFramebufferStatus()
function to check the framebuffer status
GLsizei setMultisampling(GLsizei _samples, GLboolean _fixedsamplelocations=GL_TRUE)
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
GLsizei samples_
sample count if multisampling
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
GLuint getAttachment(GLenum _attachment)
return attached texture id
GLuint stencilbuffer_
stencilbuffer