Unity 6.3
0 онлайн 95 гостей 3 в системе
Вход
Программирование в Unity Шаг 115 из 210

Нативный плагин API для графики и рендеринга

Используйте IUnityGraphics интерфейс, чтобы дать плагину доступ к общей функциональности графического устройства. Интерфейс объявлен в IUnityGraphics.h файл заголовка, расположенный в папка PluginAPI.

Следующий скрипт использует IUnityGraphics интерфейс, чтобы зарегистрировать обратный вызов:

#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 on graphics device initialization. 
            For example, D3D11 resource creation.
            break;
        }
        case kUnityGfxDeviceEventShutdown:
        {
            s_RendererType = kUnityGfxRendererNull;
            //TODO: user graphics API code to call on graphics device shutdown.
            break;
        }
        case kUnityGfxDeviceEventBeforeReset:
        {
            //TODO: user graphics API code to call before graphics device reset.
            break;
        }
        case kUnityGfxDeviceEventAfterReset:
        {
            //TODO: user graphics API code to call after graphics device reset.
            break;
        }
    };
}

Обратные вызовы плагинов на потоке отображения

Вы можете использовать многопоточность для рендеринга в Unity, если платформа и количество доступных CPUs позволяют это.

Примечание: При использовании многопоточного отображения, команды отображения API выполняются на отдельном потоке от скриптов MonoBehaviour. Связь между основным потоком и потоком отображения означает, что ваш плагин может не начать отображение сразу, в зависимости от того, сколько работы основной поток отдал потоку отображения.

Чтобы выполнить рендеринг из плагина, вызовите GL.IssuePluginEvent из управляемого скрипта плагина. Это заставляет конвейер рендеринга Unity вызывать основную функцию из потока рендеринга, как показано в следующем примере кода. Например, если вы вызываете GL.IssuePluginEvent из функции OnPostRender Camera, функция вызывает обратный вызов плагина сразу после того, как камера завершит рендеринг.

В следующем примере показан основной код плагина:

// 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);

Сигнатура обратного вызова UnityRenderingEvent предоставлена в IUnityGraphics.h в примере Native Rendering Plugin.

Плагин с использованием OpenGL графики API

Существует два вида объектов OpenGL:

  • Объекты, совместно используемые в контекстах OpenGL, такие как текстура, буфер, рендербуфер, семплер, запрос, шейдер и объекты программы.
  • Для-OpenGL контекстных объектов, таких как массив вершин, буфер кадров, конвейер программы, обратная связь преобразования и синхронизирующие объекты.

Unity использует несколько контекстов OpenGL. При инициализации и закрытии Редактора и Проигрывателя Unity опирается на главный контекст, но при рендеринге использует выделенные контексты. То есть, во время событий kUnityGfxDeviceEventInitialize и kUnityGfxDeviceEventShutdown нельзя создавать объекты по контексту.

Плагин с использованием Vulkan графики API

При разработке графического плагина, использующего Vulkan графика API, вы можете включить отладку через слои проверки. Чтобы включить слои проверки, выполните следующие действия для предотвращения сбоев во время выполнения плагина:

  • Добавьте плагин слоя проверки в тот же каталог, что и плагин для собственной графики.
  • Настроить идентичные Загрузить при запуске настройки как для нативного, так и для Vulkan плагины уровня проверки в плагин Inspector окно.

Расширения рендеринга API

Unity также поддерживает низкоуровневые расширения рендеринга, которые могут получать обратные вызова, когда происходят определенные события. Это в основном используется для реализации и управления низкоуровневым рендерингом в вашем плагине и позволяет ему работать с многопоточной рендерингом Unity.

Из-за низкоуровневой природы этого расширения, плагин может потребоваться предварительно загрузить до создания устройств. В настоящее время соглашение основано на именах; имя плагина должно начинаться с GfxPlugin, например: GfxPluginMyNativePlugin.

Определение расширения рендеринга, выделенное Unity, находится в файле IUnityRenderingExtensions.h, расположенном в папке PluginAPI.

Все платформы, поддерживающие нативные плагины, поддерживают эти расширения.

Чтобы воспользоваться преимуществами расширения рендеринга, плагин должен экспортировать UnityRenderingExtEvent и, по желанию, UnityRenderingExtQuery. Для получения дополнительной информации, обратитесь к документации, предоставленной внутри файла заголовка.

Обратные вызовы плагинов на потоке отображения

Плагин вызывается через UnityRenderingExtEvent всякий раз, когда Unity вызывает одно из встроенных событий. Обратные вызова также могут быть добавлены к CommandBuffers через CommandBuffer.IssuePluginEventAndData или CommandBuffer.IssuePluginCustomBlit из скриптов.

Дополнительные ресурсы