Introduced support for controlling mipmapping of osgTerrain::ImageLayer and compression of osgTerrain::HeightFieldLayer.

This commit is contained in:
Robert Osfield
2008-10-20 08:43:25 +00:00
parent 351ac1614c
commit 10186190f6
18 changed files with 430 additions and 71 deletions

View File

@@ -646,7 +646,7 @@ int main(int argc, char** argv)
std::string filterName;
osgTerrain::Layer::Filter filter = osgTerrain::Layer::LINEAR;
osg::Texture::FilterMode filter = osg::Texture::LINEAR;
bool readParameter = false;
float minValue, maxValue;
@@ -705,7 +705,7 @@ int main(int argc, char** argv)
hfl->setLocator(locator.get());
hfl->setValidDataOperator(validDataOperator.get());
hfl->setFilter(filter);
hfl->setMagFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -740,7 +740,7 @@ int main(int argc, char** argv)
imageLayer->setImage(image.get());
imageLayer->setLocator(locator.get());
imageLayer->setValidDataOperator(validDataOperator.get());
imageLayer->setFilter(filter);
imageLayer->setMagFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -775,7 +775,7 @@ int main(int argc, char** argv)
imageLayer->setImage(image.get());
imageLayer->setLocator(locator.get());
imageLayer->setValidDataOperator(validDataOperator.get());
imageLayer->setFilter(filter);
imageLayer->setMagFilter(filter);
if (offset!=0.0f || scale!=1.0f)
{
@@ -805,11 +805,11 @@ int main(int argc, char** argv)
if (filterName=="NEAREST")
{
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<std::endl;
filter = osgTerrain::Layer::NEAREST;
filter = osg::Texture::NEAREST;
}
else if (filterName=="LINEAR")
{
filter = osgTerrain::Layer::LINEAR;
filter = osg::Texture::LINEAR;
osg::notify(osg::NOTICE)<<"--filter "<<filterName<<std::endl;
}
else
@@ -819,7 +819,7 @@ int main(int argc, char** argv)
if (terrainTile->getColorLayer(layerNum))
{
terrainTile->getColorLayer(layerNum)->setFilter(filter);
terrainTile->getColorLayer(layerNum)->setMagFilter(filter);
}
}

View File

@@ -267,7 +267,8 @@ class OSG_EXPORT GraphicsContext : public Object
inline const Vec4& getClearColor() const { return _clearColor; }
/** Set the clear mask used in glClear(..).
* Defaults to GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT. */
* Defaults to 0 - so no clear is done by default by the GraphicsContext, instead the Camera's attached the GraphicsContext will do the clear.
* GraphicsContext::setClearMask() is useful for when the Camera's Viewports don't conver the whole context, so the context will fill in the gaps. */
inline void setClearMask(GLbitfield mask) { _clearMask = mask; }
/** Get the clear mask.*/

View File

@@ -77,17 +77,20 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
void setDefaultValue(const osg::Vec4& value) { _defaultValue = value; }
const osg::Vec4& getDefaultValue() const { return _defaultValue; }
enum Filter
{
NEAREST,
LINEAR
};
/** Set the texture filter to use when do texture associated with this layer.*/
void setFilter(Filter filter) { _filter = filter; }
/** Set the minification texture filter to use when do texture associated with this layer.*/
void setMinFilter(osg::Texture::FilterMode filter) { _minFilter = filter; }
/** Get the minification texture filter to use when do texture associated with this layer.*/
osg::Texture::FilterMode getMinFilter() const { return _minFilter; }
/** Set the magniification texture filter to use when do texture associated with this layer.*/
void setMagFilter(osg::Texture::FilterMode filter) { _magFilter = filter; }
/** Get the magnification texture filter to use when do texture associated with this layer.*/
osg::Texture::FilterMode getMagFilter() const { return _magFilter; }
/** Get the texture filter to use when do texture associated with this layer.*/
Filter getFilter() const { return _filter; }
/** Return image associated with layer if supported. */
@@ -209,7 +212,8 @@ class OSGTERRAIN_EXPORT Layer : public osg::Object
unsigned int _maxLevel;
osg::ref_ptr<ValidDataOperator> _validDataOperator;
osg::Vec4 _defaultValue;
Filter _filter;
osg::Texture::FilterMode _minFilter;
osg::Texture::FilterMode _magFilter;
};

