ogre文字动态加载实现和bug修改

来源:互联网 发布:java程序员书籍推荐 编辑:程序博客网 时间:2024/06/06 03:42

一、简略版基础知识

ogre中文字加载代码如下:

    Ogre::String name = "Sample";    Ogre::FontPtr font = Ogre::FontManager::getSingleton().getByName(mName);    font->setType(Ogre::FT_TRUETYPE);    font->setTrueTypeSize(24);    font->setTrueTypeResolution(96);    font->addCodePointRange(Ogre::Font::CodePointRange(33, 166));//英文    font->addCodePointRange(Ogre::Font::CodePointRange(8451, 8451));//℃    font->load();

其中:
addCodePointRange()函数可以在load()函数前多次添加。
load()函数用于将addCodePointRange()包含的问题从字库中载入,并且绘制成一张图片,保存在font中的一个material里面。(图片最小为512*512像素。)

如果,load()函数调用后,要需要显示addCodePointRange()函数中不包含的文字。需要先调用unload()函数,再重新添加所有文字,然后再调用load()函数。代码如下:

font->unload();font->addCodePointRange(Ogre::Font::CodePointRange(21387,21387));font->load();

其中:
unload()函数卸载font中的material里面的图片内容。
addCodePointRange()函数在font里面保存了一个vector结构保存所有文字。
再通过load()函数加载。

二、ogre文字动态加载实现

1、实现动态加载字体
首先,管理一个文字code的list。每次使用文字的是先在list中查找,是否已经存在这个文字,如果不存在,用addCodePointRange()函数添加。
每次添加新的文字后,先unload(),再load(),font就重新加载了material里的图片。
伪代码如下(大概吧,领会精神):

    Ogre::FontPtr font = Ogre::FontManager::getSingleton().getByName(mName);    font->unload();    font->clearCodePointRanges();    font->addCodePointRange(Ogre::Font::CodePointRange(33,166)); //英文    CharactorList::iterator iter = mQueuedDictionary.begin();    for (; iter != mQueuedDictionary.end(); ++iter)    {        font->addCodePointRange(Ogre::Font::CodePointRange(*iter,*iter));    }    font->load();

2、 刷新相关material
由于load()函数中重新创建了一个material,所以在该函数前所有设置的字体material都以及作废了,需要重新设置成新的字体material。
具体方法,代码如下:

        element->setMaterialName("");        element->setCaption(element->getCaption());

因为setMaterialName()设置为空后,setCaption()函数中会,提取font中的material进行设置。
强调:由于是字体font中的material重新创建、加载的,所以所有已经应用到字体的element都需要如上面那样刷新。可以做一个listener实现。

三、对于ogre1.9版本的bug修改。

我在ogre1.9版本中应用上述方法进行实现,出现了一个bug。
在unload()函数中,被卸载的字体material,只是做了一个delete的标记,估计是资源管理器什么时候会删除。反正我用完unload()函数很快就用load()函数了。调用load()函数时创建新的material,但是旧的还没有删除呢。

        element->setMaterialName("");        element->setCaption(element->getCaption());

最后,跟踪上面代码设置的时候material的指针还是旧的。新的material的名字和旧的一样,但是指针不一样,不知道怎么找到……

我在unload()函数后,手动删除了font中material的图片纹理。代码修改如下:

Ogre::FontPtr font = Ogre::FontManager::getSingleton().getByName(mName);Ogre::Material* mf1 = font->getMaterial().getPointer();Ogre::TexturePtr texf1 = mf1->getTechnique(0)->getPass(0)->getTextureUnitState(0)->_getTexturePtr();font->unload();if (texf1->getLoadingState() == Ogre::Texture::LOADSTATE_UNLOADED)    Ogre::TextureManager::getSingleton().remove(texf1->getHandle());font->clearCodePointRanges();font->addCodePointRange(Ogre::Font::CodePointRange(33,166)); //英文CharactorList::iterator iter = mQueuedDictionary.begin();for (; iter != mQueuedDictionary.end(); ++iter){    font->addCodePointRange(Ogre::Font::CodePointRange(*iter,*iter));}font->load();

感觉这么做挺暴力,还没有时间找其他方法。目前,还没有出错或者崩溃,不过使用不多也是一个原因。谁还有更好的方法告诉我啊!互相促进!

PS,吐槽一下。
这个东西弄得挺费劲,但是感觉完全没有用处啊!
两万个各种认不认识的汉字,加载一次才3、4秒,不要总是加载卸载速度不就快了嘛。等到网页全部打开再加载一次,不就快了嘛!

PS,PS。常用汉字是3500个。有谁有这些汉字的Unicode表啊。不是所有汉字的Unicode,是跳出率的常用3500个汉字的Unicode码表,这个感觉挺常用的,怎么就没找到?哪位亲有的话给我发一份啊!O(∩_∩)O谢谢

大概就这样了,这个知识点的blog终于让我糊弄出来了,完结!

0 0