OSG按强度显示las点云数据示例

如何解析las数据网上教程很多,不赘述,解析完成后,可以将点云强度(intensity)转为osg的VertexAttribArray,参考如下代码

osg::ref_ptr geode = new osg::Geode;
osg::ref_ptr geometry = new osg::Geometry;
osg::ref_ptr pointArray = new osg::Vec3Array;
osg::ref_ptr colorArray = new osg::Vec4Array;
osg::ref_ptr intensityArray = new osg::FloatArray;

for (int i = 0; i < pointCloud.size(); i++)
{
	LasPoint tmpPoint = pointCloud[i];
    // position
	pointArray->push_back(osg::Vec3(tmpPoint.P.X(), tmpPoint.P.Y(), tmpPoint.P.Z()));	
    // color	
    colorArray->push_back(																
		osg::Vec4((float)tmpPoint.C[0] / 255.0f,
		(float)tmpPoint.C[1] / 255.0f,
			(float)tmpPoint.C[2] / 255.0f,
			1));
    // intensity [0.0, 1.0]
	intensityArray->push_back(tmpPoint.I);												
}

geometry->setVertexArray(pointArray.get());
geometry->setColorArray(colorArray.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
// bind intensity to vertex attribute location 2
geometry->setVertexAttribArray(2, intensityArray);										
geometry->setVertexAttribBinding(2, osg::Geometry::BIND_PER_VERTEX);

geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, pointCloud.size()));

geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geode->addDrawable(geometry.get());

las的强度数据转换成osg格式后,可以在着色器(shader)里自定义渲染效果,参考如下代码

static char * vertexShader = {
		"uniform vec4 colorBar[256];\n"
	
		"in float intensity;\n"

		"void main(void ){\n"
		"	int index = clamp((int)(255.0 * intensity), 0, 255);\n"
		"	gl_FrontColor = colorBar[index];\n"
		"   gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;\n"
		"}\n"
};

static char * fragShader = {
		"void main(void){\n"
		"	gl_FragColor = gl_Color;\n"
		"}\n"
};

最终调用着色器(shader)代码如下

// load the data
osg::ref_ptr root = new osg::Group;
osg::ref_ptr loadedModel = osgDB::readRefNodeFiles(arguments);
if (!loadedModel)
{
	std::cout << arguments.getApplicationName() <<": No data loaded" << std::endl;
	return 1;
}
loadedModel->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);

// create a simple greyscale color bar
osg::Uniform* uniform = new osg::Uniform(osg::Uniform::FLOAT_VEC4, "colorBar", 256);
for (int i = 0; i < 256; i++)
{
	uniform->setElement(i, osg::Vec4(i / 255., i / 255., i / 255., 1.));
}

// add shader
osg::Shader * vS = new osg::Shader(osg::Shader::FRAGMENT, fragShader);
osg::Shader * fS = new osg::Shader(osg::Shader::VERTEX, vertexShader);
osg::Program * program = new osg::Program;
program->addShader(vS);
program->addShader(fS);
program->addBindAttribLocation("intensity", 2); // intensity value is stored in vertex attribute location 2

osg::StateSet * ss = loadedModel->getOrCreateStateSet();
ss->addUniform(uniform);
ss->setAttributeAndModes(program, osg::StateAttribute::ON);

root->addChild(loadedModel);

其他类似显示效果,如按高程显示、按gpstime显示等都可以参考此代码,把各自对应的upper&lower bound作为uniform传入shader即可

你可能感兴趣的:(C++,OSG,shader,c++,osg)