OSG 之学习十:OSG 显示点云一

更新:2019年8月


为了促进同行业人员(特指 LiDAR 点云处理人员或相近行业)的技术交流,解决平时开发过程中遇到的技术性问题,博主建立一个QQ群,欢迎大家积极加入,共同引领点云行业的快速发展 ~

群名:LiDAR点云部落
群号:190162198

在这里插入图片描述

说明


osg虽然不是很火,但是对于非计算机专业的人来说确实是一个神器,osg其实也是来自于opengl,它可以理解为一个高度封装的opengl图像库,由于其没有太多太多的技术门槛以及扩展性不高,导致其市场一直不温不火,但是其封装的LOD技术,多线程技术以及显示还是为急需做平台又不想投入大量时间的人提供了便利。博主就是属于其中之一,由于点云数据越来越大,如今数据点不超过1个亿都不好意思称作大数据。由于opengl的LOD技术国内在这方面保密甚为严格,当然各行各业都是这样,这也是国内技术一直远远落后于国外的原因之一吧!其实很多工具真的很有用,但是苦于没有入门教程,所以只能望洋兴叹,这也是国内编程技术的现状之一吧!目前博主也是尽自己的一点绵薄之力把一些有用的入门教程奉献给大家,希望能给那些还在点云显示道路上挣扎的人一点点帮助!同时也呼吁大家能把一些并没有什么核心竞争力的编程知识共享一下,因为每一篇有用的博客都有可能开启一个人的编程之路,废话不多说,直接上代码,保证直接运行可用

有兴趣者可以参考我的上另一篇文档:OSG 之学习十一:OSG 显示点云二

代码


  • 我在此基础上做了一个简单修改,方便大家使用
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator>
#include <osgUtil/Optimizer>

// 读取点云文件,临时用的
#include <fstream>
#include <sstream>
#include <vector>

int main() {

    // 新建一个 group
    osg::ref_ptr<osg::Group> root = new osg::Group();
    // 创建一个 viewer
    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
    // 添加状态事件
    viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));

    // 新建一个 osg::GraphicsContext::Traits,描述窗口的属性
    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
    traits->x = 40;
    traits->y = 40;
    traits->width = 600;
    traits->height = 480;
    traits->windowDecoration = true;
    traits->doubleBuffer = true;
    traits->sharedContext = 0;

    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());

    osg::ref_ptr<osg::Camera> camera = new osg::Camera;
    camera->setGraphicsContext(gc.get());
    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));
    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;
    camera->setDrawBuffer(buffer);
    camera->setReadBuffer(buffer);

    // add this slave camera to the viewer, with a shift left of the projection matrix
    viewer->addSlave(camera.get());

    // 创建顶点数组
    osg::ref_ptr<osg::Vec3Array> coords = new osg::Vec3Array();
    // 创建颜色
    osg::ref_ptr<osg::Vec4Array> color = new osg::Vec4Array();

    /读取点云文件//
    int cloudNum = 0;
    {
        // 这里演示读取一个 .txt 点云文件
        std::ifstream ifs("E:/LY/Lab1-Filter/data2/2-1-origin-resample.txt");
        std::string line;
        while (getline(ifs, line)) {
            std::stringstream ss(line);
            std::vector<double> v;
            std::string str;
            while (getline(ss, str, ' '))
                v.push_back(std::stod(str));
            coords->push_back(osg::Vec3(v[0], v[1], v[2]));
            color->push_back(osg::Vec4(v[3] / 255.0, v[4] / 255.0, v[5] / 255.0, 1.0f));

            cloudNum++;
        }
        ifs.close();
    }
    /读取点云文件//

    //创建几何体
    osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry();
    // 设置顶点数组
    geometry->setVertexArray(coords.get());
    geometry->setColorArray(color.get());
    geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);

    osg::Vec3Array *normals = new osg::Vec3Array;
    normals->push_back(osg::Vec3(0.0f, 1.0f, 0.0f));
    // geometry->setNormalArray(normals);
    // geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
    // 设置关联方式
    geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, cloudNum));

    // 添加到叶节点
    osg::ref_ptr<osg::Geode> geode = new osg::Geode();
    geode->addDrawable(geometry.get());
    root->addChild(geode.get());

    //root->getOrCreateStateSet()->setMode(GL_LIGHTING, StateAttribute::OFF | StateAttribute::OVERRIDE);

    // 优化场景数据
    osgUtil::Optimizer optimizer;
    optimizer.optimize(root.get());
    viewer->setSceneData(root.get());

    // 窗口大小变化事件
    viewer->addEventHandler(new osgViewer::WindowSizeHandler);

    viewer->realize();
    viewer->run();
    return viewer->run();
}

在这里插入图片描述

  • 2
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值