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 "vtkOpenGLError.h"
22 #include "vtkOpenGLFramebufferObject.h"
23 #include "vtkOpenGLRenderWindow.h"
24 #include "vtkOpenGLState.h"
25 #include "vtkRenderState.h"
26 #include "vtkRenderer.h"
27 #include "vtkTextureObject.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(
99 &this->ViewportWidth, &this->ViewportHeight, &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, VTK_UNSIGNED_CHAR, false);
126 }
127 this->ColorTexture->Resize(this->ViewportWidth, this->ViewportHeight);
128
129 // Depth texture
130 this->DepthTexture->SetContext(renWin);
131 if (!this->DepthTexture->GetHandle())
132 {
133 this->DepthTexture->AllocateDepth(this->ViewportWidth, this->ViewportHeight, this->DepthFormat);
134 }
135 this->DepthTexture->Resize(this->ViewportWidth, this->ViewportHeight);
136
137 if (this->FrameBufferObject == nullptr)
138 {
139 this->FrameBufferObject = vtkOpenGLFramebufferObject::New();
140 this->FrameBufferObject->SetContext(renWin);
141 }
142
143 ostate->PushFramebufferBindings();
144 this->RenderDelegate(s, this->ViewportWidth, this->ViewportHeight, this->ViewportWidth,
145 this->ViewportHeight, this->FrameBufferObject, this->ColorTexture, this->DepthTexture);
146
147 ostate->PopFramebufferBindings();
148
149 // now copy the result to the outer FO
150 ostate->PushReadFramebufferBinding();
151 this->FrameBufferObject->Bind(vtkOpenGLFramebufferObject::GetReadMode());
152
153 ostate->vtkglViewport(
154 this->ViewportX, this->ViewportY, this->ViewportWidth, this->ViewportHeight);
155 ostate->vtkglScissor(this->ViewportX, this->ViewportY, this->ViewportWidth, this->ViewportHeight);
156
157 ostate->vtkglBlitFramebuffer(0, 0, this->ViewportWidth, this->ViewportHeight, this->ViewportX,
158 this->ViewportY, this->ViewportX + this->ViewportWidth, this->ViewportY + this->ViewportHeight,
159 GL_COLOR_BUFFER_BIT, GL_LINEAR);
160
161 ostate->PopReadFramebufferBinding();
162
163 vtkOpenGLCheckErrorMacro("failed after Render");
164 }
165
166 //------------------------------------------------------------------------------
167 // Description:
168 // Release graphics resources and ask components to release their own
169 // resources.
170 // \pre w_exists: w!=0
ReleaseGraphicsResources(vtkWindow * w)171 void vtkFramebufferPass::ReleaseGraphicsResources(vtkWindow* w)
172 {
173 assert("pre: w_exists" && w != nullptr);
174
175 this->Superclass::ReleaseGraphicsResources(w);
176
177 if (this->FrameBufferObject != nullptr)
178 {
179 this->FrameBufferObject->Delete();
180 this->FrameBufferObject = nullptr;
181 }
182 if (this->ColorTexture != nullptr)
183 {
184 this->ColorTexture->ReleaseGraphicsResources(w);
185 }
186 if (this->DepthTexture != nullptr)
187 {
188 this->DepthTexture->ReleaseGraphicsResources(w);
189 }
190 }
191