Sometimes,我们为了构建更加逼真的效果,就会用到纹理“贴”图,或叫纹理映射。

本文是一个对圆柱体进行纹理“贴”图的例子,把一张二维的图“贴”到圆柱体的表面。

VTK笔记——纹理“贴”图

圆柱体的创建可参考如何创建圆柱体

关键代码:

vtkSmartPointer<vtkTexture> texture =
	vtkSmartPointer<vtkTexture>::New();
texture->SetInputConnection(/*bmpReader*/jpegReader->GetOutputPort());
texture->InterpolateOn();

// map two-dimensional to three-dimensional, use cylinder
vtkSmartPointer<vtkTextureMapToCylinder> textureMap =
	vtkSmartPointer<vtkTextureMapToCylinder>::New();
textureMap->SetInputConnection(cylinderSource->GetOutputPort());

vtkSmartPointer<vtkTransformTextureCoords> transformTextureCoords =
	vtkSmartPointer<vtkTransformTextureCoords>::New();
transformTextureCoords->SetInputConnection(textureMap->GetOutputPort());
//transformTextureCoords->SetScale(1, 1, 0);

vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =
	vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(/*textureMap*/transformTextureCoords->GetOutputPort());

vtkSmartPointer<vtkActor> cylinderActor =
	vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
cylinderActor->SetTexture(texture);

效果图:

VTK笔记——纹理“贴”图

完整代码:

#include <vtkCylinderSource.h>
#include <vtkLineSource.h>
#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkTubeFilter.h>
#include <vtkBMPReader.h>
#include <vtkJPEGReader.h>
#include <vtkTexture.h>
#include <vtkTextureMapToCylinder.h>
#include <vtkTransformTextureCoords.h>

int main(int, char *[])
{
	// Create a Cylinder
	vtkSmartPointer<vtkCylinderSource> cylinderSource = 
		vtkSmartPointer<vtkCylinderSource>::New();
	cylinderSource->SetHeight(10.0);
	cylinderSource->SetCenter(0.0, 0.0, 0.0);
	cylinderSource->SetRadius(2.0);
	cylinderSource->SetResolution(50);

	// Load a bmp file
	vtkSmartPointer<vtkBMPReader> bmpReader =
		vtkSmartPointer<vtkBMPReader>::New();
	bmpReader->SetFileName("girl.bmp");

	// or Load a jpeg file
	vtkSmartPointer<vtkJPEGReader> jpegReader =
		vtkSmartPointer<vtkJPEGReader>::New();
	jpegReader->SetFileName("girl.jpg");

	vtkSmartPointer<vtkTexture> texture =
		vtkSmartPointer<vtkTexture>::New();
	texture->SetInputConnection(/*bmpReader*/jpegReader->GetOutputPort());
	texture->InterpolateOn();

	// map two-dimensional to three-dimensional, use cylinder
	vtkSmartPointer<vtkTextureMapToCylinder> textureMap =
		vtkSmartPointer<vtkTextureMapToCylinder>::New();
	textureMap->SetInputConnection(cylinderSource->GetOutputPort());

	vtkSmartPointer<vtkTransformTextureCoords> transformTextureCoords =
		vtkSmartPointer<vtkTransformTextureCoords>::New();
	transformTextureCoords->SetInputConnection(textureMap->GetOutputPort());
	//transformTextureCoords->SetScale(1, 1, 0);

	vtkSmartPointer<vtkPolyDataMapper> cylinderMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	cylinderMapper->SetInputConnection(/*textureMap*/transformTextureCoords->GetOutputPort());

	vtkSmartPointer<vtkActor> cylinderActor =
		vtkSmartPointer<vtkActor>::New();
	cylinderActor->SetMapper(cylinderMapper);
	cylinderActor->SetTexture(texture);

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->SetSize(600, 600);
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderer->AddActor(cylinderActor);

	renderWindow->Render();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

FYI:

VTK纹理映射原理介绍

VTK纹理映射之vtkTransformTextureCoods

VTK笔记——纹理“贴”图

相关文章: