窗口共用:
窗口共用,实际上就是一个窗口中放入很多个Render,他们使用一个窗口,使用一个交互器,在之前的代码片段中,已有对这方面的简介。
窗口共用有很多地方,例如:“刺激战场”游戏里面一个组队时,可以分别对每个人物模型进行旋转,就可以通过多个Render来实现,当然实际上它并不一定这样实现的。下面代码中,创建四个模型,地球、圆柱、球体、立方体,他们位于不同的Render中。
int main(int argc, char* argv[])
{
// 地球,立方体,圆柱,球体
vtkSmartPointer<vtkEarthSource> Earth = vtkSmartPointer<vtkEarthSource>::New();
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
// 设置
Earth->SetRadius(5);
Earth->SetOnRatio(6); // 精度(0~16)0最精确
cube->SetXLength(6);
cube->SetYLength(5);
cube->SetZLength(3); // 设置立方体的xyz三边长度
cylinder->SetHeight(6);
cylinder->SetRadius(3);
sphere->SetRadius(5);
sphere->SetThetaResolution(20); // 设置球体一个方向的精度(实际对应经度方向)(这表示20条经度线)
sphere->SetPhiResolution(20); // 设置纬度方向的精度(这表示有20条纬度线)
// 四个绘制器
vtkSmartPointer<vtkPolyDataMapper> EarthMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
EarthMapper->SetInputConnection(Earth->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> cubeMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cubeMapper->SetInputConnection(cube->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> cylinderMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
cylinderMapper->SetInputConnection(cylinder->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
sphereMapper->SetInputConnection(sphere->GetOutputPort());
// 四个演员
vtkSmartPointer<vtkActor> EarthActor = vtkSmartPointer<vtkActor>::New();
EarthActor->SetMapper(EarthMapper);
vtkSmartPointer<vtkActor> cubeActor = vtkSmartPointer<vtkActor>::New();
cubeActor->SetMapper(cubeMapper);
vtkSmartPointer<vtkActor> cylinderActor = vtkSmartPointer<vtkActor>::New();
cylinderActor->SetMapper(cylinderMapper);
vtkSmartPointer<vtkActor> sphereActor = vtkSmartPointer<vtkActor>::New();
sphereActor->SetMapper(sphereMapper);
// 四个渲染器。分别位于mainWindow的四个方向
vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
renderer1->AddActor(EarthActor);
renderer1->SetBackground(1.0, 0.0, 0.0);
renderer1->SetViewport(0.0, 0.0, 0.5, 0.5); // 左下角为地球渲染器
vtkSmartPointer<vtkRenderer> renderer2 = vtkSmartPointer<vtkRenderer>::New();
renderer2->AddActor(cubeActor);
renderer2->SetBackground(0.0, 1.0, 0.0);
renderer2->SetViewport(0.5, 0.0, 1.0, 0.5); // 右下角为立方体
vtkSmartPointer<vtkRenderer> renderer3 = vtkSmartPointer<vtkRenderer>::New();
renderer3->AddActor(cylinderActor);
renderer3->SetBackground(0.0, 0.0, 1.0);
renderer3->SetViewport(0.0, 0.5, 0.5, 1.0); // 左上角 圆柱
vtkSmartPointer<vtkRenderer> renderer4 = vtkSmartPointer<vtkRenderer>::New();
renderer4->AddActor(sphereActor);
renderer4->SetBackground(1.0, 1.0, 0.0);
renderer4->SetViewport(0.5, 0.5, 1.0, 1.0); // 右上角球体
// mainWindow
vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer(renderer1);
renWin->AddRenderer(renderer2);
renWin->AddRenderer(renderer3);
renWin->AddRenderer(renderer4);
renWin->SetSize(640, 480);
renWin->Render();
renWin->SetWindowName("ViewPort");
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleTrackballCamera> interatorStyle = vtkInteractorStyleTrackballCamera::New();
interactor->SetInteractorStyle(interatorStyle);
interactor->SetRenderWindow(renWin);
renWin->Render();
interactor->Initialize();
interactor->Start();
return 0;
}
程序中,对于四个图像的位置,SetViewport里面传递的坐标,实际上,vtkRenderWindow的坐标系统是左下角位(0, 0),右上角位(1, 1),所以,最总的结果如图:
此时,我们鼠标在哪一幅图中点击,移动,那一个就会旋转,缩放等动作,实现了一个渲染窗口放置多个渲染器
下面是对应的网格图,为了看的跟清楚,放大了,图中,网格保色部分离我们近,黑色远(透过模型才看得到):
坐标系统:
VTK中,坐标系统主要分为四大类:
1、模型坐标系:创建模型的时候,模型所在的坐标系统,例如,我们创建一个模型的时候,模型本身有一个坐标系统,我们可以使用SetCenter等,实际就是在模型坐标系统。
2:世界坐标系:左后窗口中添加的Render,实际上,里面就是一个世界坐标系,所有的灯光,Actor都在这个坐标系下,对于Actor,我们知道可以使用SetUserTransform来设置转换矩阵,从而设置旋转移动等。实际上,这个是设置的Actor在世界空间的位置,Actor还有一个责任是将内部的模型坐标转化到世界坐标,显示他们。
3:View坐标系统:实际上,这就是相机所看到的坐标系统,XYZ三房巷范围均为(-1,1),相机负责将世界坐标转化到View坐标,供我们看。
4:显示坐标:这个很好理解,显示坐标就是这个Render所处的窗口的这部分。实际上,就是屏幕的像素值。
在VTK中,模型坐标系统通常用的很少,即使是创建模型的时候,一般也会默认模型处于中心,否则容易带来不必要的麻烦,其他三种坐标系使用比较多,世界坐标系用于容纳所有Actor、灯光、相机等,View坐标系直接与显示相关,显示坐标与交互相关,例如模型拾取,交互器响应等。VTK中,坐标系统之间的变换都是由类vtkCoordinate进行管理的