Commit 26fb00d2 authored by Christopher Tenter's avatar Christopher Tenter
Browse files

Snapshot fix, Post-Processing was ignored in snapshots

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@17797 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 68058dd6
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "FBO.hh" #include "FBO.hh"
#include "GLState.hh" #include "GLState.hh"
#include "GLError.hh"
//== NAMESPACES =============================================================== //== NAMESPACES ===============================================================
...@@ -19,7 +20,7 @@ namespace ACG ...@@ -19,7 +20,7 @@ namespace ACG
FBO::FBO() FBO::FBO()
: fbo_(0), depthbuffer_(0), stencilbuffer_(0), width_(0), height_(0) : fbo_(0), depthbuffer_(0), stencilbuffer_(0), width_(0), height_(0), samples_(0), fixedsamplelocation_(GL_TRUE), prevFbo_(0)
{ {
} }
...@@ -69,13 +70,15 @@ init() ...@@ -69,13 +70,15 @@ init()
void void
FBO:: FBO::
attachTexture2D( GLenum _attachment, GLuint _texture ) attachTexture2D( GLenum _attachment, GLuint _texture, GLenum _target )
{ {
// bind fbo // bind fbo
bind(); bind();
// add texture to frame buffer object // add texture to frame buffer object
glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, _attachment, GL_TEXTURE_2D, _texture, 0 ); glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, _attachment, _target, _texture, 0 );
checkGLError();
// check status // check status
checkFramebufferStatus(); checkFramebufferStatus();
...@@ -84,7 +87,7 @@ attachTexture2D( GLenum _attachment, GLuint _texture ) ...@@ -84,7 +87,7 @@ attachTexture2D( GLenum _attachment, GLuint _texture )
unbind(); unbind();
// track texture id // track texture id
attachments_[_attachment] = _texture; attachments_[_attachment] = std::pair<GLuint, GLenum>(_texture, _target);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -95,32 +98,41 @@ void FBO::attachTexture2D( GLenum _attachment, GLsizei _width, GLsizei _height, ...@@ -95,32 +98,41 @@ void FBO::attachTexture2D( GLenum _attachment, GLsizei _width, GLsizei _height,
GLuint texID; GLuint texID;
glGenTextures(1, &texID); glGenTextures(1, &texID);
GLenum target = samples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
// store texture id in internal array // store texture id in internal array
RenderTexture intID; RenderTexture intID;
intID.id = texID; intID.id = texID;
intID.internalFormat = _internalFmt; intID.internalFormat = _internalFmt;
intID.format = _format; intID.format = _format;
intID.target = target;
internalTextures_.push_back(intID); internalTextures_.push_back(intID);
// specify texture // specify texture
glBindTexture(GL_TEXTURE_2D, texID); glBindTexture(target, texID);
glTexParameteri(target, GL_TEXTURE_WRAP_S, _wrapMode);
glTexParameteri(target, GL_TEXTURE_WRAP_T, _wrapMode);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _wrapMode); if (!samples_)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _wrapMode); {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _minFilter); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, _minFilter);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _magFilter); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, _magFilter);
glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, GL_FLOAT, 0);
}
else
glTexImage2DMultisample(target, samples_, _internalFmt, _width, _height, fixedsamplelocation_);
glTexImage2D(GL_TEXTURE_2D, 0, _internalFmt, _width, _height, 0, _format, GL_FLOAT, 0); checkGLError();
width_ = _width; width_ = _width;
height_ = _height; height_ = _height;
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(target, 0);
// attach // attach
attachTexture2D(_attachment, texID); attachTexture2D(_attachment, texID, target);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -131,32 +143,41 @@ void FBO::attachTexture2DDepth( GLsizei _width, GLsizei _height, GLuint _interna ...@@ -131,32 +143,41 @@ void FBO::attachTexture2DDepth( GLsizei _width, GLsizei _height, GLuint _interna
GLuint texID; GLuint texID;
glGenTextures(1, &texID); glGenTextures(1, &texID);
GLenum target = samples_ ? GL_TEXTURE_2D_MULTISAMPLE : GL_TEXTURE_2D;
// store texture id in internal array // store texture id in internal array
RenderTexture intID; RenderTexture intID;
intID.id = texID; intID.id = texID;
intID.internalFormat = _internalFmt; intID.internalFormat = _internalFmt;
intID.format = _format; intID.format = _format;
intID.target = target;
internalTextures_.push_back(intID); internalTextures_.push_back(intID);
// specify texture // specify texture
glBindTexture(GL_TEXTURE_2D, texID); glBindTexture(target, texID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(target, 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); if (!samples_)
{
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(target, 0, _internalFmt, _width, _height, 0, _format, _format == GL_DEPTH_STENCIL ? GL_UNSIGNED_INT_24_8 : GL_FLOAT, 0);
}
else
glTexImage2DMultisample(target, samples_, _internalFmt, _width, _height, fixedsamplelocation_);
checkGLError();
width_ = _width; width_ = _width;
height_ = _height; height_ = _height;
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(target, 0);
// attach // attach
attachTexture2D(GL_DEPTH_ATTACHMENT, texID); attachTexture2D(GL_DEPTH_ATTACHMENT, texID, target);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -222,6 +243,9 @@ bind() ...@@ -222,6 +243,9 @@ bind()
if ( !fbo_ ) if ( !fbo_ )
return false; return false;
// save previous fbo id
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&prevFbo_);
// bind framebuffer object // bind framebuffer object
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, fbo_ ); ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, fbo_ );
...@@ -235,7 +259,7 @@ FBO:: ...@@ -235,7 +259,7 @@ FBO::
unbind() unbind()
{ {
//set to normal rendering //set to normal rendering
ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, 0 ); ACG::GLState::bindFramebuffer( GL_FRAMEBUFFER_EXT, prevFbo_ );
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -285,29 +309,53 @@ checkFramebufferStatus() ...@@ -285,29 +309,53 @@ checkFramebufferStatus()
GLuint FBO::getAttachment( GLenum _attachment ) GLuint FBO::getAttachment( GLenum _attachment )
{ {
return attachments_[_attachment]; return attachments_[_attachment].first;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void FBO::resize( GLsizei _width, GLsizei _height ) void FBO::resize( GLsizei _width, GLsizei _height, bool _forceResize )
{ {
if (_width != width_ ||_height != height_) if (_width != width_ ||_height != height_ || _forceResize)
{ {
bool reattachTextures = false;
// resize every texture stored in internal array // resize every texture stored in internal array
for (size_t i = 0; i < internalTextures_.size(); ++i) for (size_t i = 0; i < internalTextures_.size(); ++i)
{ {
RenderTexture* rt = &internalTextures_[i]; RenderTexture* rt = &internalTextures_[i];
glBindTexture(GL_TEXTURE_2D, rt->id); // check if we have to convert to multisampling
glTexImage2D(GL_TEXTURE_2D, 0, rt->internalFormat, _width, _height, 0, rt->format, GL_FLOAT, 0); if (rt->target != GL_TEXTURE_2D_MULTISAMPLE && samples_ > 0)
{
rt->target = GL_TEXTURE_2D_MULTISAMPLE;
reattachTextures = true;
}
glBindTexture(rt->target, rt->id);
if (!samples_)
glTexImage2D(rt->target, 0, rt->internalFormat, _width, _height, 0, rt->format, rt->format == GL_DEPTH_STENCIL ? GL_UNSIGNED_INT_24_8 : GL_FLOAT, 0);
else
glTexImage2DMultisample(rt->target, samples_, rt->internalFormat, _width, _height, fixedsamplelocation_);
} }
// store new size // store new size
width_ = _width; width_ = _width;
height_ = _height; height_ = _height;
if (reattachTextures)
{
for (AttachmentList::iterator it = attachments_.begin(); it != attachments_.end(); ++it)
{
attachTexture2D( it->first, it->second.first, it->second.second );
}
}
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
} }
...@@ -319,6 +367,26 @@ GLuint FBO::getFboID() ...@@ -319,6 +367,26 @@ GLuint FBO::getFboID()
return fbo_; return fbo_;
} }
void FBO::setMultisampling( GLsizei _samples, GLboolean _fixedsamplelocations /*= GL_TRUE*/ )
{
// clamp sample count to max supported
GLint maxSamples;
glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);
if (_samples > maxSamples) _samples = maxSamples;
// issue texture reloading when params changed
bool reloadTextures = (samples_ != _samples || fixedsamplelocation_ != _fixedsamplelocations);
samples_ = _samples;
fixedsamplelocation_ = _fixedsamplelocations;
// force a texture reloading to apply new multisampling
if (reloadTextures)
resize(width_, height_, true);
}
//============================================================================= //=============================================================================
} // namespace ACG } // namespace ACG
......
...@@ -52,6 +52,12 @@ public: ...@@ -52,6 +52,12 @@ public:
/// function to generate the framebuffer object /// function to generate the framebuffer object
void init(); void init();
/// enable/disable multisampling
void setMultisampling(GLsizei _samples, GLboolean _fixedsamplelocations = GL_TRUE);
/// get number of samples
GLsizei getMultisamplingCount() const {return samples_;}
/// function to attach a texture to fbo /// function to attach a texture to fbo
void attachTexture2D( GLenum _attachment, void attachTexture2D( GLenum _attachment,
GLsizei _width, GLsizei _height, GLsizei _width, GLsizei _height,
...@@ -60,8 +66,9 @@ public: ...@@ -60,8 +66,9 @@ public:
GLint _minFilter = GL_NEAREST, GLint _minFilter = GL_NEAREST,
GLint _magFilter = GL_NEAREST); GLint _magFilter = GL_NEAREST);
/// function to attach a texture to fbo /// function to attach a texture to fbo
void attachTexture2D( GLenum _attachment, GLuint _texture ); void attachTexture2D( GLenum _attachment, GLuint _texture, GLenum _target = GL_TEXTURE_2D );
/// function to attach a depth-buffer texture to fbo (using GL_DEPTH_ATTACHMENT) /// 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 ); void attachTexture2DDepth( GLsizei _width, GLsizei _height, GLuint _internalFmt = GL_DEPTH_COMPONENT32, GLenum _format = GL_DEPTH_COMPONENT );
...@@ -79,7 +86,13 @@ public: ...@@ -79,7 +86,13 @@ public:
GLuint getFboID(); GLuint getFboID();
/// resize function (if textures created by this class) /// resize function (if textures created by this class)
void resize(GLsizei _width, GLsizei _height); void resize(GLsizei _width, GLsizei _height, bool _forceResize = false);
/// get width of fbo texture
GLsizei width() const {return width_;}
/// get height of fbo texture
GLsizei height() const {return height_;}
/// bind the fbo and sets it as rendertarget /// bind the fbo and sets it as rendertarget
bool bind(); bool bind();
...@@ -102,11 +115,17 @@ private: ...@@ -102,11 +115,17 @@ private:
GLuint stencilbuffer_; GLuint stencilbuffer_;
/// attached textures /// attached textures
std::map<GLenum, GLuint> attachments_; // key: attachment index typedef std::map<GLenum, std::pair<GLuint, GLenum> > AttachmentList;
AttachmentList attachments_; // key: attachment index, value: <tex_id, target>
struct RenderTexture struct RenderTexture
{ {
// opengl buf id
GLuint id; GLuint id;
// GL_TEXTURE_2D, GL_TEXTURE_2D_MULTISAMPLE..
GLenum target;
GLenum internalFormat, format; GLenum internalFormat, format;
}; };
/// textures created by this class /// textures created by this class
...@@ -114,6 +133,16 @@ private: ...@@ -114,6 +133,16 @@ private:
/// width and height of render textures /// width and height of render textures
GLsizei width_, height_; GLsizei width_, height_;
/// sample count if multisampling
GLsizei samples_;
/// enable fixed sample location if multisampling
GLboolean fixedsamplelocation_;
/// handle of previously bound fbo
GLuint prevFbo_;
}; };
......
...@@ -250,9 +250,6 @@ void IRenderer::prepareRenderingPipeline(ACG::GLState* _glState, ACG::SceneGraph ...@@ -250,9 +250,6 @@ void IRenderer::prepareRenderingPipeline(ACG::GLState* _glState, ACG::SceneGraph
void IRenderer::finishRenderingPipeline() void IRenderer::finishRenderingPipeline()
{ {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
glDepthMask(1); glDepthMask(1);
glColorMask(1,1,1,1); glColorMask(1,1,1,1);
......
...@@ -61,6 +61,8 @@ ...@@ -61,6 +61,8 @@
#include <ACG/Scenegraph/CoordsysNode.hh> #include <ACG/Scenegraph/CoordsysNode.hh>
#include <ACG/Scenegraph/SceneGraphAnalysis.hh> #include <ACG/Scenegraph/SceneGraphAnalysis.hh>
#include <ACG/GL/gl.hh> #include <ACG/GL/gl.hh>
#include <ACG/GL/GLError.hh>
#include <ACG/GL/FBO.hh>
#include <iostream> #include <iostream>
#include <string> #include <string>
...@@ -166,8 +168,7 @@ glViewer::glViewer( QGraphicsScene* _scene, ...@@ -166,8 +168,7 @@ glViewer::glViewer( QGraphicsScene* _scene,
flyAnimationOrthogonal_(0), flyAnimationOrthogonal_(0),
flyAngle_(0.0), flyAngle_(0.0),
currentAnimationPos_(0.0), currentAnimationPos_(0.0),
flyMoveBack_(false), flyMoveBack_(false)
sceneTexReadBackWidth_(0), sceneTexReadBackHeight_(0)
{ {
// widget stuff // widget stuff
...@@ -636,76 +637,64 @@ void glViewer::drawScene() ...@@ -636,76 +637,64 @@ void glViewer::drawScene()
// } // }
// QGLFramebufferObject fbo( glstate_->viewport_width(),glstate_->viewport_height(),QGLFramebufferObject::CombinedDepthStencil );
//
// fbo.bind();
updatePostProcessingBufs(glstate_->viewport_width(),glstate_->viewport_height());
// glBindFramebuffer(GL_FRAMEBUFFER, postProcessFBO_);
// Check if we use build in default renderer // Check if we use build in default renderer
if ( renderManager().activeId( properties_.viewerId() ) == 0 ) { if ( renderManager().activeId( properties_.viewerId() ) == 0 ) {
drawScene_mono(); drawScene_mono();
} else { } else {
renderManager().active( properties_.viewerId() )->plugin->render(glstate_,properties_); renderManager().active( properties_.viewerId() )->plugin->render(glstate_,properties_);
} }
checkGLError();
// glBindFramebuffer(GL_FRAMEBUFFER, 0);
// =================================================================================
// Post-Processing pipeline
const int numPostProcessors = postProcessorManager().numActive(properties_.viewerId());
// ================================================================================= if (numPostProcessors)
// Post-Processing pipeline {
GLuint backbufferFbo = 0;
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, (GLint*)&backbufferFbo);
readBackBuffer(glstate_);
int numPostProcessors = postProcessorManager().numActive(properties_.viewerId()); updatePostProcessingBufs(glstate_->viewport_width(),glstate_->viewport_height());
// // DEBUG testing post processor chain readBackBuffer(glstate_);
// if (numPostProcessors == 1)
// {
// postProcessorManager().append("Grayscale Postprocessor Plugin", properties_.viewerId());
// postProcessorManager().append("Red Postprocessor Plugin", properties_.viewerId());
//
// numPostProcessors += 2;
// }
// 1st post processing source: back buffer // 1st post processing source: active fbo
int postProcSrc = 1; int postProcSrc = 1;
PostProcessorInput postProcInput; PostProcessorInput postProcInput;
postProcInput.colorTex_ = sceneTexReadBack_.id();
postProcInput.depthTex_ = depthTexReadBack_.id();
postProcInput.width = sceneTexReadBackWidth_;
postProcInput.height = sceneTexReadBackHeight_;
postProcInput.colorTex_ = readBackFbo_.getAttachment(GL_COLOR_ATTACHMENT0);
postProcInput.depthTex_ = readBackFbo_.getAttachment(GL_DEPTH_ATTACHMENT);
postProcInput.width = readBackFbo_.width();
postProcInput.height = readBackFbo_.height();
// execute post processing chain with 2 FBOs // execute post processing chain with 2 FBOs
for (int i = 0; i < numPostProcessors; ++i) { for (int i = 0; i < numPostProcessors; ++i) {
int postProcTarget = 1 - postProcSrc; int postProcTarget = 1 - postProcSrc;
GLuint targetFBO = postProcessFBO_[postProcTarget].getFboID(); GLuint targetFBO = postProcessFBO_[postProcTarget].getFboID();
// write to back buffer in last step // write to back buffer in last step
if (i + 1 == numPostProcessors) if (i + 1 == numPostProcessors)
targetFBO = 0; targetFBO = backbufferFbo;
// apply post processor // apply post processor
PostProcessorInfo* proc = postProcessorManager().active( properties_.viewerId(), i ); PostProcessorInfo* proc = postProcessorManager().active( properties_.viewerId(), i );
if (proc && proc->plugin) if (proc && proc->plugin)
proc->plugin->postProcess(glstate_, postProcInput, targetFBO); proc->plugin->postProcess(glstate_, postProcInput, targetFBO);
// swap target/source fbo // swap target/source fbo
postProcSrc = postProcTarget; postProcSrc = postProcTarget;
postProcInput.colorTex_ = postProcessFBO_[postProcSrc].getAttachment(GL_COLOR_ATTACHMENT0); postProcInput.colorTex_ = postProcessFBO_[postProcSrc].getAttachment(GL_COLOR_ATTACHMENT0);
}
} }
// ================================================================================= // =================================================================================
...@@ -2118,7 +2107,7 @@ void glViewer::applyProperties() { ...@@ -2118,7 +2107,7 @@ void glViewer::applyProperties() {
// Make sure the right buffer is used in non stereo setup // Make sure the right buffer is used in non stereo setup
makeCurrent(); makeCurrent();
ACG::GLState::drawBuffer(GL_BACK); ACG::GLState::drawBuffer(ACG::GLState::getFramebufferDraw() ? GL_COLOR_ATTACHMENT0 : GL_BACK);
// Required for stereo toggling // Required for stereo toggling
updateProjectionMatrix (); updateProjectionMatrix ();
...@@ -2166,17 +2155,18 @@ void glViewer::snapshot(QImage& _image, int _width, int _height, bool _alpha, bo ...@@ -2166,17 +2155,18 @@ void glViewer::snapshot(QImage& _image, int _width, int _height, bool _alpha, bo
format.setTextureTarget(GL_TEXTURE_2D); format.setTextureTarget(GL_TEXTURE_2D);
// set the attachments as in the standard rendering // set the attachments as in the standard rendering
format.setAttachment(QFramebufferObject::CombinedDepthStencil);