用OSG Cookbook中的draw实例渲染点云数据不工作
Rendering point cloud data with draw instancing from OSG Cookbook not working
我正在使用OSG渲染点云。我遵循OSG烹饪书中的例子"用绘制实例渲染点云数据",展示了如何用许多实例制作一个点,然后通过纹理将点位置转移到显卡上。然后使用着色器将点从纹理中拉出,并将每个实例移动到正确的位置。渲染的内容似乎有两个问题。
首先,与更直接的渲染方法相比,这些点不在正确的位置。看起来它们从0开始大致缩放错了,某种位置上的乘法因子。
第二,图像模糊。点数通常位于正确的位置;在应该放一个大物体的地方有很多点。但是,我看不出是什么东西。用我的工作(但较慢)渲染方法渲染的数据看起来很清晰。
我已经验证,我有相同的输入数据进入纹理和绘制列表在这两种方法,所以它似乎必须与渲染的东西。
下面是设置几何的代码,它几乎是直接从课本中复制的。
osg::Geometry* geo = new osg::Geometry;
osg::ref_ptr<osg::Image> img = new osg::Image;
img->allocateImage(w,h, 1, GL_RGBA, GL_FLOAT);
osg::BoundingBox box;
float* data = (float*)img->data();
for (unsigned long int k=0; k<NPoints; k++)
{
*(data++) = cloud->x[k];
*(data++) = cloud->y[k];
*(data++) = cloud->z[k];
*(data++) = cloud->meta[0][k];
box.expandBy(cloud->x[k],cloud->y[k],cloud->z[k]);
}
geo->setUseDisplayList(false);
geo->setUseVertexBufferObjects(true);
geo->setVertexArray( new osg::Vec3Array(1));
geo->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1, stop) );
geo->setInitialBound(box);
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage( img);
tex->setInternalFormat( GL_RGBA32F_ARB );
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
这里是着色器代码。
void main () {
float row;
row = float(gl_InstanceID) / float(width);
vec2 uv = vec2( fract(row), floor(row) / float(height) );
vec4 texValue = texture2D(defaultTex,uv);
vec4 pos = gl_Vertex + vec4(texValue.xyz, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * pos;
}
经过大量的实验,我发现来自OSG Cookbook的示例代码有一些问题。
比例问题(第一个问题)是在着色器。
vec4 pos = gl_Vertex + vec4(texValue.xyz, 1.0);
应该vec4 pos = gl_Vertex + vec4(texValue.xyz, 0.0);
这是因为gl_Vertex是一个3向量,有一个额外的1元素来辅助矩阵变换。这个元素应该总是1。本例创建了另一个3+1向量,并将其添加到gl_Vertex,使其为2。用零代替1,比例问题就解决了。
模糊(第二个问题)是由纹理插值引起的。
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
必须是
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);
,这样插值器将只从纹理中获取值,而不是从相邻的纹理像素(可能是点云另一侧的点)中进行插值。在解决了这两个问题之后,这个例子就像广告中宣传的那样工作了,在我有限的测试中似乎快了一点。
相关文章:
- 输入数据成员未按要求工作
- 如果用户不小心给出了不正确的数据类型,cin 如何工作?
- C++ TCP 套接字通信 - 连接按预期工作,几秒钟后失败,没有收到新数据,read() 和 recv() 块
- 德拉吉诺 LG01-S 收到异常数据包并停止工作
- Qt C++ - 如何将数据从工作线程传递到主线程?
- 输入数据类型检查循环未按预期工作 (C++)
- 程序 使用链表插入数据时停止工作
- curl发送JSON数据不使用C 工作
- 将数据集几乎平均分配给工作线程
- 现代 OpenGL 多维数据集旋转未按预期工作
- 在Qt中使用工作线程将数据写入文件的正确方法是什么?
- 如何让我的构造函数和函数工作,以便我的 main() 能够同时显示字符串和 int 数据
- C 插座未接收传入的数据包,在Python中工作
- 现代C++.从继续执行的工作线程返回数据结构
- 基于PHP示例,与C 中数据结构一起工作的多态性示例
- 如何将数据文件加载到自动Excel工作表文档
- C++指针给出数据类型为"int"的错误,但与"char"一起工作正常
- 将数据输入到 2-D 数组中,这是如何工作的
- 插入[n X n]矩阵类型的数据,并在运行时对其进行访问.将std::映射工作
- QModelIndex::数据不工作