在应用程序中使用PhysXSDK,首先要初始化一些全局对象。当程序结束时,释放这些对象。(经过测试,physx的内存管理做得非常好了,几乎没有资源泄漏情况)。
Foundation and Physics
- 首先在程序启动的时候,需要创建一个Foundation对象(俗称地基,表演的舞台)
static PxDefaultErrorCallback gDefaultErrorCallback;//错误处理接口,可根据需要继承重写
static PxDefaultAllocator gDefaultAllocatorCallback;//内存分配器,可根据需要继承重写,比如用jemalloc,tcmalloc
mFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback,
gDefaultErrorCallback);
if(!mFoundation)
fatalError("PxCreateFoundation failed!");
- 创建顶层PxPhysics对象
bool recordMemoryAllocations = true;
mPvd = PxCreatePvd(*gFoundation);
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
mPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, PxTolerancesScale(), recordMemoryAllocations, mPvd);
if(!mPhysics)
fatalError("PxCreatePhysics failed!");
//PVD是physx调试器
//PxTolerancesScale根据项目设置缩放比例
//recordMemoryAllocations是否进行内存分析,这样pvd可以调试
SDK建议
如果平台上内存有限,将PhysX链接为一个静态库时,要避免链接一些特性,节约内存。目前可选的功能有:
Articulations
Height Fields
Cloth
Particles
如果应用程序需要此功能的一个子集,建议调用PxCreateBasePhysics而不是PxCreatePhysics,然后手动注册所需的组件。
physx::PxPhysics* customCreatePhysics(physx::PxU32 version,
physx::PxFoundation& foundation,
const physx::PxTolerancesScale& scale,
bool trackOutstandingAllocations
physx::PxPvd* pvd)
{
physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale,
trackOutstandingAllocations, pvd);
if(!physics)
return NULL;
PxRegisterArticulations(*physics);
PxRegisterHeightFields(*physics);
return physics;
}
注意,只有在当静态库链接的时候,这么做才会节约内存。
释放资源
mPhysics->release();
mFoundation->release();
典型启动和退出流程,参见官方helloworld示例
void initPhysics(bool interactive)
{
//创建Foundation
gFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, gAllocator, gErrorCallback);
//创建pvd
gPvd = PxCreatePvd(*gFoundation);
PxPvdTransport* transport = PxDefaultPvdSocketTransportCreate(PVD_HOST, 5425, 10);
gPvd->connect(*transport,PxPvdInstrumentationFlag::eALL);
//顶层physx
gPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *gFoundation, PxTolerancesScale(),true,gPvd);
//场景属性
PxSceneDesc sceneDesc(gPhysics->getTolerancesScale());
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
gDispatcher = PxDefaultCpuDispatcherCreate(2);
sceneDesc.cpuDispatcher = gDispatcher;
sceneDesc.filterShader = PxDefaultSimulationFilterShader;
gScene = gPhysics->createScene(sceneDesc);
}
//释放流程,调用release
void cleanupPhysics(bool interactive)
{
PX_UNUSED(interactive);
gScene->release();
gDispatcher->release();
gPhysics->release();
PxPvdTransport* transport = gPvd->getTransport();
gPvd->release();
transport->release();
gFoundation->release();
printf("SnippetHelloWorld done.\n");
}