OSG两个独立的相机观测

这篇博客介绍了如何在OpenSceneGraph(OSG)中创建两个独立的相机视图,一个模拟坦克驾驶员的视角,另一个由osgViewer::Viewer控制。内容涉及到低层次的OSG接口,包括设置摄像机、视口和场景的细节。
摘要由CSDN通过智能技术生成

OSG两个独立的相机观测

 
目标

在场景中创建两个视口。其中一个用于从坦克驾驶员的视角观察场景。该视口将被渲染于屏幕的上半部分。第二个视口由缺省的osgViewer::Viewer类接口(轨迹球,飞行等控制器)控制。它将被渲染于屏幕的中下部分。

概述:

OSG向开发人员提供了各种的抽象层次接口。前面的教程讨论的主要是一些较高层级的接口应用:例如使用Viewer类来控制视点,场景,交互设备和窗口系统。OSG的优势之一,就是可以允许开发者在使用高层次的接口的同时,访问较低层次的抽象接口。本章将使用一些低抽象层级的功能,对视点进行控制,并使用相应的类渲染场景。

代码:

为了创建两个视口,我们需要提供两个独立可控的摄像机。与OSG 1.2版本中所述不同的是,本例中将不再使用Prodecer::CameraConfig类,而是将多个不同的视口添加到组合视口 CompositeViewer类当中。下面的函数即用于实现添加视口并设置其中的摄像机位置。

void createView (osgViewer::CompositeViewer *viewer,//查看器,一个相框

osg::ref_ptr<osg::Group> scene,//场景

osg::ref_ptr<osg::GraphicsContext> gc,//显示设置定义相框的大小,View和Viewr在屏幕上的大小,位置

osgGA::TrackballManipulator* Tman,//放置相机的位置

int x, int y, int width, int height)//视口的大小,从多大的窗口看场景
 double left,right,top,bottom,near,far, aspectratio; 
 double frusht, fruswid, fudge; 
 bool gotfrustum = true; 

// 向最终的组合视口添加一个新的视口,并设置其操控方式。
两台独立的相机观测  此博文包含图片	(2012-07-11 08:57:41)转载▼
标签: 杂谈	分类: StudyNotes
目标
在场景中创建两个视口。其中一个用于从坦克驾驶员的视角观察场景。该视口将被渲染于屏幕的上半部分。第二个视口由缺省的osgViewer::Viewer类接口(轨迹球,飞行等控制器)控制。它将被渲染于屏幕的中下部分。
概述:
OSG向开发人员提供了各种的抽象层次接口。前面的教程讨论的主要是一些较高层级的接口应用:例如使用Viewer类来控制视点,场景,交互设备和窗口系统。OSG的优势之一,就是可以允许开发者在使用高层次的接口的同时,访问较低层次的抽象接口。本章将使用一些低抽象层级的功能,对视点进行控制,并使用相应的类渲染场景。
代码:
为了创建两个视口,我们需要提供两个独立可控的摄像机。与OSG 1.2版本中所述不同的是,本例中将不再使用Prodecer::CameraConfig类,而是将多个不同的视口添加到组合视口 CompositeViewer类当中。下面的函数即用于实现添加视口并设置其中的摄像机位置。
void createView (osgViewer::CompositeViewer *viewer,//查看器,一个相框

osg::ref_ptr<osg::Group> scene,//场景

osg::ref_ptr<osg::GraphicsContext> gc,//显示设置定义相框的大小,View和Viewr在屏幕上的大小,位置

osgGA::TrackballManipulator* Tman,//放置相机的位置

int x, int y, int width, int height)//视口的大小,从多大的窗口看场景

{

double left,right,top,bottom,near,far, aspectratio;

double frusht, fruswid, fudge;

bool gotfrustum = true; 

// 向最终的组合视口添加一个新的视口,并设置其操控方式。
//View是一个显示窗口
osgViewer::View* view = new osgViewer::View;
//在查看器中加入显示窗口
viewer->addView(view);
//显示窗口设定自身相机的位置
view->setCameraManipulator(Tman);

// 设置视口的场景数据,并设置摄像机的截锥坐标。
//指定场景
view->setSceneData(scene.get());
//指定视口的大小,通过个窗口的大小来查看场景,也就是相片的大小
view->getCamera()->setViewport(new osg::Viewport(x,y, width,height));
//指定相机的焦距
view->getCamera()-> getProjectionMatrixAsFrustum(left,right,

bottom,top,

near,far);

if (gotfrustum) 

{

aspectratio = (double) width/ (double) height;

frusht = top - bottom;

fruswid = right - left;

fudge = frusht*aspectratio/fruswid;

right = right*fudge;

left = left*fudge;

view->getCamera()-> setProjectionMatrixAsFrustum(left,right,

bottom,top,

near,far);

}
//指定相机中的图像在屏幕上的显示方法,与系统相关
view->getCamera()->setGraphicsContext(gc.get());// 添加渲染状态控制器

//这个控制器,控制图的光照,材质等
osg::ref_ptr<osgGA::StateSetManipulator> statesetManipulator = new osgGA::StateSetManipulator;

statesetManipulator->setStateSet(view->getCamera()->getOrCreateStateSet());

view->addEventHandler( statesetManipulator.get() );

}
现在我们已经有了设置摄像机的函数,在仿真的其余部分中,我们将不再赘述有关基本场景建立(包括一个地形模型以及在其上运动的坦克)的内容。相关的代码可以从源程序中获取。我们需要对坦克模型添加一个位移变换节点。这样我们就可以将摄像机的位置置于坦克的后上访,以便进行观察。
int main( int argc, char **argv )

{

// 场景根节点和坦克模型节点指针。

osg::ref_ptr<osg::Group> rootNode; 

osg::ref_ptr<osg::Group> ownTank; 

osgGA::TrackballManipulator *Tman1 = new osgGA::TrackballManipulator();

osgGA::TrackballManipulator *Tman2 = new osgGA::TrackballManipulator();

// 建立场景和坦克。

if (!setupScene(rootNode, ownTank))

{

std::cout<< "problem setting up scene" << std::endl;

return -1;

}
// 声明一个位于坦克偏后上方的位移变换节点。将其添加到坦克节点。

osg::PositionAttitudeTransform * followerOffset =

new osg::PositionAttitudeTransform();

followerOffset->setPosition( osg::Vec3(0.0,-25.0,10) );

followerOffset->setAttitude(

osg::Quat( osg::DegreesToRadians(-15.0), osg::Vec3(1,0,0) ) );

ownTank.get()->addChild(followerOffset);
// 声明一个自定义的位移累加器类,以便放置相机。将其关联给上面的变换节点。

transformAccumulator* tankFollowerWorldCoords = new transformAccumulator();

tankFollowerWorldCoords->attachToGroup(followerOffset);
// 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值