1 /*=========================================================================
2 
3    Program: ParaView
4    Module:    vtkDepthImageProcessingPass.cxx
5 
6    Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
7    All rights reserved.
8 
9    ParaView is a free software; you can redistribute it and/or modify it
10    under the terms of the ParaView license version 1.2.
11 
12    See License_v1.2.txt for the full ParaView license.
13    A copy of this license can be obtained by contacting
14    Kitware Inc.
15    28 Corporate Drive
16    Clifton Park, NY 12065
17    USA
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
23 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 =========================================================================*/
32 /*----------------------------------------------------------------------
33 Acknowledgement:
34 This algorithm is the result of joint work by Electricité de France,
35 CNRS, Collège de France and Université J. Fourier as part of the
36 Ph.D. thesis of Christian BOUCHENY.
37 ------------------------------------------------------------------------*/
38 
39 #include "vtkDepthImageProcessingPass.h"
40 #include "vtkObjectFactory.h"
41 #include <cassert>
42 #include "vtkRenderState.h"
43 #include "vtkRenderer.h"
44 #include "vtkOpenGLFramebufferObject.h"
45 #include "vtkTextureObject.h"
46 #include "vtkOpenGLRenderWindow.h"
47 #include "vtkOpenGLRenderUtilities.h"
48 
49 #include "vtkPixelBufferObject.h"
50 #include "vtkCamera.h"
51 #include "vtkMath.h"
52 
53 // ----------------------------------------------------------------------------
vtkDepthImageProcessingPass()54 vtkDepthImageProcessingPass::vtkDepthImageProcessingPass()
55 {
56   this->Origin[0] = 0;
57   this->Origin[1] = 0;
58   this->Width = 0;
59   this->Height = 0;
60   this->W = 0;
61   this->H = 0;
62   this->ExtraPixels = 0;
63 }
64 
65 // ----------------------------------------------------------------------------
66 vtkDepthImageProcessingPass::~vtkDepthImageProcessingPass() = default;
67 
68 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)69 void vtkDepthImageProcessingPass::PrintSelf(ostream& os, vtkIndent indent)
70 {
71   this->Superclass::PrintSelf(os,indent);
72 }
73 
74 // ----------------------------------------------------------------------------
75 // Description:
76 // Render delegate with a image of different dimensions than the
77 // original one.
78 // \pre s_exists: s!=0
79 // \pre fbo_exists: fbo!=0
80 // \pre fbo_has_context: fbo->GetContext()!=0
81 // \pre target_exists: target!=0
82 // \pre target_has_context: target->GetContext()!=0
RenderDelegate(const vtkRenderState * s,int width,int height,int newWidth,int newHeight,vtkOpenGLFramebufferObject * fbo,vtkTextureObject * colortarget,vtkTextureObject * depthtarget)83 void vtkDepthImageProcessingPass::RenderDelegate(const vtkRenderState *s,
84                                             int width,
85                                             int height,
86                                             int newWidth,
87                                             int newHeight,
88                                             vtkOpenGLFramebufferObject *fbo,
89                                             vtkTextureObject *colortarget,
90                                             vtkTextureObject *depthtarget)
91 {
92   assert("pre: s_exists" && s!=nullptr);
93   assert("pre: fbo_exists" && fbo!=nullptr);
94   assert("pre: fbo_has_context" && fbo->GetContext()!=nullptr);
95   assert("pre: colortarget_exists" && colortarget!=nullptr);
96   assert("pre: colortarget_has_context" && colortarget->GetContext()!=nullptr);
97   assert("pre: depthtarget_exists" && depthtarget!=nullptr);
98   assert("pre: depthtarget_has_context" && depthtarget->GetContext()!=nullptr);
99 
100   vtkRenderer *r=s->GetRenderer();
101   vtkRenderState s2(r);
102   s2.SetPropArrayAndCount(s->GetPropArray(),s->GetPropArrayCount());
103 
104   // Adapt camera to new window size
105   vtkCamera *savedCamera=r->GetActiveCamera();
106   savedCamera->Register(this);
107   vtkCamera *newCamera=vtkCamera::New();
108   newCamera->DeepCopy(savedCamera);
109 
110   r->SetActiveCamera(newCamera);
111 
112   if(newCamera->GetParallelProjection())
113   {
114     newCamera->SetParallelScale(
115       newCamera->GetParallelScale()*newHeight/static_cast<double>(height));
116   }
117   else
118   {
119     double large;
120     double small;
121     if(newCamera->GetUseHorizontalViewAngle())
122     {
123       large=newWidth;
124       small=width;
125     }
126     else
127     {
128       large=newHeight;
129       small=height;
130 
131     }
132     double angle=vtkMath::RadiansFromDegrees(newCamera->GetViewAngle());
133     angle = 2.0*atan(tan(angle/2.0)*large/static_cast<double>(small));
134 
135     newCamera->SetViewAngle(vtkMath::DegreesFromRadians(angle));
136   }
137 
138   s2.SetFrameBuffer(fbo);
139 
140   fbo->AddColorAttachment(
141     fbo->GetDrawMode(), 0,colortarget);
142 
143   // because the same FBO can be used in another pass but with several color
144   // buffers, force this pass to use 1, to avoid side effects from the
145   // render of the previous frame.
146   fbo->ActivateDrawBuffer(0);
147 
148   fbo->AddDepthAttachment(fbo->GetDrawMode(), depthtarget);
149   fbo->StartNonOrtho(newWidth, newHeight);
150 
151   // 2. Delegate render in FBO
152   //glEnable(GL_DEPTH_TEST);
153   vtkOpenGLRenderUtilities::MarkDebugEvent(
154         "Start vtkDepthImageProcessingPass delegate render");
155   this->DelegatePass->Render(&s2);
156   vtkOpenGLRenderUtilities::MarkDebugEvent(
157         "End vtkDepthImageProcessingPass delegate render");
158 
159   this->NumberOfRenderedProps+=
160     this->DelegatePass->GetNumberOfRenderedProps();
161 
162   newCamera->Delete();
163   r->SetActiveCamera(savedCamera);
164   savedCamera->UnRegister(this);
165 }
166 
167 // ----------------------------------------------------------------------------
168 // Description:
169 // Read window size from parent
170 // \pre s_exists: s!=0
171 //
ReadWindowSize(const vtkRenderState * s)172 void vtkDepthImageProcessingPass::ReadWindowSize(const vtkRenderState* s)
173 {
174     assert("pre: s_exists" && s!=nullptr);
175 
176     vtkOpenGLFramebufferObject *fbo=vtkOpenGLFramebufferObject::SafeDownCast
177       (s->GetFrameBuffer());
178     vtkRenderer *r = s->GetRenderer();
179     if(fbo==nullptr)
180     {
181       r->GetTiledSizeAndOrigin(&this->Width, &this->Height,
182                                &this->Origin[0], &this->Origin[1]);
183     }
184     else
185     {
186       int size[2];
187       fbo->GetLastSize(size);
188       this->Origin[0] = 0;
189       this->Origin[1] = 0;
190       this->Width=size[0];
191       this->Height=size[1];
192     }
193 }
194