/*========================================================================= Program: ParaView Module: vtkEDLShading.cxx Copyright (c) Sandia Corporation, Kitware Inc. All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ /*---------------------------------------------------------------------- Acknowledgement: This algorithm is the result of joint work by Electricité de France, CNRS, Collège de France and Université J. Fourier as part of the Ph.D. thesis of Christian BOUCHENY. ------------------------------------------------------------------------*/ #include "vtkEDLShading.h" #include "vtkCamera.h" #include "vtkMath.h" #include "vtkObjectFactory.h" #include "vtkOpenGLError.h" #include "vtkOpenGLFramebufferObject.h" #include "vtkOpenGLRenderUtilities.h" #include "vtkOpenGLRenderWindow.h" #include "vtkOpenGLShaderCache.h" #include "vtkOpenGLState.h" #include "vtkPropCollection.h" #include "vtkRenderState.h" #include "vtkRenderer.h" #include "vtkShaderProgram.h" #include "vtkTextureObject.h" #include "vtk_glew.h" #include #include #include #include "vtkEDLBilateralFilterFS.h" #include "vtkEDLComposeFS.h" #include "vtkEDLShadeFS.h" #include "vtkTextureObjectVS.h" //#define VTK_EDL_SHADING_DEBUG namespace { void annotate(const std::string& str) { vtkOpenGLRenderUtilities::MarkDebugEvent(str); } } vtkStandardNewMacro(vtkEDLShading); //------------------------------------------------------------------------------ vtkEDLShading::vtkEDLShading() { this->ProjectionFBO = nullptr; this->ProjectionColorTexture = nullptr; this->ProjectionDepthTexture = nullptr; this->EDLHighFBO = nullptr; this->EDLHighShadeTexture = nullptr; this->EDLLowFBO = nullptr; this->EDLLowShadeTexture = nullptr; this->EDLLowBlurTexture = nullptr; this->EDLIsFiltered = true; // init neighbours in image space for (int c = 0; c < 8; c++) { float x, y; x = cos(2 * vtkMath::Pi() * float(c) / 8.); y = sin(2 * vtkMath::Pi() * float(c) / 8.); this->EDLNeighbours[c][0] = x / sqrt(x * x + y * y); this->EDLNeighbours[c][1] = y / sqrt(x * x + y * y); this->EDLNeighbours[c][2] = 0.; this->EDLNeighbours[c][3] = 0.; } this->EDLLowResFactor = 2; this->Zn = 0.1; this->Zf = 1.0; } //------------------------------------------------------------------------------ vtkEDLShading::~vtkEDLShading() { if (this->ProjectionFBO != nullptr) { vtkErrorMacro(<< "FrameBufferObject should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->ProjectionColorTexture != nullptr) { vtkErrorMacro(<< "ColorTexture should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->ProjectionDepthTexture != nullptr) { vtkErrorMacro(<< "DepthTexture should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->EDLHighFBO != nullptr) { vtkErrorMacro(<< "FrameBufferObject should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->EDLHighShadeTexture != nullptr) { vtkErrorMacro(<< "ColorTexture should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->EDLLowFBO != nullptr) { vtkErrorMacro(<< "FrameBufferObject should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->EDLLowShadeTexture != nullptr) { vtkErrorMacro(<< "ColorTexture should have been deleted in " << "ReleaseGraphicsResources()."); } if (this->EDLLowBlurTexture != nullptr) { vtkErrorMacro(<< "ColorTexture should have been deleted in " << "ReleaseGraphicsResources()."); } } //------------------------------------------------------------------------------ void vtkEDLShading::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "DelegatePass:"; if (this->DelegatePass != nullptr) { this->DelegatePass->PrintSelf(os, indent); } else { os << "(none)" << endl; } } //------------------------------------------------------------------------------ // Description: // Initialize framebuffers and associated texture objects, // with link to render state s void vtkEDLShading::EDLInitializeFramebuffers(vtkRenderState& s) { vtkRenderer* r = s.GetRenderer(); vtkOpenGLCheckErrorMacro("failed before Initialize"); vtkOpenGLRenderWindow* renWin = vtkOpenGLRenderWindow::SafeDownCast(r->GetRenderWindow()); // PROJECTION FBO and TEXTURES // if (this->ProjectionFBO == nullptr) { this->ProjectionFBO = vtkOpenGLFramebufferObject::New(); this->ProjectionFBO->SetContext(renWin); } s.SetFrameBuffer(this->ProjectionFBO); renWin->GetState()->PushFramebufferBindings(); this->ProjectionFBO->Bind(); // Color texture if (this->ProjectionColorTexture == nullptr) { this->ProjectionColorTexture = vtkTextureObject::New(); this->ProjectionColorTexture->SetContext(this->ProjectionFBO->GetContext()); } if (this->ProjectionColorTexture->GetWidth() != static_cast(this->W) || this->ProjectionColorTexture->GetHeight() != static_cast(this->H)) { this->ProjectionColorTexture->Create2D(this->W, this->H, 4, VTK_FLOAT, false); } // Depth texture if (this->ProjectionDepthTexture == nullptr) { this->ProjectionDepthTexture = vtkTextureObject::New(); this->ProjectionDepthTexture->SetContext(this->ProjectionFBO->GetContext()); } if (this->ProjectionDepthTexture->GetWidth() != static_cast(this->W) || this->ProjectionDepthTexture->GetHeight() != static_cast(this->H)) { this->ProjectionDepthTexture->AllocateDepth(this->W, this->H, vtkTextureObject::Float32); } // Apply textures // to make things clear, we write all this->ProjectionFBO->AddColorAttachment(0, this->ProjectionColorTexture); this->ProjectionFBO->ActivateDrawBuffer(0); this->ProjectionFBO->AddDepthAttachment(this->ProjectionDepthTexture); this->ProjectionDepthTexture->SetWrapS(vtkTextureObject::ClampToEdge); this->ProjectionDepthTexture->SetWrapT(vtkTextureObject::ClampToEdge); this->ProjectionDepthTexture->SetMinificationFilter(vtkTextureObject::Linear); this->ProjectionDepthTexture->SetLinearMagnification(true); this->ProjectionDepthTexture->Bind(); this->ProjectionDepthTexture->SendParameters(); renWin->GetState()->PopFramebufferBindings(); // EDL-RES1 FBO and TEXTURE // if (this->EDLHighFBO == nullptr) { this->EDLHighFBO = vtkOpenGLFramebufferObject::New(); this->EDLHighFBO->SetContext(renWin); } s.SetFrameBuffer(EDLHighFBO); // Color texture if (this->EDLHighShadeTexture == nullptr) { this->EDLHighShadeTexture = vtkTextureObject::New(); this->EDLHighShadeTexture->SetContext(this->EDLHighFBO->GetContext()); } if (this->EDLHighShadeTexture->GetWidth() != static_cast(this->W) || this->EDLHighShadeTexture->GetHeight() != static_cast(this->H)) { this->EDLHighShadeTexture->Create2D(this->W, this->H, 4, VTK_FLOAT, false); } renWin->GetState()->PushFramebufferBindings(); this->EDLHighFBO->Bind(); this->EDLHighFBO->AddColorAttachment(0, this->EDLHighShadeTexture); this->EDLHighFBO->ActivateDrawBuffer(0); this->EDLHighFBO->AddDepthAttachment(); renWin->GetState()->PopFramebufferBindings(); // EDL-RES2 FBO and TEXTURE // if (this->EDLLowFBO == nullptr) { this->EDLLowFBO = vtkOpenGLFramebufferObject::New(); this->EDLLowFBO->SetContext(renWin); } s.SetFrameBuffer(EDLLowFBO); // Color texture if (this->EDLLowShadeTexture == nullptr) { this->EDLLowShadeTexture = vtkTextureObject::New(); this->EDLLowShadeTexture->SetContext(this->EDLLowFBO->GetContext()); } if (this->EDLLowShadeTexture->GetWidth() != static_cast(this->W / EDLLowResFactor) || this->EDLLowShadeTexture->GetHeight() != static_cast(this->H / EDLLowResFactor)) { this->EDLLowShadeTexture->Create2D( this->W / EDLLowResFactor, this->H / EDLLowResFactor, 4, VTK_FLOAT, false); } // Blur texture if (this->EDLLowBlurTexture == nullptr) { this->EDLLowBlurTexture = vtkTextureObject::New(); this->EDLLowBlurTexture->SetContext(this->EDLLowFBO->GetContext()); } if (this->EDLLowBlurTexture->GetWidth() != static_cast(this->W / EDLLowResFactor) || this->EDLLowBlurTexture->GetHeight() != static_cast(this->H / EDLLowResFactor)) { this->EDLLowBlurTexture->Create2D( this->W / EDLLowResFactor, this->H / EDLLowResFactor, 4, VTK_FLOAT, false); } renWin->GetState()->PushFramebufferBindings(); this->EDLLowFBO->Bind(); this->EDLLowFBO->AddColorAttachment(0, this->EDLLowShadeTexture); this->EDLLowFBO->ActivateDrawBuffer(0); this->EDLLowFBO->AddDepthAttachment(); this->EDLLowShadeTexture->SetWrapS(vtkTextureObject::ClampToEdge); this->EDLLowShadeTexture->SetWrapT(vtkTextureObject::ClampToEdge); this->EDLLowShadeTexture->SetMinificationFilter(vtkTextureObject::Linear); this->EDLLowShadeTexture->SetLinearMagnification(true); this->EDLLowShadeTexture->Bind(); this->EDLLowShadeTexture->SendParameters(); this->EDLLowBlurTexture->SetWrapS(vtkTextureObject::ClampToEdge); this->EDLLowBlurTexture->SetWrapT(vtkTextureObject::ClampToEdge); this->EDLLowBlurTexture->SetMinificationFilter(vtkTextureObject::Linear); this->EDLLowBlurTexture->SetLinearMagnification(true); this->EDLLowBlurTexture->Bind(); this->EDLLowBlurTexture->SendParameters(); renWin->GetState()->PopFramebufferBindings(); vtkOpenGLCheckErrorMacro("failed after Initialize"); } //------------------------------------------------------------------------------ // Description: // Initialize shaders // void vtkEDLShading::EDLInitializeShaders(vtkOpenGLRenderWindow* renWin) { #ifdef VTK_EDL_SHADING_DEBUG cout << "EDL: INITIALIZE SHADERS" << endl; #endif // EDL SHADE // if (this->EDLShadeProgram.Program == nullptr) { this->EDLShadeProgram.Program = renWin->GetShaderCache()->ReadyShaderProgram(vtkTextureObjectVS, vtkEDLShadeFS, ""); } // EDL COMPOSE // if (this->EDLComposeProgram.Program == nullptr) { this->EDLComposeProgram.Program = renWin->GetShaderCache()->ReadyShaderProgram(vtkTextureObjectVS, vtkEDLComposeFS, ""); } // BILATERAL FILTER // if (this->BilateralProgram.Program == nullptr) { this->BilateralProgram.Program = renWin->GetShaderCache()->ReadyShaderProgram(vtkTextureObjectVS, vtkEDLBilateralFilterFS, ""); } #ifdef VTK_EDL_SHADING_DEBUG cout << "... done" << endl; #endif } //------------------------------------------------------------------------------ // Description: // Render EDL in full resolution // bool vtkEDLShading::EDLShadeHigh(vtkRenderState& s, vtkOpenGLRenderWindow* renWin) { // VARIABLES // float d = 1.0; float F_scale = 5.0; float SX = 1. / float(this->W); float SY = 1. / float(this->H); float L[3] = { 0., 0., -1. }; // ACTIVATE SHADER // renWin->GetShaderCache()->ReadyShaderProgram(this->EDLShadeProgram.Program); // ACTIVATE FBO // s.SetFrameBuffer(this->EDLHighFBO); this->EDLHighShadeTexture->Activate(); renWin->GetState()->PushFramebufferBindings(); this->EDLHighFBO->Bind(); this->EDLHighFBO->AddColorAttachment(0, this->EDLHighShadeTexture); this->EDLHighFBO->ActivateDrawBuffer(0); this->EDLHighFBO->Start(this->W, this->H); // DEPTH TEXTURE PARAMETERS this->ProjectionDepthTexture->Activate(); vtkShaderProgram* prog = this->EDLShadeProgram.Program; // shader parameters prog->SetUniformi("s2_depth", this->ProjectionDepthTexture->GetTextureUnit()); prog->SetUniformf("d", d); prog->SetUniformf("F_scale", F_scale); prog->SetUniformf("SX", SX); prog->SetUniformf("SY", SY); prog->SetUniform3f("L", L); prog->SetUniform4fv("N", 8, this->EDLNeighbours); prog->SetUniformf("Znear", this->Zn); prog->SetUniformf("Zfar", this->Zf); // compute the scene bounding box, and set the scene size to the diagonal of it. double bb[6]; vtkMath::UninitializeBounds(bb); bool boundsSet = false; for (int i = 0; i < s.GetPropArrayCount(); i++) { const double* bounds = s.GetPropArray()[i]->GetBounds(); if (bounds) { if (!boundsSet) { bb[0] = bounds[0]; bb[1] = bounds[1]; bb[2] = bounds[2]; bb[3] = bounds[3]; bb[4] = bounds[4]; bb[5] = bounds[5]; boundsSet = true; } else { bb[0] = (bb[0] < bounds[0] ? bb[0] : bounds[0]); bb[1] = (bb[1] > bounds[1] ? bb[1] : bounds[1]); bb[2] = (bb[2] < bounds[2] ? bb[2] : bounds[2]); bb[3] = (bb[3] > bounds[3] ? bb[3] : bounds[3]); bb[4] = (bb[4] < bounds[4] ? bb[4] : bounds[4]); bb[5] = (bb[5] > bounds[5] ? bb[5] : bounds[5]); } } } float diag = (bb[1] - bb[0]) * (bb[1] - bb[0]) + (bb[3] - bb[2]) * (bb[3] - bb[2]) + (bb[5] - bb[4]) * (bb[5] - bb[4]); diag = sqrt(diag); prog->SetUniformf("SceneSize", diag); // RENDER AND FREE ALL this->EDLHighFBO->RenderQuad(0, this->W - 1, 0, this->H - 1, prog, this->EDLShadeProgram.VAO); // this->ProjectionDepthTexture->Deactivate(); this->EDLHighShadeTexture->Deactivate(); renWin->GetState()->PopFramebufferBindings(); return true; // succeeded } //------------------------------------------------------------------------------ // Description: // Render EDL in low resolution // bool vtkEDLShading::EDLShadeLow(vtkRenderState& s, vtkOpenGLRenderWindow* renWin) { // VARIABLES // float d = 2.0; float F_scale = 5.0; float SX = 1. / float(this->W / this->EDLLowResFactor); float SY = 1. / float(this->H / this->EDLLowResFactor); float L[3] = { 0., 0., -1. }; // ACTIVATE FBO // s.SetFrameBuffer(this->EDLLowFBO); this->EDLLowShadeTexture->Activate(); this->EDLLowShadeTexture->SetLinearMagnification(true); this->EDLLowShadeTexture->SendParameters(); renWin->GetState()->PushFramebufferBindings(); this->EDLLowFBO->Bind(); this->EDLLowFBO->AddColorAttachment(0, this->EDLLowShadeTexture); this->EDLLowFBO->ActivateDrawBuffer(0); this->EDLLowFBO->Start(this->W / this->EDLLowResFactor, this->H / this->EDLLowResFactor); // ACTIVATE SHADER // renWin->GetShaderCache()->ReadyShaderProgram(this->EDLShadeProgram.Program); // DEPTH TEXTURE PARAMETERS vtkShaderProgram* prog = this->EDLShadeProgram.Program; this->ProjectionDepthTexture->Activate(); // shader parameters prog->SetUniformi("s2_depth", this->ProjectionDepthTexture->GetTextureUnit()); prog->SetUniformf("d", d); prog->SetUniformf("F_scale", F_scale); prog->SetUniformf("SX", SX); prog->SetUniformf("SY", SY); prog->SetUniform3f("L", L); prog->SetUniform4fv("N", 8, this->EDLNeighbours); // USELESS, ALREADY DEFINED IN FULL RES prog->SetUniformf("Znear", this->Zn); prog->SetUniformf("Zfar", this->Zf); // RENDER AND FREE ALL // this->EDLLowFBO->RenderQuad(0, this->W / this->EDLLowResFactor - 1, 0, this->H / this->EDLLowResFactor - 1, prog, this->EDLShadeProgram.VAO); this->ProjectionDepthTexture->Deactivate(); this->EDLLowShadeTexture->Deactivate(); renWin->GetState()->PopFramebufferBindings(); return true; // succeeded } //------------------------------------------------------------------------------ // Description: // Bilateral Filter low resolution shaded image // bool vtkEDLShading::EDLBlurLow(vtkRenderState& s, vtkOpenGLRenderWindow* renWin) { // shader parameters float SX = 1. / float(this->W / this->EDLLowResFactor); float SY = 1. / float(this->H / this->EDLLowResFactor); int EDL_Bilateral_N = 5; float EDL_Bilateral_Sigma = 2.5; // ACTIVATE SHADER // renWin->GetShaderCache()->ReadyShaderProgram(this->BilateralProgram.Program); // ACTIVATE FBO // s.SetFrameBuffer(this->EDLLowFBO); this->EDLLowBlurTexture->Activate(); renWin->GetState()->PushFramebufferBindings(); this->EDLLowFBO->Bind(); this->EDLLowFBO->AddColorAttachment(0, this->EDLLowBlurTexture); this->EDLLowFBO->ActivateDrawBuffer(0); this->EDLLowFBO->Start(this->W / EDLLowResFactor, this->H / EDLLowResFactor); // DEPTH TEXTURE PARAMETERS vtkShaderProgram* prog = this->BilateralProgram.Program; // DEPTH TEXTURE PARAMETERS this->EDLLowShadeTexture->Activate(); this->ProjectionDepthTexture->Activate(); // shader parameters prog->SetUniformi("s2_I", this->EDLLowShadeTexture->GetTextureUnit()); prog->SetUniformi("s2_D", this->ProjectionDepthTexture->GetTextureUnit()); prog->SetUniformf("SX", SX); prog->SetUniformf("SY", SY); prog->SetUniformi("N", EDL_Bilateral_N); prog->SetUniformf("sigma", EDL_Bilateral_Sigma); this->EDLLowFBO->RenderQuad(0, this->W / this->EDLLowResFactor - 1, 0, this->H / this->EDLLowResFactor - 1, prog, this->BilateralProgram.VAO); this->EDLLowBlurTexture->Deactivate(); this->EDLLowShadeTexture->Deactivate(); this->ProjectionDepthTexture->Deactivate(); renWin->GetState()->PopFramebufferBindings(); return EDLIsFiltered; } //------------------------------------------------------------------------------ // Description: // Compose color and shaded images // bool vtkEDLShading::EDLCompose(const vtkRenderState*, vtkOpenGLRenderWindow* renWin) { // this->EDLIsFiltered = true; // ACTIVATE SHADER // renWin->GetShaderCache()->ReadyShaderProgram(this->EDLComposeProgram.Program); vtkOpenGLState* ostate = renWin->GetState(); // DEPTH TEXTURE PARAMETERS vtkShaderProgram* prog = this->EDLComposeProgram.Program; // EDL shaded texture - full res this->EDLHighShadeTexture->Activate(); prog->SetUniformi("s2_S1", this->EDLHighShadeTexture->GetTextureUnit()); // EDL shaded texture - low res // this->EDLLowBlurTexture->SetLinearMagnification(true); // this->EDLLowBlurTexture->SendParameters(); if (this->EDLIsFiltered) { this->EDLLowBlurTexture->Activate(); prog->SetUniformi("s2_S2", this->EDLLowBlurTexture->GetTextureUnit()); } else { this->EDLLowShadeTexture->Activate(); prog->SetUniformi("s2_S2", this->EDLLowShadeTexture->GetTextureUnit()); } // initial color texture this->ProjectionColorTexture->Activate(); prog->SetUniformi("s2_C", this->ProjectionColorTexture->GetTextureUnit()); // DRAW CONTEXT - prepare blitting // // Prepare blitting ostate->vtkglClearColor(1., 1., 1., 1.); ostate->vtkglClearDepth(1.0); ostate->vtkglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // IMPORTANT since we enable depth writing hereafter ostate->vtkglDisable(GL_BLEND); ostate->vtkglEnable(GL_DEPTH_TEST); vtkOpenGLState::ScopedglDepthFunc depthFuncState(ostate); ostate->vtkglDepthFunc(GL_ALWAYS); // IMPORTANT : so that depth information is propagated ostate->vtkglDisable(GL_SCISSOR_TEST); int blitSize[2] = { this->W - 1 - 2 * this->ExtraPixels, this->H - 1 - 2 * this->ExtraPixels }; this->EDLHighShadeTexture->CopyToFrameBuffer(this->ExtraPixels, this->ExtraPixels, blitSize[0], blitSize[1], this->Origin[0], this->Origin[1], this->Origin[0] + blitSize[0], this->Origin[1] + blitSize[1], prog, this->EDLComposeProgram.VAO); // FREE ALL // if (this->EDLIsFiltered) { this->EDLLowBlurTexture->Deactivate(); } else { this->EDLLowShadeTexture->Deactivate(); } this->EDLHighShadeTexture->Deactivate(); this->ProjectionColorTexture->Deactivate(); return true; } //------------------------------------------------------------------------------ // Description: // Perform rendering according to a render state \p s. // \pre s_exists: s!=0 void vtkEDLShading::Render(const vtkRenderState* s) { assert("pre: s_exists" && s != nullptr); annotate("Start vtkEDLShading::Render"); this->NumberOfRenderedProps = 0; vtkRenderer* r = s->GetRenderer(); vtkOpenGLRenderWindow* renWin = vtkOpenGLRenderWindow::SafeDownCast(r->GetRenderWindow()); if (this->DelegatePass != nullptr) { ////////////////////////////////////////////////////// // // 2. DEFINE SIZE and ACCORDING RENDER STATE // this->ReadWindowSize(s); // this->extraPixels = 20; Obsolete this->ExtraPixels = 0; // extra pixels to zero in the new system this->W = this->Width + 2 * this->ExtraPixels; this->H = this->Height + 2 * this->ExtraPixels; vtkRenderState s2(r); s2.SetPropArrayAndCount(s->GetPropArray(), s->GetPropArrayCount()); ////////////////////////////////////////////////////// // // 3. INITIALIZE FBOs and SHADERS // // FBOs // annotate("Start vtkEDLShading Initialization"); this->EDLInitializeFramebuffers(s2); // Shaders // this->EDLInitializeShaders(renWin); annotate("End vtkEDLShading Initialization"); if (this->EDLShadeProgram.Program == nullptr || this->EDLComposeProgram.Program == nullptr || this->BilateralProgram.Program == nullptr) { return; } ////////////////////////////////////////////////////// // // 4. DELEGATE RENDER IN PROJECTION FBO // // double znear, zfar; r->GetActiveCamera()->GetClippingRange(znear, zfar); this->Zf = zfar; this->Zn = znear; // cout << " -- ZNEAR/ZFAR : " << Zn << " || " << Zf << endl; renWin->GetState()->PushFramebufferBindings(); this->ProjectionFBO->Bind(); annotate("Start vtkEDLShading::RenderDelegate"); this->RenderDelegate(s, this->Width, this->Height, this->W, this->H, this->ProjectionFBO, this->ProjectionColorTexture, this->ProjectionDepthTexture); annotate("End vtkEDLShading::RenderDelegate"); // system("PAUSE"); ////////////////////////////////////////////////////// // // 5. EDL SHADING PASS - FULL RESOLUTION // #if EDL_HIGH_RESOLUTION_ON annotate("Start vtkEDLShading::ShadeHigh"); if (!this->EDLShadeHigh(s2, renWin)) { renWin->GetState()->PopFramebufferBindings(); } annotate("End vtkEDLShading::ShadeHigh"); #endif // EDL_HIGH_RESOLUTION_ON ////////////////////////////////////////////////////// // // 6. EDL SHADING PASS - LOW RESOLUTION + blur pass // #if EDL_LOW_RESOLUTION_ON annotate("Start vtkEDLShading::ShadeLow"); if (!this->EDLShadeLow(s2, renWin)) { renWin->GetState()->PopFramebufferBindings(); } annotate("End vtkEDLShading::ShadeLow"); if (this->EDLIsFiltered) { annotate("Start vtkEDLShading::BlurLow"); this->EDLBlurLow(s2, renWin); annotate("End vtkEDLShading::BlurLow"); } // Low-res processing reduces the viewport dimensions. // Reset the viewport after to ensure that following passes get the right viewport size. renWin->GetState()->vtkglViewport(this->Origin[0], this->Origin[1], this->Width, this->Height); #endif // EDL_LOW_RESOLUTION_ON ////////////////////////////////////////////////////// // // 7. COMPOSITING PASS (in original framebuffer) // if (s->GetFrameBuffer() != nullptr) { vtkOpenGLFramebufferObject::SafeDownCast(s->GetFrameBuffer())->Bind(); } renWin->GetState()->PopFramebufferBindings(); annotate("Start vtkEDLShading::Compose"); if (!this->EDLCompose(s, renWin)) { return; } annotate("End vtkEDLShading::Compose"); } else { vtkWarningMacro(<< " no delegate."); } annotate("END vtkEDLShading::Render"); } //------------------------------------------------------------------------------ // Description: // Release graphics resources and ask components to release their own // resources. // \pre w_exists: w!=0 void vtkEDLShading::ReleaseGraphicsResources(vtkWindow* w) { assert("pre: w_exists" && w != nullptr); // SHADERS this->EDLShadeProgram.ReleaseGraphicsResources(w); this->EDLComposeProgram.ReleaseGraphicsResources(w); this->BilateralProgram.ReleaseGraphicsResources(w); // FBOs and TOs // if (this->ProjectionFBO != nullptr) { this->ProjectionFBO->Delete(); this->ProjectionFBO = nullptr; } if (this->ProjectionColorTexture != nullptr) { this->ProjectionColorTexture->Delete(); this->ProjectionColorTexture = nullptr; } if (this->ProjectionDepthTexture != nullptr) { this->ProjectionDepthTexture->Delete(); this->ProjectionDepthTexture = nullptr; } if (this->EDLHighFBO != nullptr) { this->EDLHighFBO->Delete(); this->EDLHighFBO = nullptr; } if (this->EDLHighShadeTexture != nullptr) { this->EDLHighShadeTexture->Delete(); this->EDLHighShadeTexture = nullptr; } if (this->EDLLowFBO != nullptr) { this->EDLLowFBO->Delete(); this->EDLLowFBO = nullptr; } if (this->EDLLowShadeTexture != nullptr) { this->EDLLowShadeTexture->Delete(); this->EDLLowShadeTexture = nullptr; } if (this->EDLLowBlurTexture != nullptr) { this->EDLLowBlurTexture->Delete(); this->EDLLowBlurTexture = nullptr; } this->Superclass::ReleaseGraphicsResources(w); }