OgreBullet已经很久没人更新,看到主页上的配置ogre与bullet的都比较旧,于是参考文章Building OgreBullet with OgreSDK 1.8.1 on Windows.。期间遇到的问题颇多,但最终成功,先看效果图吧。
首先是下载安装ogre1.8.1、bullet-2.82与OgreBullet
ogreSDK1.8.1可以直接下载安装ogreSDK1.8.1
下载安装后查看环境变量里面是否有了 OGRE_HOME这一项,如果没有就把ogre的根目录加到环境变量中。
bullet-2.82-r2704的安装bullet download中选择2.82版本。解压缩后进入其build文件夹,双击“vs2010.bat”文件,生成vs2010文件夹,打开其vs项目在release与debug下全部生成。为了避免以后出链接的问题,可以在这就把所有项目属性内运行库改为动态(与ogre的统一):项目属性-》c/c++-》代码生成-》运行库(debug下为MDd,release下为MD)
添加BULLET_ROOT到环境变量,值为bullet的根目录(如:D:\OGRE\bullet-2.82-r2704)
OgreBullet的下载:需要用到svn,不了解的可以从网上下载,并看下使用。在这儿就简单说一下,下载安装完毕之后,在你的目录中新建文件夹“OgreBullet”,右键点击“svn检出”或者“svn checkOut”,并复制下面地址到URL
https://svn.code.sf.net/p/ogreaddons/code/trunk/ogrebullet
,点击确定即可看到下载中。慢慢下吧哈。
修改OgreBullet:
下载完成ogrebullet之后,打开OgreBullet_VC8.sln,做以下设置与修改:
Dynamics_Demos项目:
配置属性-》c/c++》常规 -》附加包含目录 添加:
$(BULLET_ROOT)\src
$(BULLET_ROOT)\Extras\ConvexDecomposition
..\..\include
..\..\..\include
..\..\..\..\Collisions\include
..\..\..\..\Dynamics\include
$(OGRE_HOME)\include\Ogre
$(OGRE_HOME)\boost
$(OGRE_HOME)\include
$(OGRE_HOME)\include\OIS
配置属性-》链接器》常规:
..\..\..\..\lib\$(Configuration)
$(OGRE_HOME)\lib\$(Configuration)
$(OGRE_HOME)\boost\lib
$(BULLET_ROOT)\lib
配置属性-》链接器》输入:
OgreMain_d.lib
OIS_d.lib
OgreBulletCollisions_d.lib
OgreBulletDynamics_d.lib
BulletCollision_vs2010_debug.lib
BulletDynamics_vs2010_debug.lib
LinearMath_vs2010_debug.lib
ConvexDecomposition_vs2010_debug.lib
OgreBulletDynamicsDemo_d.lib
上面是debug下,release下的:
OgreMain.lib
ois.lib
OgreBulletCollisions.lib
OgreBulletDynamics.lib
BulletCollision_vs2010.lib
BulletDynamics_vs2010.lib
LinearMath_vs2010.lib
ConvexDecomposition_vs2010.lib
应用并确定。
OgreBulletCollisions项目:
配置属性-》c/c++》常规 -》附加包含目录 添加:
..\..\include
$(BULLET_ROOT)\src
$(BULLET_ROOT)\Extras\ConvexDecomposition
$(OGRE_HOME)\include
$(OGRE_HOME)\include\Ogre
$(OGRE_HOME)\boost
OgreBulletDynamics项目:
配置属性-》c/c++》常规 -》附加包含目录 添加:
..\..\include
..\..\..\Collisions\include
$(BULLET_ROOT)\src
$(OGRE_HOME)\include
$(OGRE_HOME)\include\Ogre
$(OGRE_HOME)\boost
然后是项目中代码的修改。
要做的修改:
```
OgreBulletDynamicsWorld.cpp中
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0()); // For older Bullet versions (original code)
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1()); // For older Bullet versions (original code)
修改为:
#if BT_BULLET_VERSION>=281
btCollisionObject* obA = const_cast<btCollisionObject*>(contactManifold->getBody0());; // For newer Bullet versions
btCollisionObject* obB = const_cast<btCollisionObject*>(contactManifold->getBody1()); // For newer Bullet versions
#else
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0()); // For older Bullet versions (original code)
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1()); // For older Bullet versions (original code)
#endif
OgreBulletCollisionsRay.cpp中
return mWorld->findObject(static_cast<btCollisionWorld::ClosestRayResultCallback *> (mRayResultCallback)->m_collisionObject);
修改为:
#if BT_BULLET_VERSION>=281
return mWorld->findObject(const_cast<btCollisionObject*>(static_cast<btCollisionWorld::ClosestRayResultCallback *> (mRayResultCallback)->m_collisionObject));
#else
return mWorld->findObject(static_cast<btCollisionWorld::ClosestRayResultCallback *> (mRayResultCallback)->m_collisionObject);
#endif
OgreBulletCollisionsWorld.cpp中
btCollisionObject* obA = static_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = static_cast<btCollisionObject*>(contactManifold->getBody1());
修改为:
btCollisionObject* obA = const_cast<btCollisionObject*>(contactManifold->getBody0());
btCollisionObject* obB = const_cast<btCollisionObject*>(contactManifold->getBody1());
程序修改基本完成,改一下配置的东西
resouce.cfg中:
[Bootstrap]
Zip=D:/OgreBullet/Demos/Media/packs/OgreCore.zip
[General]
……
FileSystem=D:/OgreBullet/Demos/Media
FileSystem=D:/OgreBullet/Demos/Media/fonts
FileSystem=D:/OgreBullet/Demos/Media/materials/programs
FileSystem=D:/OgreBullet/Demos/Media/materials/scripts
FileSystem=D:/OgreBullet/Demos/Media/materials/textures
FileSystem=D:/OgreBullet/Demos/Media/models
FileSystem=D:/OgreBullet/Demos/Media/overlays
FileSystem=D:/OgreBullet/Demos/Media/particle
FileSystem=D:/OgreBullet/Demos/Media/gui
[Bullet]
FileSystem=D:/OgreBullet/Demos/Media/OgreBullet
FileSystem=D:/OgreBullet/Demos/Media/materials
FileSystem=D:/OgreBullet/Demos/Media/textures
当然其中的目录要写成你自己的。
运行程序,如果没有问题,恭喜你,成功。
当然我就不算幸运的那一类人,先是提示lib的冲突,主要就是把所有附加依赖项中的lib的生成方式以及该项目的生成方式都变成 MDd(release下为MD),如果没有这样做,可能的提醒:
MSVCRTD.lib(ti_inst.obj) : error LNK2005: “private: __thiscall type_info::type_info(class type_info const &)” (??0type_info@@AAE@ABV0@@Z) 已经在LIBCMTD.lib(typinfo.obj) 中定义
哎,虽然俺也知道,但是还是因为粗心,忘了把ConvexDecomposition.lib的生成方式改过来,折腾了半天才发现。
最后一个问题则是提醒了
MSVCRTD.lib(wcrtexew.obj) : error LNK2019: 无法解析的外部符号 _wWinMain@16,该符号在函数 ___tmainCRTStartup 中被引用
这个提醒有点变态,按照网上说的方式不见效,所以就按照Ogre AppWizard生成的项目,重新改了下代码。
main.cpp中修改为
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char *argv[])
#endif
{
// Create application object
std::vector<OgreBulletListener *> ogrebulletscenes;
std::vector <OgreBulletListener *>::iterator it;
ogrebulletscenes.push_back(new Primitives_Demo());
ogrebulletscenes.push_back(new Trimesh_Demo());
ogrebulletscenes.push_back(new Vehicles_Demo());
ogrebulletscenes.push_back(new Constraints_Demo());
ogrebulletscenes.push_back(new Terrain_Demo());
ogrebulletscenes.push_back(new Ragdoll_Demo());
//ogrebulletscenes.push_back(new Constraints_Demo());
ogrebulletscenes[0]->setNextKey(KC_F1);
ogrebulletscenes[1]->setNextKey(KC_F2);
ogrebulletscenes[2]->setNextKey(KC_F3);
ogrebulletscenes[3]->setNextKey(KC_F4);
ogrebulletscenes[4]->setNextKey(KC_F5);
ogrebulletscenes[5]->setNextKey(KC_F6);
//ogrebulletscenes[3]->setNextKey(KC_F4);
//ogrebulletscenes[4]->setNextKey(KC_F5);
// Create the application and try to run it
OgreBulletApplication app(&ogrebulletscenes);
//dff app;
try {
app.go();
} catch( Ogre::Exception& e ) {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else
std::cerr << "An exception has occured: " <<
e.getFullDescription().c_str() << std::endl;
#endif
}
it = ogrebulletscenes.begin();
while (it != ogrebulletscenes.end())
{
delete *it;
++it;
}
return 0;
}
#ifdef __cplusplus
}
#endif
到此,ogre与bullet之旅可以开始了。