一,用Liblas读取点云数据,获取点云位置和颜色
二,将点云位置和颜色分别代入geode的位置数组和颜色数组
三,用glsl设置半透明。需要注意的是
1,颜色数组是用attribute,所以要用
geom->setVertexAttribArray(10, colors, osg::Array::BIND_PER_VERTEX);
program->addBindAttribLocation(“colors”, 10);
2,由于颜色数组是绑定到顶点的,所以要在shader中把颜色从顶点着色器传递到片元着色器。
即
“varying vec4 outColors;”
3,alpha值是uniform,所以在stateset中设置
osg::ref_ptrosg::Uniform alphaValue = new osg::Uniform(“alpha”, 0.1f);
stateset->addUniform(alphaValue);
4,开启混合
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
代码如下:
//通过Liblas读取.las文件,并在osg中显示出来,用shader,先在片元着色器指定使用绿色
#include <liblas/liblas.hpp>
#include
#include
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osg/CoordinateSystemNode>
#include <osg/Switch>
#include <osg/Types>
#include <osgText/Text>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>
#include <osgGA/Device>
#include
#include <osg/Shader>
osg::ref_ptrosg::Geode getGeodeFromLas(std::string strLasFileName)
{
std::ifstream ifs;
ifs.open(strLasFileName, std::ios::in | std::ios::binary);
liblas::ReaderFactory f;
liblas::Reader reader = f.CreateWithStream(ifs);
liblas::Header const& header = reader.GetHeader();
int pointCount = header.GetPointRecordsCount();
std::cout << "pointCount:" << pointCount << std::endl;
osg::ref_ptr<osg::Geode> geode = new osg::Geode;
osg::ref_ptr<osg::Geometry> geom = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
osg::ref_ptr<osg::Vec4Array> colors = new osg::Vec4Array;
for (int i = 0; i < pointCount; i++)
{
bool readSuccess = reader.ReadPointAt(i);
if (!readSuccess)
{
continue;
}
liblas::Point const& p = reader.GetPoint();
float red = p.GetColor().GetRed() * 1.0 / 65535;
//float green = p.GetColor().GetGreen()* 1.0 / 65535;
float green = 1.0;
float blue = p.GetColor().GetBlue()* 1.0 / 65535;
// std::cout << "red =" << red << ";green=" << green << ";blue=" << blue << std::endl;
colors->push_back(osg::Vec4(red, green, blue, 1.0)); //这里强制把颜色设置为蓝色
double x = p.GetX();
double y = p.GetY();
double z = p.GetZ();
// std::cout << "x =" << x << ";y=" << y << ";z=" << z << std::endl;
vertices->push_back(osg::Vec3(x, y, z));
}
geom->setVertexAttribArray(10, colors, osg::Array::BIND_PER_VERTEX);
geom->setColorArray(colors, osg::Array::BIND_PER_VERTEX);
geom->setVertexArray(vertices);
geom->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, vertices->size()));
geode->addDrawable(geom);
return geode.release();
}
static const char * vertexShader =
{
“in vec4 colors;\n”
“varying vec4 outColors;”
“void main(void)\n”
“{\n”
“outColors = colors;”
" gl_Position = ftransform();\n"
“}\n”
};
static const char *psShader =
{
“uniform float alpha;”
“varying vec4 outColors;”
“void main(void)\n”
“{\n”
//“gl_FragColor = vec4(0.0f,1.0f,0.0f,1.0);\n”
“gl_FragColor = outColors;\n”
“gl_FragColor.a = alpha;\n”
“}\n”
};
int main()
{
//std::string strLasFileName = “d:/ddss.las”;
std::string strLasFileName = “d:/test.las”;
osg::ref_ptr<osg::Group> grp = new osg::Group;
osg::ref_ptr<osg::Geode> geode = getGeodeFromLas(strLasFileName);
grp->addChild(geode);
osg::ref_ptr<osg::StateSet> stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::ref_ptr<osg::Shader> vs = new osg::Shader(osg::Shader::VERTEX, vertexShader);
osg::ref_ptr<osg::Shader> ps = new osg::Shader(osg::Shader::FRAGMENT, psShader);
osg::ref_ptr<osg::Program> program = new osg::Program;
program->addShader(vs);
program->addShader(ps);
program->addBindAttribLocation("colors", 10);
osg::ref_ptr<osg::Uniform> alphaValue = new osg::Uniform("alpha", 0.1f);
stateset->addUniform(alphaValue);
stateset->setAttribute(program, osg::StateAttribute::ON);
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer;
viewer->setSceneData(grp);
viewer->run();
return 0;
}
运行结果:alpha = 0.1时,
alpha = 0.5时
alpha = 1.0时,