In addition to the basic script interface, Native Code Plugins in Unity can receive callbacks when certain events happen. This is mostly used to implement low-level rendering in your plugin and enable it to work with Unity’s multithreaded rendering.
A plugin can receive notification about events on the graphics device by exporting a UnitySetGraphicsDevice
function. This will be called when the graphics device is created, before it is destroyed, and also before and after the device is “reset” (this only happens with Direct3D 9). The function has parameters which will receive the device pointer, device type and the kind of event that is taking place.
// If exported by a plugin, this function will be called
// when graphics device is created, destroyed,
// and before and after it is reset (ie, resolution changed).
extern "C" void EXPORT_API UnitySetGraphicsDevice (
void* device,
int deviceType,
int eventType);
Possible values for deviceType:
enum GfxDeviceRenderer
{
kGfxRendererOpenGL = 0, // desktop OpenGL
kGfxRendererD3D9 = 1, // Direct3D 9
kGfxRendererD3D11 = 2, // Direct3D 11
kGfxRendererGCM = 3, // PlayStation 3
kGfxRendererNull = 4, // "null" device (used in batch mode)
kGfxRendererXenon = 6, // Xbox 360
kGfxRendererOpenGLES20 = 8, // OpenGL ES 2.0
kGfxRendererOpenGLES30 = 11, // OpenGL ES 3.0
kGfxRendererGXM = 12, // PlayStation Vita
kGfxRendererPS4 = 13, // PlayStation 4
kGfxRendererXboxOne = 14, // Xbox One
kGfxRendererMetal = 16, // iOS Metal
};
Possible values for eventType:
enum GfxDeviceEventType
{
kGfxDeviceEventInitialize = 0,
kGfxDeviceEventShutdown = 1,
kGfxDeviceEventBeforeReset = 2,
kGfxDeviceEventAfterReset = 3,
};
Rendering in Unity can be multithreaded if the platform and number of available CPUs will allow for it. When multithreaded rendering is used, the rendering API commands happen on a thread which is completely separate from the one that runs MonoBehaviour scripts. Consequently, it is not always possible for your plugin to start doing some rendering immediately, since might interfere with whatever the render thread is doing at the time.
In order to do any rendering from the plugin, you should call GL.IssuePluginEvent from your script, which will cause your plugin to be called from the render thread. For example, if you call GL.IssuePluginEvent from the camera’s OnPostRender function, you get a plugin callback immediately after the camera has finished rendering.
// If exported by a plugin, this function will be called for
// GL.IssuePluginEvent script calls. The function will be called
// on a rendering thread; note that when multithreaded rendering
// is used, the render thread WILL BE DIFFERENT from the main
// thread, on which all scripts & other game logic are executed!
// You have responsibility for ensuring any necessary
// synchronization with other plugin script calls takes place.
extern "C" void EXPORT_API UnityRenderEvent (int eventID);
An example of a low-level rendering plugin can be downloaded here. It demonstrates two things:
The project works with: