diff --git a/examples/osgterrain/osgterrain.cpp b/examples/osgterrain/osgterrain.cpp index 3828be87d..0af0f55d9 100644 --- a/examples/osgterrain/osgterrain.cpp +++ b/examples/osgterrain/osgterrain.cpp @@ -42,13 +42,69 @@ #include #include - #include #include #include #include +class OSGVIEWER_EXPORT FilterHandler : public osgGA::GUIEventHandler +{ +public: + + FilterHandler(osgTerrain::GeometryTechnique* gt): + _gt(gt) {} + + bool handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa) + { + if (!_gt) return false; + + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYDOWN): + { + if (ea.getKey() == 'g') + { + osg::notify(osg::NOTICE)<<"Gaussian"<setFilterMatrixAs(osgTerrain::GeometryTechnique::GAUSSIAN); + return true; + } + else if (ea.getKey() == 's') + { + osg::notify(osg::NOTICE)<<"Smooth"<setFilterMatrixAs(osgTerrain::GeometryTechnique::SMOOTH); + return true; + } + else if (ea.getKey() == 'S') + { + osg::notify(osg::NOTICE)<<"Sharpen"<setFilterMatrixAs(osgTerrain::GeometryTechnique::SHARPEN); + return true; + } + else if (ea.getKey() == '+') + { + _gt->setFilterWidth(_gt->getFilterWidth()*1.1); + return true; + } + else if (ea.getKey() == '-') + { + _gt->setFilterWidth(_gt->getFilterWidth()/1.1); + return true; + } + break; + } + default: + break; + } + return false; + + } + +protected: + + osg::observer_ptr _gt; + +}; @@ -57,7 +113,7 @@ int main(int argc, char** argv) osg::ArgumentParser arguments(&argc, argv); // construct the viewer. - osgViewer::Viewer viewer; + osgViewer::Viewer viewer(arguments); // set up the camera manipulators. { @@ -92,6 +148,10 @@ int main(int argc, char** argv) // add the stats handler viewer.addEventHandler(new osgViewer::StatsHandler); + // add the record camera path handler + viewer.addEventHandler(new osgViewer::RecordCameraPathHandler); + + double x = 0.0; double y = 0.0; double w = 1.0; @@ -254,7 +314,7 @@ int main(int argc, char** argv) osg::notify(osg::NOTICE)<<"--filter "<setColorFilter(layerNum, osgTerrain::TerrainNode::NEAREST); } - else if (filterName=="LINEAER") + else if (filterName=="LINEAR") { osg::notify(osg::NOTICE)<<"--filter "<setColorFilter(layerNum, osgTerrain::TerrainNode::LINEAR); @@ -298,6 +358,8 @@ int main(int argc, char** argv) terrain->setTerrainTechnique(geometryTechnique.get()); + viewer.addEventHandler(new FilterHandler(geometryTechnique.get())); + if (!terrain) return 0; // return 0; diff --git a/include/osgTerrain/GeometryTechnique b/include/osgTerrain/GeometryTechnique index ec0658217..7ed250e4a 100644 --- a/include/osgTerrain/GeometryTechnique +++ b/include/osgTerrain/GeometryTechnique @@ -106,6 +106,25 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique virtual void cleanSceneGraph(); virtual void dirty(); + + + + void setFilterWidth(float filterWidth); + float getFilterWidth() const { return _filterWidth; } + + void setFilterMatrix(const osg::Matrix3& matrix); + osg::Matrix3& getFilterMatrix() { return _filterMatrix; } + const osg::Matrix3& getFilterMatrix() const { return _filterMatrix; } + + enum FilterType + { + GAUSSIAN, + SMOOTH, + SHARPEN + }; + + void setFilterMatrixAs(FilterType filterType); + protected: @@ -116,6 +135,11 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique osg::ref_ptr _terrainGeometry; osg::ref_ptr _geometry; + + float _filterWidth; + osg::ref_ptr _filterWidthUniform; + osg::Matrix3 _filterMatrix; + osg::ref_ptr _filterMatrixUniform; }; } diff --git a/src/osgTerrain/GeometryTechnique.cpp b/src/osgTerrain/GeometryTechnique.cpp index 913747918..8a5e97429 100644 --- a/src/osgTerrain/GeometryTechnique.cpp +++ b/src/osgTerrain/GeometryTechnique.cpp @@ -1,4 +1,4 @@ -/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield + /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or @@ -29,6 +29,8 @@ using namespace osgTerrain; GeometryTechnique::GeometryTechnique() { + setFilterWidth(0.1); + setFilterMatrixAs(GAUSSIAN); } GeometryTechnique::GeometryTechnique(const GeometryTechnique& gt,const osg::CopyOp& copyop): @@ -40,6 +42,44 @@ GeometryTechnique::~GeometryTechnique() { } +void GeometryTechnique::setFilterWidth(float filterWidth) +{ + _filterWidth = filterWidth; + if (!_filterWidthUniform) _filterWidthUniform = new osg::Uniform("filterWidth",_filterWidth); + else _filterWidthUniform->set(filterWidth); +} + +void GeometryTechnique::setFilterMatrix(const osg::Matrix3& matrix) +{ + _filterMatrix = matrix; + if (!_filterMatrixUniform) _filterMatrixUniform = new osg::Uniform("filterMatrix",_filterMatrix); + else _filterMatrixUniform->set(_filterMatrix); +} + +void GeometryTechnique::setFilterMatrixAs(FilterType filterType) +{ + switch(filterType) + { + case(SMOOTH): + setFilterMatrix(osg::Matrix3(0.0, 0.5/2.5, 0.0, + 0.5/2.5, 0.5/2.5, 0.5/2.5, + 0.0, 0.5/2.5, 0.0)); + break; + case(GAUSSIAN): + setFilterMatrix(osg::Matrix3(0.0, 1.0/8.0, 0.0, + 1.0/8.0, 4.0/8.0, 1.0/8.0, + 0.0, 1.0/8.0, 0.0)); + break; + case(SHARPEN): + setFilterMatrix(osg::Matrix3(0.0, -1.0, 0.0, + -1.0, 5.0, -1.0, + 0.0, -1.0, 0.0)); + break; + + }; +} + + void GeometryTechnique::init() { osg::notify(osg::NOTICE)<<"Doing init()"<setAttribute(program); // get shaders from source - std::string vertexShaderFile = osgDB::findDataFile("lookup.vert"); + std::string vertexShaderFile = osgDB::findDataFile("shaders/lookup.vert"); if (!vertexShaderFile.empty()) { program->addShader(osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexShaderFile)); @@ -427,7 +467,7 @@ void GeometryTechnique::init() osg::notify(osg::NOTICE)<<"Not found lookup.vert"<addShader(osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentShaderFile)); @@ -443,6 +483,12 @@ void GeometryTechnique::init() osg::Uniform* lookupTexture = new osg::Uniform("lookupTexture",tf_index); stateset->addUniform(lookupTexture); + stateset->addUniform(_filterWidthUniform.get()); + stateset->addUniform(_filterMatrixUniform.get()); + + osg::Uniform* lightingEnabled = new osg::Uniform("lightingEnabled",true); + stateset->addUniform(lightingEnabled); + osg::Uniform* minValue = new osg::Uniform("minValue", tf->getMinimum()); stateset->addUniform(minValue); @@ -477,6 +523,7 @@ void GeometryTechnique::init() void GeometryTechnique::update(osgUtil::UpdateVisitor* nv) { + }