Added use of GLSL filters

This commit is contained in:
Robert Osfield
2007-06-18 12:10:46 +00:00
parent c8c1e1107e
commit d4309ce69a
3 changed files with 139 additions and 6 deletions

View File

@@ -42,13 +42,69 @@
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgTerrain/TerrainNode>
#include <osgTerrain/GeometryTechnique>
#include <osgTerrain/Layer>
#include <iostream>
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"<<std::endl;
_gt->setFilterMatrixAs(osgTerrain::GeometryTechnique::GAUSSIAN);
return true;
}
else if (ea.getKey() == 's')
{
osg::notify(osg::NOTICE)<<"Smooth"<<std::endl;
_gt->setFilterMatrixAs(osgTerrain::GeometryTechnique::SMOOTH);
return true;
}
else if (ea.getKey() == 'S')
{
osg::notify(osg::NOTICE)<<"Sharpen"<<std::endl;
_gt->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<osgTerrain::GeometryTechnique> _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 "<<filterName<<std::endl;
terrain->setColorFilter(layerNum, osgTerrain::TerrainNode::NEAREST);
}
else if (filterName=="LINEAER")
else if (filterName=="LINEAR")
{
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<std::endl;
terrain->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;

View File

@@ -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> _terrainGeometry;
osg::ref_ptr<osg::Geometry> _geometry;
float _filterWidth;
osg::ref_ptr<osg::Uniform> _filterWidthUniform;
osg::Matrix3 _filterMatrix;
osg::ref_ptr<osg::Uniform> _filterMatrixUniform;
};
}

View File

@@ -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()"<<std::endl;
@@ -417,7 +457,7 @@ void GeometryTechnique::init()
stateset->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"<<std::endl;
}
std::string fragmentShaderFile = osgDB::findDataFile("lookup.frag");
std::string fragmentShaderFile = osgDB::findDataFile("shaders/lookup.frag");
if (!fragmentShaderFile.empty())
{
program->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)
{
}