最近PhysX SDK 3.2 發布了,出於好奇,下載來看了看,發現還是很不錯的。相比2.x,變化很大,功能也更加強大。3.1版本中有點讓人混亂的庫名稱也得到了規範,同時還加了兩個新的範例。一個是角色布料類比,一個是自訂重力(這個和Havok中的那個例子基本上是一樣的)。
從3.x開始,SDK的範例都用一個Sample架構套件裝了,研究起來不是太方便,花了點時間寫了個測試程式。(CSDN不會排版代碼,醜了點,將就看吧)
#include <PxPhysicsAPI.h>
#include <extensions\PxDefaultSimulationFilterShader.h>
#include <extensions\PxExtensionsAPI.h>
#include <extensions\PxDefaultAllocator.h>
#include <extensions\PxDefaultErrorCallback.h>
#include <foundation/PxFoundation.h>
#include <pxtask/PxCudaContextManager.h>
#include <physxprofilesdk\PxProfileZoneManager.h>
#include <PxScene.h>
//3.x開始用命名空間了
using namespace physx;
bool recordMemoryAllocations = true;
//出錯的回呼函數,Havok也一樣,大同小異
static PxDefaultErrorCallback gDefaultErrorCallback;
static PxDefaultAllocator gDefaultAllocatorCallback;
static PxSimulationFilterShader gDefaultFilterShader = PxDefaultSimulationFilterShader;
int main(int argc, char** argv)
{
PxFoundation* mFoundation = PxCreateFoundation(PX_PHYSICS_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback);
if(!mFoundation){
printf("PxCreateFoundation failed!");
return -1;
}
bool recordMemoryAllocations = true;
//PxProfileZoneManager用來做效能分析用的
PxProfileZoneManager* mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation);
if(!mProfileZoneManager){
printf("PxProfileZoneManager::createProfileZoneManager failed!\n");
return -1;
}
//檢測並初始化CUDA模組,如果你有支援CUDA的顯卡,這裡就可以用到了。(建議裝上最新的顯卡驅動,再來測試本程式)。
pxtask::CudaContextManagerDesc cudaContextManagerDesc;
pxtask::CudaContextManager* mCudaContextManager = pxtask::createCudaContextManager(*mFoundation, cudaContextManagerDesc, mProfileZoneManager);
if(mCudaContextManager){
if(!mCudaContextManager->contextIsValid()){
mCudaContextManager->release();
mCudaContextManager = NULL;
}
}
if(mCudaContextManager){
printf("Device Name: %s\n", mCudaContextManager->getDeviceName());
printf("Driver Version: %d\n", mCudaContextManager->getDriverVersion());
printf("Total Bytes: %d\n", mCudaContextManager->getDeviceTotalMemBytes());
printf("core count: %d\n", mCudaContextManager->getMultiprocessorCount());
}
//PxTolerancesScale()是用來做Scale的,不過SDK說還沒做出來,只是佔個坑
PxPhysics* mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation,
PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager);
if(!mPhysics){
printf("PxCreatePhysics failed!\n");
return -1;
}
if(!PxInitExtensions(*mPhysics)){
printf("PxInitExtensions failed!\n");
return -1;
}
physx::PxCooking* mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, PxCookingParams());
if(!mCooking){
printf("PxCreateCooking failed!\n");
return -1;
}
PxScene* mScene;
PxSceneDesc sceneDesc(mPhysics->getTolerancesScale());
sceneDesc.gravity = PxVec3(0.0f, -9.81f, 0.0f);
//建立CPU分發器(字面翻譯,我的譯法),PxDefaultCpuDispatcherCreate的參數是線程數
pxtask::CpuDispatcher* mCpuDispatcher;
if(!sceneDesc.cpuDispatcher){
mCpuDispatcher = PxDefaultCpuDispatcherCreate(4);
if(!mCpuDispatcher){
printf("PxDefaultCpuDispatcherCreate failed!\n");
return -1;
}
sceneDesc.cpuDispatcher = mCpuDispatcher;
}
if(!sceneDesc.filterShader){
sceneDesc.filterShader = gDefaultFilterShader;
}
//嘗試使用GPU分發器
if(!sceneDesc.gpuDispatcher && mCudaContextManager){
sceneDesc.gpuDispatcher = mCudaContextManager->getGpuDispatcher();
}
//建立物理情境,上面搞那麼多,其實就為了這一行
mScene = mPhysics->createScene(sceneDesc);
if(!mScene){
printf("createscene failed!\n");
return -1;
}else{
printf("createscene successful!\n");
}
//按順序一個一個release,否則會提示警告
mPhysics->release();
mCooking->release();
mCudaContextManager->release();
PxCloseExtensions();
mFoundation->release();
return 0;
}
以上就是全部的測試代碼了。個人覺得3.2版本的PhysX已經非常成熟了,更加的專業,和他的Havok相比,不分伯仲。如果配合顯卡加上CUDA強悍的硬體加速能力,可以說是更勝一籌。順便說一下,Nvidia還提供了Linux和Android版本的SDK,跨平台做的很好。不像Havok免費版本只能使用兩個組件,還必須限定死在Windows平台上。