/*========================================================================= Program: ParaView Module: vtkDepthImageProcessingPass.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 "vtkDepthImageProcessingPass.h" #include "vtkObjectFactory.h" #include "vtkOpenGLFramebufferObject.h" #include "vtkOpenGLRenderUtilities.h" #include "vtkOpenGLRenderWindow.h" #include "vtkRenderState.h" #include "vtkRenderer.h" #include "vtkTextureObject.h" #include #include "vtkCamera.h" #include "vtkMath.h" #include "vtkPixelBufferObject.h" //------------------------------------------------------------------------------ vtkDepthImageProcessingPass::vtkDepthImageProcessingPass() { this->Origin[0] = 0; this->Origin[1] = 0; this->Width = 0; this->Height = 0; this->W = 0; this->H = 0; this->ExtraPixels = 0; } //------------------------------------------------------------------------------ vtkDepthImageProcessingPass::~vtkDepthImageProcessingPass() = default; //------------------------------------------------------------------------------ void vtkDepthImageProcessingPass::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); } //------------------------------------------------------------------------------ // Description: // Render delegate with a image of different dimensions than the // original one. // \pre s_exists: s!=0 // \pre fbo_exists: fbo!=0 // \pre fbo_has_context: fbo->GetContext()!=0 // \pre target_exists: target!=0 // \pre target_has_context: target->GetContext()!=0 void vtkDepthImageProcessingPass::RenderDelegate(const vtkRenderState* s, int width, int height, int newWidth, int newHeight, vtkOpenGLFramebufferObject* fbo, vtkTextureObject* colortarget, vtkTextureObject* depthtarget) { assert("pre: s_exists" && s != nullptr); assert("pre: fbo_exists" && fbo != nullptr); assert("pre: fbo_has_context" && fbo->GetContext() != nullptr); assert("pre: colortarget_exists" && colortarget != nullptr); assert("pre: colortarget_has_context" && colortarget->GetContext() != nullptr); assert("pre: depthtarget_exists" && depthtarget != nullptr); assert("pre: depthtarget_has_context" && depthtarget->GetContext() != nullptr); vtkRenderer* r = s->GetRenderer(); vtkRenderState s2(r); s2.SetPropArrayAndCount(s->GetPropArray(), s->GetPropArrayCount()); // Adapt camera to new window size vtkCamera* savedCamera = r->GetActiveCamera(); savedCamera->Register(this); vtkCamera* newCamera = vtkCamera::New(); newCamera->DeepCopy(savedCamera); r->SetActiveCamera(newCamera); if (newCamera->GetParallelProjection()) { newCamera->SetParallelScale( newCamera->GetParallelScale() * newHeight / static_cast(height)); } else { double large; double small; if (newCamera->GetUseHorizontalViewAngle()) { large = newWidth; small = width; } else { large = newHeight; small = height; } double angle = vtkMath::RadiansFromDegrees(newCamera->GetViewAngle()); angle = 2.0 * atan(tan(angle / 2.0) * large / static_cast(small)); newCamera->SetViewAngle(vtkMath::DegreesFromRadians(angle)); } s2.SetFrameBuffer(fbo); fbo->Bind(); fbo->AddColorAttachment(0, colortarget); // because the same FBO can be used in another pass but with several color // buffers, force this pass to use 1, to avoid side effects from the // render of the previous frame. fbo->ActivateDrawBuffer(0); fbo->AddDepthAttachment(depthtarget); fbo->StartNonOrtho(newWidth, newHeight); // 2. Delegate render in FBO // glEnable(GL_DEPTH_TEST); vtkOpenGLRenderUtilities::MarkDebugEvent("Start vtkDepthImageProcessingPass delegate render"); this->DelegatePass->Render(&s2); vtkOpenGLRenderUtilities::MarkDebugEvent("End vtkDepthImageProcessingPass delegate render"); this->NumberOfRenderedProps += this->DelegatePass->GetNumberOfRenderedProps(); newCamera->Delete(); r->SetActiveCamera(savedCamera); savedCamera->UnRegister(this); } //------------------------------------------------------------------------------ // Description: // Read window size from parent // \pre s_exists: s!=0 // void vtkDepthImageProcessingPass::ReadWindowSize(const vtkRenderState* s) { assert("pre: s_exists" && s != nullptr); vtkOpenGLFramebufferObject* fbo = vtkOpenGLFramebufferObject::SafeDownCast(s->GetFrameBuffer()); vtkRenderer* r = s->GetRenderer(); if (fbo == nullptr) { r->GetTiledSizeAndOrigin(&this->Width, &this->Height, &this->Origin[0], &this->Origin[1]); } else { int size[2]; fbo->GetLastSize(size); this->Origin[0] = 0; this->Origin[1] = 0; this->Width = size[0]; this->Height = size[1]; } }