.. _Startup:

-----------------------
Startup and Shutdown
-----------------------

===============================
Introduction
===============================

The first step in using the PhysX SDK in a program is the initialization of some global objects.  These objects can be released when PhysX is no longer needed to free resources.  This chapter describes how to do this.

===============================
Foundation and Physics
===============================

First, in some startup code, create a *PxFoundation* object::

    static PxDefaultErrorCallback gDefaultErrorCallback;
    static PxDefaultAllocator gDefaultAllocatorCallback;

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

Every PhysX module requires a *PxFoundation* instance to be available. The required parameters are a version ID, an allocator callback and an error callback. *PX_PHYSICS_VERSION*, is a macro predefined in our headers to enable PhysX to check for a version mismatch between the headers and the corresponding SDK DLLs. 

Usually, the allocator callback and error callback are specific to the application, but PhysX provides default implementations that make it easy to get started. See :ref:`MemoryManagement` and :ref:`ErrorReporting` for more details of these callbacks. (The actual sample code supports an advanced memory allocator that tracks allocations instead of the default, but we have omitted that detail here).

An optional profile zone manager enables the performance profiling capabilities of the PhysX Visual Debugger (for more information please see Sections :ref:`ProfileZone`).

Now create the top-level *PxPhysics* object::

    bool recordMemoryAllocations = true;        
    mProfileZoneManager = &PxProfileZoneManager::createProfileZoneManager(mFoundation);
    if(!mProfileZoneManager)
        fatalError("PxProfileZoneManager::createProfileZoneManager failed!");
    
    mPhysics = PxCreatePhysics(PX_PHYSICS_VERSION, *mFoundation, 
        PxTolerancesScale(), recordMemoryAllocations, mProfileZoneManager);
    if(!mPhysics)
        fatalError("PxCreatePhysics failed!");

Again, the version ID has to be passed in. The *PxTolerancesScale* parameter makes it easier to author content at different scales and still have PhysX work as expected, but to get started simply pass a default object of this type. The *recordMemoryAllocations* parameter specifies whether to perform memory profiling. The optional profile zone manager, typically created with *PxProfileZoneManager::createProfileZoneManager()*, enables the performance profiling capabilities of the PhysX Visual Debugger. 

===============================
Cooking 
===============================

The PhysX cooking library provides utilities for creating, converting, and serializing bulk data. Depending on your application, you may wish to link to the cooking library in order to process such data at runtime. Alternatively you may be able to process all such data in advance and just load it into memory as required. Initialize the cooking library as follows::
      
    mCooking = PxCreateCooking(PX_PHYSICS_VERSION, *mFoundation, PxCookingParams(scale));
    if (!mCooking)
        fatalError("PxCreateCooking failed!");

The *PxCookingParams* struct configures the cooking library to target different platforms, use non-default tolerances or produce optional outputs. It is important to use consistent *PxTolerancesScale* values everywhere in your application (see :ref:`PxToleranceScale` for more details).

The cooking library generates data through a streaming interface. In the samples, implementations of streams are provided in the PxToolkit library to read and write from files and memory buffers. Heightfield or Trianglemesh cooked meshes can be directly inserted into *PxPhysics* without serialization using the *PxPhysicsInsertionCallback*. The default callback must be used and can be obtained using the *PxPhysics::getPhysicsInsertionCallback()*.

===============================
Extensions
===============================

The extensions library  contains many functions that may be useful to a large class of users, but which some users may prefer to omit from their application either for code size reasons or to avoid use of certain subsystems, such as those pertaining to networking. Initializing the extensions library requires the *PxPhysics* object::

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

.. _optionalSDKComponents:
        
===============================
Optional SDK Components
===============================


When linking PhysX as a static library on memory constrained platforms, it is possible to avoid linking the code of some PhysX features that are not always used in order to save memory.  Currently the optional features are:

    * Articulations
    * Height Fields
    * Cloth
    * Particles


If your application requires a subset of this functionality, it is recommended that you call *PxCreateBasePhysics* as opposed to *PxCreatePhysics* and then manually register the components you require.  Below is an example that registers some of the options::

    physx::PxPhysics* customCreatePhysics(physx::PxU32 version,
        physx::PxFoundation& foundation,
        const physx::PxTolerancesScale& scale,
        bool trackOutstandingAllocations,
        physx::PxProfileZoneManager* profileZoneManager)
    {
        physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale, 
            trackOutstandingAllocations, profileZoneManager);
            
        if(!physics)
            return NULL;

        PxRegisterArticulations(*physics);
        PxRegisterHeightFields(*physics);
        
        return physics;
    }
                                            
Note that this will only save memory when linking PhysX as a static library, as we rely on the linker to strip out the unused code.

===============================
Delay-Loading DLLs
===============================

The PhysXCommon DLL is marked as delay-loaded inside of the PhysX and PhysXCooking projects. So it is possible to have delay-loaded PhysXCommon, PhysX and PhysXCooking DLLs. 

+++++++++++++++++++++++++++++++
PhysXCommon DLL load
+++++++++++++++++++++++++++++++

The application links against PhysXCommon DLL, and will usually load PhysXCommon.dll before any other PhysX DLL. The DLL loaded by the application must be the same one that will be used by the PhysX and PhysXCooking DLLs.  In the PhysX and PhysXCooking DLLs, the choice of PhysXCommon use is made as follows:

 * If delay load hook is specified the PhysXCommon name provided by user is used
 * If delay load hook is not specified
    * The PhysX or PhysXCooking DLL string name is read, and scanned for a substring: DEBUG, CHECKED, or PROFILE
    * If a substring is found, then the corresponding PhysXCommonDEBUG.dll, PhysXCommonCHECKED.dll, or PhysXCommonPROFILE.dll is used, otherwise PhysXCommon.dll is used.


+++++++++++++++++++++++++++++++
PxDelayLoadHook
+++++++++++++++++++++++++++++++

If you need to load a different PhysXCommon DLL, it is possible to create a *PxDelayLoadHook* and define the name of PhysXCommon DLL that should be loaded by PhysX DLL and PhysXCooking DLL, please see the following example::

    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"; }
    } gDelayLoadHook;

Now the hook must be set to PhysX and PhysXCooking::

    PxDelayLoadHook::SetPhysXInstance(&gDelayLoadHook);
    PxDelayLoadHook::SetPhysXCookingInstance(&gDelayLoadHook);
    
+++++++++++++++++++++++++++++++
PhysXCommon Secure Load
+++++++++++++++++++++++++++++++

All PhysX DLLs distributed by NVIDIA are signed. The PhysXCommon DLL signature is checked, when it is loaded by PhysX or PhysXCooking. If signature test fails the application is terminated.

===============================
Shutting Down
===============================

To dispose of any PhysX object, call its *release()* method.  This will destroy the object, and all contained objects.  The precise behavior depends on the object type being released, so refer to the reference guide for details.  To shut down the extensions library, call the function *PxCloseExtensions()*. To shut down physics, call *release()* on the *PxPhysics* object, and this will clean up all of the physics objects::

    mPhysics->release();
    
Do not forget to release the foundation object as well, but only after all other PhysX modules have been released::

    mFoundation->release();

