osg.View是OpenSceneGraph中一个用来显示视景的类,它是渲染模块osgViewer的一部分。osg.View可以方便地创建和配置多个摄像机视角,并管理视景的渲染过程。该类提供了特定的接口来控制相机的位置、方向,以及相应的投影矩阵,而不需要使用OpenGL代码。
创建osg.View对象的步骤如下:
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 100;
traits->y = 100;
traits->width = 800;
traits->height = 600;
traits->windowDecoration = true;
traits->doubleBuffer = true;
osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
camera->setGraphicsContext(gc.get());
camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
osg::ref_ptr<osg::View> view = new osg::View;
view->setCamera(camera.get());
上面的代码演示了如何创建一个视景对象。osg.View维护了一个或多个osg.Camera对象。这里只创建了一个相机对象并设置了其在窗口中的位置和大小。
设置渲染的场景图:
osg::Group* root = new osg::Group;
view->setSceneData(root);
或者通过使用插件来从文件加载场景图:
osgDB::Registry::instance()->loadPlugin("osgdb_fbx.so");
osg::ref_ptr<osg::Node> scene = osgDB::readNodeFile("test.fbx");
view->setSceneData(scene);
osg.View使用osg::Camera类来维护摄像机,因此可使用一些osg::Camera的功能,例如设置相机的位置、方向、投影矩阵等:
osg::Vec3d eye(0.0f, 0.0f, 10.0f);
osg::Vec3d center(0.0f, 0.0f, 0.0f);
osg::Vec3d up(0.0f, 1.0f, 0.0f);
camera->setViewMatrixAsLookAt(eye, center, up);
camera->setProjectionMatrixAsPerspective(30.0f, 1.0f, 1.0f, 1000.0f);
现在我们可以使用osg.View类直接进行场景渲染:
while (!viewer.done())
{
view->frame();
}
osg.View的可视化器是一种事件处理程序,通过它可以为osg.View添加鼠标响应、键盘输入等事件处理。osg.View提供了启用和禁用此功能的方法:
bool manipulateCamera = true; // 是否启用鼠标控制相机视角
osg::ref_ptr<osgGA::TrackballManipulator> tb = new osgGA::TrackballManipulator;
tb->setAllowThrow(false);
view->setCameraManipulator(manipulateCamera ? tb.get() : nullptr);
上面的代码演示了如何使用osg::GA::TrackballManipulator来管理相机,并使用osg.View的方法开启或关闭相机控制功能。
osg.View提供了很多与视景相关的其他功能。例如,可以指定当前视角的相机修改器,并指定特定视角的还原位置:
osg::ref_ptr<osgGA::TrackballManipulator> tb = dynamic_cast<osgGA::TrackballManipulator*>(view->getCameraManipulator());
tb->setHomePosition(osg::Vec3d(0.0, 0.0, 2.0), osg::Vec3d(), osg::Z_AXIS);
view->setCameraManipulator(tb.get());