1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkFramebufferPass.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #include "vtkFramebufferPass.h"
17 #include "vtkObjectFactory.h"
18 #include <cassert>
19 
20 // #include "vtkCamera.h"
21 #include "vtkRenderState.h"
22 #include "vtkRenderer.h"
23 #include "vtkOpenGLFramebufferObject.h"
24 #include "vtkTextureObject.h"
25 #include "vtkOpenGLRenderWindow.h"
26 #include "vtkOpenGLError.h"
27 #include "vtkOpenGLState.h"
28 // #include "vtkShaderProgram.h"
29 // #include "vtkOpenGLShaderCache.h"
30 // #include "vtkOpenGLRenderWindow.h"
31 // #include "vtkOpenGLVertexArrayObject.h"
32 
33 #include "vtkOpenGLHelper.h"
34 
35 vtkStandardNewMacro(vtkFramebufferPass);
36 
37 // ----------------------------------------------------------------------------
vtkFramebufferPass()38 vtkFramebufferPass::vtkFramebufferPass()
39 {
40   this->FrameBufferObject=nullptr;
41   this->ColorTexture = vtkTextureObject::New();
42   this->DepthTexture = vtkTextureObject::New();
43   this->DepthFormat = vtkTextureObject::Float32;
44   this->ColorFormat = vtkTextureObject::Fixed8;
45 }
46 
47 // ----------------------------------------------------------------------------
~vtkFramebufferPass()48 vtkFramebufferPass::~vtkFramebufferPass()
49 {
50   if(this->FrameBufferObject!=nullptr)
51   {
52     vtkErrorMacro(<<"FrameBufferObject should have been deleted in ReleaseGraphicsResources().");
53   }
54    if(this->ColorTexture!=nullptr)
55    {
56     this->ColorTexture->Delete();
57     this->ColorTexture = nullptr;
58    }
59    if(this->DepthTexture !=nullptr)
60    {
61     this->DepthTexture->Delete();
62     this->DepthTexture = nullptr;
63    }
64 }
65 
66 // ----------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)67 void vtkFramebufferPass::PrintSelf(ostream& os, vtkIndent indent)
68 {
69   this->Superclass::PrintSelf(os,indent);
70 }
71 
72 // ----------------------------------------------------------------------------
73 // Description:
74 // Perform rendering according to a render state \p s.
75 // \pre s_exists: s!=0
Render(const vtkRenderState * s)76 void vtkFramebufferPass::Render(const vtkRenderState *s)
77 {
78   assert("pre: s_exists" && s!=nullptr);
79 
80   vtkOpenGLClearErrorMacro();
81 
82   this->NumberOfRenderedProps=0;
83 
84   vtkRenderer *r=s->GetRenderer();
85   vtkOpenGLRenderWindow *renWin = static_cast<vtkOpenGLRenderWindow *>(r->GetRenderWindow());
86   vtkOpenGLState *ostate = renWin->GetState();
87 
88   if(this->DelegatePass == nullptr)
89   {
90     vtkWarningMacro(<<" no delegate.");
91     return;
92   }
93 
94   // 1. Create a new render state with an FO.
95   if(s->GetFrameBuffer()==nullptr)
96   {
97     // get the viewport dimensions
98     r->GetTiledSizeAndOrigin(&this->ViewportWidth,&this->ViewportHeight,
99                              &this->ViewportX,&this->ViewportY);
100   }
101   else
102   {
103     int size[2];
104     s->GetWindowSize(size);
105     this->ViewportWidth=size[0];
106     this->ViewportHeight=size[1];
107     this->ViewportX=0;
108     this->ViewportY=0;
109   }
110 
111   this->ColorTexture->SetContext(renWin);
112   if (!this->ColorTexture->GetHandle())
113   {
114     if (this->ColorFormat == vtkTextureObject::Float16)
115     {
116       this->ColorTexture->SetInternalFormat(GL_RGBA16F);
117       this->ColorTexture->SetDataType(GL_FLOAT);
118     }
119     if (this->ColorFormat == vtkTextureObject::Float32)
120     {
121       this->ColorTexture->SetInternalFormat(GL_RGBA32F);
122       this->ColorTexture->SetDataType(GL_FLOAT);
123     }
124     this->ColorTexture->Create2D(
125       this->ViewportWidth, this->ViewportHeight, 4,
126       VTK_UNSIGNED_CHAR, false);
127   }
128   this->ColorTexture->Resize(this->ViewportWidth, this->ViewportHeight);
129 
130   // Depth texture
131   this->DepthTexture->SetContext(renWin);
132   if (!this->DepthTexture->GetHandle())
133   {
134     this->DepthTexture->AllocateDepth(
135       this->ViewportWidth, this->ViewportHeight, this->DepthFormat);
136   }
137   this->DepthTexture->Resize(this->ViewportWidth, this->ViewportHeight);
138 
139   if(this->FrameBufferObject==nullptr)
140   {
141     this->FrameBufferObject=vtkOpenGLFramebufferObject::New();
142     this->FrameBufferObject->SetContext(renWin);
143   }
144 
145   this->FrameBufferObject->SaveCurrentBindingsAndBuffers();
146   this->RenderDelegate(s,
147     this->ViewportWidth, this->ViewportHeight,
148     this->ViewportWidth, this->ViewportHeight,
149     this->FrameBufferObject,
150     this->ColorTexture, this->DepthTexture);
151 
152   this->FrameBufferObject->RestorePreviousBindingsAndBuffers();
153 
154 
155   // now copy the result to the outer FO
156   this->FrameBufferObject->SaveCurrentBindingsAndBuffers(
157     this->FrameBufferObject->GetReadMode());
158   this->FrameBufferObject->Bind(
159     this->FrameBufferObject->GetReadMode());
160 
161   ostate->vtkglViewport(this->ViewportX, this->ViewportY,
162     this->ViewportWidth, this->ViewportHeight);
163   ostate->vtkglScissor(this->ViewportX, this->ViewportY,
164     this->ViewportWidth, this->ViewportHeight);
165 
166   glBlitFramebuffer(
167     0, 0, this->ViewportWidth, this->ViewportHeight,
168     this->ViewportX, this->ViewportY,
169     this->ViewportX + this->ViewportWidth,
170     this->ViewportY + this->ViewportHeight,
171     GL_COLOR_BUFFER_BIT,
172     GL_LINEAR);
173 
174   this->FrameBufferObject->RestorePreviousBindingsAndBuffers(
175     this->FrameBufferObject->GetReadMode());
176 
177   vtkOpenGLCheckErrorMacro("failed after Render");
178 }
179 
180 // ----------------------------------------------------------------------------
181 // Description:
182 // Release graphics resources and ask components to release their own
183 // resources.
184 // \pre w_exists: w!=0
ReleaseGraphicsResources(vtkWindow * w)185 void vtkFramebufferPass::ReleaseGraphicsResources(vtkWindow *w)
186 {
187   assert("pre: w_exists" && w!=nullptr);
188 
189   this->Superclass::ReleaseGraphicsResources(w);
190 
191   if(this->FrameBufferObject!=nullptr)
192   {
193     this->FrameBufferObject->Delete();
194     this->FrameBufferObject=nullptr;
195   }
196    if(this->ColorTexture!=nullptr)
197    {
198     this->ColorTexture->ReleaseGraphicsResources(w);
199    }
200    if(this->DepthTexture!=nullptr)
201    {
202     this->DepthTexture->ReleaseGraphicsResources(w);
203    }
204 }
205