スポンサーリンク

VTKでカスタムシェーダを使用し、SelectColorArrayで指定した色情報を編集する

カスタム頂点シェーダでSelectColorArrayで指定した色を編集する。フラグメントシェーダ側での編集はやや難しいので次回。

SelectColorArrayで選択した色情報は、頂点シェーダ側ではvertexColorVSOutput に格納されている。コードはこの色から赤を0に設定している。頂点シェーダの実装以外はデフォルトのものを使う。

#include <iostream>

//VTK_MODULE_INITに必要
#include <vtkAutoInit.h>


#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

//円筒とその表示に必要
#include <vtkCylinderSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkPointData.h>


// shader
#include <vtkShaderProperty.h>
#include <vtkOpenGLPolyDataMapper.h>
#include <vtkUniforms.h>


#pragma comment(lib,"opengl32.lib")
#pragma comment(lib,"psapi.lib")
#pragma comment(lib,"dbghelp.lib")
#pragma comment(lib,"ws2_32.lib")


//必須
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);


// データに色情報を追加
void SetColor(vtkSmartPointer<vtkPolyData> data, const char* scalarname, std::array<unsigned char, 3> rgb) {

  size_t PointNum = data->GetNumberOfPoints();

  vtkSmartPointer<vtkUnsignedCharArray> colorsNew = vtkSmartPointer<vtkUnsignedCharArray>::New();
  colorsNew->SetNumberOfComponents(3);
  colorsNew->SetName(scalarname);
  for (int i = 0; i < PointNum; i++) {

    // ランダムな色を作成
    double r = vtkMath::Random(0.0, 255.0);
    double g = vtkMath::Random(0.0, 255.0);
    double b = vtkMath::Random(0.0, 255.0);

    colorsNew->InsertNextTuple3(r,g,b);
  }
  data->GetPointData()->AddArray(colorsNew);

}

void setShader(vtkSmartPointer<vtkActor> actor) {
  auto shaderProperty = actor->GetShaderProperty();

  shaderProperty->AddVertexShaderReplacement(
    "//VTK::Color::Impl",
    true,
    R"(
//VTK::Color::Impl

// 頂点カラーから赤を除去
vertexColorVSOutput = vec4(
  0.0,
  vertexColorVSOutput.g,
  vertexColorVSOutput.b,
  1.0
);
  )",
    false);

}

int
main(int /*argc*/, char** /*argv*/) { // シリンダー作成 vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New(); cylinder->SetResolution(50); cylinder->SetHeight(3.0); cylinder->SetRadius(1.0); cylinder->Update(); // actorを作成 vtkSmartPointer<vtkPolyData> points = cylinder->GetOutput(); SetColor(points, "ColorsRed", { 255,0,0 }); SetColor(points, "ColorsBlue", { 0,0,255 }); // actorを作成 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(points); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); ////////////////////////////////////// ////////////////////////////////////// ////////////////////////////////////// // 使用する色をAddArrayで指定したスカラー値を使用するように設定 mapper->SetScalarVisibility(1); // スカラー値を使用して色をつける設定 mapper->SetScalarModeToUsePointFieldData(); // スカラー値はポイントデータに設定されているものを使用 mapper->SetColorModeToDefault(); // カラーモードをデフォルトに設定 // 使用する色の選択 mapper->SelectColorArray("ColorsBlue"); mapper->Modified();// マッパーを更新 ////////////////////////////////////// ////////////////////////////////////// ////////////////////////////////////// // カスタムシェーダを設定 setShader(actor); mapper->Modified();// マッパーを更新 ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->ResetCamera(); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); ////////////////////////////////////// auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); interactor->Start(); //イベントループへ入る return 0; }
本来の色
頂点シェーダで編集した色

コメントを残す

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

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


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