スポンサーリンク

VTKでEDLシェーダを使用してみる

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);
    }

}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: