44#include <ACG/GL/acg_glew.hh>
46#include "DepthPeeling.hh"
52#include <ACG/GL/ShaderCache.hh>
53#include <ACG/GL/GLError.hh>
54#include <ACG/GL/ScreenQuad.hh>
77 _code->push_back(
"float dp_prevDepth = texture(g_DepthLayer, sg_vScreenPos).x;");
78 _code->push_back(
"if (gl_FragCoord.z <= dp_prevDepth) discard;");
83 _code->push_back(
"outFragment = vec4(sg_cColor.rgb * sg_cColor.a, sg_cColor.a);");
84 _code->push_back(
"outDepth = gl_FragCoord.z;");
102 _code->push_back(
"outFragment = vec4(sg_cColor.rgb * sg_cColor.a, 1.0 - sg_cColor.a);");
103 _code->push_back(
"outDepth = gl_FragCoord.z;");
116 _shader->
addUniform(
"sampler2D g_DepthLayer");
117 _shader->
addUniform(
"sampler2D g_FrontLayer");
126 _code->push_back(
"float fragDepth = gl_FragCoord.z;");
132 _code->push_back(
"vec2 depthLayer = texture(g_DepthLayer, sg_vScreenPos).xy;");
133 _code->push_back(
"vec4 forwardTemp = texture(g_FrontLayer, sg_vScreenPos);");
138 _code->push_back(
"vec2 depthLayer = texture2D(g_DepthLayer, sg_vScreenPos).xy;");
139 _code->push_back(
"vec4 forwardTemp = texture2D(g_FrontLayer, sg_vScreenPos);");
141 _code->push_back(
"outDepth = vec4(depthLayer, 0, 0);");
142 _code->push_back(
"outFragment = forwardTemp;");
143 _code->push_back(
"outBackColor = vec4(0,0,0,0);");
146 _code->push_back(
"float nearestDepth = -depthLayer.x;");
147 _code->push_back(
"float farthestDepth = depthLayer.y;");
148 _code->push_back(
"float alphaMultiplier = 1.0 - forwardTemp.w;");
151 _code->push_back(
"if (fragDepth < nearestDepth || fragDepth > farthestDepth) {");
152 _code->push_back(
"outDepth = vec4(-1,-1,-1,-1);");
153 _code->push_back(
"return;");
154 _code->push_back(
"}");
156 _code->push_back(
"if (fragDepth > nearestDepth && fragDepth < farthestDepth) {");
157 _code->push_back(
"outDepth = vec4(-fragDepth, fragDepth, 0, 0);");
158 _code->push_back(
"return;");
159 _code->push_back(
"}");
165 _code->push_back(
"outDepth = vec4(-1,-1,-1,-1);");
166 _code->push_back(
"outFragment = forwardTemp;");
168 _code->push_back(
"if (fragDepth == nearestDepth) {");
169 _code->push_back(
"outFragment.xyz += sg_cColor.rgb * sg_cColor.a * alphaMultiplier;");
170 _code->push_back(
"outFragment.w = 1.0 - alphaMultiplier * (1.0 - sg_cColor.a);");
174 _code->push_back(
"} else {");
175 _code->push_back(
"outBackColor += sg_cColor;");
176 _code->push_back(
"}");
187 _code->push_back(
"outFragment = vec4(-gl_FragCoord.z, gl_FragCoord.z, 0, 0);");
201#define RENDERFLAG_ALLOW_PEELING 1
206DepthPeeling::DepthPeeling()
207 : peelMode_(1), copyFrontDepth_(1), maxPeelCount_(20), peelBlend_(0), peelFinal_(0), peelQueryID_(0),
208peelBlendDual_(0), peelFinalDual_(0)
213DepthPeeling::~DepthPeeling()
219QString DepthPeeling::checkOpenGL()
224 return QString(
"Insufficient OpenGL Version! OpenGL 3.2 or higher required");
232void DepthPeeling::initializePlugin()
237void DepthPeeling::exit()
248 delete peelFinalDual_;
258void DepthPeeling::slotModeChanged( QAction * _action)
261 if ( _action->text() ==
"Front to Back") {
263 }
else if ( _action->text() ==
"Dual") {
266 std::cerr <<
"Error : optionHandling unable to find peeling mode!!! " << _action->text().toStdString() << std::endl;
303 int lastPeeledObject = -1;
305 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
308 lastPeeledObject = i;
311 if (lastPeeledObject == -1)
314 for (
int i = 0; i < numRenderObjects; ++i)
332 const GLenum depthTarget = GL_COLOR_ATTACHMENT0;
333 const GLenum colorTarget = GL_COLOR_ATTACHMENT1;
334 const GLenum colorBlendTarget = GL_COLOR_ATTACHMENT4;
335 GLenum peelLayerTargets[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
337 const float clearDepth = 1.0f;
343 glBindFramebuffer(GL_FRAMEBUFFER, viewRes->singleFbo_->
getFboID());
347 glColorMask(1,1,1,1);
350 glDrawBuffer(colorBlendTarget);
352 glClear(GL_COLOR_BUFFER_BIT);
355 glDrawBuffer(colorTarget);
356 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
357 glClear(GL_COLOR_BUFFER_BIT);
360 glDrawBuffer(depthTarget);
361 glClearColor(clearDepth, 0.0f, 0.0f, 0.0f);
362 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
367 peelLayerTargets[0] = colorBlendTarget;
368 peelLayerTargets[1] = depthTarget;
369 glDrawBuffers(2, peelLayerTargets);
372 glDisable(GL_ALPHA_TEST);
374 glEnable(GL_DEPTH_TEST);
375 glDepthFunc(GL_LESS);
376 glDisable(GL_CULL_FACE);
378 for (
int i = 0; i < numRenderObjects; ++i)
405 const int currID = pass & 1;
406 const int prevID = 1 - currID;
407 const int bufID = currID * 2;
412 const GLenum targetBuffer[2] = {colorTarget + bufID, depthTarget + bufID};
418 glDrawBuffer(targetBuffer[0]);
419 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
420 glClear(GL_COLOR_BUFFER_BIT);
422 glDrawBuffer(targetBuffer[1]);
423 glClearColor(clearDepth, 0.0f, 0.0f, 0.0f);
424 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
427 glDrawBuffers(2, targetBuffer);
431 glEnable(GL_DEPTH_TEST);
438 glActiveTexture(GL_TEXTURE4);
439 glBindTexture(GL_TEXTURE_2D, viewRes->singleDepthTex_[prevID]);
442 for (
int k = 0; k < numRenderObjects; ++k)
462 glEndQuery(GL_SAMPLES_PASSED);
469 glDrawBuffer(colorBlendTarget);
472 glColorMask(1,1,1,1);
474 glDisable(GL_DEPTH_TEST);
477 glBlendEquation(GL_FUNC_ADD);
479 GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
485 glActiveTexture(GL_TEXTURE0);
486 glBindTexture(GL_TEXTURE_2D, viewRes->singleFrontTex_[currID]);
495 GLuint passedSamples;
496 glGetQueryObjectuiv(
peelQueryID_, GL_QUERY_RESULT, &passedSamples);
497 if (passedSamples == 0)
506 glColorMask(1,1,1,1);
508 glDisable(GL_DEPTH_TEST);
522 glActiveTexture(GL_TEXTURE0);
523 glBindTexture(GL_TEXTURE_2D, viewRes->singleBlendTex_);
533 glEnable(GL_DEPTH_TEST);
550 int lastPeeledObject = -1;
552 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
555 lastPeeledObject = i;
561 for (
int i = 0; i < numRenderObjects; ++i)
578 glColorMask(1,1,1,1);
584 glBindFramebuffer(GL_FRAMEBUFFER, viewRes->dualFbo_->
getFboID());
586 const GLenum depthTarget = GL_COLOR_ATTACHMENT0;
587 const GLenum colorTargets[] = {GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
588 const GLenum colorBlendTarget = GL_COLOR_ATTACHMENT6;
591 glDrawBuffers(2, colorTargets);
592 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
593 glClear(GL_COLOR_BUFFER_BIT);
596 glDrawBuffer(colorBlendTarget);
598 glClear(GL_COLOR_BUFFER_BIT);
601 glDrawBuffer(depthTarget);
602 glClearColor(-1.0f, -1.0f, 0.0f, 0.0f);
603 glClear(GL_COLOR_BUFFER_BIT);
609 glBlendEquation(GL_MAX_EXT);
611 if(_glState->compatibilityProfile())
612 glDisable(GL_ALPHA_TEST);
614 glEnable(GL_DEPTH_TEST);
615 glDepthFunc(GL_LESS);
616 glDisable(GL_CULL_FACE);
618 for (
int i = 0; i < numRenderObjects; ++i)
644 const int prevID = 1 - currID;
645 const int bufID = currID * 3;
647 GLenum targetBuffer[3];
648 targetBuffer[0] = GL_COLOR_ATTACHMENT0 + bufID;
649 targetBuffer[1] = GL_COLOR_ATTACHMENT1 + bufID;
650 targetBuffer[2] = GL_COLOR_ATTACHMENT2 + bufID;
654 glDrawBuffers(2, targetBuffer + 1);
655 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
656 glClear(GL_COLOR_BUFFER_BIT);
659 glDrawBuffer(targetBuffer[0]);
660 glClearColor(-1.0f, -1.0f, 0.0f, 0.0f);
661 glClear(GL_COLOR_BUFFER_BIT);
668 glBlendEquation(GL_MAX_EXT);
669 glDrawBuffers(3, targetBuffer);
675 glActiveTexture(GL_TEXTURE5);
676 glBindTexture(GL_TEXTURE_2D, viewRes->dualFrontTex_[prevID]);
678 glActiveTexture(GL_TEXTURE4);
679 glBindTexture(GL_TEXTURE_2D, viewRes->dualDepthTex_[prevID]);
682 glActiveTexture(GL_TEXTURE0);
685 for (
int i = 0; i < numRenderObjects; ++i)
702 if (locOutFrag != 1 ||
704 locOutBackColor != 2)
737 glDrawBuffer(colorBlendTarget);
739 glBlendEquation(GL_FUNC_ADD);
743 glActiveTexture(GL_TEXTURE0);
744 glBindTexture(GL_TEXTURE_2D, viewRes->dualBackTex_[currID]);
754 glEndQuery(GL_SAMPLES_PASSED_ARB);
759 GLuint passedSamples;
760 glGetQueryObjectuiv(
peelQueryID_, GL_QUERY_RESULT, &passedSamples);
761 if (passedSamples == 0)
771 glColorMask(1,1,1,1);
773 glDisable(GL_DEPTH_TEST);
777 peelFinalDual_->
use();
785 peelFinalDual_->
setUniform(
"BkgColor", bkgColor);
790 peelFinalDual_->
setUniform(
"FrontSceneTex", 0);
791 peelFinalDual_->
setUniform(
"BackSceneTex", 1);
793 glActiveTexture(GL_TEXTURE1);
794 glBindTexture(GL_TEXTURE_2D, viewRes->dualBlendTex_);
796 glActiveTexture(GL_TEXTURE0);
797 glBindTexture(GL_TEXTURE_2D, viewRes->dualFrontTex_[currID]);
842 std::cout <<
"error: missing vertex declaration" << std::endl;
861 if (p->alpha < 1.0f &&
863 p->depthWrite && (p->
depthFunc == GL_LESS ||
869 ShaderCache::getInstance()->getProgram(&p->
shaderDesc);
877DepthPeeling::ViewerResources::ViewerResources()
878: width_(0), height_(0), singleBlendTex_(0), singleFbo_(0), dualBlendTex_(0), dualFbo_(0)
880 memset(singleDepthTex_, 0,
sizeof(singleDepthTex_));
881 memset(singleFrontTex_, 0,
sizeof(singleFrontTex_));
883 memset(dualDepthTex_, 0,
sizeof(dualDepthTex_));
884 memset(dualFrontTex_, 0,
sizeof(dualFrontTex_));
885 memset(dualBackTex_, 0,
sizeof(dualBackTex_));
889DepthPeeling::ViewerResources::~ViewerResources()
896void DepthPeeling::ViewerResources::resize(
bool _dualPeeling,
unsigned int _width,
unsigned int _height)
898 if (!_width || !_height)
918 wrapmode = GL_CLAMP_TO_EDGE;
922 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT0, width_, height_, GL_R32F, GL_RGB, wrapmode, GL_NEAREST, GL_NEAREST);
923 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT1, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
925 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT2, width_, height_, GL_R32F, GL_RGB, wrapmode, GL_NEAREST, GL_NEAREST);
926 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT3, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
928 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT4, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
930 singleFbo_->attachTexture2DDepth(width_, height_);
932 singleDepthTex_[0] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT0);
933 singleDepthTex_[1] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT2);
935 singleFrontTex_[0] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT1);
936 singleFrontTex_[1] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT3);
938 singleBlendTex_ = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT4);
941 singleFbo_->checkFramebufferStatus();
946 singleFbo_->resize(_width, _height);
967 wrapmode = GL_CLAMP_TO_EDGE;
971 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT0, width_, height_, GL_RG32F, GL_RGB, wrapmode, GL_NEAREST, GL_NEAREST);
972 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT1, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
973 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT2, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
975 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT3, width_, height_, GL_RG32F, GL_RGB, wrapmode, GL_NEAREST, GL_NEAREST);
976 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT4, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
977 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT5, width_, height_, GL_RGBA, GL_RGBA, wrapmode, GL_NEAREST, GL_NEAREST);
979 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT6, width_, height_, GL_RGB, GL_RGB, wrapmode, GL_NEAREST, GL_NEAREST);
981 dualDepthTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT0);
982 dualDepthTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT3);
984 dualFrontTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT1);
985 dualFrontTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT4);
987 dualBackTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT2);
988 dualBackTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT5);
990 dualBlendTex_ = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT6);
993 dualFbo_->checkFramebufferStatus();
998 dualFbo_->resize(_width, _height);
1003 glBindFramebuffer(GL_FRAMEBUFFER, 0);
1015 ShaderProgGenerator::registerModifier(&PeelInitModifier::instance);
1016 ShaderProgGenerator::registerModifier(&PeelLayerModifier::instance);
1052 ShaderProgGenerator::registerModifier(&PeelDualInitModifier::instance);
1053 ShaderProgGenerator::registerModifier(&PeelDualLayerModifier::instance);
1061 if (!peelFinalDual_)
1062 peelFinalDual_ =
GLSL::loadProgram(
"DepthPeeling/screenquad_330.glsl",
"DepthPeeling/final_dual_330.glsl");
1069 if (!peelFinalDual_)
1070 peelFinalDual_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/final_dual.glsl");
1086 &PeelInitModifier::instance, &PeelLayerModifier::instance,
1087 &PeelDualInitModifier::instance, &PeelDualLayerModifier::instance
1093 infoString +=
"PeelInit:\n\n\n";
1095 std::vector<ACG::ShaderModifier*> mods;
1096 mods.push_back(availableMods[
peelMode_*2]);
1101 infoString +=
"\n\n-----------------------------------------------\n\n\n\n";
1102 infoString +=
"PeelLayer:\n\n\n";
1104 mods[0] = availableMods[
peelMode_*2 + 1];
GLuint getFboID()
return opengl id
int viewport_width() const
get viewport width
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
const Vec4f & clear_color() const
get background color
int viewport_height() const
get viewport height
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
std::vector< ACG::RenderObject * > sortedObjects_
sorted list of renderobjects without overlay objects (sorted in rendering order)
virtual void copyDepthToBackBuffer(GLuint _depthTex, float _scale=1.0f)
Copy texture to depth buffer.
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects)
virtual void renderObject(ACG::RenderObject *_obj, GLSL::Program *_prog=0, bool _constRenderStates=false, const std::vector< unsigned int > *_shaderModifiers=0)
Render one renderobject.
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
virtual void prepareRenderingPipeline(ACG::GLState *_glState, ACG::SceneGraph::DrawModes::DrawMode _drawMode, ACG::SceneGraph::BaseNode *_scenegraphRoot)
Prepares renderer and OpenGL for any draw-related calls including.
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
int numLights_
Number of Lights.
virtual QString dumpCurrentRenderObjectsToString(ACG::RenderObject **_list=0, bool _outputShaders=false, std::vector< ACG::ShaderModifier * > *_modifiers=0)
Outputs the current render objects to the string.
virtual void restoreInputFbo()
Restore the previously saved input Fbo configuration (fbo id + viewport)
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
void addOutput(const QString &_output)
Add one GLSL output specifier.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
static void setShaderDir(QString _dir)
GLSL::Program * peelBlend_
blends one depth-layer into the current scene target
int peelMode_
mode: 0 -> front to back peeling, 1 -> dual peeling
int maxPeelCount_
max peel count
std::map< int, ViewerResources > viewerRes_
void initDepthPeeling()
Allocate framebuffers and load shaders for depth-peeling.
GLSL::Program * peelFinal_
final copy into back-buffer
void renderFrontPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene from front to back, one layer per pass
GLuint peelQueryID_
occlusion query determining end of peeling (last layer)
void addRenderObject(ACG::RenderObject *_renderObject)
overide addRenderObject function to include OIT check
void initDualDepthPeeling()
Allocate framebuffers and load shaders for dual-depth-peeling.
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
GLSL::Program * peelBlendDual_
dual depth peeling shaders
void renderDualPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene with dual depth peeling, two layers per pass
int getFragDataLocation(const char *_name)
Get location of the fragment data output.
void disable()
Resets to standard rendering pipeline.
void link()
Links the shader objects to the program.
void use()
Enables the program object for using.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
void bindFragDataLocation(unsigned int _index, const char *_name)
Bind fragment output data to name.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
ACG::Vec4f backgroundColor()
Get current background color.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
Namespace providing different geometric functions concerning angles.
bool openGLVersion(const int _major, const int _minor, bool _verbose)
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
unsigned int internalFlags_
may be used internally by the renderer
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
Collection of framebuffers for each viewport.
unsigned int height_
viewer window height
unsigned int width_
viewer window width