TTK
Loading...
Searching...
No Matches
ttkCinemaDarkroomShader.cpp
Go to the documentation of this file.
2
3#include <vtkInformation.h>
4
5#include <vtkDataArray.h>
6#include <vtkDataSet.h>
7#include <vtkPointData.h>
8
9#include <vtkCamera.h>
10#include <vtkOpenGLPolyDataMapper.h>
11#include <vtkOpenGLRenderWindow.h>
12#include <vtkOpenGLRenderer.h>
13#include <vtkPlaneSource.h>
14#include <vtkRenderWindow.h>
15#include <vtkWindowToImageFilter.h>
16
17#include <vtkFloatArray.h>
18#include <vtkUnsignedCharArray.h>
19
20#include <vtkOpenGLTexture.h>
21#include <vtkProperty.h>
22#include <vtkShaderProperty.h>
23#include <vtkTextureObject.h>
24
25#include <vtkFramebufferPass.h>
26#include <vtkRenderStepsPass.h>
27
28#include <boost/algorithm/string.hpp>
29
30#include <ttkMacros.h>
31#include <ttkUtils.h>
32
34
37 this->CreateRenderer();
38
39 this->SetNumberOfInputPorts(1);
40 this->SetNumberOfOutputPorts(1);
41}
42
44
46 vtkInformation *info) {
47 if(port == 0) {
48 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
49 return 1;
50 }
51 return 0;
52}
53
55 vtkInformation *info) {
56 if(port == 0) {
58 return 1;
59 }
60 return 0;
61}
62
64 return std::string(R"(
65
66//VTK::System::Dec // always start with this line in your VS
67
68attribute vec4 vertexMC;
69varying vec4 vPos;
70
71void main () {
72 vPos = vertexMC/2. + vec4(0.5,0.5,0.5,0);
73 gl_Position = vertexMC;
74}
75
76 )");
77}
78
80 return std::string(R"(
81
82//VTK::System::Dec // always start with these lines in your FS
83//VTK::Output::Dec // always start with these lines in your FS
84
85varying vec4 vPos;
86
87void main(void) {
88 gl_FragData[0] = vec4(1,0,0,1);
89}
90
91 )");
92}
93
94std::string
96 std::string result = source;
97
98 for(const auto &it : this->Replacements)
99 boost::replace_all(result, it.first, it.second.toString());
100
101 return result;
102}
103
104int ttkCinemaDarkroomShader::AddReplacement(const std::string &name,
105 const std::vector<double> &values,
106 const bool &isInt) {
107 auto it = this->Replacements.find(name);
108 if(it == this->Replacements.end()) {
109 this->Replacements.emplace(std::piecewise_construct,
110 std::forward_as_tuple(name),
111 std::forward_as_tuple(values, isInt));
112 } else {
113 it->second.values = values;
114 }
115
116 return 1;
117}
118
121 ps->SetOrigin(-1, -1, 0);
122 ps->SetPoint1(1, -1, 0);
123 ps->SetPoint2(-1, 1, 0);
124 ps->Update();
125
126 this->FullScreenQuad = vtkSmartPointer<vtkPolyData>::New();
127 this->FullScreenQuad->ShallowCopy(ps->GetOutput());
128 this->FullScreenQuadActor = vtkSmartPointer<vtkActor>::New();
129
131 mapper->SetInputData(this->FullScreenQuad);
132 this->FullScreenQuadActor->SetMapper(mapper);
133
134 return 1;
135}
136
138 // Renderer
140 this->Renderer->AddActor(this->FullScreenQuadActor);
141 this->Renderer->SetBackground(0, 0, 0);
142
143 // Camera
144 auto camera = vtkSmartPointer<vtkCamera>::New();
145 camera->SetParallelProjection(true);
146 camera->SetClippingRange(0, 2);
147 camera->SetPosition(0, 0, 1);
148 camera->SetFocalPoint(0, 0, 0);
149 camera->SetParallelScale(
150 1); // Will be ignored because quad positions are fixed
151 this->Renderer->SetActiveCamera(camera);
152
153 this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
154
155 return 1;
156}
157
158int ttkCinemaDarkroomShader::InitRenderer(vtkImageData *outputImage) {
159 int dim[3];
160 outputImage->GetDimensions(dim);
161
162 this->AddReplacement("cResolution", {(double)dim[0], (double)dim[1]});
163
164 // Window
165 int *size = this->RenderWindow->GetSize();
166 if(size[0] != dim[0] || size[1] != dim[1]) {
167 ttk::Timer timer;
168 this->printMsg("Initializing Renderer (" + std::to_string(dim[0]) + "x"
169 + std::to_string(dim[1]) + ")",
171
172 this->RenderWindow = vtkSmartPointer<vtkRenderWindow>::New();
173 this->RenderWindow->AddRenderer(this->Renderer);
174 this->RenderWindow->SetMultiSamples(0); // Disable AA
175 this->RenderWindow->OffScreenRenderingOn();
176
177 auto windowAsOGL = vtkOpenGLRenderWindow::SafeDownCast(this->RenderWindow);
178 if(windowAsOGL == nullptr) {
179 return 0;
180 }
181 windowAsOGL->SetSize(dim[0], dim[1]);
182 windowAsOGL->Initialize();
183
184 this->printMsg("Initializing Renderer (" + std::to_string(dim[0]) + "x"
185 + std::to_string(dim[1]) + ")",
186 1, timer.getElapsedTime(), 1);
187 }
188
189 return 1;
190}
191
193 int arrayIdx,
194 int textureIdx) {
195 int dim[3];
196 image->GetDimensions(dim);
197
198 auto inputArray = this->GetInputArrayToProcess(arrayIdx, image);
199 if(!inputArray || this->GetInputArrayAssociation(arrayIdx, image) != 0) {
200 this->printErr("Unable to retrieve input point data array "
201 + std::to_string(arrayIdx) + ".");
202 return 0;
203 }
204
205 std::string textureName = "tex" + std::to_string(textureIdx);
206
207 auto properties = this->FullScreenQuadActor->GetProperty();
208 // if texture already exists remove it
209 if(properties->GetTexture(textureName.data()))
210 properties->RemoveTexture(textureName.data());
211
212 // create texture
214
215 auto textureObj = vtkSmartPointer<vtkTextureObject>::New();
216 textureObj->SetContext(
217 vtkOpenGLRenderWindow::SafeDownCast(this->RenderWindow));
218 textureObj->SetWrapT(vtkTextureObject::ClampToEdge);
219 textureObj->SetWrapS(vtkTextureObject::ClampToEdge);
220 textureObj->Create2DFromRaw(
221 dim[0], dim[1], inputArray->GetNumberOfComponents(),
222 inputArray->GetDataType(), ttkUtils::GetVoidPointer(inputArray));
223 texture->SetTextureObject(textureObj);
224 texture->InterpolateOn();
225
226 // add texture to properties
227 properties->SetTexture(textureName.data(), texture);
228
229 return 1;
230}
231
232int ttkCinemaDarkroomShader::Render(vtkImageData *image,
233 const std::string &name) {
234 ttk::Timer timer;
235 int dim[3];
236 image->GetDimensions(dim);
237 this->printMsg(
238 "Rendering (" + std::to_string(dim[0]) + "x" + std::to_string(dim[1]) + ")",
240
241 this->FullScreenQuadActor->GetShaderProperty()->SetVertexShaderCode(
242 this->PerformReplacements(this->GetVertexShaderCode()).data());
243 this->FullScreenQuadActor->GetShaderProperty()->SetFragmentShaderCode(
244 this->PerformReplacements(this->GetFragmentShaderCode()).data());
245
247 buffer->SetName(name.data());
248 buffer->SetNumberOfComponents(4);
249 buffer->SetNumberOfTuples(dim[0] * dim[1]);
250
251 this->RenderWindow->Render();
252 this->RenderWindow->GetRGBACharPixelData(
253 0, 0, dim[0] - 1, dim[1] - 1, 1, buffer);
254
255 image->GetPointData()->AddArray(buffer);
256 image->GetPointData()->SetActiveScalars(buffer->GetName());
257
258 this->printMsg(
259 "Rendering (" + std::to_string(dim[0]) + "x" + std::to_string(dim[1]) + ")",
260 1, timer.getElapsedTime(), 1);
261
262 return 1;
263}
static vtkInformationIntegerKey * SAME_DATA_TYPE_AS_INPUT_PORT()
Base Class for all CinemaDarkroom Shaders.
virtual int Render(vtkImageData *image, const std::string &name)
int FillInputPortInformation(int port, vtkInformation *info) override
~ttkCinemaDarkroomShader() override
int InitRenderer(vtkImageData *outputImage)
int AddTexture(vtkImageData *image, int arrayIdx, int textureIdx)
int FillOutputPortInformation(int port, vtkInformation *info) override
int AddReplacement(const std::string &name, const std::vector< double > &values, const bool &isInt=false)
virtual std::string GetFragmentShaderCode()
std::string PerformReplacements(const std::string &input)
virtual std::string GetVertexShaderCode()
static void * GetVoidPointer(vtkDataArray *array, vtkIdType start=0)
Definition: ttkUtils.cpp:225
int printMsg(const std::string &msg, const debug::Priority &priority=debug::Priority::INFO, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cout) const
Definition: Debug.h:118
int printErr(const std::string &msg, const debug::LineMode &lineMode=debug::LineMode::NEW, std::ostream &stream=std::cerr) const
Definition: Debug.h:149
double getElapsedTime()
Definition: Timer.h:15
vtkStandardNewMacro(ttkCinemaDarkroomShader)