文章目录
更新: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();
}