from:
PhysX Documentation(The PhysX SDK/Guide/Basics/SDK Initialization)
PhysX Documentation(The PhysX SDK/Guide/Basics/Memory Management)
PhysX Documentation(The PhysX SDK/Guide/Basics/Error Reporting)
SDK Initialization
1.包含NxPhysics.h头文件,如果要引用windows.h,必须define一个NONIMMAX。
#inlucde "NxPhysics.h"
#define NOMINMAX
#include <windows.h>
#define NOMINMAX
#include <windows.h>
2.创建SDK对象
// 成功的话会返回一个NxPhysicsSDK指针
// NxPhysicsSDK是单件模式的,也就是说多次create返回的都是同一实例
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, &myAllocator, &myOutputStream);
if(!gPhysicsSDK)
Error("Wrong SDK DLL version?");
// NxPhysicsSDK是单件模式的,也就是说多次create返回的都是同一实例
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, &myAllocator, &myOutputStream);
if(!gPhysicsSDK)
Error("Wrong SDK DLL version?");
参数1NX_PHYSICS_SDK_VERSION,是SDK头文件中定义的版本宏。
参数2,可选参数,默认NULL。是用户实现的NxUserAllocator接口,内存管理的东东。
参数3,可选参数,默认NULL。是用户实现的NxUserOutputStream接口。错误报告的东东。
3.释放SDK对象
gPhysicsSDK->release();
虽然NxPhysicsSDK对象是单件模式的,但它有一个引用计数的东东,每create一次都需要有一次release来释放。
另外,多次NxCreatePhysicsSDK时,后续allocator参数会被忽略,始终使用第一次用的那个;output stream参数正常。
参数2相关: Memory Management
创建SDK对象时,可以指定一个自定义的内存管理类。对PC用户来说这不是特别有用,但在对内存管理有特殊要求的系统上就很管用。不管杂说,它允许用户监控SDK的内存使用情况,这才是重点。
要让SDK使用自定义的内存管理方式,需要实现NxUserAllocator接口中的所有纯虚方法(它们和标准C的内存管理方法malloc/realloc/free是对应的,感觉就是重写了标准C的方法)。
但SDK并不保证在每个需要内存分配的地方都是真的调用了自定义的allocator,很可能是在开始的时候通过你自定义的allocator分配了一大块内存,然后在需要的时候SDK内部用自己的方法来分配或干点别的这块内存。
这也就意味着,如果要使用自定义的内存管理方式,就必须在SDK创建之初传入。SDK创建之后,这个allocator参数不能修改和移除。
需要注意:allocator就是一个纯粹独立的内存管理类,不要它里面调用任何SDK的方法。
一个实现的allocator
class MyAllocator : public NxUserAllocator
{
public:
void * malloc(NxU32 size)
{
return ::malloc(size);
}
void * mallocDEBUG(NxU32 size,const char *fileName, int line)
{
return ::_malloc_dbg(size,_NORMAL_BLOCK, fileName, line);
}
void * realloc(void * memory, NxU32 size)
{
return ::realloc(memory,size);
}
void free(void * memory)
{
::free(memory);
}
} myAllocator;
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, &myAllocator, 0);
{
public:
void * malloc(NxU32 size)
{
return ::malloc(size);
}
void * mallocDEBUG(NxU32 size,const char *fileName, int line)
{
return ::_malloc_dbg(size,_NORMAL_BLOCK, fileName, line);
}
void * realloc(void * memory, NxU32 size)
{
return ::realloc(memory,size);
}
void free(void * memory)
{
::free(memory);
}
} myAllocator;
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, &myAllocator, 0);
还需要保证allocator是线程安全的,因为在SDK内部它肯定是多线程调用这些内存管理方法的。
通常操作系统提供的都是线程安全的,除非链接了单线程CRT。
参数3相关: Error Reporting
SDK也允许用户通过实现NxUserOutputStream接口类自定义错误日志的读写类。
(注:2.8.4该接口需要实现3个接口方法,3.0只需1个方法。)
同allocator一样,在这个实现的用于错误报告的stream类中,也不能调用SDK的任何方法。
和allocator不同,不需保证线程安全。
class MyOutputStream : public NxUserOutputStream
{
void reportError (NxErrorCode code, const char *message, const char* file, int line)
{
//this should be routed to the application
//specific error handling. If this gets hit
//then you are in most cases using the SDK
//wrong and you need to debug your code!
//however, code may just be a warning or
//information.
if (code < NXE_DB_INFO)
{
MessageBox(NULL, message, "SDK Error", MB_OK),
exit(1);
}
}
NxAssertResponse reportAssertViolation (const char *message, const char *file,int line)
{
//this should not get hit by
// a properly debugged SDK!
assert(0);
return NX_AR_CONTINUE;
}
void print (const char *message)
{
printf("SDK says: %s\n", message);
}
{
void reportError (NxErrorCode code, const char *message, const char* file, int line)
{
//this should be routed to the application
//specific error handling. If this gets hit
//then you are in most cases using the SDK
//wrong and you need to debug your code!
//however, code may just be a warning or
//information.
if (code < NXE_DB_INFO)
{
MessageBox(NULL, message, "SDK Error", MB_OK),
exit(1);
}
}
NxAssertResponse reportAssertViolation (const char *message, const char *file,int line)
{
//this should not get hit by
// a properly debugged SDK!
assert(0);
return NX_AR_CONTINUE;
}
void print (const char *message)
{
printf("SDK says: %s\n", message);
}
} myOutputStream;