【无标题】

PhysX3.4文档(1) --startup shutdown

startup shutdown

introduction


使用physx sdk的第一步是初始化一个全局对象。这些对象会在physx不在需要这些资源时relese。

Foundation and Physics


首先我们需要创建PxFoundation对象

static PxDefaultErrorCallback gDefaultErrorCallback;
static PxDefaultAllocator gDefaultAllocatorCallback;

mFoundation = PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback,
    gDefaultErrorCallback);
if(!mFoundation)
    fatalError("PxCreateFoundation failed!");

每一个physx需要一个可用的PxFoundation实例。需要传入的参数是一个version ID、一个allocator callback和一个error callback。PX_PHYSICS_VERSION是一个定义在头文件中的宏,,它能够检查头文件个相关联的SDK DLLs是否象匹配。

通常来说,allocator callback和error callback是特定的,physx为了让我们能够轻松地开始也提供了一个默认的实现。

接下来我们需要创建最顶层的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!");
  • version ID同样需要传入。

  • PxTolerancesScale()能够在不同的scale下标注上下文(author context)并使得physx在传入默认对象的情况下能够正常工作。

  • recordMemoryAllocations指明是否进行内存分析。

  • PVD实例是可选项,能够开启debug并使用Physx Visual Debugger进行分析。

Cooking


physx cooking library提供创建、转换序列化大量数据的工具。根据自己的香炉需求,你可以希望链接cooking library以在运行时处理这些数据。当然你也可以预先将所有数据处理好然后在需要时经数据装入内存中。初始化cooking library的过程如下:

mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, PxCookingParams(scale));
if (!mCooking)
    fatalError("PxCreateCooking failed!");

PxCookingParams是一个对cooking library进行配置的结构体,它将cooking library指向不同的平台(target different platform)、是否使用非默认的tolerances以及是否创建可选的输出。注意,在工程中需要使用一致的PxTolerancesScale。

cooking library使用streaming interface来生成数据。在例子中,PxToolKit库提供了streams的实现,streams用于文件和buffer的读写。

通过使用PxPhysicsInsertionCallback,高程信息(Heightfield)或者三角网格(Trianglemesh)cooking的网格能够不通过序列化之间插入PxPhysics中。这种情况下我们必须使用默认的回调,默认回调通过PxPhysics::getPhysicsInsertionCallback()获取。

Extension

extensions library 包含了很多方法,这些方法对于很多用户都有用,但是某些用户可能出于代码量的大小或者避免使用某些子系统的原因省略掉不使用。初始化extensions library需要PxPhysics对象

if (!PxInitExtensions(*mPhysics, mPvd))
    fatalError("PxInitExtensions failed!");

Optional SDK Components


当我们在内存受限的平台上将physx作为静态库链接时,我们可以避免链接部分physx的feature来节约内存。目前可供原则的部分为

  • 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;
}

注意只有当将physx作为静态链接库时才能节省内存,因为我们依靠链接器来去除未使用的代码。

Delay-Loading DLLs


PhysX ,PhysXCooking ,PhysXCommonPxPvdSDK项目中,PhysXCommon DLL PxFoundation DLLPxPvdSDK DLL被标记为延迟装载(Delay-Loading)

PhysXCommon DLL and PxFoundation DLL load

应用程序链接到PhysXCommon DLL,会在装在其他DLL之前先装载PxFoundation.dllPxPvdSDKPhysXCommon.dll。应用程序装载的DLL必须和PhysXPhysXCooking DLLs使用的一样。在PhysXPhysXCooking DLLs中关于PhysXCommon,PxFoundationPxPvdSDK由如下规则构成:

  • 如果延迟加载hook指定了PhysXCommon名称,则使用用户提供的PhysXCommonPxPvdSDK名称
    • 如果延迟加载hook没有指定,则会使用相应的PhysXCommon``PxFoundation或者PxPvdSDK

PxDelayLoadHook

