如何解析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即可