Raymond,
We had a similar problem with a few, older, air field models. Luckily the polygons that represent the stripes where positioned in the models scene-graph to draw last (with respect to the model). All that was required was for us to turn off depth for the sections that needed it (indicated by comments at the nodes that mattered). ////////////////////////////////////////////////////////////////////////////// class SetAllNodesToNoDepth : public osg::NodeVisitor { public: SetAllNodesToNoDepth(): osg::NodeVisitor( osg::NodeVisitor::TRAVERSE_ALL_CHILDREN ) {} void apply( osg::Node& node ) { osg::StateSet* stateset = node.getStateSet(); if ( stateset ) { stateset->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF ); node.setStateSet( stateset ); } traverse(node); } }; ... model->accept( new SetAllNodesToNoDepth() ); ... I think the order can be managed with render bins as well. There are a few ways to skin that cat. Good luck! -B -----Original Message----- From: osg-users-boun...@lists.openscenegraph.org [mailto:osg-users-boun...@lists.openscenegraph.org] On Behalf Of Raymond Bosman Sent: Monday, November 28, 2011 8:25 AM To: osg-users@lists.openscenegraph.org Subject: Re: [osg-users] How to create a decal on a road segment? To demonstrate the problem here is a screenshot. [Image: http://forum.openscenegraph.org/files/ramp_segment_587.png ] The code below shows a simplified version of the problem. When you look at the same angle as shown in the screenshot, the 'lanes' (red triangles) will appear through the 'road' (green rectangles). Code: #include <osg/Geode> #include <osg/Geometry> #include <osg/ShapeDrawable> #include <osg/Depth> #include <osgViewer/Viewer> #include <osgGA/TrackballManipulator> #include <osgDB/WriteFile> #include <vector> #include <osg/Stencil> osg::Geometry * createGeometry( const std::vector<float> &roadheight, float width, osg::Vec4Array *color, bool isDecal ) { osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry; // Geometry osg::Vec3Array* vertices = new osg::Vec3Array; for( int i = 0; i < roadheight.size(); ++i ) { vertices->push_back(osg::Vec3( (float) i, 0 , roadheight[i])); if( !isDecal || i % 2 == 1 ) { vertices->push_back(osg::Vec3( (float) i, width , roadheight[i])); } } geometry->setVertexArray(vertices); // Set color geometry->setColorArray(color); geometry->setColorBinding(osg::Geometry::BIND_OVERALL); // Normals, all upwards for now osg::Vec3Array* normals = new osg::Vec3Array; normals->push_back(osg::Vec3(0.0f,0.0f,1.0f)); geometry->setNormalArray(normals); geometry->setNormalBinding(osg::Geometry::BIND_OVERALL); geometry->addPrimitiveSet(new osg::DrawArrays( ( isDecal ? osg::PrimitiveSet::TRIANGLES : osg::PrimitiveSet::TRIANGLE_STRIP ) ,0,vertices->size())); return geometry.release(); } osg::Geode* stencilGeometry( osg::Geometry *road, osg::Geometry *decal) { osg::Geode *geode = new osg::Geode; // Write to stencil buffer { osg::Stencil* stencil = new osg::Stencil; stencil->setFunction(osg::Stencil::ALWAYS, 1,~0u); // Always pass where we draw. Write 1 to stencil buffer. stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::REPLACE, osg::Stencil::REPLACE); osg::StateSet *stateset = road->getOrCreateStateSet(); stateset->setRenderBinDetails(1,"RenderBin"); stateset->setAttributeAndModes(stencil,osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_STENCIL_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } geode->addDrawable( road ); { osg::Stencil* stencil = new osg::Stencil; stencil->setFunction(osg::Stencil::EQUAL, 1, ~0u); // Draw only if 1. stencil->setOperation(osg::Stencil::KEEP, osg::Stencil::KEEP, osg::Stencil::KEEP); osg::StateSet *stateset = decal->getOrCreateStateSet(); stateset->setRenderBinDetails(1,"RenderBin"); stateset->setAttributeAndModes(stencil,osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_STENCIL_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); } geode->addDrawable( decal ); return geode; } osg::Geode* multipassGeometry( osg::Geometry *road, osg::Geometry *decal) { osg::Geode *geode = new osg::Geode; // road { osg::StateSet *stateset = road->getOrCreateStateSet(); stateset->setRenderBinDetails(1,"RenderBin"); stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE); geode->addDrawable( road ); } // Decal { osg::StateSet *stateset = decal->getOrCreateStateSet(); stateset->setRenderBinDetails(1,"RenderBin"); stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); stateset->setMode(GL_CULL_FACE, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); geode->addDrawable( decal ); } // road again { osg::Geometry *road2 = (osg::Geometry *) road->clone(osg::CopyOp::DEEP_COPY_STATESETS); osg::StateSet *stateset = road2->getOrCreateStateSet(); stateset->setRenderBinDetails(1,"RenderBin"); stateset->setMode(GL_DEPTH_TEST, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE); osg::ColorMask *mask = new osg::ColorMask(false, false, false, false); stateset->setAttributeAndModes(mask, osg::StateAttribute::ON); geode->addDrawable( road2 ); } return geode; } int main(int argc, char *argv[]) { const bool ENABLE_STENCILING = false; osg::DisplaySettings::instance()->setMinimumNumStencilBits(1); osg::ArgumentParser args(&argc, argv); osgViewer::Viewer viewer(args); unsigned int clearMask = viewer.getCamera()->getClearMask(); viewer.getCamera()->setClearMask(clearMask | GL_STENCIL_BUFFER_BIT); viewer.getCamera()->setClearStencil(0); osg::Group* root = new osg::Group; std::vector<float> roadHeight; roadHeight.push_back( 1.0f ); roadHeight.push_back( 1.0f ); roadHeight.push_back( 0.0f ); roadHeight.push_back( 0.0f ); // Create the 'road'. osg::Vec4Array* green = new osg::Vec4Array; green->push_back( osg::Vec4(0.0f, 1.0f, 0.0f, 1.0f )); osg::Geometry *geometry = createGeometry( roadHeight, 1.0f, green, false ); // Create the 'lane markers' osg::Vec4Array* red = new osg::Vec4Array; red->push_back( osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f) ); osg::Geometry *decalGeom = createGeometry( roadHeight, 1.0f, red ,true ); osg::Geode* geode = 0; if ( ENABLE_STENCILING ) { geode = stencilGeometry( geometry, decalGeom ); } else { geode = multipassGeometry(geometry, decalGeom ); } if( geode ) { viewer.setSceneData( geode ); } viewer.run(); return 0; } Raymond. ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=44074#44074 Attachments: http://forum.openscenegraph.org//files/ramp_segment_587.png _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org