osgEarth开发之OSG解构——失败的尝试

来源:互联网 发布:正规的淘宝代运营 编辑:程序博客网 时间:2024/05/18 08:11

概述

本文在吸收了《最长的一帧》以及相关参考资料的基础之上解读OSG的基础数据结构,渲染方法。

实现

在这第一部分里,要理解的是run函数的实现,因为以下这一段证明了它的重要性和强大的能力。


int main(){//....osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;/**如果指向的目录没有数据OSG的屏幕上不会有数据显示*/osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("D:/OpenSceneGraph/data/cow.osg");viewer->setSceneData(node.get());return viewer->run();}


按照《最长的一帧》中的说法,所有的绘制工作会在一个循环里面完成:

while( !viewer->done() ){      viewer->frame();}

但在第一段并没有出现相关的代码,可以确定这些实现细节必须在run函数中实现了。

首先,我希望通过自己实现的控制器显示场景结点数据,这个跟run函数无关,是教程里的一个小例子,至于run函数我是用了上面的这个循环替代,结果却出乎意料,在场景中看不到我加载的模型。

源代码:


int main(){//....osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;//osg::ref_ptr<osg::Group> root = new osg::Group;/**如果指向的目录没有数据OSG的屏幕上不会有数据显示*/osg::ref_ptr<osg::Node> node = osgDB::readNodeFile("D:/OpenSceneGraph/data/cow.osg");//........................viewer->setSceneData(node.get());viewer->setCameraManipulator(new RunImplement);//仿真渲染初始化viewer->realize();/**最长的一帧  实践版*///渲染每一帧while(!viewer->done()){viewer->frame();}return 0;}

如果控制器设置为TrackballManipulator,就可以在场景中看到模型。这让我纳闷,在实现RunImplement这个控制器的时候是缺少了什么东西才导致这样的意外的呢?目前我现了几个osgGA::OrbitManipulator中的虚函数,这些函数是显示节点场景数据的接口。具体实现如下:


#include "run.h"RunImplement::RunImplement(){m_vPosition = osg::Vec3d(10,10,2);m_vRotation = osg::Vec3d(0,0,0);}osg::Matrixd RunImplement::getMatrix() const{osg::Matrixd mat;mat.makeTranslate(m_vPosition);return mat * osg::Matrixd::rotate(m_vRotation[0],osg::X_AXIS,m_vRotation[1],osg::Y_AXIS,m_vRotation[2],osg::Z_AXIS);}osg::Matrixd RunImplement::getInverseMatrix() const{osg::Matrixd mat;mat.makeTranslate(m_vPosition);return mat * osg::Matrixd::inverse(osg::Matrixd::rotate(m_vRotation[0],osg::X_AXIS,m_vRotation[1],osg::Y_AXIS,m_vRotation[2],osg::Z_AXIS));}void RunImplement::setByInverseMatrix( const osg::Matrixd& matrix ){}void RunImplement::setByMatrix( const osg::Matrixd& matrix ){}

头文件:run.h


/****最长的一帧,实例演示*/#ifndef RUN_H__#define RUN_H__#include <windows.h> // gl.h 大量引用该文件中的接口#if _DEBUG#pragma comment( lib, "opengl32")#pragma comment( lib, "osgd") #pragma comment( lib, "osgViewerd") #pragma comment( lib, "osgDBd") #pragma comment( lib, "OpenThreadsd") #pragma comment( lib, "osgUtild")#pragma comment( lib, "osgGAd")#else#pragma comment( lib, "opengl32")#pragma comment( lib, "osg") #pragma comment( lib, "osgViewer") #pragma comment( lib, "osgDB") #pragma comment( lib, "OpenThreads") #pragma comment( lib, "osgUtil")#pragma comment( lib, "osgGA")#endif#include <osg/Node>#include <osg/Geode>#include <osg/Group>#include <osg/PositionAttitudeTransform>#include <osg/MatrixTransform>#include <osg/Matrixd>#include <osg/AnimationPath>#include <iostream>#include <osgViewer/Viewer>#include <osgViewer/ViewerEventHandlers>#include <osgGA/OrbitManipulator>#include <osgDB/ReadFile>#include <osgDB/WriteFile>#include <osgUtil/Optimizer>#include <osgGA/TrackballManipulator>/*! 开始一个类*/class RunImplement: public osgGA::OrbitManipulator{public:RunImplement();public:virtual void setByMatrix( const osg::Matrixd& matrix );virtual void setByInverseMatrix( const osg::Matrixd& matrix );virtual osg::Matrixd getMatrix() const;virtual osg::Matrixd getInverseMatrix() const;private:osg::Vec3d m_vPosition;osg::Vec3d m_vRotation;};#endif /* END_OF_RUNIMPLEMENT */

解决问题

思之再三,觉得看不到节点数据的原因无非就两个:

一、数据没有被加载到场景中,

二、加载了节点数据,但是由于参数不正确,导致数据不可见。

OSG在OrbitManipulator中设置了许多显示设置的参数,所以场景结点数据就得到正确的显示,在子类TrackballManipulator中构造函数直接使用了StandardManipulator中的setVerticalAxisFixed(false)这个函数,鉴于目前只是实现run函数中的流程,对于osg::Displaysettings里面的具体细节后面再讨论。


原创粉丝点击