51 #include <ACG/GL/acg_glew.hh> 53 #include "DepthPeeling.hh" 59 #include <ACG/GL/ShaderCache.hh> 60 #include <ACG/GL/GLError.hh> 61 #include <ACG/GL/ScreenQuad.hh> 84 _code->push_back(
"float dp_prevDepth = texture(g_DepthLayer, sg_vScreenPos).x;");
85 _code->push_back(
"if (gl_FragCoord.z <= dp_prevDepth) discard;");
90 _code->push_back(
"outFragment = vec4(sg_cColor.rgb * sg_cColor.a, sg_cColor.a);");
91 _code->push_back(
"outDepth = gl_FragCoord.z;");
109 _code->push_back(
"outFragment = vec4(sg_cColor.rgb * sg_cColor.a, 1.0 - sg_cColor.a);");
110 _code->push_back(
"outDepth = gl_FragCoord.z;");
123 _shader->
addUniform(
"sampler2D g_DepthLayer");
124 _shader->
addUniform(
"sampler2D g_FrontLayer");
133 _code->push_back(
"float fragDepth = gl_FragCoord.z;");
135 _code->push_back(
"vec2 depthLayer = texture2D(g_DepthLayer, sg_vScreenPos).xy;");
136 _code->push_back(
"vec4 forwardTemp = texture2D(g_FrontLayer, sg_vScreenPos);");
138 _code->push_back(
"outDepth = vec4(depthLayer, 0, 0);");
139 _code->push_back(
"outFragment = forwardTemp;");
140 _code->push_back(
"outBackColor = vec4(0,0,0,0);");
143 _code->push_back(
"float nearestDepth = -depthLayer.x;");
144 _code->push_back(
"float farthestDepth = depthLayer.y;");
145 _code->push_back(
"float alphaMultiplier = 1.0 - forwardTemp.w;");
148 _code->push_back(
"if (fragDepth < nearestDepth || fragDepth > farthestDepth) {");
149 _code->push_back(
"outDepth = vec4(-1,-1,-1,-1);");
150 _code->push_back(
"return;");
151 _code->push_back(
"}");
153 _code->push_back(
"if (fragDepth > nearestDepth && fragDepth < farthestDepth) {");
154 _code->push_back(
"outDepth = vec4(-fragDepth, fragDepth, 0, 0);");
155 _code->push_back(
"return;");
156 _code->push_back(
"}");
162 _code->push_back(
"outDepth = vec4(-1,-1,-1,-1);");
163 _code->push_back(
"outFragment = forwardTemp;");
165 _code->push_back(
"if (fragDepth == nearestDepth) {");
166 _code->push_back(
"outFragment.xyz += sg_cColor.rgb * sg_cColor.a * alphaMultiplier;");
167 _code->push_back(
"outFragment.w = 1.0 - alphaMultiplier * (1.0 - sg_cColor.a);");
171 _code->push_back(
"} else {");
172 _code->push_back(
"outBackColor += sg_cColor;");
173 _code->push_back(
"}");
184 _code->push_back(
"outFragment = vec4(-gl_FragCoord.z, gl_FragCoord.z, 0, 0);");
198 #define RENDERFLAG_ALLOW_PEELING 1 203 DepthPeeling::DepthPeeling()
204 : peelMode_(1), copyFrontDepth_(1), maxPeelCount_(20), peelBlend_(0), peelFinal_(0), peelQueryID_(0),
205 peelBlendDual_(0), peelFinalDual_(0)
210 DepthPeeling::~DepthPeeling()
216 QString DepthPeeling::checkOpenGL()
219 return QString(
"Insufficient OpenGL Version! OpenGL 3.2 or higher required");
224 missing +=
"GL_ARB_vertex_buffer_object extension missing\n";
228 missing +=
"GL_ARB_vertex_program extension missing\n";
232 missing +=
"GL_ARB_occlusion_query extension missing\n";
238 void DepthPeeling::initializePlugin()
243 void DepthPeeling::slotModeChanged( QAction * _action)
246 if ( _action->text() ==
"Front to Back") {
248 }
else if ( _action->text() ==
"Dual") {
251 std::cerr <<
"Error : optionHandling unable to find peeling mode!!! " << _action->text().toStdString() << std::endl;
268 renderFrontPeeling(_glState, _properties);
270 renderDualPeeling(_glState, _properties);
274 finishRenderingPipeline();
284 const int numRenderObjects = getNumRenderObjects();
288 int lastPeeledObject = -1;
290 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
292 if ((sortedObjects_[i]->internalFlags_ & RENDERFLAG_ALLOW_PEELING) && sortedObjects_[i]->alpha < 0.99f)
293 lastPeeledObject = i;
296 if (lastPeeledObject == -1)
299 for (
int i = 0; i < numRenderObjects; ++i)
300 renderObject(sortedObjects_[i]);
317 const GLenum depthTarget = GL_COLOR_ATTACHMENT0;
318 const GLenum colorTarget = GL_COLOR_ATTACHMENT1;
319 const GLenum colorBlendTarget = GL_COLOR_ATTACHMENT4;
320 GLenum peelLayerTargets[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
322 const float clearDepth = 1.0f;
328 glBindFramebuffer(GL_FRAMEBUFFER, viewRes->singleFbo_->
getFboID());
332 glColorMask(1,1,1,1);
335 glDrawBuffer(colorBlendTarget);
337 glClear(GL_COLOR_BUFFER_BIT);
340 glDrawBuffer(colorTarget);
341 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
342 glClear(GL_COLOR_BUFFER_BIT);
345 glDrawBuffer(depthTarget);
346 glClearColor(clearDepth, 0.0f, 0.0f, 0.0f);
347 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
352 peelLayerTargets[0] = colorBlendTarget;
353 peelLayerTargets[1] = depthTarget;
354 glDrawBuffers(2, peelLayerTargets);
357 glDisable(GL_ALPHA_TEST);
359 glEnable(GL_DEPTH_TEST);
360 glDepthFunc(GL_LESS);
361 glDisable(GL_CULL_FACE);
363 for (
int i = 0; i < numRenderObjects; ++i)
376 renderObject(sortedObjects_[i], initProg,
true);
382 copyDepthToBackBuffer(viewRes->singleDepthTex_[0], 1.0f);
388 for (
int pass = 1; pass < maxPeelCount_; ++pass)
390 const int currID = pass & 1;
391 const int prevID = 1 - currID;
392 const int bufID = currID * 2;
397 const GLenum targetBuffer[2] = {colorTarget + bufID, depthTarget + bufID};
403 glDrawBuffer(targetBuffer[0]);
404 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
405 glClear(GL_COLOR_BUFFER_BIT);
407 glDrawBuffer(targetBuffer[1]);
408 glClearColor(clearDepth, 0.0f, 0.0f, 0.0f);
409 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
412 glDrawBuffers(2, targetBuffer);
416 glEnable(GL_DEPTH_TEST);
419 glBeginQuery(GL_SAMPLES_PASSED, peelQueryID_);
423 glActiveTexture(GL_TEXTURE4);
424 glBindTexture(GL_TEXTURE_2D, viewRes->singleDepthTex_[prevID]);
427 for (
int k = 0; k < numRenderObjects; ++k)
429 if ((sortedObjects_[k]->internalFlags_ & RENDERFLAG_ALLOW_PEELING) && sortedObjects_[k]->alpha < 0.99f)
443 renderObject(sortedObjects_[k], peelProg,
true);
447 glEndQuery(GL_SAMPLES_PASSED);
454 glDrawBuffer(colorBlendTarget);
457 glColorMask(1,1,1,1);
459 glDisable(GL_DEPTH_TEST);
462 glBlendEquation(GL_FUNC_ADD);
464 GL_ZERO, GL_ONE_MINUS_SRC_ALPHA);
468 peelBlend_->setUniform(
"BlendTex", 0);
470 glActiveTexture(GL_TEXTURE0);
471 glBindTexture(GL_TEXTURE_2D, viewRes->singleFrontTex_[currID]);
480 GLuint passedSamples;
481 glGetQueryObjectuiv(peelQueryID_, GL_QUERY_RESULT, &passedSamples);
482 if (passedSamples == 0)
491 glColorMask(1,1,1,1);
493 glDisable(GL_DEPTH_TEST);
503 peelFinal_->setUniform(
"BkgColor", bkgColor);
505 peelFinal_->setUniform(
"SceneTex", 0);
507 glActiveTexture(GL_TEXTURE0);
508 glBindTexture(GL_TEXTURE_2D, viewRes->singleBlendTex_);
518 glEnable(GL_DEPTH_TEST);
531 const int numRenderObjects = getNumRenderObjects();
535 int lastPeeledObject = -1;
537 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
539 if ((sortedObjects_[i]->internalFlags_ & RENDERFLAG_ALLOW_PEELING) && sortedObjects_[i]->alpha < 0.99f)
540 lastPeeledObject = i;
546 for (
int i = 0; i < numRenderObjects; ++i)
547 renderObject(sortedObjects_[i]);
554 initDualDepthPeeling();
563 glColorMask(1,1,1,1);
569 glBindFramebuffer(GL_FRAMEBUFFER, viewRes->dualFbo_->
getFboID());
571 const GLenum depthTarget = GL_COLOR_ATTACHMENT0;
572 const GLenum colorTargets[] = {GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
573 const GLenum colorBlendTarget = GL_COLOR_ATTACHMENT6;
576 glDrawBuffers(2, colorTargets);
577 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
578 glClear(GL_COLOR_BUFFER_BIT);
581 glDrawBuffer(colorBlendTarget);
583 glClear(GL_COLOR_BUFFER_BIT);
586 glDrawBuffer(depthTarget);
587 glClearColor(-1.0f, -1.0f, 0.0f, 0.0f);
588 glClear(GL_COLOR_BUFFER_BIT);
594 glBlendEquation(GL_MAX_EXT);
596 glDisable(GL_ALPHA_TEST);
598 glEnable(GL_DEPTH_TEST);
599 glDepthFunc(GL_LESS);
600 glDisable(GL_CULL_FACE);
602 for (
int i = 0; i < numRenderObjects; ++i)
606 renderObject(sortedObjects_[i], initProg,
true);
614 copyDepthToBackBuffer(viewRes->dualDepthTex_[0], -1.0f);
625 for (
int pass = 1; 1 && pass < maxPeelCount_; ++pass)
628 const int prevID = 1 - currID;
629 const int bufID = currID * 3;
631 GLenum targetBuffer[3];
632 targetBuffer[0] = GL_COLOR_ATTACHMENT0 + bufID;
633 targetBuffer[1] = GL_COLOR_ATTACHMENT1 + bufID;
634 targetBuffer[2] = GL_COLOR_ATTACHMENT2 + bufID;
638 glDrawBuffers(2, targetBuffer + 1);
639 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
640 glClear(GL_COLOR_BUFFER_BIT);
643 glDrawBuffer(targetBuffer[0]);
644 glClearColor(-1.0f, -1.0f, 0.0f, 0.0f);
645 glClear(GL_COLOR_BUFFER_BIT);
652 glBlendEquation(GL_MAX_EXT);
653 glDrawBuffers(3, targetBuffer);
659 glActiveTexture(GL_TEXTURE5);
660 glBindTexture(GL_TEXTURE_2D, viewRes->dualFrontTex_[prevID]);
662 glActiveTexture(GL_TEXTURE4);
663 glBindTexture(GL_TEXTURE_2D, viewRes->dualDepthTex_[prevID]);
666 glActiveTexture(GL_TEXTURE0);
669 for (
int i = 0; i < numRenderObjects; ++i)
686 if (locOutFrag != 1 ||
688 locOutBackColor != 2)
700 renderObject(sortedObjects_[i], peelProg,
true);
721 glDrawBuffer(colorBlendTarget);
723 glBlendEquationEXT(GL_FUNC_ADD);
727 glActiveTexture(GL_TEXTURE0);
728 glBindTexture(GL_TEXTURE_2D, viewRes->dualBackTex_[currID]);
731 glBeginQuery(GL_SAMPLES_PASSED_ARB, peelQueryID_);
733 peelBlendDual_->use();
734 peelBlendDual_->setUniform(
"BlendTex", 0);
738 glEndQuery(GL_SAMPLES_PASSED_ARB);
743 GLuint passedSamples;
744 glGetQueryObjectuiv(peelQueryID_, GL_QUERY_RESULT, &passedSamples);
745 if (passedSamples == 0)
755 glColorMask(1,1,1,1);
757 glDisable(GL_DEPTH_TEST);
761 peelFinalDual_->use();
769 peelFinalDual_->setUniform(
"BkgColor", bkgColor);
774 peelFinalDual_->setUniform(
"FrontSceneTex", 0);
775 peelFinalDual_->setUniform(
"BackSceneTex", 1);
777 glActiveTexture(GL_TEXTURE1);
778 glBindTexture(GL_TEXTURE_2D, viewRes->dualBlendTex_);
780 glActiveTexture(GL_TEXTURE0);
781 glBindTexture(GL_TEXTURE_2D, viewRes->dualFrontTex_[currID]);
787 peelFinalDual_->disable();
826 std::cout <<
"error: missing vertex declaration" << std::endl;
829 renderObjects_.push_back(*_renderObject);
845 if (p->alpha < 1.0f &&
847 p->depthWrite && (p->
depthFunc == GL_LESS ||
861 DepthPeeling::ViewerResources::ViewerResources()
862 : width_(0), height_(0), singleBlendTex_(0), singleFbo_(0), dualBlendTex_(0), dualFbo_(0)
864 memset(singleDepthTex_, 0,
sizeof(singleDepthTex_));
865 memset(singleFrontTex_, 0,
sizeof(singleFrontTex_));
867 memset(dualDepthTex_, 0,
sizeof(dualDepthTex_));
868 memset(dualFrontTex_, 0,
sizeof(dualFrontTex_));
869 memset(dualBackTex_, 0,
sizeof(dualBackTex_));
873 DepthPeeling::ViewerResources::~ViewerResources()
880 void DepthPeeling::ViewerResources::resize(
bool _dualPeeling,
unsigned int _width,
unsigned int _height)
882 if (!_width || !_height)
901 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT0, width_, height_, GL_R32F, GL_RGB, GL_CLAMP, GL_NEAREST, GL_NEAREST);
902 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT1, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
904 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT2, width_, height_, GL_R32F, GL_RGB, GL_CLAMP, GL_NEAREST, GL_NEAREST);
905 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT3, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
907 singleFbo_->attachTexture2D(GL_COLOR_ATTACHMENT4, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
909 singleFbo_->attachTexture2DDepth(width_, height_);
911 singleDepthTex_[0] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT0);
912 singleDepthTex_[1] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT2);
914 singleFrontTex_[0] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT1);
915 singleFrontTex_[1] = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT3);
917 singleBlendTex_ = singleFbo_->getAttachment(GL_COLOR_ATTACHMENT4);
920 singleFbo_->checkFramebufferStatus();
925 singleFbo_->resize(_width, _height);
944 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT0, width_, height_, GL_RG32F, GL_RGB, GL_CLAMP, GL_NEAREST, GL_NEAREST);
945 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT1, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
946 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT2, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
948 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT3, width_, height_, GL_RG32F, GL_RGB, GL_CLAMP, GL_NEAREST, GL_NEAREST);
949 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT4, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
950 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT5, width_, height_, GL_RGBA, GL_RGBA, GL_CLAMP, GL_NEAREST, GL_NEAREST);
952 dualFbo_->attachTexture2D(GL_COLOR_ATTACHMENT6, width_, height_, GL_RGB, GL_RGB, GL_CLAMP, GL_NEAREST, GL_NEAREST);
954 dualDepthTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT0);
955 dualDepthTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT3);
957 dualFrontTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT1);
958 dualFrontTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT4);
960 dualBackTex_[0] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT2);
961 dualBackTex_[1] = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT5);
963 dualBlendTex_ = dualFbo_->getAttachment(GL_COLOR_ATTACHMENT6);
966 dualFbo_->checkFramebufferStatus();
971 dualFbo_->resize(_width, _height);
976 glBindFramebuffer(GL_FRAMEBUFFER, 0);
984 if (peelBlend_ && peelFinal_ && peelQueryID_)
993 peelBlend_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/blend.glsl");
996 peelFinal_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/final.glsl");
1000 glGenQueries(1, &peelQueryID_);
1008 if (peelBlendDual_ && peelFinalDual_ && peelQueryID_)
1016 if (!peelBlendDual_)
1017 peelBlendDual_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/blend_dual.glsl");
1019 if (!peelFinalDual_)
1020 peelFinalDual_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/final_dual.glsl");
1024 glGenQueries(1, &peelQueryID_);
1035 &PeelInitModifier::instance, &PeelLayerModifier::instance,
1036 &PeelDualInitModifier::instance, &PeelDualLayerModifier::instance
1042 infoString +=
"PeelInit:\n\n\n";
1044 std::vector<ACG::ShaderModifier*> mods;
1045 mods.push_back(availableMods[peelMode_*2]);
1047 infoString += dumpCurrentRenderObjectsToString(&sortedObjects_[0],_outputShaderInfo, &mods);
1050 infoString +=
"\n\n-----------------------------------------------\n\n\n\n";
1051 infoString +=
"PeelLayer:\n\n\n";
1053 mods[0] = availableMods[peelMode_*2 + 1];
1055 infoString += dumpCurrentRenderObjectsToString(&sortedObjects_[0],_outputShaderInfo, &mods);
1091 #if QT_VERSION < 0x050000 1092 Q_EXPORT_PLUGIN2( depthpeelingshaderrenderer ,
DepthPeeling );
static void setShaderDir(QString _dir)
void addRenderObject(ACG::RenderObject *_renderObject)
overide addRenderObject function to include OIT check
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void bindFragDataLocation(unsigned int _index, const char *_name)
Bind fragment output data to name.
const Vec4f & clear_color() const
get background color
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
GLuint getFboID()
return opengl id
void renderDualPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene with dual depth peeling, two layers per pass
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
void link()
Links the shader objects to the program.
void initDepthPeeling()
Allocate framebuffers and load shaders for depth-peeling.
unsigned int internalFlags_
may be used internally by the renderer
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
int viewport_width() const
get viewport width
void use()
Enables the program object for using.
void initDualDepthPeeling()
Allocate framebuffers and load shaders for dual-depth-peeling.
bool openGLVersion(const int _major, const int _minor)
int getFragDataLocation(const char *_name)
Get location of the fragment data output.
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
Collection of framebuffers for each viewport.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
void renderFrontPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene from front to back, one layer per pass
Namespace providing different geometric functions concerning angles.
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
bool checkExtensionSupported(const std::string &_extension)
int viewport_height() const
get viewport height
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
Interface class between scenegraph and renderer.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
static unsigned int registerModifier(ShaderModifier *_modifier)
Shader modifiers have to be registered before they can be used. They also must remain allocated for t...
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
unsigned int width_
viewer window width
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
ACG::Vec4f backgroundColor()
Get current background color.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
unsigned int height_
viewer window height
void addOutput(const QString &_output)
Add one GLSL output specifier.
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking