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)
90 std::cerr <<
"Framebuffer object not supported! " << std::endl;
96 glGenFramebuffersEXT( 1, &
fbo_ );
108 glDeleteFramebuffersEXT( 1, &
fbo_ );
118 for (AttachmentList::iterator it = attachments_.begin(); it != attachments_.end(); ++it)
119 if (it->second.id && it->second.owner)
120 glDeleteTextures(1, &it->second.id);
128 #ifdef GL_VERSION_3_2
133 glFramebufferTexture( GL_FRAMEBUFFER_EXT, _attachment, _texture, _level );
153 if (prevTex.owner && prevTex.id)
154 glDeleteTextures(1, &prevTex.id);
157 attachments_[_attachment] = intID;
159 std::cerr <<
"error: FBO::attachTexture unsupported - update glew headers and rebuild" << std::endl;
173 glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, _attachment, _target, _texture, 0 );
187 intID.target = _target;
191 if (prevTex.owner && prevTex.id)
192 glDeleteTextures(1, &prevTex.id);
195 attachments_[_attachment] = intID;
200 void FBO::attachTexture2D( GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode , GLint _minFilter , GLint _magFilter )
204 glGenTextures(1, &texID);
206 #ifdef GL_ARB_texture_multisample
207 GLenum target =
samples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
209 GLenum target = GL_TEXTURE_2D;
210 #endif // GL_ARB_texture_multisample
217 if (_minFilter != GL_NEAREST || _magFilter != GL_NEAREST)
219 std::cerr <<
"ACG::FBO - Multisampled texture must be filtered with GL_NEAREST!" << std::endl;
221 _minFilter = _magFilter = GL_NEAREST;
228 intID.internalFormat = _internalFmt;
229 intID.format = _format;
231 intID.target = target;
233 intID.wrapMode = _wrapMode;
234 intID.minFilter = _minFilter;
235 intID.magFilter = _magFilter;
240 glBindTexture(target, texID);
243 #ifdef GL_ARB_texture_multisample
246 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
247 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
248 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
249 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
250 glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, intID.gltype, 0);
255 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
256 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
257 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
258 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
259 glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, intID.gltype, 0);
260 #endif // GL_ARB_texture_multisample
268 glBindTexture(target, 0);
274 attachments_[_attachment] = intID;
279 void FBO::attachTexture3D( GLenum _attachment, GLsizei _width, GLsizei _height, GLsizei _depth, GLuint _internalFmt, GLenum _format, GLint _wrapMode , GLint _minFilter , GLint _magFilter )
283 glGenTextures(1, &texID);
285 GLenum target = GL_TEXTURE_3D;
290 intID.internalFormat = _internalFmt;
291 intID.format = _format;
293 intID.target = target;
294 intID.dim =
ACG::Vec3i(_width, _height, _depth);
295 intID.wrapMode = _wrapMode;
296 intID.minFilter = _minFilter;
297 intID.magFilter = _magFilter;
302 glBindTexture(target, texID);
304 glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
305 glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
306 glTexParameteri(target, GL_TEXTURE_WRAP_R, _wrapMode);
307 glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
308 glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
309 glTexImage3D(target, 0, _internalFmt, _width, _height, _depth, 0, _format, GL_FLOAT, 0);
316 glBindTexture(target, 0);
322 attachments_[_attachment] = intID;
329 attachTexture2D(GL_DEPTH_ATTACHMENT, _width, _height, _internalFmt, _format, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST);
336 attachTexture2D(GL_STENCIL_ATTACHMENT_EXT, _width, _height, GL_STENCIL_INDEX8, GL_STENCIL_INDEX, GL_CLAMP_TO_EDGE, GL_NEAREST, GL_NEAREST);
352 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
depthbuffer_);
355 #ifdef GL_ARB_texture_multisample
356 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
samples_, GL_DEPTH_COMPONENT, _width, _height);
358 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, _width, _height);
363 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
388 #ifdef GL_ARB_texture_multisample
389 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
samples_, GL_STENCIL_INDEX, _width, _height);
391 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX, _width, _height);
396 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
stencilbuffer_);
423 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT,
depthbuffer_);
426 #ifdef GL_ARB_texture_multisample
427 glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT,
samples_, GL_DEPTH_STENCIL, _width, _height);
429 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL, _width, _height);
435 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
436 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,
depthbuffer_);
454 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&
prevFbo_);
455 glGetIntegerv(GL_DRAW_BUFFER, (GLint*)&prevDrawBuffer_);
488 status = ( GLenum ) glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
492 case GL_FRAMEBUFFER_COMPLETE_EXT:
495 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
496 std::cout <<
" Framebuffer incomplete attachment\n";
498 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
499 std::cout <<
"Unsupported framebuffer format\n";
501 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
502 std::cout <<
"Framebuffer incomplete, missing attachment\n";
504 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
505 std::cout <<
"Framebuffer incomplete, attached images must have same dimensions\n";
507 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
508 std::cout <<
"Framebuffer incomplete, attached images must have same format\n";
510 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
511 std::cout <<
"Framebuffer incomplete, missing draw buffer\n";
513 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
514 std::cout <<
"Framebuffer incomplete, missing read buffer\n";
517 std::cout <<
"Framebuffer incomplete, attached images must have same multisample count\n";
520 std::cout <<
"Unhandled case\n";
524 return ( status == GL_FRAMEBUFFER_COMPLETE_EXT );
531 return attachments_[_attachment].id;
538 return attachments_[_attachment].internalFormat;
543 void FBO::resize( GLsizei _width, GLsizei _height,
bool _forceResize )
545 if (_width !=
width_ ||_height != height_ || _forceResize)
552 glDeleteFramebuffersEXT(1, &
fbo_);
553 glGenFramebuffersEXT(1, &
fbo_);
557 temp.swap(attachments_);
560 for (AttachmentList::iterator it = temp.begin(); it != temp.end(); ++it)
567 glDeleteTextures(1, &rt->id);
572 #ifdef GL_ARB_texture_multisample
573 case GL_TEXTURE_2D_MULTISAMPLE:
575 attachTexture2D(it->first, _width, _height, rt->internalFormat, rt->format, rt->wrapMode, rt->minFilter, rt->magFilter);
579 attachTexture3D(it->first, _width, _height, rt->dim[2], rt->internalFormat, rt->format, rt->wrapMode, rt->minFilter, rt->magFilter);
583 std::cout <<
"FBO::resize - unknown resize target " << rt->target << std::endl;
610 static GLint maxSamples = -1;
612 glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
614 if (_samples >= maxSamples) _samples = maxSamples - 1;
621 int safeSampleCount = 1;
623 while (safeSampleCount < _samples)
624 safeSampleCount <<= 1;
626 while (safeSampleCount >= maxSamples)
627 safeSampleCount >>= 1;
629 _samples = safeSampleCount;
632 recreateTextures = recreateTextures || (
samples_ != _samples);
640 if (recreateTextures)
static void bindFramebuffer(GLenum _target, GLuint _framebuffer)
replaces glBindFramebuffer, supports locking
GLsizei width_
width and height of render textures
Namespace providing different geometric functions concerning angles.
GLsizei samples_
sample count if multisampling
void attachTexture2D(GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode=GL_CLAMP, GLint _minFilter=GL_NEAREST, GLint _magFilter=GL_NEAREST)
function to attach a texture to fbo
void addDepthStencilBuffer(GLuint _width, GLuint _height)
add a packed depth24_stencil8 renderbuffer
void addDepthBuffer(GLuint _width, GLuint _height)
function to add a depth renderbuffer to the fbo
void addStencilBuffer(GLuint _width, GLuint _height)
function to add a stencil renderbuffer to the fbo
bool checkExtensionSupported(const std::string &_extension)
VectorT< signed int, 3 > Vec3i
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
void resize(GLsizei _width, GLsizei _height, bool _forceResize=false)
resize function (if textures created by this class)
GLuint getFboID()
return opengl id
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)
GLuint getAttachment(GLenum _attachment)
return attached texture id
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)
GLuint fbo_
handle of frame buffer object
void init()
function to generate the framebuffer object
GLuint getInternalFormat(GLenum _attachment)
return internal texture format of attachment
FBO()
Default constructor.
GLuint prevFbo_
handle of previously bound fbo
GLboolean fixedsamplelocation_
enable fixed sample location if multisampling
GLuint stencilbuffer_
stencilbuffer
void attachTexture2DStencil(GLsizei _width, GLsizei _height)
function to attach a stencil-buffer texture to fbo (texformat = GL_STENCIL_INDEX8) ...
GLuint depthbuffer_
depthbuffer
void attachTexture(GLenum _attachment, GLuint _texture, GLuint _level=0)
attach a texture of arbitrary dimension (requires OpenGL 3.2)
void unbind()
unbind fbo, go to normal rendering mode
void del()
delete fbo and all internally created render textures
bool checkFramebufferStatus()
function to check the framebuffer status
GLsizei setMultisampling(GLsizei _samples, GLboolean _fixedsamplelocations=GL_TRUE)
bool bind()
bind the fbo and sets it as rendertarget