Added support for using geometry shaders to align the quad diagonals with the local terrain

git-svn-id: http://svn.openscenegraph.org/osg/OpenSceneGraph/trunk@14658 16af8721-9629-0410-8352-f15c8da7e697
This commit is contained in:
Robert Osfield 2015-01-16 11:03:11 +00:00
parent 3e3d7e4dc1
commit 249c0ff208
2 changed files with 69 additions and 11 deletions

View File

@ -113,6 +113,8 @@ class OSGTERRAIN_EXPORT GeometryPool : public osg::Referenced
protected: protected:
virtual ~GeometryPool(); virtual ~GeometryPool();
bool _useGeometryShader;
OpenThreads::Mutex _geometryMapMutex; OpenThreads::Mutex _geometryMapMutex;
GeometryMap _geometryMap; GeometryMap _geometryMap;

View File

@ -41,7 +41,8 @@ const osgTerrain::Locator* osgTerrain::computeMasterLocator(const osgTerrain::Te
// //
// GeometryPool // GeometryPool
// //
GeometryPool::GeometryPool() GeometryPool::GeometryPool():
_useGeometryShader(false)
{ {
} }
@ -103,8 +104,9 @@ osg::ref_ptr<SharedGeometry> GeometryPool::getOrCreateGeometry(osgTerrain::Terra
osg::ref_ptr<SharedGeometry> geometry = new SharedGeometry; osg::ref_ptr<SharedGeometry> geometry = new SharedGeometry;
_geometryMap[key] = geometry; _geometryMap[key] = geometry;
SharedGeometry::VertexToHeightFieldMapping& vthfm = geometry->getVertexToHeightFieldMapping(); geometry->setUseVertexBufferObjects(true);
SharedGeometry::VertexToHeightFieldMapping& vthfm = geometry->getVertexToHeightFieldMapping();
osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array; osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
geometry->setVertexArray(vertices.get()); geometry->setVertexArray(vertices.get());
@ -246,7 +248,7 @@ osg::ref_ptr<SharedGeometry> GeometryPool::getOrCreateGeometry(osgTerrain::Terra
} }
} }
#if 1 #if 0
bool smallTile = numVertices <= 16384; bool smallTile = numVertices <= 16384;
osg::ref_ptr<osg::DrawElements> elements = smallTile ? osg::ref_ptr<osg::DrawElements> elements = smallTile ?
@ -299,9 +301,10 @@ osg::ref_ptr<SharedGeometry> GeometryPool::getOrCreateGeometry(osgTerrain::Terra
#else #else
bool smallTile = numVertices <= 16384; bool smallTile = numVertices <= 16384;
GLenum primitiveTypes = _useGeometryShader ? GL_LINES_ADJACENCY : GL_QUADS;
osg::ref_ptr<osg::DrawElements> elements = smallTile ? osg::ref_ptr<osg::DrawElements> elements = smallTile ?
static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(GL_QUADS)) : static_cast<osg::DrawElements*>(new osg::DrawElementsUShort(primitiveTypes)) :
static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(GL_QUADS)); static_cast<osg::DrawElements*>(new osg::DrawElementsUInt(primitiveTypes));
elements->reserveElements( (nx-1) * (ny-1) * 4 + (nx-1)*2*4 + (ny-1)*2*4 ); elements->reserveElements( (nx-1) * (ny-1) * 4 + (nx-1)*2*4 + (ny-1)*2*4 );
geometry->addPrimitiveSet(elements.get()); geometry->addPrimitiveSet(elements.get());
@ -582,14 +585,33 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
#endif #endif
bool useLighting = true;
bool useTextures = true;
osg::ref_ptr<osg::Program> program = new osg::Program; osg::ref_ptr<osg::Program> program = new osg::Program;
_programMap[layerTypes] = program; _programMap[layerTypes] = program;
// add shader that provides the lighting functions
program->addShader(osgDB::readShaderFile("shaders/lighting.vert"));
// OSG_NOTICE<<") creating new Program "<<program.get()<<std::endl; // OSG_NOTICE<<") creating new Program "<<program.get()<<std::endl;
if (num_HeightField>0) if (num_HeightField>0)
{ {
#include "shaders/terrain_displacement_mapping_vert.cpp" #include "shaders/terrain_displacement_mapping_vert.cpp"
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_vert)); osg::ref_ptr<osg::Shader> shader = osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_vert);
if (_useGeometryShader)
{
// prepend define to enable the compute shader style
shader->setShaderSource(std::string("#define COMPUTE_DIAGONALS\n")+shader->getShaderSource());
}
if (useLighting)
{
// prepend define to enable lighting
shader->setShaderSource(std::string("#define GL_LIGHTING\n")+shader->getShaderSource());
}
program->addShader(shader.get());
} }
else else
{ {
@ -597,31 +619,52 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_flat_vert)); program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.vert", terrain_displacement_mapping_flat_vert));
} }
if (_useGeometryShader)
{
program->addShader(osgDB::readShaderFile("shaders/terrain_displacement_mapping.geom"));
program->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, 4 );
program->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, GL_LINES_ADJACENCY );
program->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, GL_TRIANGLE_STRIP);
}
if (num_Contour>0) if (num_Contour>0)
{ {
OSG_NOTICE<<"No support for Contour yet."<<std::endl; OSG_NOTICE<<"No support for Contour yet."<<std::endl;
} }
{ {
osg::ref_ptr<osg::Shader> shader;
if (num_Color==0) if (num_Color==0)
{ {
#include "shaders/terrain_displacement_mapping_frag.cpp" #include "shaders/terrain_displacement_mapping_frag.cpp"
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping.frag", terrain_displacement_mapping_frag)); shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping.frag", terrain_displacement_mapping_frag);
} }
else if (num_Color==1) else if (num_Color==1)
{ {
#include "shaders/terrain_displacement_mapping_C_frag.cpp" #include "shaders/terrain_displacement_mapping_C_frag.cpp"
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping_C.frag", terrain_displacement_mapping_C_frag)); shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_C.frag", terrain_displacement_mapping_C_frag);
} }
else if (num_Color==2) else if (num_Color==2)
{ {
#include "shaders/terrain_displacement_mapping_CC_frag.cpp" #include "shaders/terrain_displacement_mapping_CC_frag.cpp"
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping_CC.frag", terrain_displacement_mapping_CC_frag)); shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_CC.frag", terrain_displacement_mapping_CC_frag);
} }
else if (num_Color==3) else if (num_Color==3)
{ {
#include "shaders/terrain_displacement_mapping_CCC_frag.cpp" #include "shaders/terrain_displacement_mapping_CCC_frag.cpp"
program->addShader(osgDB::readShaderFileWithFallback(osg::Shader::VERTEX, "shaders/terrain_displacement_mapping_CCC.frag", terrain_displacement_mapping_CCC_frag)); shader = osgDB::readShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/terrain_displacement_mapping_CCC.frag", terrain_displacement_mapping_CCC_frag);
}
if (shader.valid())
{
if (useTextures)
{
// prepend define to enable lighting
shader->setShaderSource(std::string("#define GL_TEXTURE_2D\n")+shader->getShaderSource());
}
program->addShader(shader.get());
} }
} }
@ -860,11 +903,24 @@ void HeightFieldDrawable::accept(osg::PrimitiveFunctor& pf) const
if (_vertices.valid()) if (_vertices.valid())
{ {
pf.setVertexArray(_vertices->size(), &((*_vertices)[0])); pf.setVertexArray(_vertices->size(), &((*_vertices)[0]));
for(osg::Geometry::PrimitiveSetList::const_iterator itr = _geometry->getPrimitiveSetList().begin(); for(osg::Geometry::PrimitiveSetList::const_iterator itr = _geometry->getPrimitiveSetList().begin();
itr != _geometry->getPrimitiveSetList().end(); itr != _geometry->getPrimitiveSetList().end();
++itr) ++itr)
{ {
(*itr)->accept(pf); const osg::DrawElementsUShort* deus = dynamic_cast<const osg::DrawElementsUShort*>(itr->get());
if (deus)
{
pf.drawElements(GL_QUADS, deus->size(), &((*deus)[0]));
}
else
{
const osg::DrawElementsUInt* deui = dynamic_cast<const osg::DrawElementsUInt*>(itr->get());
if (deui)
{
pf.drawElements(GL_QUADS, deui->size(), &((*deui)[0]));
}
}
} }
} }
else else