vtkEDLShadingを使うと簡単にEDLシェーダを使用できる。
#pragma warning(disable:4996) //VTK_MODULE_INITに必要 #include <vtkAutoInit.h> //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle); //////////////////////////////////////////////////////////// #include <vtkOpenGLRenderer.h> #include <vtkOpenGLRenderWindow.h> //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// #include <vtkRenderStepsPass.h> #include <vtkEDLShading.h> //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// #include <vtkSmartPointer.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// #include <vtkConeSource.h> #include <vtkCubeSource.h> #include <vtkPlaneSource.h> #include <vtkProperty.h> #include <vtkSphere.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> //////////////////////////////////////////////////////////// //#include <vtkCamera.h> #pragma comment(lib, "ws2_32.lib") #pragma comment(lib, "Psapi.lib") #pragma comment(lib, "Dbghelp.lib") #pragma comment(lib,"opengl32.lib") //////////////////////////////////////////////////////////// void SetTestData(vtkSmartPointer<vtkOpenGLRenderer> renderer); //////////////////////////////////////////////////////////// int main() { auto renderer = vtkSmartPointer<vtkOpenGLRenderer>::New(); auto window = vtkSmartPointer<vtkRenderWindow>::New(); window->AddRenderer(renderer); SetTestData(renderer); // 表示データの設定 renderer->ResetCamera();
// EDL シェーダの設定 auto basicPasses = vtkSmartPointer<vtkRenderStepsPass>::New(); auto edl = vtkSmartPointer<vtkEDLShading>::New(); edl->SetDelegatePass(basicPasses); // renderer に EDL を適用 renderer->SetPass(edl); // マルチサンプリングオフ。EDL とは相性が悪い。深度バッファの計算が正しく行われないため。 window->SetMultiSamples(0);
// ウィンドウサイズ window->SetSize(800, 600); auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); window->SetInteractor(interactor); interactor->Initialize(); window->Render(); interactor->Start(); return 0; } void SetTestData(vtkSmartPointer<vtkOpenGLRenderer> renderer) { { auto planeSource = vtkSmartPointer<vtkPlaneSource>::New(); planeSource->SetOrigin(-5.0, 0.0, -5.0); planeSource->SetPoint1(5.0, 0.0, -5.0); planeSource->SetPoint2(-5.0, 0.0, 5.0); planeSource->SetResolution(50, 50); planeSource->Update(); planeSource->SetCenter(0.0, -5.0, 0.0); auto planeMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); planeMapper->SetInputConnection(planeSource->GetOutputPort()); auto planeActor = vtkSmartPointer<vtkActor>::New(); planeActor->SetMapper(planeMapper); planeActor->GetProperty()->SetColor(0.8, 0.8, 0.8); // 薄いグレー planeActor->GetProperty()->SetSpecular(0.1); planeActor->GetProperty()->SetDiffuse(0.9); renderer->AddActor(planeActor); } for (int i = 0; i < 10; i++) { // x,y,zを乱数で生成 double x, y, z; x = (-0.5 + rand() / double(RAND_MAX)) * 10; y = (-0.5 + rand() / double(RAND_MAX)) * 10; z = (-0.5 + rand() / double(RAND_MAX)) * 10; auto sphereSource = vtkSmartPointer<vtkSphereSource>::New(); sphereSource->SetCenter(-2.0, 1.0, 0.0); // 床から1.0上に sphereSource->SetRadius(1.0); sphereSource->SetThetaResolution(30); sphereSource->SetPhiResolution(30); sphereSource->Update(); sphereSource->SetCenter(x, y, z); auto sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); sphereMapper->SetInputConnection(sphereSource->GetOutputPort()); auto sphereActor = vtkSmartPointer<vtkActor>::New(); sphereActor->SetMapper(sphereMapper); sphereActor->GetProperty()->SetColor(1.0, 0.2, 0.2); // 赤っぽい色 renderer->AddActor(sphereActor); } for (int i = 0; i < 10; i++) { // x,y,zを乱数で生成 double x, y, z; x = (-0.5 + rand() / double(RAND_MAX)) * 10; y = (-0.5 + rand() / double(RAND_MAX)) * 10; z = (-0.5 + rand() / double(RAND_MAX)) * 10; auto coneSource = vtkSmartPointer<vtkConeSource>::New(); coneSource->SetCenter(2.0, 0.0, 0.0); coneSource->SetRadius(1.0); coneSource->SetHeight(2.5); coneSource->SetDirection(0.0, 1.0, 0.0); // Y軸方向に伸ばす coneSource->SetResolution(30); coneSource->Update(); coneSource->SetCenter(x, y, z); auto coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); coneMapper->SetInputConnection(coneSource->GetOutputPort()); auto coneActor = vtkSmartPointer<vtkActor>::New(); coneActor->SetMapper(coneMapper); coneActor->GetProperty()->SetColor(0.2, 0.4, 1.0); // 青系 renderer->AddActor(coneActor); } for (int i = 0; i < 10; i++) { // x,y,zを乱数で生成 double x, y, z; x = (-0.5 + rand() / double(RAND_MAX)) * 10; y = (-0.5 + rand() / double(RAND_MAX)) * 10; z = (-0.5 + rand() / double(RAND_MAX)) * 10; auto cubeSource = vtkSmartPointer<vtkCubeSource>::New(); cubeSource->SetCenter(0.0, 1.0, 2.0); cubeSource->SetXLength(1.5); cubeSource->SetYLength(1.5); cubeSource->SetZLength(1.5); cubeSource->Update(); cubeSource->SetCenter(x, y, z); auto cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); cubeMapper->SetInputConnection(cubeSource->GetOutputPort()); auto cubeActor = vtkSmartPointer<vtkActor>::New(); cubeActor->SetMapper(cubeMapper); cubeActor->GetProperty()->SetColor(0.2, 1.0, 0.2); // 緑系 renderer->AddActor(cubeActor); } }