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;
288 int lastPeeledObject = -1;
290 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
293 lastPeeledObject = i;
296 if (lastPeeledObject == -1)
299 for (
int i = 0; i < numRenderObjects; ++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)
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);
423 glActiveTexture(GL_TEXTURE4);
424 glBindTexture(GL_TEXTURE_2D, viewRes->singleDepthTex_[prevID]);
427 for (
int k = 0; k < numRenderObjects; ++k)
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);
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);
507 glActiveTexture(GL_TEXTURE0);
508 glBindTexture(GL_TEXTURE_2D, viewRes->singleBlendTex_);
518 glEnable(GL_DEPTH_TEST);
535 int lastPeeledObject = -1;
537 for (
int i = numRenderObjects - 1; i > lastPeeledObject; --i)
540 lastPeeledObject = i;
546 for (
int i = 0; i < numRenderObjects; ++i)
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)
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)
721 glDrawBuffer(colorBlendTarget);
723 glBlendEquationEXT(GL_FUNC_ADD);
727 glActiveTexture(GL_TEXTURE0);
728 glBindTexture(GL_TEXTURE_2D, viewRes->dualBackTex_[currID]);
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]);
826 std::cout <<
"error: missing vertex declaration" << std::endl;
845 if (p->alpha < 1.0f &&
847 p->depthWrite && (p->
depthFunc == GL_LESS ||
853 ShaderCache::getInstance()->getProgram(&p->
shaderDesc);
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);
988 ShaderProgGenerator::registerModifier(&PeelInitModifier::instance);
989 ShaderProgGenerator::registerModifier(&PeelLayerModifier::instance);
1012 ShaderProgGenerator::registerModifier(&PeelDualInitModifier::instance);
1013 ShaderProgGenerator::registerModifier(&PeelDualLayerModifier::instance);
1019 if (!peelFinalDual_)
1020 peelFinalDual_ =
GLSL::loadProgram(
"DepthPeeling/screenquad.glsl",
"DepthPeeling/final_dual.glsl");
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]);
1050 infoString +=
"\n\n-----------------------------------------------\n\n\n\n";
1051 infoString +=
"PeelLayer:\n\n\n";
1053 mods[0] = availableMods[peelMode_*2 + 1];
1091 #if QT_VERSION < 0x050000
1092 Q_EXPORT_PLUGIN2( depthpeelingshaderrenderer ,
DepthPeeling );
void addRenderObject(ACG::RenderObject *_renderObject)
overide addRenderObject function to include OIT check
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
static void blendFuncSeparate(GLenum _srcRGB, GLenum _dstRGB, GLenum _srcAlpha, GLenum _dstAlpha)
replaces glBlendFuncSeparate, supports locking
int viewport_width() const
get viewport width
int maxPeelCount_
max peel count
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
unsigned int width_
viewer window width
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
int peelMode_
mode: 0 -> front to back peeling, 1 -> dual peeling
unsigned int height_
viewer window height
int numLights_
Number of Lights.
void link()
Links the shader objects to the program.
void renderDualPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene with dual depth peeling, two layers per pass
Namespace providing different geometric functions concerning angles.
std::vector< ACG::RenderObject * > sortedObjects_
sorted list of renderobjects without overlay objects (sorted in rendering order)
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
virtual QString dumpCurrentRenderObjectsToString(ACG::RenderObject **_list=0, bool _outputShaders=false, std::vector< ACG::ShaderModifier * > *_modifiers=0)
Outputs the current render objects to the string.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
const Vec4f & clear_color() const
get background color
void initDepthPeeling()
Allocate framebuffers and load shaders for depth-peeling.
void bindFragDataLocation(unsigned int _index, const char *_name)
Bind fragment output data to name.
static void setShaderDir(QString _dir)
void addOutput(const QString &_output)
Add one GLSL output specifier.
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
bool openGLVersion(const int _major, const int _minor)
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
GLuint peelQueryID_
occlusion query determining end of peeling (last layer)
virtual void renderObject(ACG::RenderObject *_obj, GLSL::Program *_prog=0, bool _constRenderStates=false, const std::vector< unsigned int > *_shaderModifiers=0)
Render one renderobject.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
GLSL::Program * peelBlendDual_
dual depth peeling shaders
void initDualDepthPeeling()
Allocate framebuffers and load shaders for dual-depth-peeling.
Collection of framebuffers for each viewport.
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
int viewport_height() const
get viewport height
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void renderFrontPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene from front to back, one layer per pass
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects) ...
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
unsigned int internalFlags_
may be used internally by the renderer
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.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
bool checkExtensionSupported(const std::string &_extension)
Interface class between scenegraph and renderer.
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
int getFragDataLocation(const char *_name)
Get location of the fragment data output.
void use()
Enables the program object for using.
GLSL::Program * peelBlend_
blends one depth-layer into the current scene target
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
virtual void copyDepthToBackBuffer(GLuint _depthTex, float _scale=1.0f)
Copy texture to depth buffer.
virtual void restoreInputFbo()
Restore the previously saved input Fbo configuration (fbo id + viewport)
GLuint getFboID()
return opengl id
std::map< int, ViewerResources > viewerRes_
GLSL::Program * peelFinal_
final copy into back-buffer
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
GLSL::PtrProgram loadProgram(const char *vertexShaderFile, const char *tessControlShaderFile, const char *tessEvaluationShaderFile, const char *geometryShaderFile, const char *fragmentShaderFile, const GLSL::StringList *macros, bool verbose)
void disable()
Resets to standard rendering pipeline.
ACG::Vec4f backgroundColor()
Get current background color.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.