Irrlicht学习之添加中文的支持
Irrlicht在立项之初,可能没有考虑国际化的问题,因此一开始使用的字符集都是ANSI的,似乎是在Irrlicht1.6开始,才开始在GUI和其他模块中将wchar_t当作普通字符的存储格式。但是wchar_t在不同的平台上存储又不一样,因此直到版本1.73,官方还没有提供东亚字符的显示。
在网络上搜到了几篇让Irrlicht支持中文的博客,虽然已经过去几年了,但依然受用。博客的地址将以参考文献的形式记录下来。下面将要介绍一下如何让Irrlicht支持中文。
原创文章,反对未声明的引用。原博客地址:http://blog.csdn.net/gamesdev/article/details/15378409
演示程序和源代码的下载地址:这里
1、去http://sourceforge.net/projects/freetype/files/freetype2/下载freetype2字库,freetype是绝大多数平台下载入和渲染字体的解决方案。我下载的版本是2.5.0。
2、编译freetype2字库,如果使用的是VS2008,那么可以在$${解压目录}/freetype-2.5.0.1/builds/win32/vc2008中找到sln文件打开然后在构建选项中选择Release Singlethreaded,构建。Freetype提供了2005、2008和2010、Visual C和Visual CE的支持,当然使用VS2012和VS2013也可以顺利地转换工程并且顺利地构建。
3、在VS2008中设置include和lib目录,如下图。
4、去这个地址下载Irrlicht支持中文的源码。
5、解压这几个文件,如下图:
6、建立项目,包含这几个文件。由于我们生成的freetype2静态库是使用单线程的,因此我们在“代码生成”(项目属性➡配置属性➡C/C++➡代码生成)那部分也要选择“多线程(/MT)”。
7、贴上代码,构建。我想有了上面几步作为铺垫,构建应该不会有什么问题的。
以下是我测试的演示程序截图:
测试演示程序的代码贴出来。
#include <irrlicht.h> #include "CGUITTFont.h" // 针对Windows系统的配置 #ifdef _IRR_WINDOWS_ #pragma comment( lib, "Irrlicht.lib" ) #pragma comment( lib, "freetype250MT.lib" ) #pragma comment( linker, "/subsystem:windows /ENTRY:mainCRTStartup" ) #endif // 定义空指针 #ifndef nullptr #define nullptr 0 #endif using namespace irr; using namespace core; using namespace video; using namespace scene; using namespace gui; using namespace io; class RotateYCamera// 沿着Y轴旋转的FPS摄像机 { public: RotateYCamera( ISceneManager* pSceneManager, const vector3df& pos, const vector3df& view ) { m_pCamera = pSceneManager->addCameraSceneNode( nullptr, pos, view ); m_pCamera->setTarget( view ); m_pCamera->bindTargetAndRotation( true ); m_ViewLength = view.getLength( ); m_RotateAngle = 0.0f; } void Rotate( f32 rotateSpeed ) { m_pCamera->setTarget( vector3df( m_ViewLength * cos( m_RotateAngle ), 0.0f, m_ViewLength * sin( m_RotateAngle ) ) ); m_RotateAngle += rotateSpeed; if ( m_RotateAngle > PI * 2.0f ) m_RotateAngle = 0.0f; } private: f32 m_ViewLength; f32 m_RotateAngle; ICameraSceneNode* m_pCamera; }; void CreateMap( IrrlichtDevice* pDevice ) { ISceneManager* pSMgr = pDevice->getSceneManager( ); // 获取Quake3的地图 pDevice->getFileSystem( )->addZipFileArchive( "map-20kdm2.pk3" ); IAnimatedMesh* pMesh = pSMgr->getMesh( "20kdm2.bsp" ); ISceneNode* pNode = nullptr; if ( pMesh != nullptr )// 添加八叉树渲染场景节点 { pNode = pSMgr->addOctreeSceneNode( pMesh->getMesh( 0 ) ); } if ( pNode != nullptr )// 位置偏移修正 { pNode->setPosition( vector3df( -1300, -144, -1249 ) ); } } int main( int argc, char** argv ) { IrrlichtDevice* pDevice = createDevice( EDT_OPENGL, // 渲染设备 dimension2d<u32>( 640, 480 ), // 宽和高 16, // 颜色位 false, // 是否全屏 false, // 模版缓存 false, // 垂直同步 nullptr ); // 事件接收器 if ( pDevice == nullptr ) return -1; pDevice->setWindowCaption( L"鬼火引擎演示 - 中文的支持" ); IVideoDriver* pDriver = pDevice->getVideoDriver( ); ISceneManager* pSMgr = pDevice->getSceneManager( ); IGUIEnvironment* pGUIEnv = pDevice->getGUIEnvironment( ); CreateMap( pDevice );// 创建地图 // 创建一FPS摄像机 RotateYCamera camera( pSMgr, vector3df( 0.0f, 0.0f, 0.0f ), vector3df( 5.0f, 0.0f, 5.0f ) ); // 创建中文字体 IGUIFont* pChineseFont = CGUITTFont::createTTFont( pGUIEnv, // GUI环境 L"msyh.ttf", // 字体名称 25, // 字体大小(多少磅) true, // 抗锯齿吗? true ); // 半透明吗? IGUIFont* pChineseGUIFont = CGUITTFont::createTTFont( pGUIEnv, // GUI环境 L"msyh.ttf", // 字体名称 13, // 字体大小(多少磅) true, // 抗锯齿吗? true ); // 半透明吗? IGUIWindow* pWindow = pGUIEnv->addWindow( rect<s32>( 60, 60, 200, 240 ) ); pWindow->setText( L"这是中文标题" ); pGUIEnv->getSkin( )->setFont( pChineseGUIFont ); u32 then = pDevice->getTimer( )->getTime( ); while ( pDevice->run( ) ) { pDriver->beginScene( true, // 后台缓存 true, // Z缓存 SColor( 255, 255, 255, 255 ) ); // 填充颜色 pSMgr->drawAll( ); pGUIEnv->drawAll( ); pChineseFont->draw( L"中文显示测试", // 文本(宽字符) rect<s32>( 200, 200, 300, 300 ),// 位置 SColor( 255, 255, 255, 255 ) ); // 颜色 pDriver->endScene( ); // 获取时间增量 const u32 now = pDevice->getTimer( )->getTime( ); const f32 frameDeltaTime = (f32)( now - then ); then = now; camera.Rotate( frameDeltaTime * 0.0001f );// 摄像机旋转 } return 0; }
趁着实验的成功,我将上次GUI的演示程序也一并做了汉化。程序的截图如下:
参考文献:
1、《关于irrlicht的点滴(2):实现中文显示和中文输入》
2、《irrlicht添加中文输入输出》