分享

鸟瞰图相机

 昵称12278894 2014-06-23
// 程序来自:<<OpenSceneGraph三维渲染引擎设计与实践 P174--鸟瞰图相机
//
//程序思路:
//(1)创建一个节点  Node
//(2)创建一个正交投影函数
//(3)将节点模型添加进相机
//(4)场景的优化、渲染
//
//说明一下:相机节点Camera派生自Transform类,同其他的空间变换节点没有本质区别。
//osg包含了大量的基本类节点:Node、Geode(叶节点)、Group(组节点)。OSG中其他大部分节点都继承自Group节点,少部分继承自Node节点及Geode节点。
//但Geode和Group均继承自Node节点。Geode--叶节点,它不会再有其他的子节点,但可以包含几何体信息。
//解释一下:
//Node节点读取模型,然后添加到场景Group,即将基类的信息添加进子类
//
//
//
#include "stdafx.h"

#include <osg/Camera>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

osg::Camera* createBirdsEye( const osg::BoundingSphere& bs )
{
    //创建相机节点camera 
osg::ref_ptr<osg::Camera> camera = new osg::Camera;

//清除颜色和深度缓存,这意味着这个相机渲染子场景时将会覆盖之前任何相机的渲染数据
    camera->setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

//设置相机的坐标系,设置为ABSOLUTE_RF意味着相机的所有变换矩阵和观察/投影矩阵设置都是相对于世界坐标的,不会受到上级矩阵的影响
    camera->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
    
//根据模型的包围球大小,设置相机的投影矩阵
    double viewDistance = 2.0 * bs.radius();
    double znear = viewDistance - bs.radius();
    double zfar = viewDistance + bs.radius();
    float top = bs.radius();
    float right = bs.radius();

//投影变换,设置正射投影矩阵的内容,6个参数分别表示平行视景体的6个面的位置(左,右,下,上,近,远)
//还有一个透射投影。正射投影与透射投影的区别:
//先说一下相机吧,包括3部分:1、物体在那儿,观察者所处的位置及观察角度。
//2、将看到的投影到底片上,那么有两种方式正射---底片上的物体投影与实际一样大;透射---远小近大,
//将视锥体之外的视景剪切掉,远大近小与参数far-near的值有关,视锥体外视景的裁剪与近裁切面
//(除了far以外的参数有关)有关,根据本例,视景正好都在近裁切平面内,故不会有视景被裁掉。
//物体在近裁剪面上(近裁剪面与物体之间还可能有距离,是这样,这两者之间为正射投影,能不能包含视
//景全部,就看近裁剪平面的大小).
//3,将底片上的景物投射到屏幕上。
    camera->setProjectionMatrixAsOrtho( -right, right, -top, top, znear, zfar );
    
    //设置为正看,就是对应眼睛看的方向,人的头的向上的方向。
osg::Vec3d upDirection( 0.0,1.0,0.0 );
//设置眼睛所在位置,看物体的方向
    osg::Vec3d viewDirection( 0.0,0.0,1.0 );

//设置物体的位置
    osg::Vec3d center = bs.center();

//设置人眼所在的位置
    osg::Vec3d eyePoint = center + viewDirection * viewDistance;

//视点变换函数
    camera->setViewMatrixAsLookAt( eyePoint, center, upDirection );
    
    return camera.release();
}

int main( int argc, char** argv )
{
    osg::ArgumentParser arguments( &argc, argv );
//创建一个节点,读取模型
    osg::Node* model = osgDB::readNodeFiles( arguments );
    if ( !model ) model = osgDB::readNodeFile( "lz.osg" );
    
//创建一个相机节点
    osg::Camera* camera = createBirdsEye( model->getBound() );

//将模型节点添加进相机
    camera->addChild( model );
    
    //创建Viewer对象,场景浏览器
osgViewer::Viewer viewer;
//优化场景
    viewer.setSceneData( camera );
//开始渲染
    return viewer.run();
}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多