Unity3D :低级本机插件接口
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生
低级本机插件接口
Unity 中的原生插件可以在发生某些事件时接收回调。您可以使用它在插件中实现低级渲染,以便它可以与 Unity 的多线程渲染一起使用。
接口注册表
要处理主要的 Unity 事件,插件必须导出并发挥作用。IUnityInterfaces 使插件能够访问这些功能,您可以在插件 API 中找到这些功能:UnityPluginLoadUnityPluginUnloadIUnityInterface.h
# include "IUnityInterface.h"
# include "IUnityGraphics.h"
// Unity 插件加载事件
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
}
访问图形设备
使用可在 中找到的界面,使插件能够访问通用图形设备功能。此脚本演示如何使用接口注册回调:IUnityGraphicsIUnityGraphics.hIUnityGraphics
#include "IUnityInterface.h"
#include "IUnityGraphics.h"
static IUnityInterfaces* s_UnityInterfaces = NULL;
static IUnityGraphics* s_Graphics = NULL;
static UnityGfxRenderer s_RendererType = kUnityGfxRendererNull;
// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_UnityInterfaces = unityInterfaces;
s_Graphics = unityInterfaces->Get<IUnityGraphics>();
s_Graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent);
// Run OnGraphicsDeviceEvent(initialize) manually on plugin load
// to not miss the event in case the graphics device is already initialized
OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize);
}
// Unity plugin unload event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginUnload()
{
s_Graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent);
}
static void UNITY_INTERFACE_API
OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType)
{
switch (eventType)
{
case kUnityGfxDeviceEventInitialize:
{
s_RendererType = s_Graphics->GetRenderer();
//TODO: user initialization code
break;
}
case kUnityGfxDeviceEventShutdown:
{
s_RendererType = kUnityGfxRendererNull;
//TODO: user shutdown code
break;
}
case kUnityGfxDeviceEventBeforeReset:
{
//TODO: user Direct3D 9 code
break;
}
case kUnityGfxDeviceEventAfterReset:
{
//TODO: user Direct3D 9 code
break;
}
};
}
呈现线程上的插件回调
如果平台和可用 CPU 数量允许,您可以使用多线程在 Unity 中进行渲染。
注意:使用多线程渲染时,渲染 API 命令发生在与运行 MonoBehavior 脚本的线程完全分开的线程上。主线程和渲染线程之间的通信意味着插件可能不会立即开始渲染,具体取决于主线程推送到渲染线程的工作量。
要从插件渲染,请调用 GL。来自托管插件脚本的 IssuePluginEvent。这会导致 Unity 的渲染管道从渲染线程调用本机函数,如下面的代码示例所示。例如,如果您调用 GL。IssuePluginEvent 来自相机的 OnPostRender 函数,该函数将在相机完成渲染后立即调用插件回调。
原生插件代码:
// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
// User rendering code
}
// Freely defined function to pass a callback to plugin-specific scripts
extern "C" UnityRenderingEvent UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
GetRenderEventFunc()
{
return OnRenderEvent;
}
托管插件代码:
#if UNITY_IPHONE && !UNITY_EDITOR
[DllImport ("__Internal")]
#else
[DllImport("RenderingPlugin")]
#endif
private static extern IntPtr GetRenderEventFunc();
// Queue a specific callback to be called on the render thread
GL.IssuePluginEvent(GetRenderEventFunc(), 1);
回调的签名在本机渲染插件示例中的 IUnityGraphics.h 中提供。UnityRenderingEvent
使用 OpenGL 图形 API 的插件
有两种类型的 OpenGL 对象:
- 在 OpenGL 上下文中共享的对象,例如纹理、缓冲区、渲染缓冲区、采样器、查询、着色器和程序对象。
- 每 OpenGL 上下文对象,例如顶点数组、帧缓冲区、程序管道、转换反馈和同步对象。
Unity 使用多个 OpenGL 上下文。初始化和关闭编辑器和播放器时,Unity 依赖于主上下文,但在渲染时,它使用专用上下文。这意味着您无法在 和 事件期间创建每个上下文的对象。kUnityGfxDeviceEventInitializekUnityGfxDeviceEventShutdown
由3D建模学习工作室整理翻译,转载请注明出处!