View File

@@ -617,6 +617,8 @@ void Image::readPixels(int x,int y,int width,int height,
void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMapsIfAvailable, GLenum type)
{
// osg::notify(osg::NOTICE)<<"Image::readImageFromCurrentTexture()"<<std::endl;
const osg::Texture::Extensions* extensions = osg::Texture::getExtensions(contextID,true);
const osg::Texture3D::Extensions* extensions3D = osg::Texture3D::getExtensions(contextID,true);
const osg::Texture2DArray::Extensions* extensions2DArray = osg::Texture2DArray::getExtensions(contextID,true);
@@ -655,6 +657,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_WIDTH, &width);
glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_HEIGHT, &height);
glGetTexLevelParameteriv(textureMode, numMipMaps, GL_TEXTURE_DEPTH, &depth);
// osg::notify(osg::NOTICE)<<" numMipMaps="<<numMipMaps<<" width="<<width<<" height="<<height<<" depth="<<depth<<std::endl;
if (width==0 || height==0 || depth==0) break;
}
}
@@ -662,6 +665,8 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
{
numMipMaps = 1;
}
// osg::notify(osg::NOTICE)<<"Image::readImageFromCurrentTexture() : numMipMaps = "<<numMipMaps<<std::endl;
GLint compressed = 0;

View File

@@ -906,6 +906,9 @@ void Texture::computeRequiredTextureDimensions(State& state, const osg::Image& i
height >>= 1;
}
}
// osg::notify(osg::NOTICE)<<"Texture::computeRequiredTextureDimensions() image.s() "<<image.s()<<" image.t()="<<image.t()<<" width="<<width<<" height="<<height<<" numMipmapLevels="<<numMipmapLevels<<std::endl;
// osg::notify(osg::NOTICE)<<" _resizeNonPowerOfTwoHint="<<_resizeNonPowerOfTwoHint<<" extensions->isNonPowerOfTwoTextureSupported(_min_filter)="<<extensions->isNonPowerOfTwoTextureSupported(_min_filter) <<std::endl;
}
bool Texture::areAllTextureObjectsLoaded() const
@@ -977,6 +980,7 @@ void Texture::applyTexImage2D_load(State& state, GLenum target, const Image* ima
unsigned char* data = (unsigned char*)image->data();
// osg::notify(osg::NOTICE)<<"inwidth="<<inwidth<<" inheight="<<inheight<<" image->getFileName()"<<image->getFileName()<<std::endl;
bool needImageRescale = inwidth!=image->s() || inheight!=image->t();
if (needImageRescale)

View File

@@ -596,11 +596,11 @@ osg::Image* ReadDDSFile(std::istream& _istream)
float power2_s = logf((float)s)/logf((float)2);
float power2_t = logf((float)t)/logf((float)2);
osg::notify(osg::INFO) << "ReadDDSFile info : ddsd.dwMipMapCount = "<<ddsd.dwMipMapCount<<std::endl;
osg::notify(osg::INFO) << "ReadDDSFile info : s = "<<s<<std::endl;
osg::notify(osg::INFO) << "ReadDDSFile info : t = "<<t<<std::endl;
osg::notify(osg::INFO) << "ReadDDSFile info : power2_s="<<power2_s<<std::endl;
osg::notify(osg::INFO) << "ReadDDSFile info : power2_t="<<power2_t<<std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : ddsd.dwMipMapCount = "<<ddsd.dwMipMapCount<<std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : s = "<<s<<std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : t = "<<t<<std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : power2_s="<<power2_s<<std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : power2_t="<<power2_t<<std::endl;
mipmaps.resize((unsigned int)osg::maximum(power2_s,power2_t),0);
@@ -654,7 +654,7 @@ osg::Image* ReadDDSFile(std::istream& _istream)
if (mipmaps.size()>0) osgImage->setMipmapLevels(mipmaps);
unsigned int size = osgImage->getTotalSizeInBytesIncludingMipmaps();
osg::notify(osg::INFO) << "ReadDDSFile info : size = " << size << std::endl;
osg::notify(osg::NOTICE) << "ReadDDSFile NOTICE : size = " << size << std::endl;
if(size <= 0)
{
@@ -874,6 +874,12 @@ bool WriteDDSFile(const osg::Image *img, std::ostream& fout)
SD_flags |= DDSD_MIPMAPCOUNT;
CAPS_flags |= DDSCAPS_COMPLEX | DDSCAPS_MIPMAP;
ddsd.dwMipMapCount = img->getNumMipmapLevels();
osg::notify(osg::NOTICE)<<"writing out with mipmaps ddsd.dwMipMapCount"<<ddsd.dwMipMapCount<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<"no mipmaps to write out."<<std::endl;
}

View File

@@ -701,6 +701,76 @@ osg::Vec4ubArray* DataInputStream::readVec4ubArray()
return a;
}
bool DataInputStream::readPackedFloatArray(osg::FloatArray* a)
{
int size = readInt();
a->resize(size);
if (size == 0)
return true;
if (readBool())
{
float value = readFloat();
for(int i=0; i<size; ++i)
{
(*a)[i] = value;
}
}
else
{
int packingSize = readInt();
if (packingSize==1)
{
float minValue = readFloat();
float maxValue = readFloat();
float byteMultiplier = 255.0f/(maxValue-minValue);
float byteInvMultiplier = 1.0f/byteMultiplier;
for(int i=0; i<size; ++i)
{
unsigned char byte_value = readUChar();
float value = minValue + float(byte_value)*byteInvMultiplier;
(*a)[i] = value;
}
}
else if (packingSize==2)
{
float minValue = readFloat();
float maxValue = readFloat();
float shortMultiplier = 65535.0f/(maxValue-minValue);
float shortInvMultiplier = 1.0f/shortMultiplier;
for(int i=0; i<size; ++i)
{
unsigned short short_value = readUShort();
float value = minValue + float(short_value)*shortInvMultiplier;
(*a)[i] = value;
}
}
else
{
for(int i=0; i<size; ++i)
{
(*a)[i] = readFloat();
}
}
}
if (_istream->rdstate() & _istream->failbit)
throw Exception("DataInputStream::readFloatArray(): Failed to read float array.");
if (_verboseOutput) std::cout<<"read/writeFloatArray() ["<<size<<"]"<<std::endl;
return true;
}
osg::FloatArray* DataInputStream::readFloatArray()
{
int size = readInt();

View File

@@ -74,6 +74,7 @@ public:
osg::UShortArray* readUShortArray();
osg::UIntArray* readUIntArray();
osg::Vec4ubArray* readVec4ubArray();
bool readPackedFloatArray(osg::FloatArray* floatArray);
osg::FloatArray* readFloatArray();
osg::Vec2Array* readVec2Array();
osg::Vec3Array* readVec3Array();
@@ -107,6 +108,7 @@ public:
void setLoadExternalReferenceFiles(bool b) {_loadExternalReferenceFiles=b;};
bool getLoadExternalReferenceFiles() {return _loadExternalReferenceFiles;};
typedef std::map<std::string, osg::ref_ptr<osg::Image> > ImageMap;
typedef std::map<int,osg::ref_ptr<osg::StateSet> > StateSetMap;
typedef std::map<int,osg::ref_ptr<osg::StateAttribute> > StateAttributeMap;

View File

@@ -128,6 +128,7 @@ DataOutputStream::DataOutputStream(std::ostream * ostream, const osgDB::ReaderWr
_includeExternalReferences = false;
_writeExternalReferenceFiles = false;
_useOriginalExternalReferences = true;
_maximumErrorToSizeRatio = 0.001;
_options = options;
@@ -135,26 +136,50 @@ DataOutputStream::DataOutputStream(std::ostream * ostream, const osgDB::ReaderWr
if (_options.get())
{
if(_options->getOptionString().find("noTexturesInIVEFile")!=std::string::npos) {
std::string optionsString = _options->getOptionString();
if(optionsString.find("noTexturesInIVEFile")!=std::string::npos) {
setIncludeImageMode(IMAGE_REFERENCE_FILE);
} else if(_options->getOptionString().find("includeImageFileInIVEFile")!=std::string::npos) {
} else if(optionsString.find("includeImageFileInIVEFile")!=std::string::npos) {
setIncludeImageMode(IMAGE_INCLUDE_FILE);
} else if(_options->getOptionString().find("compressImageData")!=std::string::npos) {
} else if(optionsString.find("compressImageData")!=std::string::npos) {
setIncludeImageMode(IMAGE_COMPRESS_DATA);
}
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeImageMode()=" << getIncludeImageMode() << std::endl;
setIncludeExternalReferences(_options->getOptionString().find("inlineExternalReferencesInIVEFile")!=std::string::npos);
setIncludeExternalReferences(optionsString.find("inlineExternalReferencesInIVEFile")!=std::string::npos);
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setIncludeExternalReferences()=" << getIncludeExternalReferences() << std::endl;
setWriteExternalReferenceFiles(_options->getOptionString().find("noWriteExternalReferenceFiles")==std::string::npos);
setWriteExternalReferenceFiles(optionsString.find("noWriteExternalReferenceFiles")==std::string::npos);
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setWriteExternalReferenceFiles()=" << getWriteExternalReferenceFiles() << std::endl;
setUseOriginalExternalReferences(_options->getOptionString().find("useOriginalExternalReferences")!=std::string::npos);
setUseOriginalExternalReferences(optionsString.find("useOriginalExternalReferences")!=std::string::npos);
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream.setUseOriginalExternalReferences()=" << getUseOriginalExternalReferences() << std::endl;
_compressionLevel = (_options->getOptionString().find("compressed")!=std::string::npos) ? 1 : 0;
_compressionLevel = (optionsString.find("compressed")!=std::string::npos) ? 1 : 0;
osg::notify(osg::DEBUG_INFO) << "ive::DataOutpouStream._compressionLevel=" << _compressionLevel << std::endl;
std::string::size_type terrainErrorPos = optionsString.find("TerrainMaximumErrorToSizeRatio=");
if (terrainErrorPos!=std::string::npos)
{
std::string::size_type endOfToken = optionsString.find_first_of('=', terrainErrorPos);
std::string::size_type endOfNumber = optionsString.find_first_of(' ', endOfToken);
std::string::size_type numOfCharInNumber = (endOfNumber != std::string::npos) ?
endOfNumber-endOfToken-1 :
optionsString.size()-endOfToken-1;
if (numOfCharInNumber>0)
{
std::string numberString = optionsString.substr(endOfToken+1, numOfCharInNumber);
_maximumErrorToSizeRatio = atof(numberString.c_str());
osg::notify(osg::DEBUG_INFO)<<"TerrainMaximumErrorToSizeRatio = "<<_maximumErrorToSizeRatio<<std::endl;
}
else
{
osg::notify(osg::DEBUG_INFO)<<"Error no value to TerrainMaximumErrorToSizeRatio assigned"<<std::endl;
}
}
}
#ifndef USE_ZLIB
@@ -592,6 +617,117 @@ void DataOutputStream::writeVec4ubArray(const osg::Vec4ubArray* a)
if (_verboseOutput) std::cout<<"read/writeVec4ubArray() ["<<size<<"]"<<std::endl;
}
void DataOutputStream::writePackedFloatArray(const osg::FloatArray* a, float maxError)
{
int size = a->getNumElements();
writeInt(size);
if (size==0) return;
float minValue = (*a)[0];
float maxValue = minValue;
for(int i=1; i<size; ++i)
{
if ((*a)[i]<minValue) minValue = (*a)[i];
if ((*a)[i]>maxValue) maxValue = (*a)[i];
}
if (minValue==maxValue)
{
osg::notify(osg::DEBUG_INFO)<<"Writing out "<<size<<" same values "<<minValue<<std::endl;
writeBool(true);
writeFloat(minValue);
return;
}
writeBool(false);
int packingSize = 4;
if (maxError>0.0f)
{
float byteError = 0.0f;
float byteMultiplier = 255.0f/(maxValue-minValue);
float byteInvMultiplier = 1.0f/byteMultiplier;
float shortError = 0.0f;
float shortMultiplier = 65535.0f/(maxValue-minValue);
float shortInvMultiplier = 1.0f/shortMultiplier;
float max_error_byte = 0.0f;
float max_error_short = 0.0f;
for(int i=0; i<size; ++i)
{
float value = (*a)[i];
unsigned char byteValue = (unsigned char)((value-minValue)*byteMultiplier);
unsigned short shortValue = (unsigned short)((value-minValue)*shortMultiplier);
float value_byte = minValue + float(byteValue)*byteInvMultiplier;
float value_short = minValue + float(shortValue)*shortInvMultiplier;
float error_byte = fabsf(value_byte - value);
float error_short = fabsf(value_short - value);
if (error_byte>max_error_byte) max_error_byte = error_byte;
if (error_short>max_error_short) max_error_short = error_short;
}
osg::notify(osg::DEBUG_INFO)<<"maxError "<<maxError<<std::endl;
osg::notify(osg::DEBUG_INFO)<<"Values to write "<<size<<" max_error_byte = "<<max_error_byte<<" max_error_short="<<max_error_short<<std::endl;
if (max_error_byte < maxError) packingSize = 1;
else if (max_error_short < maxError) packingSize = 2;
osg::notify(osg::DEBUG_INFO)<<"packingSize "<<packingSize<<std::endl;
}
if (packingSize==1)
{
writeInt(1);
writeFloat(minValue);
writeFloat(maxValue);
float byteMultiplier = 255.0f/(maxValue-minValue);
for(int i=0; i<size; ++i)
{
unsigned char currentValue = (unsigned char)(((*a)[i]-minValue)*byteMultiplier);
writeUChar(currentValue);
}
}
else if (packingSize==2)
{
writeInt(2);
writeFloat(minValue);
writeFloat(maxValue);
float shortMultiplier = 65535.0f/(maxValue-minValue);
for(int i=0; i<size; ++i)
{
unsigned short currentValue = (unsigned short)(((*a)[i]-minValue)*shortMultiplier);
writeUShort(currentValue);
}
}
else
{
writeInt(4);
for(int i=0; i<size; ++i)
{
writeFloat((*a)[i]);
}
}
if (_verboseOutput) std::cout<<"read/writePackedFloatArray() ["<<size<<"]"<<std::endl;
}
void DataOutputStream::writeFloatArray(const osg::FloatArray* a)
{
int size = a->getNumElements();

View File

@@ -71,6 +71,9 @@ public:
void writeVec2b(const osg::Vec2b& v);
void writeVec3b(const osg::Vec3b& v);
void writeVec4b(const osg::Vec4b& v);
void writePackedFloatArray(const osg::FloatArray* a, float maxError);
void writeFloatArray(const osg::FloatArray* a);
void writeVec2Array(const osg::Vec2Array* a);
void writeVec3Array(const osg::Vec3Array* a);
@@ -122,6 +125,10 @@ public:
void setUseOriginalExternalReferences(bool b) {_useOriginalExternalReferences=b;};
bool getUseOriginalExternalReferences() const {return _useOriginalExternalReferences;};
void setTerrainMaximumErrorToSizeRatio(double ratio) { _maximumErrorToSizeRatio = ratio; }
double getTerrainMaximumErrorToSizeRatio() const { return _maximumErrorToSizeRatio; }
bool _verboseOutput;
bool compress(std::ostream& fout, const std::string& source) const;
@@ -159,6 +166,7 @@ private:
bool _includeExternalReferences;
bool _writeExternalReferenceFiles;
bool _useOriginalExternalReferences;
double _maximumErrorToSizeRatio;
IncludeImageMode _includeImageMode;

View File

@@ -12,7 +12,16 @@
//Don't know where else to put this
namespace ive{
enum IncludeImageMode { IMAGE_REFERENCE_FILE=0,IMAGE_INCLUDE_DATA,IMAGE_INCLUDE_FILE,IMAGE_COMPRESS_DATA };
enum IncludeImageMode
{
IMAGE_REFERENCE_FILE=0,
IMAGE_INCLUDE_DATA,
IMAGE_INCLUDE_FILE,
IMAGE_COMPRESS_DATA
};
}
#endif

View File

@@ -16,6 +16,7 @@
#include "Layer.h"
#include <osgDB/ReadFile>
#include <osg/io_utils>
using namespace ive;
@@ -34,9 +35,45 @@ void HeightFieldLayer::write(DataOutputStream* out)
if (getFileName().empty() && getHeightField())
{
osg::HeightField* hf = getHeightField();
// using inline heightfield
out->writeBool(true);
out->writeShape(getHeightField());
if (out->getVersion()>=VERSION_0035)
{
// Write HeightField's properties.
out->writeUInt(hf->getNumColumns());
out->writeUInt(hf->getNumRows());
out->writeVec3(hf->getOrigin());
out->writeFloat(hf->getXInterval());
out->writeFloat(hf->getYInterval());
out->writeQuat(hf->getRotation());
out->writeFloat(hf->getSkirtHeight());
out->writeUInt(hf->getBorderWidth());
int packingSize = 1;
float maxError = 0.0f;
if (getLocator())
{
osg::Vec3d world_origin, world_corner;
getLocator()->convertLocalToModel(osg::Vec3d(0.0,0.0,0.0), world_origin);
getLocator()->convertLocalToModel(osg::Vec3d(1.0,1.0,0.0), world_corner);
double distance = (world_origin-world_corner).length();
maxError = distance * out->getTerrainMaximumErrorToSizeRatio();
}
out->writePackedFloatArray(hf->getFloatArray(), maxError);
}
else
{
out->writeShape(getHeightField());
}
}
else
{
@@ -69,8 +106,39 @@ void HeightFieldLayer::read(DataInputStream* in)
if (useInlineHeightField)
{
osg::Shape* shape = in->readShape();
setHeightField(dynamic_cast<osg::HeightField*>(shape));
if (in->getVersion()>=VERSION_0035)
{
osg::HeightField* hf = new osg::HeightField;
// Read HeightField's properties
//setColor(in->readVec4());
unsigned int col = in->readUInt();
unsigned int row = in->readUInt();
hf->allocate(col,row);
hf->setOrigin(in->readVec3());
hf->setXInterval(in->readFloat());
hf->setYInterval(in->readFloat());
hf->setRotation(in->readQuat());
hf->setSkirtHeight(in->readFloat());
hf->setBorderWidth(in->readUInt());
if (in->getVersion()>=VERSION_0035)
{
in->readPackedFloatArray(hf->getFloatArray());
}
setHeightField(hf);
}
else
{
osg::Shape* shape = in->readShape();
setHeightField(dynamic_cast<osg::HeightField*>(shape));
}
}
else
{

View File

@@ -42,8 +42,10 @@
#define VERSION_0031 31
#define VERSION_0032 32
#define VERSION_0033 33
#define VERSION_0034 34
#define VERSION_0035 35
#define VERSION VERSION_0033
#define VERSION VERSION_0035
/* The BYTE_SEX tag is used to check the endian
of the IVE file being read in. The IVE format

View File

@@ -41,13 +41,24 @@ void Layer::write(DataOutputStream* out)
if (out->getVersion() >= VERSION_0023)
{
out->writeLocator(getLocator());
out->writeUInt(getFilter());
if (out->getVersion() >= VERSION_0034)
{
out->writeUInt(getMinFilter());
out->writeUInt(getMagFilter());
}
else
{
out->writeUInt((getMagFilter()==osg::Texture::LINEAR) ? 1 : 0);
}
}
else
{
LayerHelper helper;
helper.writeLocator(out, getLocator());
}
out->writeUInt(getMinLevel());
out->writeUInt(getMaxLevel());
@@ -78,7 +89,16 @@ void Layer::read(DataInputStream* in)
if (in->getVersion() >= VERSION_0023)
{
setLocator(in->readLocator());
setFilter(osgTerrain::Layer::Filter(in->readUInt()));
if (in->getVersion() >= VERSION_0034)
{
setMinFilter(osg::Texture::FilterMode(in->readUInt()));
setMagFilter(osg::Texture::FilterMode(in->readUInt()));
}
else
{
setMagFilter(in->readUInt()==0 ? osg::Texture::NEAREST : osg::Texture::LINEAR);
}
}
else
{

View File

@@ -24,6 +24,7 @@ class ReaderWriterIVE : public ReaderWriter
supportsOption("inlineExternalReferencesInIVEFile","Export option");
supportsOption("noWriteExternalReferenceFiles","Export option");
supportsOption("useOriginalExternalReferences","Export option");
supportsOption("TerrainMaximumErrorToSizeRatio=value","Export option that controls error matric used to determine terrain HieghtField storage precision.");
supportsOption("noLoadExternalReferenceFiles","Import option");
}

View File

@@ -15,6 +15,8 @@
bool Layer_readLocalData(osg::Object &obj, osgDB::Input &fr);
bool Layer_writeLocalData(const osg::Object &obj, osgDB::Output &fw);
bool Layer_matchFilterStr(const char* str, osg::Texture::FilterMode& filter);
const char* Layer_getFilterStr(osg::Texture::FilterMode filter);
osgDB::RegisterDotOsgWrapperProxy Layer_Proxy
(
@@ -35,23 +37,19 @@ bool Layer_readLocalData(osg::Object& obj, osgDB::Input &fr)
osgTerrain::Locator* locator = dynamic_cast<osgTerrain::Locator*>(readObject.get());
if (locator) layer.setLocator(locator);
if (fr[0].matchWord("Filter"))
osg::Texture::FilterMode filter;
if (fr[0].matchWord("MinFilter") && Layer_matchFilterStr(fr[1].getStr(),filter))
{
unsigned int layerNum = 0;
if (fr.matchSequence("Filter %i"))
{
fr[1].getUInt(layerNum);
fr += 2;
}
else
{
++fr;
}
layer.setMinFilter(filter);
fr+=2;
itrAdvanced = true;
}
if (fr[0].matchWord("NEAREST")) layer.setFilter(osgTerrain::Layer::NEAREST);
else if (fr[0].matchWord("LINEAR")) layer.setFilter(osgTerrain::Layer::LINEAR);
++fr;
if ((fr[0].matchWord("Filter") || fr[0].matchWord("MagFilter")) &&
Layer_matchFilterStr(fr[1].getStr(),filter))
{
layer.setMagFilter(filter);
fr+=2;
itrAdvanced = true;
}
@@ -82,17 +80,8 @@ bool Layer_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
fw.writeObject(*layer.getLocator());
}
if (layer.getFilter()!=osgTerrain::Layer::LINEAR)
{
if (layer.getFilter()==osgTerrain::Layer::LINEAR)
{
fw.indent()<<"Filter LINEAER"<<std::endl;
}
else
{
fw.indent()<<"Filter NEAREST"<<std::endl;
}
}
fw.indent()<<"MinFilter "<<Layer_getFilterStr(layer.getMinFilter())<<std::endl;
fw.indent()<<"MagFilter "<<Layer_getFilterStr(layer.getMagFilter())<<std::endl;
if (layer.getMinLevel()!=0)
{
@@ -106,3 +95,32 @@ bool Layer_writeLocalData(const osg::Object& obj, osgDB::Output& fw)
return true;
}
bool Layer_matchFilterStr(const char* str, osg::Texture::FilterMode& filter)
{
if (strcmp(str,"NEAREST")==0) filter = osg::Texture::NEAREST;
else if (strcmp(str,"LINEAR")==0) filter = osg::Texture::LINEAR;
else if (strcmp(str,"NEAREST_MIPMAP_NEAREST")==0) filter = osg::Texture::NEAREST_MIPMAP_NEAREST;
else if (strcmp(str,"LINEAR_MIPMAP_NEAREST")==0) filter = osg::Texture::LINEAR_MIPMAP_NEAREST;
else if (strcmp(str,"NEAREST_MIPMAP_LINEAR")==0) filter = osg::Texture::NEAREST_MIPMAP_LINEAR;
else if (strcmp(str,"LINEAR_MIPMAP_LINEAR")==0) filter = osg::Texture::LINEAR_MIPMAP_LINEAR;
else if (strcmp(str,"ANISOTROPIC")==0) filter = osg::Texture::LINEAR;
else return false;
return true;
}
const char* Layer_getFilterStr(osg::Texture::FilterMode filter)
{
switch(filter)
{
case(osg::Texture::NEAREST): return "NEAREST";
case(osg::Texture::LINEAR): return "LINEAR";
case(osg::Texture::NEAREST_MIPMAP_NEAREST): return "NEAREST_MIPMAP_NEAREST";
case(osg::Texture::LINEAR_MIPMAP_NEAREST): return "LINEAR_MIPMAP_NEAREST";
case(osg::Texture::NEAREST_MIPMAP_LINEAR): return "NEAREST_MIPMAP_LINEAR";
case(osg::Texture::LINEAR_MIPMAP_LINEAR): return "LINEAR_MIPMAP_LINEAR";
}
return "";
}

View File

@@ -717,14 +717,16 @@ void GeometryTechnique::applyColorLayers()
texture2D->setImage(image);
texture2D->setMaxAnisotropy(16.0f);
texture2D->setResizeNonPowerOfTwoHint(false);
texture2D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
texture2D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getFilter()==Layer::LINEAR ? osg::Texture::LINEAR : osg::Texture::NEAREST);
texture2D->setFilter(osg::Texture::MIN_FILTER, colorLayer->getMinFilter());
texture2D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
texture2D->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
layerToTextureMap[colorLayer] = texture2D;
// osg::notify(osg::NOTICE)<<"Creating new ImageLayer texture "<<layerNum<<std::endl;
// osg::notify(osg::NOTICE)<<"Creating new ImageLayer texture "<<layerNum<<" image->s()="<<image->s()<<" image->t()="<<image->t()<<std::endl;
}
else
@@ -746,7 +748,7 @@ void GeometryTechnique::applyColorLayers()
texture1D->setImage(image);
texture1D->setResizeNonPowerOfTwoHint(false);
texture1D->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST);
texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getFilter()==Layer::LINEAR ? osg::Texture::LINEAR : osg::Texture::NEAREST);
texture1D->setFilter(osg::Texture::MAG_FILTER, colorLayer->getMagFilter());
layerToTextureMap[colorLayer] = texture1D;
}

View File

@@ -55,7 +55,8 @@ std::string osgTerrain::createCompondSetNameAndFileName(const std::string& setna
Layer::Layer():
_minLevel(0),
_maxLevel(MAXIMUM_NUMBER_OF_LEVELS),
_filter(LINEAR)
_minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR),
_magFilter(osg::Texture::LINEAR)
{
}
@@ -64,7 +65,8 @@ Layer::Layer(const Layer& layer,const osg::CopyOp& copyop):
_filename(layer._filename),
_minLevel(layer._minLevel),
_maxLevel(layer._maxLevel),
_filter(layer._filter)
_minFilter(layer._minFilter),
_magFilter(layer._magFilter)
{
}
@@ -305,7 +307,8 @@ unsigned int ImageLayer::getModifiedCount() const
ContourLayer::ContourLayer(osg::TransferFunction1D* tf):
_tf(tf)
{
_filter = NEAREST;
_minFilter = osg::Texture::NEAREST;
_magFilter = osg::Texture::NEAREST;
}
ContourLayer::ContourLayer(const ContourLayer& contourLayer,const osg::CopyOp& copyop):