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 modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
GLSL::Program * peelBlend_
blends one depth-layer into the current scene target
void modifyFragmentBeginCode(QStringList *_code)
Append code the the fragment shader.
void initDualDepthPeeling()
Allocate framebuffers and load shaders for dual-depth-peeling.
void addUniform(QString _uniform, QString _comment="")
Add one GLSL uniform specifier.
Namespace providing different geometric functions concerning angles.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
int maxPeelCount_
max peel count
GLuint peelQueryID_
occlusion query determining end of peeling (last layer)
int getFragDataLocation(const char *_name)
Get location of the fragment data output.
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.
const Vec4f & clear_color() const
get background color
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
Interface class between scenegraph and renderer.
void bindFragDataLocation(unsigned int _index, const char *_name)
Bind fragment output data to name.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
std::vector< ACG::RenderObject * > sortedObjects_
sorted list of renderobjects without overlay objects (sorted in rendering order)
static void draw(GLSL::Program *_prog=0)
Draw the screen quad.
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 modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
unsigned int internalFlags_
may be used internally by the renderer
GLenum depthFunc
GL_LESS, GL_LEQUAL, GL_GREATER ..
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
bool openGLVersion(const int _major, const int _minor)
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void addOutput(const QString &_output)
Add one GLSL output specifier.
bool checkExtensionSupported(const std::string &_extension)
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 use()
Enables the program object for using.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
Collection of framebuffers for each viewport.
int viewport_width() const
get viewport width
static void blendFunc(GLenum _sfactor, GLenum _dfactor)
replaces glBlendFunc, supports locking
GLuint getFboID()
return opengl id
int viewerId()
Get the id of the viewer this viewerproperties belongs to.
QString renderObjectsInfo(bool _outputShaderInfo)
Return a qstring of the current render objects.
void modifyFragmentIO(ShaderGenerator *_shader)
Add your own inputs/outputs to the fragment shader.
int peelMode_
mode: 0 -> front to back peeling, 1 -> dual peeling
int numLights_
Number of Lights.
void link()
Links the shader objects to the program.
std::vector< ACG::RenderObject > renderObjects_
array of renderobjects, filled by addRenderObject()
virtual void copyDepthToBackBuffer(GLuint _depthTex, float _scale=1.0f)
Copy texture to depth buffer.
void renderDualPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene with dual depth peeling, two layers per pass
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
GLSL::Program * peelFinal_
final copy into back-buffer
static void setShaderDir(QString _dir)
void modifyFragmentEndCode(QStringList *_code)
Append code the the fragment shader.
void renderFrontPeeling(ACG::GLState *_glState, Viewer::ViewerProperties &_properties)
peel the scene from front to back, one layer per pass
virtual void finishRenderingPipeline(bool _drawOverlay=true)
Draw overlay objects and reset OpenGL state.
virtual void restoreInputFbo()
Restore the previously saved input Fbo configuration (fbo id + viewport)
void initDepthPeeling()
Allocate framebuffers and load shaders for depth-peeling.
void addRenderObject(ACG::RenderObject *_renderObject)
overide addRenderObject function to include OIT check
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.
GLSL::Program * peelBlendDual_
dual depth peeling shaders
void disable()
Resets to standard rendering pipeline.
unsigned int height_
viewer window height
int viewport_height() const
get viewport height
std::map< int, ViewerResources > viewerRes_
ACG::Vec4f backgroundColor()
Get current background color.
unsigned int width_
viewer window width
int getNumRenderObjects() const
Get the number of collected render objects (not including overlay objects or gl4.2 line objects) ...