osg之显示点云

Posted z-web-2017

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了osg之显示点云相关的知识,希望对你有一定的参考价值。

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

          bool rgbIsInt=false;

	/*osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
	viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet()));*/
	osg::ref_ptr<osg::Group> root = new osg::Group();
	
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
	{
		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();

	
	//快速读取文件
	string filePath = "整数.txt";//mcolor_小数  ZSWZ2015111
	FILE* pfData = fopen(filePath.c_str(), "r");

	ifstream fileIn(filePath, ios::in);//读取文件
	string line;//读取了每一行的字符

	getline(fileIn, line);//获取第一行
	stringstream sstr(line);//给他转一下
	string token;

	int lineInNum=0;
	while (getline(sstr, token, ‘ ‘))
	{
		lineInNum ++ ;
		if (lineInNum >= 3)
		{
			if (stof(token)> 1)
			{
				rgbIsInt = true;
			}
	
		}
		
	}

	
	int num = 0;//数据点数量
	if (pfData == NULL)
	{
		cout << "DataFile does not exist!!!" << endl;
		return NULL;
	}
	else
	{
		if (rgbIsInt == false)//读小数
		{ 
			while (!feof(pfData))
			{
				float fx, fy, fz, n, m, k;
				float fa, fb, fc;
				fscanf(pfData, "%f", &fx);
				fscanf(pfData, "%f", &fy);
				fscanf(pfData, "%f", &fz);
				fscanf(pfData, "%f", &fa);
				fscanf(pfData, "%f", &fb);
				fscanf(pfData, "%f", &fc);
				coords->push_back(osg::Vec3(fx, fy, fz));
				color->push_back(osg::Vec4(fa, fb, fc, 1.0f));
				num++;
			}
		}
		else//读整数
		{
			while (!feof(pfData))
			{
				float fx, fy, fz;
				int fa, fb, fc;
				fscanf(pfData, "%f", &fx);
				fscanf(pfData, "%f", &fy);
				fscanf(pfData, "%f", &fz);
				fscanf(pfData, "%d", &fa);
				fscanf(pfData, "%d", &fb);
				fscanf(pfData, "%d", &fc);
				float aa = (float)fa / 255.00;
				float bb = (float)fb / 255.00;
				float cc = (float)fc / 255.00;
				coords->push_back(osg::Vec3(fx, fy, fz));
				color->push_back(osg::Vec4(aa, bb, cc, 1.0f));
				num++;
			}
		}
		fclose(pfData);
	}

	//创建几何体
	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, num)); //设置关联方式

	//添加到叶节点
	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->realize();
	viewer->run();
	return viewer->run();

  这是运行效果:

                                                                                     技术分享图片

            后期会把osg嵌入到Qt的方法贡献给大家,由于目前博主也在学习阶段,感觉还是控制台学习较为方便。

 


以上是关于osg之显示点云的主要内容,如果未能解决你的问题,请参考以下文章

探索未知种族之osg类生物---器官初始化四

点云处理技术之open3d第二篇:点云的基本操作篇——可视化降采样法向量裁剪和绘制点云

PCL点云处理之基于高程的粗糙度计算(一百)

[转][osg]探索未知种族之osg类生物目录

MATLAB点云处理:点云赋色 | 显示自定义颜色的点云

探索未知种族之osg类生物---渲染遍历之裁剪一