데스크톱 플랫폼용 플러그인 빌드
Low-level native plug-in Profiler API

Low-level native plug-in interface

In addition to the basic script interface, Native Code Plug-ins in Unity can receive callbacks when certain events happen. This is mostly used to implement low-level rendering in your plug-in and enable it to work with Unity’s multithreaded rendering.

Unity 에디터에서 노출되는 인터페이스를 정의하는 헤더는 에디터와 함께 제공됩니다.

인터페이스 레지스트리

A plug-in should export UnityPluginLoad and UnityPluginUnload functions to handle main Unity events. See IUnityInterface.h for the correct signatures. IUnityInterfaces is provided to the plug-in to access further Unity APIs.

# include "IUnityInterface.h"
# include "IUnityGraphics.h"
// Unity plugin load event
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    IUnityGraphics* graphics = unityInterfaces->Get<IUnityGraphics>();
}

그래픽 디바이스에 접근

A plug-in can access generic graphics device functionality by getting the IUnityGraphics interface. In earlier versions of Unity a UnitySetGraphicsDevice function had to be exported in order to receive notification about events on the graphics device. Starting with Unity 5.2 the new IUnityGraphics interface (found in IUnityGraphics.h) provides a way to register a callback.

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

Plug-in Callbacks on the Rendering Thread

Unity에서 렌더링은 플랫폼과 가능한 CPU 숫자에 따라 멀티스레드될 수 있습니다. 멀티스레드 렌더링을 사용할 때 렌더링 API 커맨드는 MonoBehaviour 스크립트를 실행하는 것과는 완전 별개의 스레드에서 실행합니다. 렌더 스레드가 어떤 작업을 하든 간섭할 수 있으므로, 플러그인에서 일부 렌더링을 항상 곧바로 시작할 수는 없습니다.

플러그인에서 모든 렌더링을 하려면 플러그인 스크립트에서 GL.IssuePluginEvent를 호출해야 합니다. 그러면 제공된 네이티브 함수를 렌더 스레드에서 호출합니다. 예를 들어 카메라의 OnPostRender 함수에서 GL.IssuePluginEvent를 호출하면 카메라가 렌더링을 종료한 직후 플러그인이 콜백됩니다.

UnityRenderingEvent 콜백의 시그니처는 IUnityGraphics.h에서 제공합니다. 네이티브 플러그인 코드 예제:

// Plugin function to handle a specific rendering event
static void UNITY_INTERFACE_API OnRenderEvent(int eventID)
{
    //TODO: 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;
}

Managed plug-in code example:

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

이런 콜백은 현재 CommandBuffer.IssuePluginEvent를 통해 CommandBuffers에 추가됩니다.

Plug-in using the OpenGL graphics API

OpenGL 오브젝트에는 OpenGL 컨텍스트(텍스처, 버퍼, 렌더 버퍼, 샘플러, 쿼리, 셰이더 및 프로그램 오브젝트) 간에 공유되는 오브젝트와 OpenGL당 컨텍스트 오브젝트(버텍스 배열, 프레임버퍼, 프로그램 파이프라인, 트랜스폼 피드백 및 동기화 오브젝트), 두 종류가 있습니다.

Unity에서는 여러 OpenGL 컨텍스트를 사용합니다. 에디터와 플레이어를 초기화하고 닫을 때는 master 컨텍스트를 사용하지만 렌더링에는 전용 컨텍스트를 사용합니다. 그러므로 kUnityGfxDeviceEventInitializekUnityGfxDeviceEventShutdown 이벤트 동안은 컨텍스트당 오브젝트를 생성할 수 없습니다.

For example, a native plug-in can’t create a vertex array object during a kUnityGfxDeviceEventInitialize event and use it in a UnityRenderingEvent callback, because the active context is not the one used during the vertex array object creation.

예제

An example of a low-level rendering plug-in is on bitbucket: bitbucket.org/Unity-Technologies/graphicsdemos (NativeRenderingPlugin folder). It demonstrates two things:

  • 모든 정규 렌더링이 완료된 후 C++ 코드에서 회전하는 삼각형을 렌더링합니다.
  • Texture.GetNativeTexturePtr로 C++ 코드에 접근해 절차적 텍스처를 채웁니다.

프로젝트는 다음에서 작동합니다.

  • Direct3D 9, Direct3D 11, Direct3D 12 및 OpenGL이 설치된 Windows(Visual Studio 2015).
  • Metal 및 OpenGL이 설치된 Mac OS X (Xcode)
  • Direct3D 11 및 Direct3D 12가 설치된 유니버설 Windows 플랫폼
  • WebGL

• 2017–05–16 편집 리뷰 없이 페이지 수정됨

데스크톱 플랫폼용 플러그인 빌드
Low-level native plug-in Profiler API