SphereMap
Repository source: SphereMap
Question
If you have a question about this example, please use the VTK Discourse Forum
Code¶
SphereMap.cxx
/*=========================================================================
Program: Visualization Toolkit
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.
=========================================================================*/
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkJPEGReader.h>
#include <vtkLight.h>
#include <vtkNew.h>
#include <vtkOpenGLPolyDataMapper.h>
#include <vtkPolyDataNormals.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSkybox.h>
#include <vtkTexture.h>
#include <vtkVersion.h>
#include <vtkXMLPolyDataReader.h>
#if VTK_VERSION_NUMBER >= 89000000000ULL
#define USE_SHADER_PROPERTIES 1
#include <vtkShaderProperty.h>
#endif
//----------------------------------------------------------------------------
int main(int argc, char* argv[])
{
if (argc < 3)
{
std::cout << "Usage: " << argv[0] << " file.vtp wintersun.jpg" << std::endl;
return EXIT_SUCCESS;
}
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(640, 480);
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> interactor;
interactor->SetRenderWindow(renderWindow);
vtkNew<vtkLight> light;
light->SetLightTypeToSceneLight();
light->SetPosition(1.0, 7.0, 1.0);
renderer->AddLight(light);
vtkNew<vtkXMLPolyDataReader> reader;
reader->SetFileName(argv[1]);
vtkNew<vtkPolyDataNormals> norms;
norms->SetInputConnection(reader->GetOutputPort());
vtkNew<vtkTexture> texture;
texture->InterpolateOn();
// mipmapping works on many systems but is not
// core 3.2 for cube maps. VTK will silently
// ignore it if it is not supported. We commented it
// out here to make valid images easier
// texture->MipmapOn();
vtkNew<vtkJPEGReader> imgReader;
imgReader->SetFileName(argv[2]);
texture->SetInputConnection(imgReader->GetOutputPort());
vtkNew<vtkOpenGLPolyDataMapper> mapper;
mapper->SetInputConnection(norms->GetOutputPort());
vtkNew<vtkActor> actor;
actor->SetPosition(0, 0, 0);
actor->SetScale(6.0, 6.0, 6.0);
actor->GetProperty()->SetSpecular(0.8);
actor->GetProperty()->SetSpecularPower(20);
actor->GetProperty()->SetDiffuse(0.1);
actor->GetProperty()->SetAmbient(0.1);
actor->GetProperty()->SetDiffuseColor(1.0, 0.0, 0.4);
actor->GetProperty()->SetAmbientColor(0.4, 0.0, 1.0);
renderer->AddActor(actor);
actor->SetTexture(texture);
actor->SetMapper(mapper);
#if USE_SHADER_PROPERTIES
vtkShaderProperty* sp = actor->GetShaderProperty();
sp->AddVertexShaderReplacement(
"//VTK::PositionVC::Dec", // replace
true, // before the standard replacements
"//VTK::PositionVC::Dec\n" // we still want the default
"out vec3 TexCoords;\n",
false // only do it once
);
#else
mapper->AddShaderReplacement(
vtkShader::Vertex,
"//VTK::PositionVC::Dec", // replace
true, // before the standard replacements
"//VTK::PositionVC::Dec\n" // we still want the default
"out vec3 TexCoords;\n",
false // only do it once
);
#endif
#if USE_SHADER_PROPERTIES
sp->AddVertexShaderReplacement(
"//VTK::PositionVC::Impl", // replace
true, // before the standard replacements
"//VTK::PositionVC::Impl\n" // we still want the default
"vec3 camPos = -MCVCMatrix[3].xyz * mat3(MCVCMatrix);\n"
"TexCoords.xyz = reflect(vertexMC.xyz - camPos, normalize(normalMC));\n",
false // only do it once
);
#else
mapper->AddShaderReplacement(
vtkShader::Vertex,
"//VTK::PositionVC::Impl", // replace
true, // before the standard replacements
"//VTK::PositionVC::Impl\n" // we still want the default
"vec3 camPos = -MCVCMatrix[3].xyz * mat3(MCVCMatrix);\n"
"TexCoords.xyz = reflect(vertexMC.xyz - camPos, normalize(normalMC));\n",
false // only do it once
);
#endif
#if USE_SHADER_PROPERTIES
sp->AddFragmentShaderReplacement(
"//VTK::Light::Dec", // replace
true, // before the standard replacements
"//VTK::Light::Dec\n" // we still want the default
"in vec3 TexCoords;\n",
false // only do it once
);
#else
mapper->AddShaderReplacement(
vtkShader::Fragment,
"//VTK::Light::Dec", // replace
true, // before the standard replacements
"//VTK::Light::Dec\n" // we still want the default
"in vec3 TexCoords;\n",
false // only do it once
);
#endif
#if USE_SHADER_PROPERTIES
sp->AddFragmentShaderReplacement(
"//VTK::Light::Impl", // replace
true, // before the standard replacements
"//VTK::Light::Impl\n"
" float phix = length(vec2(TexCoords.x, TexCoords.z));\n"
" vec3 skyColor = texture(actortexture, vec2(0.5*atan(TexCoords.z, "
"TexCoords.x)/3.1415927 + 0.5, atan(TexCoords.y,phix)/3.1415927 + "
"0.5)).xyz;\n"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular + "
"specularColor*skyColor, opacity);\n", // we still want the default
false // only do it once
);
#else
mapper->AddShaderReplacement(
vtkShader::Fragment,
"//VTK::Light::Impl", // replace
true, // before the standard replacements
"//VTK::Light::Impl\n"
" float phix = length(vec2(TexCoords.x, TexCoords.z));\n"
" vec3 skyColor = texture(actortexture, vec2(0.5*atan(TexCoords.z, "
"TexCoords.x)/3.1415927 + 0.5, atan(TexCoords.y,phix)/3.1415927 + "
"0.5)).xyz;\n"
" gl_FragData[0] = vec4(ambientColor + diffuse + specular + "
"specularColor*skyColor, opacity);\n", // we still want the default
false // only do it once
);
#endif
vtkNew<vtkSkybox> world;
world->SetProjectionToSphere();
world->SetTexture(texture);
renderer->AddActor(world);
renderer->GetActiveCamera()->SetPosition(0.0, 0.55, 2.0);
renderer->GetActiveCamera()->SetFocalPoint(0.0, 0.55, 0.0);
renderer->GetActiveCamera()->SetViewAngle(60.0);
renderer->ResetCamera();
renderer->GetActiveCamera()->Zoom(1.1);
renderer->GetActiveCamera()->Azimuth(0);
renderer->GetActiveCamera()->Elevation(5);
renderer->ResetCameraClippingRange();
renderWindow->Render();
renderWindow->SetWindowName("SphereMap");
renderWindow->Render();
vtkNew<vtkInteractorStyleTrackballCamera> style;
renderWindow->GetInteractor()->SetInteractorStyle(style);
interactor->Start();
return EXIT_SUCCESS;
}
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.12 FATAL_ERROR)
project(SphereMap)
find_package(VTK COMPONENTS
CommonCore
FiltersCore
IOImage
IOXML
InteractionStyle
RenderingContextOpenGL2
RenderingCore
RenderingFreeType
RenderingGL2PSOpenGL2
RenderingOpenGL2
)
if (NOT VTK_FOUND)
message(FATAL_ERROR "SphereMap: Unable to find the VTK build folder.")
endif()
# Prevent a "command line is too long" failure in Windows.
set(CMAKE_NINJA_FORCE_RESPONSE_FILE "ON" CACHE BOOL "Force Ninja to use response files.")
add_executable(SphereMap MACOSX_BUNDLE SphereMap.cxx )
target_link_libraries(SphereMap PRIVATE ${VTK_LIBRARIES}
)
# vtk_module_autoinit is needed
vtk_module_autoinit(
TARGETS SphereMap
MODULES ${VTK_LIBRARIES}
)
Download and Build SphereMap¶
Click here to download SphereMap and its CMakeLists.txt file. Once the tarball SphereMap.tar has been downloaded and extracted,
cd SphereMap/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./SphereMap
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.