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 + -
显示快捷键?