txparchive.cpp
来自「最新osg包」· C++ 代码 · 共 955 行 · 第 1/2 页
CPP
955 行
#include <osg/Notify>#include <osg/Geode>#include <osg/ShapeDrawable>#include <osg/AlphaFunc>#include <osg/Group>#include <osg/Image>#include <osg/Texture2D>#include <osg/Material>#include <osg/TexEnv>#include <osg/CullFace>#include <osg/Light>#include <osg/StateSet>#include <osg/Point>#include <osg/BlendFunc>#include <osg/MatrixTransform>#include <osgDB/FileUtils>#include <osgDB/FileUtils>#include <osgDB/FileNameUtils>#include <osgDB/fstream>#include <osgDB/ReadFile>#include <osgDB/WriteFile>#include <osgSim/Sector>#include <osgSim/LightPoint>#include <osgSim/LightPointNode>#include <osgSim/BlinkSequence>#include <iostream>#if defined(linux)# include <unistd.h># define _access access#endif#include "TXPArchive.h"#include "TXPParser.h"#include "TileMapper.h"#include <OpenThreads/ScopedLock>using namespace txp;#define TXPArchiveERROR(s) osg::notify(osg::NOTICE) << "txp::TXPArchive::" << (s) << " error: "void TXPArchive::SetTexMap(int key,osg::ref_ptr<osg::Texture2D> ref){ _texmap[key] = ref;}osg::ref_ptr<osg::Texture2D> TXPArchive::GetTexMapEntry(int key){ return _texmap[key];}void TXPArchive::SetStatesMap(int key,osg::ref_ptr<osg::StateSet> ref){ _statesMap[key] = ref;}osg::ref_ptr<osg::StateSet> TXPArchive::GetStatesMapEntry(int key){ return _statesMap[key];}TXPArchive::TXPArchive(): trpgr_Archive(), _id(-1), _numLODs(0), _swExtents(0.0,0.0), _neExtents(0.0,0.0), _majorVersion(-1), _minorVersion(-1), _isMaster(false), _loadMaterialsToStateSet(false){}TXPArchive::~TXPArchive(){ CloseFile();}void TXPArchive::getExtents(osg::BoundingBox& extents){ TileInfo sw, ne; trpg2iPoint tileExtents; this->GetHeader()->GetLodSize(0, tileExtents); this->getTileInfo(0, 0, 0, sw); this->getTileInfo(tileExtents.x-1, tileExtents.y-1, 0, ne); extents.set(sw.bbox._min, sw.bbox._max); extents.expandBy(ne.bbox);} bool TXPArchive::openFile(const std::string& archiveName){ std::string path = osgDB::getFilePath(archiveName); std::string name = osgDB::getSimpleFileName(archiveName); if(path.empty()) { SetDirectory("."); } else { // push the path to the front of the list so that all subsequenct // files get loaded relative to this if possible. osgDB::getDataFilePathList().push_front(path); SetDirectory(path.c_str()); } if (!OpenFile(name.c_str())) { TXPArchiveERROR("openFile()") << "couldn't open archive: " << archiveName << std::endl; return false; } if (!ReadHeader(false)) { TXPArchiveERROR("openFile()") << "couldn't read header for archive: " << archiveName << std::endl; return false; } const trpgHeader *header = GetHeader(); if (header) { header->GetNumLods(_numLODs); header->GetExtents(_swExtents,_neExtents); header->GetVersion(_majorVersion, _minorVersion); _isMaster = header->GetIsMaster(); } int numTextures; texTable.GetNumTextures(numTextures); int numModel; modelTable.GetNumModels(numModel); _models.clear(); int numMaterials; materialTable.GetNumMaterial(numMaterials); return true;}bool TXPArchive::loadMaterial(int ix){ int i = ix; if (GetStatesMapEntry(ix).get()) return true; osg::StateSet* osg_state_set = new osg::StateSet; const trpgMaterial *mat; mat = materialTable.GetMaterialRef(0,i); // Set texture int numMatTex; mat->GetNumTexture(numMatTex); // TODO : multitextuting // also note that multitexturing in terrapage can came from two sides // - multiple textures per material, and multiple materials per geometry // Note: Only in theory. The only type you'll encounter is multiple // materials per polygon. if( numMatTex ) { osg::Material *osg_material = new osg::Material; float64 alpha; mat->GetAlpha(alpha); trpgColor color; mat->GetAmbient(color); osg_material->setAmbient( osg::Material::FRONT_AND_BACK , osg::Vec4(color.red, color.green, color.blue, alpha)); mat->GetDiffuse(color); osg_material->setDiffuse(osg::Material::FRONT_AND_BACK , osg::Vec4(color.red, color.green, color.blue, alpha)); mat->GetSpecular(color); osg_material->setSpecular(osg::Material::FRONT_AND_BACK , osg::Vec4(color.red, color.green, color.blue, alpha)); mat->GetEmission(color); osg_material->setEmission(osg::Material::FRONT_AND_BACK , osg::Vec4(color.red, color.green, color.blue, alpha)); float64 shinines; mat->GetShininess(shinines); osg_material->setShininess(osg::Material::FRONT_AND_BACK , (float)shinines); osg_material->setAlpha(osg::Material::FRONT_AND_BACK ,(float)alpha); osg_state_set->setAttributeAndModes(osg_material, osg::StateAttribute::ON); SetUserDataToMaterialAttributes(*osg_state_set, *mat); if( alpha < 1.0f ) { osg_state_set->setMode(GL_BLEND,osg::StateAttribute::ON); osg_state_set->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } int alphaFunc; mat->GetAlphaFunc(alphaFunc); if( alphaFunc>=GL_NEVER && alphaFunc<=GL_ALWAYS) { float64 ref; mat->GetAlphaRef(ref); osg::AlphaFunc *osg_alpha_func = new osg::AlphaFunc; osg_alpha_func->setFunction((osg::AlphaFunc::ComparisonFunction)alphaFunc,(float)ref); osg_state_set->setAttributeAndModes(osg_alpha_func, osg::StateAttribute::ON); } for (int ntex = 0; ntex < numMatTex; ntex ++ ) { int texId; trpgTextureEnv texEnv; mat->GetTexture(ntex,texId,texEnv); // Set up texture environment osg::TexEnv *osg_texenv = new osg::TexEnv(); int32 te_mode; texEnv.GetEnvMode(te_mode); switch( te_mode ) { case trpgTextureEnv::Alpha : osg_texenv->setMode(osg::TexEnv::REPLACE); break; case trpgTextureEnv::Decal: osg_texenv->setMode(osg::TexEnv::DECAL); break; case trpgTextureEnv::Blend : osg_texenv->setMode(osg::TexEnv::BLEND); break; case trpgTextureEnv::Modulate : osg_texenv->setMode(osg::TexEnv::MODULATE); break; } osg_state_set->setTextureAttribute(ntex,osg_texenv); int wrap_s, wrap_t; texEnv.GetWrap(wrap_s, wrap_t); loadTexture(texId); osg::Texture2D* osg_texture = GetTexMapEntry(texId).get(); if(osg_texture) { osg_texture->setWrap(osg::Texture2D::WRAP_S, wrap_s == trpgTextureEnv::Repeat ? osg::Texture2D::REPEAT: osg::Texture2D::CLAMP_TO_EDGE ); osg_texture->setWrap(osg::Texture2D::WRAP_T, wrap_t == trpgTextureEnv::Repeat ? osg::Texture2D::REPEAT: osg::Texture2D::CLAMP_TO_EDGE ); // ----------- // Min filter // ----------- int32 minFilter; texEnv.GetMinFilter(minFilter); switch (minFilter) { case trpgTextureEnv::Point: case trpgTextureEnv::Nearest: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST); break; case trpgTextureEnv::Linear: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); break; case trpgTextureEnv::MipmapPoint: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_NEAREST); break; case trpgTextureEnv::MipmapLinear: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST_MIPMAP_LINEAR); break; case trpgTextureEnv::MipmapBilinear: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_NEAREST); break; case trpgTextureEnv::MipmapTrilinear: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR_MIPMAP_LINEAR); break; default: osg_texture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR); break; } // ----------- // Mag filter // ----------- int32 magFilter; texEnv.GetMagFilter(magFilter); switch (magFilter) { case trpgTextureEnv::Point: case trpgTextureEnv::Nearest: osg_texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::NEAREST); break; case trpgTextureEnv::Linear: default: osg_texture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR); break; } // pass on to the stateset. osg_state_set->setTextureAttributeAndModes(ntex,osg_texture, osg::StateAttribute::ON); if(osg_texture->getImage() && osg_texture->getImage()->isImageTranslucent()) { osg_state_set->setMode(GL_BLEND,osg::StateAttribute::ON); osg_state_set->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } } } int cullMode; mat->GetCullMode(cullMode); // Culling mode in txp means opposite from osg i.e. Front-> show front face if( cullMode != trpgMaterial::FrontAndBack) { osg::CullFace* cull_face = new osg::CullFace; switch (cullMode) { case trpgMaterial::Front: cull_face->setMode(osg::CullFace::BACK); break; case trpgMaterial::Back: cull_face->setMode(osg::CullFace::FRONT); break; } osg_state_set->setAttributeAndModes(cull_face, osg::StateAttribute::ON); } } SetStatesMap(i,osg_state_set); return true;}bool TXPArchive::loadMaterials(){ return true;}bool TXPArchive::loadTexture(int i){ if (GetTexMapEntry(i).get()) return true; bool separateGeo = false; int majorVer,minorVer; GetVersion(majorVer,minorVer); if((majorVer >= TRPG_NOMERGE_VERSION_MAJOR) && (minorVer>=TRPG_NOMERGE_VERSION_MINOR)) { separateGeo = true; } trpgrImageHelper image_helper(this->GetEndian(),getDir(),materialTable,texTable,separateGeo); const trpgTexture *tex; tex = texTable.GetTextureRef(i); if (!tex) return false; trpgTexture::ImageMode mode; tex->GetImageMode(mode); if(mode == trpgTexture::External) { char texName[ 1024 ]; texName[ 0 ] = 0; tex->GetName(texName,1023); // Create a texture by name. osg::ref_ptr<osg::Texture2D> osg_texture = new osg::Texture2D(); // make sure the Texture unref's the Image after apply, when it is no longer needed. osg_texture->setUnRefImageDataAfterApply(true); // Load Texture and Create Texture State std::string filename = osgDB::getSimpleFileName(texName); std::string path(getDir());#ifdef _WIN32 const char _PATHD = '\\';#elif defined(macintosh) const char _PATHD = ':';#else const char _PATHD = '/';#endif if( path == "." ) path = ""; else path += _PATHD ; std::string theFile = path + filename ; osg::Image* image = osgDB::readImageFile(theFile); if (image) { osg_texture->setImage(image); } else { osg::notify(osg::WARN) << "TrPageArchive::LoadMaterials() error: " << "couldn't open image: " << filename << std::endl; } SetTexMap(i,osg_texture); } else if( mode == trpgTexture::Local ) { SetTexMap(i,getLocalTexture(image_helper,tex)); } else if( mode == trpgTexture::Template ) { SetTexMap(i,0L); } else { SetTexMap(i,0L); } return (GetTexMapEntry(i).get() != 0);}bool TXPArchive::loadModel(int ix){ trpgModel *mod = modelTable.GetModelRef(ix); int type; if(!mod) return false; mod->GetType(type); // Only dealing with external models currently if (type == trpgModel::External) { char name[1024]; mod->GetName(name,1023); // Load the model. It's probably not TerraPage osg::Node *osg_model = osgDB::readNodeFile( name ); if ( !osg_model ) { osg::notify(osg::WARN) << "TrPageArchive::LoadModels() error: " << "failed to load model: " << name << std::endl; } // Do this even if it's NULL _models[ ix ] = osg_model; }/* else { trpgMemReadBuffer buf(GetEndian()); mod->Read(buf); Group *osg_model = parse->ParseScene(buf, m_gstates , m_models); m_models.push_back(osg_model); }*/ return true;}bool TXPArchive::loadModels(){ osg::notify(osg::NOTICE) << "txp:: Loading models ..." << std::endl; int numModel; modelTable.GetNumModels(numModel); // use a pointer to the models map to bootstrap our map trpgModelTable::ModelMapType *mt = modelTable.GetModelMap(); trpgModelTable::ModelMapType::iterator itr = mt->begin(); for ( ; itr != mt->end( ); itr++) { loadModel(itr->first); } osg::notify(osg::NOTICE) << "txp:: ... done." << std::endl; return true;}bool TXPArchive::loadLightAttributes(){
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?