diff --git a/Documentation/release/dev/add-radial-gradient-background.md b/Documentation/release/dev/add-radial-gradient-background.md new file mode 100644 index 0000000000000000000000000000000000000000..15157afc50c07a1f865982ee8f8a8f0d7271dd54 --- /dev/null +++ b/Documentation/release/dev/add-radial-gradient-background.md @@ -0,0 +1,17 @@ +## Add new gradient background modes + +You can now use a radial or horizontal gradient background in VTK. The background colors are interpolated smoothly +based on a distance function from the center of the viewport to each pixel in viewport coordinate space. + +You can select from various gradient background modes with `vtkViewport::SetGradientMode`. The following modes are available: + +1. `VTK_GRADIENT_VERTICAL` + Background color is used at the bottom, Background2 color is used at the top. +2. `VTK_GRADIENT_HORIZONTAL` + Background color on the left, Background2 color on the right. +3. `VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE` + Background color in the center, Background2 color on and beyond the circle/ellipse edge. Circle/Ellipse touches all sides of the square/rectangle viewport. +4. `VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER` + Background color in the center, Background2 color on and beyond the circle/ellipse edge. Circle/Ellipse touches all corners of the square/rectangle viewport. + +![Image showing different gradient modes](./add-radial-gradient-background.png) diff --git a/Documentation/release/dev/add-radial-gradient-background.png b/Documentation/release/dev/add-radial-gradient-background.png new file mode 100644 index 0000000000000000000000000000000000000000..0dc2ad314b91a28349c7b8e8c8087b943c3a630a Binary files /dev/null and b/Documentation/release/dev/add-radial-gradient-background.png differ diff --git a/Rendering/Core/Testing/Cxx/TestAreaPickerMultiblock.cxx b/Rendering/Core/Testing/Cxx/TestAreaPickerMultiblock.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3caf9b927ac306dfb5d479fa100d4423a11835b6 --- /dev/null +++ b/Rendering/Core/Testing/Cxx/TestAreaPickerMultiblock.cxx @@ -0,0 +1,167 @@ +/*========================================================================= + + Program: Visualization Toolkit + Module: TestAreaPickerMultiblock.cxx + + Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen + All rights reserved. + See Copyright.txt or http://www.kitware.com/Copyright.htm for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notice for more information. + +=========================================================================*/ +// This tests vtkHardwareSelector, vtkExtractSelectedFrustum, +// vtkRenderedAreaPicker, and vtkInteractorStyleRubberBandPick. +// +// The command line arguments are: +// -I => run in interactive mode; unless this is used, the program will +// not allow interaction and exit + +#include "vtkAbstractArray.h" +#include "vtkBoundingBox.h" +#include "vtkCompositeDataSet.h" +#include "vtkDataSetAttributes.h" +#include "vtkInformation.h" +#include "vtkTestUtilities.h" + +#include "vtkActor.h" +#include "vtkCallbackCommand.h" +#include "vtkCamera.h" +#include "vtkCompositePolyDataMapper.h" +#include "vtkDataSetReader.h" +#include "vtkExtractSelectedFrustum.h" +#include "vtkExtractSelection.h" +#include "vtkHardwareSelector.h" +#include "vtkInteractorStyleRubberBandPick.h" +#include "vtkPolyDataMapper.h" +#include "vtkProperty.h" +#include "vtkRenderWindow.h" +#include "vtkRenderWindowInteractor.h" +#include "vtkRenderedAreaPicker.h" +#include "vtkRenderer.h" +#include "vtkSelection.h" +#include "vtkSelectionNode.h" +#include "vtkSmartPointer.h" +#include "vtkSphereSource.h" +#include "vtkXMLMultiBlockDataReader.h" + +static vtkSmartPointer renderer; + +static void EndPick(vtkObject* vtkNotUsed(caller), unsigned long vtkNotUsed(eventId), void*, void*) +{ + vtkNew sel; + sel->SetRenderer(renderer); + + double x0 = renderer->GetPickX1(); + double y0 = renderer->GetPickY1(); + double x1 = renderer->GetPickX2(); + double y1 = renderer->GetPickY2(); + + sel->SetArea( + static_cast(x0), static_cast(y0), static_cast(x1), static_cast(y1)); + vtkSmartPointer res; + res.TakeReference(sel->Select()); + if (!res) + { + std::cout << "Selection not supported." << endl; + return; + } + + std::cout << "x0 " << x0 << " y0 " << y0 << "\t"; + std::cout << "x1 " << x1 << " y1 " << y1 << endl; + + // res->Print(std::cout); + const auto numSelected = res->GetNumberOfNodes(); + for (unsigned int i = 0; i < numSelected; ++i) + { + auto node = res->GetNode(i); + auto properties = node->GetProperties(); + const auto compositeIdx = properties->Get(vtkSelectionNode::COMPOSITE_INDEX()); + auto prop = properties->Get(vtkSelectionNode::PROP()); + auto actor = vtkActor::SafeDownCast(prop); + auto cpdm = vtkCompositePolyDataMapper::SafeDownCast(actor->GetMapper()); + auto inputDataset = vtkCompositeDataSet::SafeDownCast(cpdm->GetInputDataObject(0, 0)); + vtkPolyData* polydata = vtkPolyData::SafeDownCast(inputDataset->GetDataSet(compositeIdx)); + const auto& numCells = polydata->GetNumberOfCells(); + const auto& numSelectedCells = + node->GetSelectionData()->GetArray("SelectedIds")->GetNumberOfValues(); + std::cout << "numCells: " << numCells << " numSelectedCells: " << numSelectedCells << std::endl; + double polyDataBounds[6]; + polydata->GetCellsBounds(polyDataBounds); + double selectionBoundsWindowCoordinates[6]; + double selectionBoundsModelCoordinates[6]; + vtkBoundingBox polyDataBBox(polyDataBounds); + vtkBoundingBox selectionBBox(selectionBoundsModelCoordinates); + if (selectionBBox.Contains(polyDataBBox)) + { + // accept this node with index i. + } + else + { + // remove this node from the result. + } + } + // vtkSelectionNode* cellids = res->GetNode(0); + // if (auto selectionList = cellids->GetSelectionList()) + // { + // selectionList->Print(std::cout); + // } +} + +int TestAreaPickerMultiblock(int argc, char* argv[]) +{ + // Standard rendering classes + renderer = vtkSmartPointer::New(); + vtkNew renWin; + renWin->AddRenderer(renderer); + vtkNew iren; + iren->SetRenderWindow(renWin); + + // set up the view + renderer->GetActiveCamera()->SetPosition(1.5, -0.75, 7); + renderer->GetActiveCamera()->SetFocalPoint(1.5, -0.75, 0); + renderer->GetActiveCamera()->SetViewUp(0, 1, 0); + renderer->SetBackground(0.0, 0.0, 0.0); + renWin->SetSize(300, 300); + + // use the rubber band pick interactor style + vtkRenderWindowInteractor* rwi = renWin->GetInteractor(); + vtkNew rbp; + rwi->SetInteractorStyle(rbp); + + vtkNew areaPicker; + rwi->SetPicker(areaPicker); + + //////////////////////////////////////////////////////////// + // Create a unstructured grid data source to test FrustumExtractor with. + vtkNew reader; + char* cfname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/mixed-mb.vtm"); + reader->SetFileName(cfname); + delete[] cfname; + + vtkNew mapper; + mapper->SetInputConnection(reader->GetOutputPort()); + + vtkNew actor; + actor->SetMapper(mapper); + renderer->AddActor(actor); + // pass pick events to the HardwareSelector + vtkNew cbc; + cbc->SetCallback(EndPick); + cbc->SetClientData(renderer); + rwi->AddObserver(vtkCommand::EndPickEvent, cbc); + + //////////////////////////////////////////////////////////// + + // run the test + + renWin->Render(); + iren->Start(); + + renderer = nullptr; + + // Cleanup + return 0; +} diff --git a/Rendering/Core/Testing/Cxx/TestGradientBackground.cxx b/Rendering/Core/Testing/Cxx/TestGradientBackground.cxx index de997cf1b33354cb3beff89a4b3be8141991290f..cc0dc66214dded9e8c07c7f117023c62b884eb09 100644 --- a/Rendering/Core/Testing/Cxx/TestGradientBackground.cxx +++ b/Rendering/Core/Testing/Cxx/TestGradientBackground.cxx @@ -8,28 +8,44 @@ #include "vtkRenderer.h" #include "vtkSmartPointer.h" #include "vtkTestUtilities.h" - -#define VTK_CREATE(type, name) vtkSmartPointer name = vtkSmartPointer::New() +#include "vtkViewport.h" int TestGradientBackground(int argc, char* argv[]) { - VTK_CREATE(vtkRenderWindow, win); - VTK_CREATE(vtkRenderWindowInteractor, iren); - VTK_CREATE(vtkRenderer, ren); - VTK_CREATE(vtkConeSource, cone); - VTK_CREATE(vtkPolyDataMapper, map); - VTK_CREATE(vtkActor, act); + vtkNew win; + vtkNew iren; + vtkNew renderers[4]; + vtkViewport::GradientModes modes[4] = { + vtkViewport::GradientModes::VTK_GRADIENT_HORIZONTAL, + vtkViewport::GradientModes::VTK_GRADIENT_VERTICAL, + vtkViewport::GradientModes::VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE, + vtkViewport::GradientModes::VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER, + }; + vtkNew cone; + vtkNew map; + vtkNew act; map->SetInputConnection(cone->GetOutputPort()); act->SetMapper(map); - ren->AddActor(act); - ren->GradientBackgroundOn(); - ren->SetBackground(0.8, 0.4, 0.1); - ren->SetBackground2(0.1, 0.4, 0.8); - win->AddRenderer(ren); + double xmins[4] = { 0.0, 0.5, 0.0, 0.0 }; + double ymins[4] = { 0.0, 0.0, 0.25, 0.5 }; + double xmaxs[4] = { 0.5, 1.0, 1.0, 1.0 }; + double ymaxs[4] = { 0.25, 0.25, 0.5, 1.0 }; + for (int i = 0; i < 4; ++i) + { + auto ren = renderers[i].Get(); + ren->AddActor(act); + ren->GradientBackgroundOn(); + ren->SetGradientMode(modes[i]); + ren->SetBackground(0.8, 0.4, 0.1); + ren->SetBackground2(0.1, 0.4, 0.8); + ren->SetViewport(xmins[i], ymins[i], xmaxs[i], ymaxs[i]); + win->AddRenderer(ren); + } win->SetInteractor(iren); win->Render(); iren->Initialize(); + iren->UpdateSize(640, 480); int retVal = vtkRegressionTestImage(win); if (retVal == vtkRegressionTester::DO_INTERACTOR) diff --git a/Rendering/Core/Testing/Data/Baseline/TestGradientBackground.png.sha512 b/Rendering/Core/Testing/Data/Baseline/TestGradientBackground.png.sha512 index d5660be7ccc30ac04480aa2ad15833c466d0ca4b..2ff326025e59b092c890b382c80197ada214f232 100644 --- a/Rendering/Core/Testing/Data/Baseline/TestGradientBackground.png.sha512 +++ b/Rendering/Core/Testing/Data/Baseline/TestGradientBackground.png.sha512 @@ -1 +1 @@ -4d54b024380ed6e72d0d1a2caebd6d720c4bf0f71347ff92bb077fec3870052d16bb9580182af355018289bb627a6b4d8854e0ee1302a1889eba73b44c170269 +3580b3a8d3ea1e9ab7716f6d670309dbf8ea700837e82cf557287e20f63cf82262bfa677603014a33ff50620dc2ff9d6519f65e02d7daa4298c3023d142ed940 diff --git a/Rendering/Core/vtkViewport.cxx b/Rendering/Core/vtkViewport.cxx index 481057692f46b69eac3ee1464a466dfcf56662f3..da583d12725cdff2e1f77e7af2aa7ab1a439af07 100644 --- a/Rendering/Core/vtkViewport.cxx +++ b/Rendering/Core/vtkViewport.cxx @@ -22,6 +22,7 @@ #include "vtkWindow.h" #include +#include //------------------------------------------------------------------------------ // Create a vtkViewport with a black background, a white ambient light, @@ -390,6 +391,24 @@ int vtkViewport::IsInViewport(int x, int y) return 0; } +namespace +{ +const char* gradModeEnum2str_data[] = { + // clang-format off + "VTK_GRADIENT_VERTICAL", // 0 + "VTK_GRADIENT_HORIZONTAL", // 1 + "VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE", // 2 + "VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER", // 3 + // clang-format on +}; +const char* gradModeEnum2Str(vtkViewport::GradientModes& mode) +{ + using ul_type = std::underlying_type::type; + static_assert(std::is_integral::value, "GradientModes is integral."); + return gradModeEnum2str_data[static_cast(mode)]; +} +} + //------------------------------------------------------------------------------ void vtkViewport::PrintSelf(ostream& os, vtkIndent indent) { @@ -408,6 +427,7 @@ void vtkViewport::PrintSelf(ostream& os, vtkIndent indent) os << indent << "BackgroundAlpha: " << this->BackgroundAlpha << "\n"; os << indent << "GradientBackground: " << (this->GradientBackground ? "On" : "Off") << "\n"; + os << indent << "GradientMode: " << gradModeEnum2Str(this->GradientMode) << "\n"; os << indent << "Viewport: (" << this->Viewport[0] << ", " << this->Viewport[1] << ", " << this->Viewport[2] << ", " << this->Viewport[3] << ")\n"; diff --git a/Rendering/Core/vtkViewport.h b/Rendering/Core/vtkViewport.h index d7c833768bd6829a4692703c9da2683a5e538995..c4a27f5592c813c34b5392f04fcc628d30d00528 100644 --- a/Rendering/Core/vtkViewport.h +++ b/Rendering/Core/vtkViewport.h @@ -131,6 +131,32 @@ public: vtkBooleanMacro(GradientBackground, bool); ///@} + enum class GradientModes : int + { + // Background color is used at the bottom, Background2 color is used at the top. + VTK_GRADIENT_VERTICAL, + // Background color on the left, Background2 color on the right. + VTK_GRADIENT_HORIZONTAL, + // Background color in the center, Background2 color on and beyond the ellipse edge. + // Ellipse touches all sides of the viewport. The ellipse is a circle for viewports with equal + // width and height. + VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE, + // Background color in the center, Background2 color on and beyond the ellipse edge. + // Ellipse touches all corners of the viewport. The ellipse is a circle for viewports with equal + // width and height. + VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER, + }; + + ///@{ + /** + * Specify the direction of the gradient background. + * All modes smoothly interpolate the color from `Background` to `Background2` + * @sa vtkViewport::GradientModes + */ + vtkSetEnumMacro(GradientMode, GradientModes); + vtkGetEnumMacro(GradientMode, GradientModes); + ///@} + ///@{ /** * Set the aspect ratio of the rendered image. This is computed @@ -451,6 +477,7 @@ protected: double PixelAspect[2]; double Center[2]; bool GradientBackground; + GradientModes GradientMode = GradientModes::VTK_GRADIENT_VERTICAL; double EnvironmentalBG[3]; double EnvironmentalBG2[3]; diff --git a/Rendering/OpenGL2/vtkOpenGLRenderer.cxx b/Rendering/OpenGL2/vtkOpenGLRenderer.cxx index 157f82174d4da4a6b575c40ce8b61591027599f3..21f947dd2810f9b8de08efcf400f81da5534df7d 100644 --- a/Rendering/OpenGL2/vtkOpenGLRenderer.cxx +++ b/Rendering/OpenGL2/vtkOpenGLRenderer.cxx @@ -31,7 +31,10 @@ PURPOSE. See the above copyright notice for more information. #include "vtkOpenGLCamera.h" #include "vtkOpenGLError.h" #include "vtkOpenGLFXAAFilter.h" +#include "vtkOpenGLQuadHelper.h" +#include "vtkOpenGLRenderUtilities.h" #include "vtkOpenGLRenderWindow.h" +#include "vtkOpenGLShaderCache.h" #include "vtkOpenGLState.h" #include "vtkOrderIndependentTranslucentPass.h" #include "vtkPBRIrradianceTexture.h" @@ -658,87 +661,103 @@ void vtkOpenGLRenderer::Clear() ostate->vtkglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); ostate->vtkglClear(clear_mask); - // If gradient background is turned on, draw it now. if (!this->Transparent() && (this->GradientBackground || this->TexturedBackground)) { - int size[2]; - size[0] = this->GetSize()[0]; - size[1] = this->GetSize()[1]; - - double tile_viewport[4]; - this->GetRenderWindow()->GetTileViewport(tile_viewport); - - vtkNew actor; - vtkNew mapper; - vtkNew polydata; - vtkNew points; - points->SetNumberOfPoints(4); - points->SetPoint(0, 0, 0, 0); - points->SetPoint(1, size[0], 0, 0); - points->SetPoint(2, size[0], size[1], 0); - points->SetPoint(3, 0, size[1], 0); - polydata->SetPoints(points); - - vtkNew tris; - tris->InsertNextCell(3); - tris->InsertCellPoint(0); - tris->InsertCellPoint(1); - tris->InsertCellPoint(2); - tris->InsertNextCell(3); - tris->InsertCellPoint(0); - tris->InsertCellPoint(2); - tris->InsertCellPoint(3); - polydata->SetPolys(tris); - - vtkNew prod; - prod->SetOutput(polydata); - - // Set some properties. - mapper->SetInputConnection(prod->GetOutputPort()); - actor->SetMapper(mapper); - - if (this->TexturedBackground && this->GetCurrentTexturedBackground()) + auto oglRenWin = vtkOpenGLRenderWindow::SafeDownCast(this->GetRenderWindow()); + auto texture = this->GetCurrentTexturedBackground(); + std::string fs = vtkOpenGLRenderUtilities::GetFullScreenQuadFragmentShaderTemplate(); + ostate->vtkglDisable(GL_DEPTH_TEST); + // Generate VS, FS code. + if (this->TexturedBackground) { - this->GetCurrentTexturedBackground()->InterpolateOn(); - actor->SetTexture(this->GetCurrentTexturedBackground()); - - vtkNew tcoords; - float tmp[2]; - tmp[0] = 0; - tmp[1] = 0; - tcoords->SetNumberOfComponents(2); - tcoords->SetNumberOfTuples(4); - tcoords->SetTuple(0, tmp); - tmp[0] = 1.0; - tcoords->SetTuple(1, tmp); - tmp[1] = 1.0; - tcoords->SetTuple(2, tmp); - tmp[0] = 0.0; - tcoords->SetTuple(3, tmp); - polydata->GetPointData()->SetTCoords(tcoords); + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Decl", + "uniform sampler2D backgroundImage;\n" + "//VTK::FSQ::Decl"); + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " gl_FragData[0] = vec4(texture(backgroundImage, texCoord).rgb, 1.0);\n" + "//VTK::FSQ::Impl"); } - else // gradient + else // GradientBackground { - vtkNew colors; - float tmp[4]; - tmp[0] = this->Background[0] * 255; - tmp[1] = this->Background[1] * 255; - tmp[2] = this->Background[2] * 255; - tmp[3] = 255; - colors->SetNumberOfComponents(4); - colors->SetNumberOfTuples(4); - colors->SetTuple(0, tmp); - colors->SetTuple(1, tmp); - tmp[0] = this->Background2[0] * 255; - tmp[1] = this->Background2[1] * 255; - tmp[2] = this->Background2[2] * 255; - colors->SetTuple(2, tmp); - colors->SetTuple(3, tmp); - polydata->GetPointData()->SetScalars(colors); + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Decl", + "uniform vec3 stopColors[2];\n" + "uniform vec2 screenSize;\n" + "//VTK::FSQ::Decl"); + switch (this->GradientMode) + { + case GradientModes::VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_SIDE: + { + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " // computes distance of texel from the center of an ellipse.\n" + " // i.e, all texels on the perimeter of the ellipse give value=1.0\n" + " float value = clamp(length(texCoord - vec2(0.5f, 0.5f)) * 2.0f, 0.0f, 1.0f);\n" + "//VTK::FSQ::Impl"); + break; + } + case GradientModes::VTK_GRADIENT_RADIAL_VIEWPORT_FARTHEST_CORNER: + { + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " // computes distance of texel from the center of an ellipse.\n" + " // i.e, all texels on the perimeter of the ellipse give value=1.0\n" + " float value = length(texCoord - vec2(0.5f, 0.5f)) * sqrt(2.0f);\n" + "//VTK::FSQ::Impl"); + break; + } + case GradientModes::VTK_GRADIENT_HORIZONTAL: + { + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " float value = texCoord.s;\n" + "//VTK::FSQ::Impl"); + break; + } + case GradientModes::VTK_GRADIENT_VERTICAL: + default: + { + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " float value = texCoord.t;\n" + "//VTK::FSQ::Impl"); + break; + } + } + vtkShaderProgram::Substitute(fs, "//VTK::FSQ::Impl", + " gl_FragData[0] = vec4(stopColors[0].xyz * (1.0 - value) + stopColors[1].xyz * " + "value, 1.0);"); } - ostate->vtkglDisable(GL_DEPTH_TEST); - actor->RenderOverlay(this); + // create vtkOpenGLQuadHelper. + if (!this->BackgroundRenderer) + { + this->BackgroundRenderer.reset( + new vtkOpenGLQuadHelper(oglRenWin, nullptr, fs.c_str(), nullptr, false)); + } + // prep shader program. + oglRenWin->GetShaderCache()->ReadyShaderProgram(this->BackgroundRenderer->Program); + // apply uniforms. + if (this->TexturedBackground) + { + // load the texture if needed. + texture->Render(this); + this->BackgroundRenderer->Program->SetUniformi("backgroundImage", texture->GetTextureUnit()); + } + else // GradientBackground + { + float stopColors[2][3] = {}; + + std::copy(this->Background, this->Background + 3, &stopColors[0][0]); + std::copy(this->Background2, this->Background2 + 3, &stopColors[1][0]); + int vp[4]; // llX, llY, width, height + this->GetTiledSizeAndOrigin(&vp[2], &vp[3], &vp[0], &vp[1]); + float screenSize[2] = { static_cast(vp[3]), static_cast(vp[4]) }; + this->BackgroundRenderer->Program->SetUniform3fv("stopColors", 2, stopColors); + this->BackgroundRenderer->Program->SetUniform1fv("screenSize", 2, screenSize); + } + // draw the background. + this->BackgroundRenderer->Render(); + // unload texture. + if (this->TexturedBackground) + { + texture->PostRender(this); + } } ostate->vtkglEnable(GL_DEPTH_TEST); diff --git a/Rendering/OpenGL2/vtkOpenGLRenderer.h b/Rendering/OpenGL2/vtkOpenGLRenderer.h index 6db48135bb956b34a2fe58c17fc09f5b48d40c1a..a6c1cd207ec492317e66a9ab2b3b00ce4d2a3b64 100644 --- a/Rendering/OpenGL2/vtkOpenGLRenderer.h +++ b/Rendering/OpenGL2/vtkOpenGLRenderer.h @@ -24,8 +24,11 @@ #define vtkOpenGLRenderer_h #include "vtkRenderer.h" + +#include "vtkOpenGLQuadHelper.h" // for ivar #include "vtkRenderingOpenGL2Module.h" // For export macro #include "vtkSmartPointer.h" // For vtkSmartPointer +#include // for unique_ptr #include // Ivars #include // STL Header @@ -242,6 +245,7 @@ protected: vtkPBRIrradianceTexture* EnvMapIrradiance; vtkPBRPrefilterTexture* EnvMapPrefiltered; vtkSmartPointer SphericalHarmonics; + std::unique_ptr BackgroundRenderer; bool UseSphericalHarmonics; private: