Introduced support for controlling mipmapping of osgTerrain::ImageLayer and compression of osgTerrain::HeightFieldLayer.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
@@ -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 "";
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user