PxDelayLoadHook支持装载不同版本的PhysXCommon DLL`` PxFoundation DLL或者PxPvdSDK DLL。通过自定义的PxDelayLoadHook的子类向PhysX SDK提供不同的DLL名字来实现,见如下的例子

class SampleDelayLoadHook: public PxDelayLoadHook
{
    virtual const char* getPhysXCommonDEBUGDllName() const
        { return "PhysX3CommonDEBUG_x64_Test.dll"; }
    virtual const char* getPhysXCommonCHECKEDDllName() const
        { return "PhysX3CommonCHECKED_x64_Test.dll"; }
    virtual const char* getPhysXCommonPROFILEDllName() const
        { return "PhysX3CommonPROFILE_x64_Test.dll"; }
    virtual const char* getPhysXCommonDllName() const
        { return "PhysX3Common_x64_Test.dll"; }
    virtual const char* getPxFoundationDEBUGDllName() const
        { return "PxFoundationDEBUG_x64_Test.dll"; }
    virtual const char* getPxFoundationCHECKEDDllName() const
        { return "PxFoundationCHECKED_x64_Test.dll"; }
    virtual const char* getPxFoundationPROFILEDllName() const
        { return "PxFoundationPROFILE_x64_Test.dll"; }
    virtual const char* getPxFoundationDllName() const
        { return "PxFoundation_x64_Test.dll"; }
    virtual const char* getPxPvdSDKDEBUGDllName() const
        { return "PxPvdSDKDEBUG_x64_Test.dll"; }
    virtual const char* getPxPvdSDKCHECKEDDllName() const
        { return "PxPvdSDKCHECKED_x64_Test.dll"; }
    virtual const char* getPxPvdSDKPROFILEDllName() const
        { return "PxPvdSDKPROFILE_x64_Test.dll"; }
    virtual const char* getPxPvdSDKDllName() const
        { return "PxPvdSDK_x64_Test.dll"; }
} gDelayLoadHook;

接下来需要设置PhysX, PhysXCooking, PhysXCommon, PxPvdSDK的hook

PxSetPhysXDelayLoadHook(&gDelayLoadHook);
PxSetPhysXCookingDelayLoadHook(&gDelayLoadHook);
PxSetPhysXCommonDelayLoadHook(&gDelayLoadHook);
PxPvdSetFoundationDelayLoadHook(&gDelayLoadHook);

PxGpuLoadHook

PxGpuLoadHook类支持装载不同版本的DLL。可以通过自定义的PxGpuLoadHook子类向PhysX SDK提供不同的DLL名字来实现,见下

class SampleGpuLoadHook: public PxGpuLoadHook
{
    virtual const char* getPhysXGpuDEBUGDllName() const
        { return "PhysX3GpuDEBUG_x64_Test.dll"; }
    virtual const char* getPhysXGpuCHECKEDDllName() const
        { return "PhysX3GpuCHECKED_x64_Test.dll"; }
    virtual const char* getPhysXGpuPROFILEDllName() const
        { return "PhysX3GpuPROFILE_x64_Test.dll"; }
    virtual const char* getPhysXGpuDllName() const
        { return "PhysX3Gpu_x64_Test.dll"; }
} gGpuLoadHook;

设置PhysX的hook

PxSetPhysXGpuLoadHook(&gGpuLoadHook);

PhysXCommon Secure Load

所有由Nvidia分布的PhysX DLL都被签名过。通过PhysX或者PhysXCooking装载时,会检查PhysXCommon DLL的签名。如果签名验证失败会终止应用程序。

Shutting Down

调用release()方法能够dispose任何的PhysX对象。这个方法会销毁对象和其包含的所有对象。具体的行为取决于dispose的对象。

关闭extension library需要调用PxCloseExtension()

关闭physics,需要在PxPhysics对象上调用release(),它会清理所有的physics对象。

mPhysics->release();

也不要忘记释放foundation对象,最后释放

mFoundation->release();
上一篇:不同行业如何实现 安全可控的托管文件传输MFT?


下一篇:mPaaS 小程序架构解析 | 实操演示小程序如何实现多端开发