【转】让Ogre支持中文路径与中文文件名

Ogre中路径与文件名不支持中文,这是VS2005之后版本的std::fstream对中文路径处理不正确的原因,所以加载中文路径或文件名不成功,解决办法:

                  在主函数开始加入 setlocale(LC_ALL,"Chinese-simplified");


例如:

view plaincopy to clipboardprint?
virtual void createScene(void)   
{    
   setlocale(LC_ALL,"Chinese-simplified");   
   Entity* ogreHead = mSceneMgr->createEntity("Head","左慈头.mesh");   
SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();   
   headNode->attachObject(ogreHead);   

   mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));   

   virtual void createScene(void)
    { 
      setlocale(LC_ALL,"Chinese-simplified");
      Entity* ogreHead = mSceneMgr->createEntity("Head","左慈头.mesh");
     SceneNode* headNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
      headNode->attachObject(ogreHead);

      mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));
    }

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zyfu0000/archive/2009/12/07/4958731.aspx

Ogre的文件读取是使用的标准库的io库读取的,众所周知的是,在vs2005是存在着bug的。
因此想要一劳永逸的解决这个办法唯有去修改Ogre的源代码,以下为修改方法:

打开OgreFileSystem.cpp文件,找到FileSystemArchive::open方法,使用以下代码替换之:

DataStreamPtr FileSystemArchive::open(const String& filename) const
    {
         String full_path = concatenate_path(mName, filename);

        // Use filesystem to determine size 
        // (quicker than streaming to the end and back)
        struct stat tagStat;
        int ret = stat(full_path.c_str(), &tagStat);
         assert(ret == 0 && "Problem getting file size" );

        // Always open in binary mode
        static std::vector<wchar_t>     s_wchar_buf((size_t)128);
         size_t lengthUnicode = MultiByteToWideChar(CP_ACP, 0, full_path.c_str(), full_path.size(), NULL, 0);
        if (s_wchar_buf.size() < lengthUnicode + 1)
        {
             s_wchar_buf.resize(lengthUnicode * 2);
         }
         wchar_t* szUnicode = &s_wchar_buf[0];
         MultiByteToWideChar(CP_ACP, 0, full_path.c_str(), full_path.size(), szUnicode, lengthUnicode);
         szUnicode[lengthUnicode] = 0;
         std::ifstream* origStream = new std::ifstream();
         origStream->open(szUnicode, std::ios::in | std::ios::binary);

        // Should check ensure open succeeded, in case fail for some reason.
        if (origStream->fail())
        {
             delete origStream;
             OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
                "Cannot open file: " + filename,
                "FileSystemArchive::open");
         }

        /**//// Construct return stream, tell it to delete on destroy
         FileStreamDataStream* stream = new FileStreamDataStream(filename,
             origStream, tagStat.st_size, true);
        return DataStreamPtr(stream);
     }下面是一段ogre中的文件操作相关的源码

代码 
    DataStreamPtr FileSystemArchive::open(const String& filename) const
    {
        String full_path = concatenate_path(mName, filename);

        // Use filesystem to determine size 
        // (quicker than streaming to the end and back)
        struct stat tagStat;
    int ret = stat(full_path.c_str(), &tagStat);
        assert(ret == 0 && "Problem getting file size" );

        // Always open in binary mode
        std::ifstream *origStream = OGRE_NEW_T(std::ifstream, MEMCATEGORY_GENERAL)();
        origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);

        // Should check ensure open succeeded, in case fail for some reason.
        if (origStream->fail())
        {
            OGRE_DELETE_T(origStream, basic_ifstream, MEMCATEGORY_GENERAL);
            OGRE_EXCEPT(Exception::ERR_FILE_NOT_FOUND,
                "Cannot open file: " + filename,
                "FileSystemArchive::open");
        }

        /// Construct return stream, tell it to delete on destroy
        FileStreamDataStream* stream = OGRE_NEW FileStreamDataStream(filename,
            origStream, tagStat.st_size, true);
        return DataStreamPtr(stream);
    }

主要的代码是

origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);
通过在文件流打开文件之前,我们设置一下语言环境

std::locale::global(std::locale(""));
接下来我们发现,中文路径的问题解决了,但是向文件中写入整型或浮点型数据时会有问题,比如“1000”,输出之后就成了“1,000”

这正是因为我们改变了语言环境的原因,为了将修改减少到最小,我们应该在文件打开完毕后,恢复之前的设置

std::locale saveLocal = std::locale::global(std::locale(""));
origStream->open(full_path.c_str(), std::ios::in | std::ios::binary);
std::locale::global(saveLocal);

everything is fine now~


0

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/pizi0475/archive/2010/03/01/5335677.aspx

原文地址:https://www.cnblogs.com/minggoddess/p/1952192.html