From 249c0ff208868d3c313287f2ef3905b2f9a53806 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 16 Jan 2015 11:03:11 +0000 Subject: [PATCH] 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 --- include/osgTerrain/GeometryPool | 2 + src/osgTerrain/GeometryPool.cpp | 78 ++++++++++++++++++++++++++++----- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/include/osgTerrain/GeometryPool b/include/osgTerrain/GeometryPool index 9d5c23fa2..e166875f5 100644 --- a/include/osgTerrain/GeometryPool +++ b/include/osgTerrain/GeometryPool @@ -113,6 +113,8 @@ class OSGTERRAIN_EXPORT GeometryPool : public osg::Referenced protected: virtual ~GeometryPool(); + bool _useGeometryShader; + OpenThreads::Mutex _geometryMapMutex; GeometryMap _geometryMap; diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index df4b827d9..242e367bc 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -41,7 +41,8 @@ const osgTerrain::Locator* osgTerrain::computeMasterLocator(const osgTerrain::Te // // GeometryPool // -GeometryPool::GeometryPool() +GeometryPool::GeometryPool(): + _useGeometryShader(false) { } @@ -103,8 +104,9 @@ osg::ref_ptr GeometryPool::getOrCreateGeometry(osgTerrain::Terra osg::ref_ptr geometry = new SharedGeometry; _geometryMap[key] = geometry; - SharedGeometry::VertexToHeightFieldMapping& vthfm = geometry->getVertexToHeightFieldMapping(); + geometry->setUseVertexBufferObjects(true); + SharedGeometry::VertexToHeightFieldMapping& vthfm = geometry->getVertexToHeightFieldMapping(); osg::ref_ptr vertices = new osg::Vec3Array; geometry->setVertexArray(vertices.get()); @@ -246,7 +248,7 @@ osg::ref_ptr GeometryPool::getOrCreateGeometry(osgTerrain::Terra } } -#if 1 +#if 0 bool smallTile = numVertices <= 16384; osg::ref_ptr elements = smallTile ? @@ -299,9 +301,10 @@ osg::ref_ptr GeometryPool::getOrCreateGeometry(osgTerrain::Terra #else bool smallTile = numVertices <= 16384; + GLenum primitiveTypes = _useGeometryShader ? GL_LINES_ADJACENCY : GL_QUADS; osg::ref_ptr elements = smallTile ? - static_cast(new osg::DrawElementsUShort(GL_QUADS)) : - static_cast(new osg::DrawElementsUInt(GL_QUADS)); + static_cast(new osg::DrawElementsUShort(primitiveTypes)) : + static_cast(new osg::DrawElementsUInt(primitiveTypes)); elements->reserveElements( (nx-1) * (ny-1) * 4 + (nx-1)*2*4 + (ny-1)*2*4 ); geometry->addPrimitiveSet(elements.get()); @@ -582,14 +585,33 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp #endif + bool useLighting = true; + bool useTextures = true; + osg::ref_ptr program = new osg::Program; _programMap[layerTypes] = program; + // add shader that provides the lighting functions + program->addShader(osgDB::readShaderFile("shaders/lighting.vert")); + // OSG_NOTICE<<") creating new Program "<0) { #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 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 { @@ -597,31 +619,52 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp 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) { OSG_NOTICE<<"No support for Contour yet."< shader; if (num_Color==0) { #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) { #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) { #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) { #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()) { pf.setVertexArray(_vertices->size(), &((*_vertices)[0])); + for(osg::Geometry::PrimitiveSetList::const_iterator itr = _geometry->getPrimitiveSetList().begin(); itr != _geometry->getPrimitiveSetList().end(); ++itr) { - (*itr)->accept(pf); + const osg::DrawElementsUShort* deus = dynamic_cast(itr->get()); + if (deus) + { + pf.drawElements(GL_QUADS, deus->size(), &((*deus)[0])); + } + else + { + const osg::DrawElementsUInt* deui = dynamic_cast(itr->get()); + if (deui) + { + pf.drawElements(GL_QUADS, deui->size(), &((*deui)[0])); + } + } } } else