OSG的HelloWorld

加载一个飞机模型

  1. 直接上代码:

    1
    2
    3
    4
    5
    6
    7
    8
    #include <osgViewer/Viewer>
    #include <osgDB/ReadFile>

    int main() {
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    viewer->setSceneData(osgDB::readNodeFile("glider.osg"));
    return viewer->run();
    }
  2. 看看结果

  3. 代码很好理解,首先引入了类库,在main函数中,初始化了一个viewer,在这里使用的是osg中的超级指针(还不是很懂),随后给这个viewer设置了sceneData,设置的数据是打开了一个飞机的osg文件,最后就是渲染整个场景了。

  4. 与之前接触的Cesium的一些定义是类似的,比如Viewer和Scene。

添加一些帮助事件

  1. cmd中使用osgviewer glider.osg跑的程序,自带了一些基础功能,例如缩放、帮助、全屏、显示帧速等等。

  2. 我们写的程序则是没有键盘事件的,但是保留了缩放、旋转的功能。

  3. 先添加一些键盘的监听事件

    1
    2
    3
    4
    5
    6
    7
    8
    #include <osgViewer/ViewerEventHandlers>

    //添加帮助事件
    viewer->addEventHandler(new osgViewer::HelpHandler);
    viewer->addEventHandler(new osgViewer::StatsHandler);
    viewer->addEventHandler(new osgViewer::WindowSizeHandler);
    viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
    viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);
  4. 现在运行,就会发现sfh都已经有了相应的功能。如果没有反应,检查键盘是不是选择的英语(美国),正确显示如下图。

    win10似乎是需要自己添加的。

自定义一个帮助事件

  1. 这里参考源码中定义帮助页中的行规则

  2. 模拟一个事件类,注意定义的命名空间应尽可能的不与osg官方定义冲突。

    1
    2
    3
    4
    5
    6
    7
    class PrintName : public osgGA::GUIEventHandler {
    public:
    virtual void getUsage(osg::ApplicationUsage& usage) const {
    //eno为快捷键名称,emm...为对应的快捷键说明
    usage.addKeyboardMouseBinding("eno", "emm.......");
    }
    };
  3. viewer添加帮助事件

    1
    viewer->addEventHandler(new PrintName);
  4. OK,来看看结果,自定义的eno已经添加进去了。似乎还挺有趣

添加一个定时器,计算一下读取模型的时间

  1. 我们加载模型的方式需要改变一下

    1
    2
    3
    4
    5
    6
    // old
    viewer->setSceneData(osgDB::readNodeFile("glider.osg"));
    // new
    osg::ref_ptr<osg::Node> node = new osg::Node;
    node = osgDB::readNodeFile("glider.osg");
    viewer->setSceneData(node.get());
  2. 申请一个定时器类,两个时间类。这里的Timer_t相当于long long

    1
    2
    3
    osg::Timer* timer = new osg::Timer;
    osg::Timer_t start_time = 0;
    osg::Timer_t end_time = 0;
  3. 计算时间

    1
    2
    3
    4
    5
    6
    7
    8
    #include <iostream>
    using namespace std;

    start_time = timer->tick();
    node = osgDB::readNodeFile("glider.osg");
    end_time = timer->tick();

    cout << "01.模型读取时间为:" << timer->delta_s(start_time, end_time) << endl;
  4. 结果

  5. 看看另一种方法,定义两个单精度时间变量

    1
    2
    float start_time_f = 0;
    float end_time_f = 0;
  6. 计算时间

    1
    2
    3
    4
    5
    start_time_f = viewer->elapsedTime();
    node = osgDB::readNodeFile("glider.osg");
    end_time_f = viewer->elapsedTime();

    cout << "02.模型读取时间为:" << end_time_f - start_time_f << endl;
  7. 看看结果

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osgViewer/ViewerEventHandlers>
#include <iostream>
using namespace std;

class PrintName : public osgGA::GUIEventHandler {
public:
virtual void getUsage(osg::ApplicationUsage& usage) const {
usage.addKeyboardMouseBinding("eno", "emm.......");
}
};

int main() {
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
osg::ref_ptr<osg::Node> node = new osg::Node;
osg::Timer* timer = new osg::Timer;

osg::Timer_t start_time = 0;
osg::Timer_t end_time = 0;
float start_time_f = 0;
float end_time_f = 0;

start_time = timer->tick();
start_time_f = viewer->elapsedTime();

node = osgDB::readNodeFile("glider.osg");

end_time_f = viewer->elapsedTime();
end_time = timer->tick();

cout << "01.模型读取时间为:" << timer->delta_s(start_time, end_time) << endl;
cout << "02.模型读取时间为:" << end_time_f - start_time_f << endl;

viewer->addEventHandler(new PrintName);
viewer->addEventHandler(new osgViewer::HelpHandler);
viewer->addEventHandler(new osgViewer::StatsHandler);
viewer->addEventHandler(new osgViewer::WindowSizeHandler);
viewer->addEventHandler(new osgViewer::ScreenCaptureHandler);
viewer->addEventHandler(new osgViewer::RecordCameraPathHandler);

viewer->setSceneData(node.get());
return viewer->run();
}