openscenegraph

OSG Outline only appears on one side of geometry


I'm trying to make an outline appear around a piece of 2D geometry in a scene. The outline appears only on one side of the geometry and I want it to appear on both sides. I assume there's a setting I need to specify but being new to OSG I don't know what this might be; I can't discern it from the documentation or online examples either.

The geometry is basically a flat plane consisting of a bunch of smaller flat planes with stalks sticking out of one side.

enter image description here

What I currently have

What I currently have

// Initialize an outline
osg::ref_ptr<osgFX::Outline> vCellOutline = new osgFX::Outline;
mModel3D->addChild(vCellOutline); // Add it as a child of the grid so it appears in the scene
vCellOutline->setWidth(8); // Set some stuff so it appears
vCellOutline->setColor(osg::Vec4(1, 1, 0, 1));
osg::ref_ptr<osg::StateSet> vOutlineState = vCellOutline->getOrCreateStateSet();
vOutlineState->setMode(GL_LIGHTING, osg::StateAttribute::PROTECTED | osg::StateAttribute::ON);

// Add the cell as a child of the outline
vCellOutline->addChild(vCellGeode);

I've tried increasing the width since I thought maybe it wasn't showing through, but it makes no difference. The outline disappears when the camera views the geometry from beyond a "side on" perspective.

I did some googling and tried various things like assigning a two-sided light model (in case it wasn't being lit properly), trying to disable culling via e.g.

vOutlineState->setMode(GL_CULL_FACE, osg::StateAttribute::OFF);
vCellOutline->setCullingActive(false);

But that didn't do anything. I thought I'd found the solution when I saw that, by default, osg Outlines cull their front-facing polys, so I tried:

osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
cf->setMode(osg::CullFace::FRONT);
vOutlineState->setAttributeAndModes(cf, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);

But again, no effect. Interestingly I can turn off the back-facing polys using this method.


Solution

  • Doing this has worked:

    osg::ref_ptr<osg::CullFace> cf = new osg::CullFace;
    cf->setMode(osg::CullFace::FRONT);
    vOutlineState->setAttributeAndModes(cf, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);
    

    And:

    osg::ref_ptr<osg::PolygonMode> polyMode = new osg::PolygonMode;
    polyMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::LINE);
    vOutlineState->setAttributeAndModes(polyMode, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
    

    I guess because the front-facing stuff is not explicitly set up in the Outline class; only the back-facing stuff is.


    As an aside, I then had an issue where the outline would disappear when viewed directly head-on from the front. I still don't know why, but I changed my "view head-on" code to offset the perspective slightly, which is enough to bring the outline back.