概述
本文在吸收了《最长的一帧》以及相关参考资料的基础之上解读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这个控制器的时候是缺少了什么东西才导致这样的意外的呢?目前我是按照一个视频教程上的指导实现了几个其中几个虚函数,这些函数是显示节点数据的接口。具体实现如下:
#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 */
解决问题
思之再三,觉得看不到节点数据的原因无非就两个:
一、数据没有被加载到场景中,
二、加载了节点数据,但是由于参数不正确,导致数据不可见。