计算机图形学中的坐标系统主要有4种,分别是Model系统,World坐标系统,View坐标系统和Display坐标系统,此外还有两种不同的表示坐标点的方式:以屏幕像素为单位和归一化坐标值。
- Model坐标是采用定义模型时候采用的坐标系统,通常是局部的笛卡尔坐标系,
- World坐标系统是放置Actor的三维坐标系,Actor(vtkActor类)其中的一个功能就是负责将模型从Model坐标系变换到World坐标系统。每一个模型可以定义自己的Model坐标系统,但是World坐标系统只能有一个。每一个Actor必须通过缩放、平移、旋转等操作将Model坐标系变换到World坐标系。World坐标系同时也是相机和灯光所在的坐标系。
- View坐标系表示的是相机看见的坐标系统。X、Y、Z轴取值为[-1,1]表示平面上的距离,Z表示到相机的距离。相机负责将World坐标系变成View坐标系
- Display坐标系与View坐标系类似,但是各坐标轴的取值不是[-1,1],而是使用屏幕像素值。所以可以吧不同的渲染场景放到一个窗口中进行演示。
实现效果
步骤拆分
- 定义Cube、Cone、cylinder、sphere 四个要放在对应场景中的物体(source)
- 分别构造他们的mapper
sphereMapper->SetInputConnection(sphere->GetOutputPort()); - 通过vtkActor来具象化这些物体(SetMapper)
- 定义renderer1、renderer2、renderer3、renderer4四个不同的场景渲染器。然后将他们分别规定渲染窗口的哪些位置。
- 将这些渲染器都加入到窗口当中去:
AddRenderer
关键代码
vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
renderer1->AddActor(coneActor);
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);
代码实现
#include <vtkConeSource.h>
#include <vtkCubeSource.h>
#include <vtkCylinderSource.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSmartPointer.h>
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
int main()
{
vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New();
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
vtkSmartPointer<vtkCylinderSource> cylinder = vtkSmartPointer<vtkCylinderSource>::New();
vtkSmartPointer<vtkSphereSource> sphere = vtkSmartPointer<vtkSphereSource>::New();
vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
coneMapper->SetInputConnection(cone->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> coneActor = vtkSmartPointer<vtkActor>::New();
coneActor->SetMapper(coneMapper);
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);
vtkSmartPointer<vtkRenderer> renderer1 = vtkSmartPointer<vtkRenderer>::New();
renderer1->AddActor(coneActor);
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);
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();
interactor->SetRenderWindow(renWin);
renWin->Render();
interactor->Initialize();
interactor->Start();
return EXIT_SUCCESS;
}