Commit 4eda82ba authored by Jan Möbius's avatar Jan Möbius
Browse files

Framebuffer object interface extensions for postprocessor pipeline

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@17457 383ad7c9-94d9-4d36-a494-682f7c89f535
parent abbd5bb4
......@@ -16,21 +16,30 @@ namespace ACG
//== IMPLEMENTATION ==========================================================
FBO::FBO()
: fbo_(0), depthbuffer_(0), stencilbuffer_(0), width_(0), height_(0)
{
}
FBO::
~FBO()
{
if(fbo_) {
// delete framebuffer object
// delete framebuffer object
if(fbo_)
glDeleteFramebuffersEXT( 1, &fbo_ );
}
if(depthbuffer_) {
// delete render buffer
// delete render buffer
if(depthbuffer_)
glDeleteRenderbuffersEXT(1, &depthbuffer_);
}
if(stencilbuffer_) {
// delete stencil buffer
// delete stencil buffer
if(stencilbuffer_)
glDeleteRenderbuffersEXT(1, &stencilbuffer_);
}
for (size_t i = 0; i < internalTextures_.size(); ++i)
glDeleteTextures(1, &internalTextures_[i].id);
}
//-----------------------------------------------------------------------------
......@@ -39,21 +48,21 @@ void
FBO::
init()
{
// Create framebuffer object
if (!checkExtensionSupported("GL_EXT_framebuffer_object")) {
std::cout << "Framebuffer object not supported! " << std::endl;
exit( 1 );
}
// Create framebuffer object
if (!checkExtensionSupported("GL_EXT_framebuffer_object")) {
std::cerr << "Framebuffer object not supported! " << std::endl;
exit( 1 );
}
// test whether fbo hasn't been created before
if(!fbo_)
glGenFramebuffersEXT( 1, &fbo_ );
// test whether fbo hasn't been created before
if(!fbo_)
glGenFramebuffersEXT( 1, &fbo_ );
// check status
checkFramebufferStatus();
// check status
checkFramebufferStatus();
// unbind fbo
unbind();
// unbind fbo
unbind();
}
//-----------------------------------------------------------------------------
......@@ -62,17 +71,92 @@ void
FBO::
attachTexture2D( GLenum _attachment, GLuint _texture )
{
// bind fbo
bind();
// bind fbo
bind();
// add texture to frame buffer object
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, _attachment, GL_TEXTURE_2D, _texture, 0 );
// add texture to frame buffer object
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, _attachment, GL_TEXTURE_2D, _texture, 0 );
// check status
checkFramebufferStatus();
// check status
checkFramebufferStatus();
// unbind fbo
unbind();
// unbind fbo
unbind();
// track texture id
attachments_[_attachment] = _texture;
}
//-----------------------------------------------------------------------------
void FBO::attachTexture2D( GLenum _attachment, GLsizei _width, GLsizei _height, GLuint _internalFmt, GLenum _format, GLint _wrapMode /*= GL_CLAMP*/, GLint _minFilter /*= GL_LINEAR*/, GLint _magFilter /*= GL_LINEAR*/ )
{
// gen texture id
GLuint texID;
glGenTextures(1, &texID);
// store texture id in internal array
RenderTexture intID;
intID.id = texID;
intID.internalFormat = _internalFmt;
intID.format = _format;
internalTextures_.push_back(intID);
// specify texture
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _magFilter);
glTexImage2D(GL_TEXTURE_2D, 0, _internalFmt, _width, _height, 0, _format, GL_FLOAT, 0);
width_ = _width;
height_ = _height;
glBindTexture(GL_TEXTURE_2D, 0);
// attach
attachTexture2D(_attachment, texID);
}
//-----------------------------------------------------------------------------
void FBO::attachTexture2DDepth( GLsizei _width, GLsizei _height, GLuint _internalFmt /*= GL_DEPTH_COMPONENT32*/, GLenum _format /*= GL_DEPTH_COMPONENT */ )
{
// gen texture id
GLuint texID;
glGenTextures(1, &texID);
// store texture id in internal array
RenderTexture intID;
intID.id = texID;
intID.internalFormat = _internalFmt;
intID.format = _format;
internalTextures_.push_back(intID);
// specify texture
glBindTexture(GL_TEXTURE_2D, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, _internalFmt, _width, _height, 0, _format, GL_FLOAT, 0);
width_ = _width;
height_ = _height;
glBindTexture(GL_TEXTURE_2D, 0);
// attach
attachTexture2D(GL_DEPTH_ATTACHMENT, texID);
}
//-----------------------------------------------------------------------------
......@@ -92,7 +176,7 @@ addDepthBuffer( GLuint _width, GLuint _height )
// attach to framebuffer object
if ( bind() )
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer_);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, depthbuffer_);
// check status
checkFramebufferStatus();
......@@ -118,7 +202,7 @@ addStencilBuffer( GLuint _width, GLuint _height )
// attach to framebuffer object
if ( bind() )
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencilbuffer_);
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, stencilbuffer_);
// check status
checkFramebufferStatus();
......@@ -135,13 +219,13 @@ bool
FBO::
bind()
{
if ( !fbo_ )
return false;
if ( !fbo_ )
return false;
// bind framebuffer object
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, fbo_ );
// bind framebuffer object
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, fbo_ );
return true;
return true;
}
//-----------------------------------------------------------------------------
......@@ -150,8 +234,8 @@ void
FBO::
unbind()
{
//set to normal rendering
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, 0 );
//set to normal rendering
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, 0 );
}
//-----------------------------------------------------------------------------
......@@ -160,41 +244,79 @@ bool
FBO::
checkFramebufferStatus()
{
GLenum status;
status = ( GLenum ) glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
std::cout << "Framebuffer status: " << status << std::endl;
switch ( status )
GLenum status;
status = ( GLenum ) glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
std::cout << "Framebuffer status: " << status << std::endl;
switch ( status )
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
std::cout << "Framebuffer ok\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
std::cout << " Framebuffer incomplete attachment\n";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
std::cout << "Unsupported framebuffer format\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
std::cout << "Framebuffer incomplete, missing attachment\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
std::cout << "Framebuffer incomplete, attached images must have same dimensions\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
std::cout << "Framebuffer incomplete, attached images must have same format\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
std::cout << "Framebuffer incomplete, missing draw buffer\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
std::cout << "Framebuffer incomplete, missing read buffer\n";
break;
default:
std::cout << "Unhandled case\n";
break;
}
return ( status == GL_FRAMEBUFFER_COMPLETE_EXT );
}
//-----------------------------------------------------------------------------
GLuint FBO::getAttachment( GLenum _attachment )
{
return attachments_[_attachment];
}
//-----------------------------------------------------------------------------
void FBO::resize( GLsizei _width, GLsizei _height )
{
if (_width != width_ ||_height != height_)
{
// resize every texture stored in internal array
for (size_t i = 0; i < internalTextures_.size(); ++i)
{
case GL_FRAMEBUFFER_COMPLETE_EXT:
std::cout << "Framebuffer ok\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
std::cout << " Framebuffer incomplete attachment\n";
break;
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
std::cout << "Unsupported framebuffer format\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
std::cout << "Framebuffer incomplete, missing attachment\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
std::cout << "Framebuffer incomplete, attached images must have same dimensions\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
std::cout << "Framebuffer incomplete, attached images must have same format\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
std::cout << "Framebuffer incomplete, missing draw buffer\n";
break;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
std::cout << "Framebuffer incomplete, missing read buffer\n";
break;
default:
std::cout << "Unhandled case\n";
break;
RenderTexture* rt = &internalTextures_[i];
glBindTexture(GL_TEXTURE_2D, rt->id);
glTexImage2D(GL_TEXTURE_2D, 0, rt->internalFormat, _width, _height, 0, rt->format, GL_FLOAT, 0);
}
return ( status == GL_FRAMEBUFFER_COMPLETE_EXT );
// store new size
width_ = _width;
height_ = _height;
glBindTexture(GL_TEXTURE_2D, 0);
}
}
GLuint FBO::getFboID()
{
return fbo_;
}
......
......@@ -18,6 +18,8 @@
#include <iostream>
#include <cstdlib>
#include <map>
#include <vector>
#include <ACG/GL/gl.hh>
......@@ -36,28 +38,48 @@ namespace ACG {
A more elaborate description follows.
*/
class FBO
class ACGDLLEXPORT FBO
{
public:
// fbo_ braucht initialen Wert.
/// Default constructor
FBO() : fbo_(0), depthbuffer_(0), stencilbuffer_(0) {}
FBO();
/// Destructor
~FBO();
/// function to generate the framebuffer object
void init();
/// function to attach a texture to fbo
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 attachTexture2D( GLenum _attachment, GLuint _texture );
/// function to attach a depth-buffer texture to fbo (using GL_DEPTH_ATTACHMENT)
void attachTexture2DDepth( GLsizei _width, GLsizei _height, GLuint _internalFmt = GL_DEPTH_COMPONENT32, GLenum _format = GL_DEPTH_COMPONENT );
/// function to add a depth buffer to the fbo
void addDepthBuffer( GLuint _width, GLuint _height );
/// function to add a stencil buffer to the fbo
void addStencilBuffer( GLuint _width, GLuint _height );
/// return attached texture id
GLuint getAttachment( GLenum _attachment );
/// return opengl id
GLuint getFboID();
/// resize function (if textures created by this class)
void resize(GLsizei _width, GLsizei _height);
/// bind the fbo and sets it as rendertarget
bool bind();
......@@ -78,8 +100,20 @@ private:
/// stencilbuffer
GLuint stencilbuffer_;
/// attached textures
std::map<GLenum, GLuint> attachments_; // key: attachment index
struct RenderTexture
{
GLuint id;
GLenum internalFormat, format;
};
/// textures created by this class
std::vector<RenderTexture> internalTextures_;
/// width and height of render textures
GLsizei width_, height_;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment