From Maria Ten, "I divide the init method of the

geometrytechnique in submethods to made more easy the inheritance
between the user and osg-class. This is a first step to add more
functions in osgTerrain. Maybe the subdivision of the method have to
be in the terraintechnique because is the base class of
GeometryTechnique. If Robert or anyone think that this is better i
change this class too."
This commit is contained in:
Robert Osfield 2007-08-16 14:13:10 +00:00
parent 65ecea4e4a
commit 2f41234793
2 changed files with 143 additions and 41 deletions

View File

@ -19,6 +19,7 @@
#include <osg/Geometry>
#include <osgTerrain/TerrainTechnique>
#include <osgTerrain/Locator>
namespace osgTerrain {
@ -33,6 +34,20 @@ class OSGTERRAIN_EXPORT GeometryTechnique : public TerrainTechnique
virtual void init();
virtual Locator* computeMasterLocator();
virtual const osg::Vec3d computeCenterModel(Locator* masterLocator);
virtual void generateGeometry(Locator* masterLocator, const osg::Vec3d& centerModel);
virtual void applyColorLayers();
virtual void applyTransferFunctions();
virtual void applyTransparency();
virtual void smoothGeometry();
virtual void update(osgUtil::UpdateVisitor* nv);
virtual void cull(osgUtil::CullVisitor* nv);

View File

@ -96,28 +96,39 @@ void GeometryTechnique::setFilterMatrixAs(FilterType filterType)
};
}
void GeometryTechnique::init()
{
osg::notify(osg::NOTICE)<<"Doing init()"<<std::endl;
if (!_terrain) return;
BufferData& buffer = getWriteBuffer();
Locator* masterLocator = computeMasterLocator();
osg::Vec3d centerModel = computeCenterModel(masterLocator);
generateGeometry(masterLocator, centerModel);
applyColorLayers();
applyTransferFunctions();
applyTransparency();
smoothGeometry();
if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true);
_dirty = false;
swapBuffers();
}
Locator* GeometryTechnique::computeMasterLocator()
{
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
osgTerrain::Terrain::Filter filter = _terrain->getColorFilter(0);
// if the elevationLayer and colorLayer are the same, and there is colorTF then
// simply assing as a texture coordinate.
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
osg::notify(osg::NOTICE)<<"elevationLayer = "<<elevationLayer<<std::endl;
osg::notify(osg::NOTICE)<<"colorLayer = "<<colorLayer<<std::endl;
osg::notify(osg::NOTICE)<<"colorTF = "<<colorTF<<std::endl;
Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
@ -126,9 +137,25 @@ void GeometryTechnique::init()
if (!masterLocator)
{
osg::notify(osg::NOTICE)<<"Problem, no locator found in any of the terrain layers"<<std::endl;
return;
return 0;
}
return masterLocator;
}
const osg::Vec3d GeometryTechnique::computeCenterModel(Locator* masterLocator)
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
if (!elevationLocator) elevationLocator = masterLocator;
if (!colorLocator) colorLocator = masterLocator;
@ -168,11 +195,7 @@ void GeometryTechnique::init()
osg::notify(osg::NOTICE)<<"bottomLeftNDC = "<<bottomLeftNDC<<std::endl;
osg::notify(osg::NOTICE)<<"topRightNDC = "<<topRightNDC<<std::endl;
buffer._geode = new osg::Geode;
buffer._transform = new osg::MatrixTransform;
buffer._transform->addChild(buffer._geode.get());
osg::Vec3d centerNDC = (bottomLeftNDC + topRightNDC)*0.5;
osg::Vec3d centerModel = (bottomLeftNDC + topRightNDC)*0.5;
@ -180,10 +203,30 @@ void GeometryTechnique::init()
buffer._transform->setMatrix(osg::Matrix::translate(centerModel));
return centerModel;
}
void GeometryTechnique::generateGeometry(Locator* masterLocator, const osg::Vec3d& centerModel)
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
if (!colorLocator) colorLocator = masterLocator;
buffer._geode = new osg::Geode;
if(buffer._transform.valid())
buffer._transform->addChild(buffer._geode.get());
buffer._geometry = new osg::Geometry;
if (buffer._geometry.valid()) buffer._geode->addDrawable(buffer._geometry.get());
unsigned int numRows = 100;
unsigned int numColumns = 100;
@ -329,7 +372,6 @@ void GeometryTechnique::init()
}
}
// populate primitive sets
bool optimizeOrientations = _elevations!=0;
bool swapOrientation = !(masterLocator->orientationOpenGL());
@ -339,7 +381,7 @@ void GeometryTechnique::init()
if (buffer._geometry.valid()) buffer._geometry->addPrimitiveSet(elements);
for(j=0; j<numRows-1; ++j)
for(unsigned int j=0; j<numRows-1; ++j)
{
for(unsigned int i=0; i<numColumns-1; ++i)
{
@ -410,11 +452,25 @@ void GeometryTechnique::init()
}
}
// if (_terrainGeometry.valid()) _terrainGeometry->setUseDisplayList(false);
if (buffer._geometry.valid()) buffer._geometry->setUseVertexBufferObjects(true);
}
bool containsTransparency = false;
void GeometryTechnique::applyColorLayers()
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
osgTerrain::Terrain::Filter filter = _terrain->getColorFilter(0);
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
int color_index = -1;
if (colorLayer)
{
color_index++;
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
if (imageLayer)
{
@ -435,18 +491,30 @@ void GeometryTechnique::init()
//image->setInternalTextureFormat(GL_LUMINANCE32F_ARB);
image->setInternalTextureFormat(GL_LUMINANCE16);
}
else
{
containsTransparency = image->isImageTranslucent();
}
}
}
}
void GeometryTechnique::applyTransferFunctions()
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
int color_index = -1;
int tf_index = -1;
if (colorLayer) {
color_index++;
tf_index++;
}
if (tf)
{
osg::notify(osg::NOTICE)<<"Requires TransferFunction"<<std::endl;
tf_index++;
osg::Image* image = tf->getImage();
osg::StateSet* stateset = buffer._geode->getOrCreateStateSet();
osg::Texture1D* texture1D = new osg::Texture1D;
@ -456,8 +524,6 @@ void GeometryTechnique::init()
texture1D->setFilter(osg::Texture::MAG_FILTER, osg::Texture::NEAREST);
stateset->setTextureAttributeAndModes(tf_index, texture1D, osg::StateAttribute::ON);
containsTransparency = image->isImageTranslucent();
if (colorLayer)
{
osg::notify(osg::NOTICE)<<"Using fragment program"<<std::endl;
@ -510,6 +576,31 @@ void GeometryTechnique::init()
osg::notify(osg::NOTICE)<<"Using standard OpenGL fixed function pipeline"<<std::endl;
}
}
}
void GeometryTechnique::applyTransparency()
{
BufferData& buffer = getWriteBuffer();
osgTerrain::Layer* elevationLayer = _terrain->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrain->getColorLayer(0);
osg::TransferFunction* colorTF = _terrain->getColorTransferFunction(0);
// if the elevationLayer and colorLayer are the same, and there is colorTF then
// simply assing as a texture coordinate.
if ((elevationLayer==colorLayer) && colorTF) colorLayer = 0;
bool containsTransparency = false;
if (colorLayer)
{
osgTerrain::ImageLayer* imageLayer = dynamic_cast<osgTerrain::ImageLayer*>(colorLayer);
if (imageLayer) {
osg::TransferFunction1D* tf = dynamic_cast<osg::TransferFunction1D*>(colorTF);
if (tf) containsTransparency = tf->getImage()->isImageTranslucent();
else containsTransparency = imageLayer->getImage()->isImageTranslucent();
}
}
if (containsTransparency)
{
@ -518,23 +609,19 @@ void GeometryTechnique::init()
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
}
// if (_terrainGeometry.valid()) _terrainGeometry->setUseDisplayList(false);
if (buffer._geometry.valid()) buffer._geometry->setUseVertexBufferObjects(true);
}
void GeometryTechnique::smoothGeometry()
{
BufferData& buffer = getWriteBuffer();
if (buffer._geometry.valid())
{
osgUtil::SmoothingVisitor smoother;
smoother.smooth(*buffer._geometry);
}
if (buffer._transform.valid()) buffer._transform->setThreadSafeRefUnref(true);
_dirty = false;
swapBuffers();
}
void GeometryTechnique::update(osgUtil::UpdateVisitor* uv)
{
if (_terrain) _terrain->osg::Group::traverse(*uv);