0

I am fairly new to OpenSceneGraph and I am working on an application that generates point clouds. We first create an osg::Geometry object containing the points of a particular area, we then create an osg::Geode that contains the geometry and then we add it as a child to an osg::Group that contains all of the terrain points. We then add that as the scene data of our osgViewer::Viewer in which we also setup our camera.

So we generate our geode/geometry like this:

osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry());
geometry->setVertexArray(vertices.get());
geometry->setColorArray(colors.get());
geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, static_cast<int>(segment_size)));
geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
geometry->getOrCreateStateSet()->setRenderingHint(osg::StateSet::OPAQUE_BIN);
osg::ref_ptr<osg::Geode> geode(new osg::Geode());
geode->addDrawable(geometry.get());
geode->setNodeMask(TERRAIN_ENABLED_NODE_MASK);

And we add it to our group and viewer like this:

m_terrain_group = new osg::Group();    
m_terrain_group->addChild(geode);
m_viewer = new osgViewer::Viewer();
m_viewer->setCamera(make_camera(width(), height(), m_graphics_window_embedded));
m_viewer->setCameraManipulator(make_camera_manipulator(), true);
m_viewer->setThreadingModel(osgViewer::Viewer::SingleThreaded);
m_viewer->realize();
m_viewer->setSceneData(m_terrain_group);

The make_camera function looks like this:

osg::Camera* OsgWidget::make_camera(int width, int height, osg::GraphicsContext* graphics_context) const noexcept
{
    double aspect_ratio = static_cast<double>(width) / static_cast<double>(height);

    osg::CullSettings cull_settings;
    cull_settings.setCullingMode(osg::CullSettings::CullingModeValues::VIEW_FRUSTUM_SIDES_CULLING | osg::CullSettings::CullingModeValues::CLUSTER_CULLING);
    cull_settings.setCullMask(TERRAIN_ENABLED_NODE_MASK);

    osg::Camera* camera = new osg::Camera();
    camera->setViewport(0, 0, width, height);
    camera->setProjectionMatrixAsPerspective(m_camera_vertical_fov, aspect_ratio, m_camera_clipping_planes.first, m_camera_clipping_planes.second);
    camera->setGraphicsContext(graphics_context);
    camera->setCullSettings(cull_settings);
    camera->getOrCreateStateSet()->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
    return camera;
}

The final results looks like this when moving the camera:

enter image description here

As you can see, the depth of the points seems very wrong, with planes popping in and out of each other.

Does anyone have a clue on how to fix this? Am I even looking at the right part of the code to fix this?

  • 1
    I must admit that I know a bit about OpenGL but haven't yet worked with OpenScenegraph. How did you set near and far clip distance for the perspective view? I suspect these are the values given by `m_camera_clipping_planes.first, m_camera_clipping_planes.second`. (So bigger the distance of far and near so worse the quality of depth test.) Btw. do you have depth test enabled at all? Is it enabled by default? – Scheff's Cat Nov 09 '21 at 16:19
  • I guessed correctly. ;-) [osg::Camera::setProjectionMatrixAsPerspective()](https://weber.itn.liu.se/~karlu20/tmp/OpenSceneGraph/classosg_1_1Camera.html#afe4fab17f1cc5b4664c17ed79717aabb) – Scheff's Cat Nov 09 '21 at 16:23
  • I also found this: [how to se the near and far clip plane?](https://osg-users.openscenegraph.narkive.com/m1UWFwTl/how-to-se-the-near-and-far-clip-plane-setprojectionmatrixasperspective-not-working) – Scheff's Cat Nov 09 '21 at 16:27
  • 1
    @Scheff'sCat Oh wow, there it is, depth testing was not enabled. I looked into enabling depth test and I found the following line m_terrain_group->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON); and there it is, it works, thank you so much. – Mathieu Poulin Nov 09 '21 at 17:13

1 Answers1

2

As suggested by @Scheff'sCat, depth testing was not enabled. Adding the following line fixed my problem.

m_terrain_group->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON);