// Example low level rendering Unity plugin #include "PlatformBase.h" #include "RenderAPI.h" #include "IUnityLog.h" #include "IUnityRenderingExtensions.h" #include #include #include // -------------------------------------------------------------------------- // UnitySetInterfaces static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType); static IUnityInterfaces *s_unity_interfaces = NULL; static IUnityGraphics *s_graphics = NULL; static IUnityLog *s_unity_logptr = nullptr; void unityLog(const char *msg) { UNITY_LOG(s_unity_logptr, msg); } extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces *unityInterfaces) { s_unity_interfaces = unityInterfaces; s_graphics = s_unity_interfaces->Get(); s_graphics->RegisterDeviceEventCallback(OnGraphicsDeviceEvent); s_unity_logptr = s_unity_interfaces->Get(); unityLog("UnityPluginLoad"); #if SUPPORT_VULKAN if (s_graphics->GetRenderer() == kUnityGfxRendererNull) { extern void RenderAPI_Vulkan_OnPluginLoad(IUnityInterfaces *); RenderAPI_Vulkan_OnPluginLoad(unityInterfaces); } #endif // SUPPORT_VULKAN // Run OnGraphicsDeviceEvent(initialize) manually on plugin load OnGraphicsDeviceEvent(kUnityGfxDeviceEventInitialize); } extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload() { s_graphics->UnregisterDeviceEventCallback(OnGraphicsDeviceEvent); } #if UNITY_WEBGL typedef void(UNITY_INTERFACE_API *PluginLoadFunc)(IUnityInterfaces *unityInterfaces); typedef void(UNITY_INTERFACE_API *PluginUnloadFunc)(); extern "C" void UnityRegisterRenderingPlugin(PluginLoadFunc loadPlugin, PluginUnloadFunc unloadPlugin); extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API RegisterPlugin() { UnityRegisterRenderingPlugin(UnityPluginLoad, UnityPluginUnload); } #endif // -------------------------------------------------------------------------- // GraphicsDeviceEvent static RenderAPI *s_current_api = NULL; static UnityGfxRenderer s_device_type = kUnityGfxRendererNull; static void UNITY_INTERFACE_API OnGraphicsDeviceEvent(UnityGfxDeviceEventType eventType) { // Create graphics API implementation upon initialization if (eventType == kUnityGfxDeviceEventInitialize) { assert(s_current_api == NULL); unityLog("kUnityGfxDeviceEventInitialize"); s_device_type = s_graphics->GetRenderer(); s_current_api = createRenderAPI(s_device_type); } // Let the implementation process the device related events if (s_current_api) { s_current_api->processDeviceEvent(eventType, s_unity_interfaces); } // Cleanup graphics API implementation upon shutdown if (eventType == kUnityGfxDeviceEventShutdown) { delete s_current_api; s_current_api = NULL; s_device_type = kUnityGfxRendererNull; } } // -------------------------------------------------------------------------- // OnRenderEvent // This will be called for GL.IssuePluginEvent script calls; eventID will // be the integer passed to IssuePluginEvent. In this example, we just ignore // that value. enum NativeRenderingEvent { EnableVRS = 1, DisableVRS, EnableFGExtrapolation, PreFGExtrapolation, DoFGExtrapolation, PostFGExtrapolation, DisableFGExtrapolation, SpatialUpScale, }; static void UNITY_INTERFACE_API OnRenderEventAndData(int eventID, void *data) { // unityLog("OnRenderEventAndData0"); // Unknown / unsupported graphics device type? Do nothing if (s_current_api == NULL) return; switch ((NativeRenderingEvent)eventID) { case NativeRenderingEvent::EnableVRS: { s_current_api->enableVRS(data); break; } case NativeRenderingEvent::DisableVRS: { s_current_api->disableVRS(); break; } case NativeRenderingEvent::EnableFGExtrapolation: { s_current_api->enableFGExtrapolation(data); break; } case NativeRenderingEvent::DisableFGExtrapolation: { break; } case NativeRenderingEvent::PreFGExtrapolation: { break; } case NativeRenderingEvent::PostFGExtrapolation: { break; } case NativeRenderingEvent::SpatialUpScale: { s_current_api->spatialUpScale(data); break; } case NativeRenderingEvent::DoFGExtrapolation: { AFMEParam *param = (AFMEParam *)data; s_current_api->doFGExtrapolation(param->src, param->data, param->dst); break; } default: break; } } extern "C" UnityRenderingEventAndData UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API GetRenderEventAndDataFunc() { return OnRenderEventAndData; } extern "C" UNITY_INTERFACE_EXPORT bool GetFeatureSupport(int feature) { if (s_current_api == NULL) return false; return s_current_api->getFeatureSupport((GraphicsFeature)feature); } extern "C" UNITY_INTERFACE_EXPORT void SetVKPSOHook(bool enable) { s_current_api->SetVKPSOHook(enable); } // -------------------------------------------------------------------------- // DX12 plugin specific // -------------------------------------------------------------------------- //extern "C" UNITY_INTERFACE_EXPORT void *UNITY_INTERFACE_API GetRenderTexture() //{ // return s_current_api->getRenderTexture(); //} // //extern "C" UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API SetRenderTexture(UnityRenderBuffer rb) //{ // s_current_api->setRenderTextureResource(rb); //} // //extern "C" UNITY_INTERFACE_EXPORT bool UNITY_INTERFACE_API IsSwapChainAvailable() //{ // return s_current_api->isSwapChainAvailable(); //} // //extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetPresentFlags() //{ // return s_current_api->getPresentFlags(); //} // //extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetSyncInterval() //{ // return s_current_api->getSyncInterval(); //} // //extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetBackBufferWidth() //{ // return s_current_api->getBackbufferHeight(); //} // //extern "C" UNITY_INTERFACE_EXPORT unsigned int UNITY_INTERFACE_API GetBackBufferHeight() //{ // return s_current_api->getBackbufferWidth(); //}