Re: [osg-users] How to create a decal on a road segment?

2011-11-30 Thread Raymond Bosman
Hi Brad,

Thanks for your answer. 
Currently, I place the decal on the road segment without depth testing. For 
flat surfaces (planes) it works fine. When the road has a bump or has an 
incline the depth test seems to be needed. Some lane markers are drawn where 
they should be hidden (depth test fail).

I start to think there is no overall solution. Probably have to separate the 
problem in two:

1. 2D Surfaces: Use stencil buffer.
2. 3D Surfaces: Use polygon offset, height offset.


Cheers, Raymond.

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=44130#44130





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] How to create a decal on a road segment?

2011-11-28 Thread Raymond Bosman
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::vectorfloat roadheight, float 
width, osg::Vec4Array *color, bool isDecal )
{
  osg::ref_ptrosg::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::vectorfloat roadHeight;
roadHeight.push_back( 1.0f );
roadHeight.push_back( 1.0f );
roadHeight.push_back( 0.0f );
  

Re: [osg-users] How to create a decal on a road segment?

2011-11-28 Thread Raymond Bosman
Hi,

Thanks for your answer, but unfortunately the multi-pass technique gives the 
same result as the stencil buffer. (I tried it, to be really sure.)

Cheers Raymond.

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=44073#44073




Attachments: 
http://forum.openscenegraph.org//files/ramp_segment_170.png


___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


Re: [osg-users] How to create a decal on a road segment?

2011-11-28 Thread Brad Colbert
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::vectorfloat roadheight, float 
width, osg::Vec4Array *color, bool isDecal )
{
  osg::ref_ptrosg::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 = 

[osg-users] How to create a decal on a road segment?

2011-11-25 Thread Raymond Bosman
Hi all,

We are trying to create a road with lane lines and other markers on top. For 
the lane markers and the road segment we create separate geometry. 
When we place the geometry on top of the asphalt we got Z-fighting. 

To solve the Z-fighting issues, we tried to use Stencil buffers. In our 
solution this works great for flat surfaces, but not for roads with a steep 
incline.
Some road markers which should not be visible are drawn. This happens because 
the lane lines are drawn without depth buffer testing and doesn't know that a 
part of the lane lines are not visible. The depth buffer is disabled and 
stencil_test enabled to prevent Z-fighting.

Does anyone know a solution to this problem or another approach to create lane 
markers on top of the road?
We tried to use Polygon Offsets, but doesn't give great results.


(Unfortunately, I could not attach an image of the problem or add sample code 
to demonstrate the problem, because it is my first post to this forum.)


Any help would be appreciated! 

Cheers,
Raymond

--
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=44029#44029





___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org



Re: [osg-users] How to create a decal on a road segment?

2011-11-25 Thread Chris 'Xenon' Hanson
On 11/24/2011 10:39 AM, Raymond Bosman wrote:
 Does anyone know a solution to this problem or another approach to create 
 lane markers on top of the road?
 We tried to use Polygon Offsets, but doesn't give great results.

  Have you tried the first multi-pass technique here?

http://glprogramming.com/red/chapter14.html#name12

-- 
Chris 'Xenon' Hanson, omo sanza lettere. xe...@alphapixel.com 
http://www.alphapixel.com/
  Digital Imaging. OpenGL. Scene Graphs. GIS. GPS. Training. Consulting. 
Contracting.
There is no Truth. There is only Perception. To Perceive is to Exist. - 
Xen
___
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org