1.纹理映射
纹理映射是将纹理空间中的纹理像素映射到屏幕空间中的像素过程。纹理生成过程实质上是将所定义的纹理映射为某种三维物体表面的属性,并参与后续的光照计算。在三维图形中,纹理映射应用的十分广泛,尤其是描述具有真实感的物体。
实现纹理映射主要是建立纹理空间与模型空间、模型空间与屏幕空间之间的映射关系,如下图所示
其 中纹理空间可以定义为u-v空间,每个坐标轴的范围为(0,1)。对于一个纹理图像,其左下角的坐标为(0,0),右上角(1,1)。而对于简单的参数模型,可以方便地建立模型与纹理空间的映射关系,例如球面、圆柱面。
根据图形学三维空间变换容易实现模型空间到屏幕空间的变换,因此最终显示在计算机屏幕的图像及时纹理映射后的结果。
面对无参数曲面的纹理映射技术,通常需要将纹理空间的映射分解为两个简单映射,需要引入一个包围景物的中介映射媒介。步骤如下:现将二维纹理空间映射为一个简单的三维物体表面(球面圆柱面等);然后将该中介物体表面的纹理映射到模型表面(例如,一模型表面的法线与中建模型的角点作为映射点),这就可以实现由纹理空间到模型空间映射。
2.VTK中实现纹理映射
VTK中定义了多个类实现纹理空间到模型空间的映射
- vtkTextureMapToPlane:通过一个平面建立纹理空间到模型空间的映射关系
- vtkTextureToSphere:通过球面建立映射关系;
- vtkTextureMapToCylinder:通过圆柱面建立映射关系;
- vtkTexture:实现加载纹理;
- vtkTransformTextureCoords:实现纹理坐标的平移和缩放。
3.使用vtkTextureMapToCylinder建立纹理映射实例
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSmartPointer.h>
#include <vtkBMPReader.h> //读入纹理图像
#include <vtkTexture.h> //加载纹理图像
#include <vtkXMLPolyDataReader.h>//加载模型数据
#include <vtkTextureMapToCylinder.h>//采用圆柱作为中介
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOrientationMarkerWidget.h>
#include <vtkAxesActor.h>
#include <vtkOrientationMarkerWidget.h>
int main(int argc, char* argv[])
{
vtkSmartPointer<vtkBMPReader> texReader =
vtkSmartPointer<vtkBMPReader>::New();
texReader->SetFileName("data/Lena.bmp");
vtkSmartPointer<vtkTexture> texture =
vtkSmartPointer<vtkTexture>::New();
texture->SetInputConnection(texReader->GetOutputPort());
vtkSmartPointer<vtkXMLPolyDataReader> modelReader =
vtkSmartPointer<vtkXMLPolyDataReader>::New();
modelReader->SetFileName("data/cow.vtp");
//纹理映射
vtkSmartPointer<vtkTextureMapToCylinder> texturemap =
vtkSmartPointer<vtkTextureMapToCylinder>::New();
texturemap->SetInputConnection(modelReader->GetOutputPort());
/*******************************************************************/
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(texturemap->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
actor->SetTexture(texture); //加载纹理图
//设定坐标系
vtkSmartPointer<vtkAxesActor> axes =
vtkSmartPointer<vtkAxesActor>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
renderer->SetBackground(0, 0, 0);
vtkSmartPointer<vtkRenderWindow> rw =
vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(renderer);
rw->SetSize(640, 480);
rw->SetWindowName("TextureMap");
vtkSmartPointer<vtkRenderWindowInteractor> rwi =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
rwi->SetRenderWindow(rw);
/**********************************************************/
vtkSmartPointer<vtkOrientationMarkerWidget> widget =
vtkSmartPointer<vtkOrientationMarkerWidget>::New();
widget->SetOutlineColor(1, 1, 1);
widget->SetViewport(0, 0, 0.3, 0.3);
widget->SetOrientationMarker(axes);
widget->SetInteractor(rwi);
widget->SetEnabled(1);
widget->InteractiveOn();
/**********************************************************/
renderer->ResetCamera();
rw->Render();
rwi->Start();
return 0;
}