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