#pragma once
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkTexture.h>
#include <vtkImageData.h>
//! @brief 指定サイズの矩形を作成
//! @note テクスチャ座標設定済み
//! @param width 幅(ピクセル)
//! @param height 高さ(ピクセル)
//! @return 矩形ポリゴンのvtkPolyData
vtkSmartPointer<vtkPolyData>
MakeScreenAlignedQuad(float width, float height);
//! @brief 矩形ポリゴンのサイズを変更
//! @param quad 矩形ポリゴンのvtkPolyData
//! @param newWidth 新しい幅(ピクセル)
//! @param newHeight 新しい高さ(ピクセル)
//! @return なし
void ResizeQuad(vtkPolyData* quad, float newWidth, float newHeight);
//! @brief vtkTextureにvtkImageDataをセット
//! @param texture テクスチャオブジェクト
//! @param image 画像データオブジェクト
//! @return なし
void SetTextureImage(vtkTexture* texture, vtkImageData* image);
//! @brief 画像配列から vtkImageData を生成
//! @param pixels 画像ピクセル配列(RGBAまたはRGB)
//! @param width 画像幅(ピクセル)
//! @param height 画像高さ(ピクセル)
//! @param numComponents ピクセルあたりの成分数(3または4)
vtkSmartPointer<vtkImageData>
MakeImageDataFromBuffer(
const unsigned char* pixels,
int width, int height,
int numComponents
);
#include "MyTexture.hpp"
#include <vtkFloatArray.h>
#include <vtkPointData.h>
vtkSmartPointer<vtkPolyData>
MakeScreenAlignedQuad(float width, float height)
{
vtkNew<vtkPoints> pts;
pts->SetNumberOfPoints(4);
pts->SetPoint(0, 0.0, 0.0, 0.0);
pts->SetPoint(1, width, 0.0, 0.0);
pts->SetPoint(2, width, height, 0.0);
pts->SetPoint(3, 0.0, height, 0.0);
vtkNew<vtkCellArray> polys;
vtkIdType ids[4] = { 0,1,2,3 };
polys->InsertNextCell(4, ids);
vtkNew<vtkFloatArray> tcoords;
tcoords->SetName("TCoords");
tcoords->SetNumberOfComponents(2);
tcoords->InsertNextTuple2(0.f, 0.f); // 左下
tcoords->InsertNextTuple2(1.f, 0.f); // 右下
tcoords->InsertNextTuple2(1.f, 1.f); // 右上
tcoords->InsertNextTuple2(0.f, 1.f); // 左上
vtkNew<vtkPolyData> pd;
pd->SetPoints(pts);
pd->SetPolys(polys);
pd->GetPointData()->SetTCoords(tcoords);
return pd;
}
vtkSmartPointer<vtkImageData>
MakeImageDataFromBuffer(
const unsigned char* pixels,
int width,
int height,
int numComponents
)
{
vtkNew<vtkImageData> img;
img->SetDimensions(width, height, 1);
img->AllocateScalars(VTK_UNSIGNED_CHAR, numComponents);
const int stride = numComponents;
auto* dst = static_cast<unsigned char*>(img->GetScalarPointer());
std::memcpy(dst, pixels, static_cast<size_t>(width) * height * stride);
return img;
}
void ResizeQuad(vtkPolyData* quad, float newWidth, float newHeight)
{
auto* pts = quad->GetPoints();
pts->SetPoint(0, 0.0, 0.0, 0.0);
pts->SetPoint(1, newWidth, 0.0, 0.0);
pts->SetPoint(2, newWidth, newHeight, 0.0);
pts->SetPoint(3, 0.0, newHeight, 0.0);
pts->Modified();
quad->Modified();
}
void SetTextureImage(vtkTexture* texture, vtkImageData* image)
{
texture->SetInputData(image);
texture->InterpolateOn(); // バイリニア補間
texture->RepeatOff(); // 画像外は伸ばさない
texture->EdgeClampOn();
texture->Modified();
}
// テクスチャオブジェクト作成 ///////////////
vtkNew<vtkTexture> texture;
// 画像データ作成 ///////////////////////////
std::vector<unsigned char> pixels = MakeCheckerRGBA(256, 256, 32);
// 画像データをvtkImageDataに変換 ///////////
vtkSmartPointer<vtkImageData> imgdata = MakeImageDataFromBuffer(pixels.data(), 256, 256, 4);
// テクスチャに画像データをセット ///////////
SetTextureImage(texture, imgdata);
// ポリゴン作成 /////////////////////////////
auto poly_quad = MakeScreenAlignedQuad(100, 200);
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputData(poly_quad);
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
actor->SetTexture(texture);
auto renderer = vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);