563 lines
15 KiB
C++
563 lines
15 KiB
C++
// Copyright PICO Technology Co., Ltd. All rights reserved.
|
|
// This plugin incorporates portions of the Unreal® Engine. Unreal® is a trademark or registered trademark of Epic Games, Inc. in the United States of America and elsewhere.
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#include "PXR_Splash.h"
|
|
#include "PXR_HMD.h"
|
|
#include "Misc/ScopeLock.h"
|
|
#include "XRThreadUtils.h"
|
|
#include "PXR_Log.h"
|
|
#include "TextureResource.h"
|
|
#include "GlobalRenderResources.h"
|
|
|
|
FPXRSplash::FPXRSplash(FPICOXRHMD* InPICOXRHMD)
|
|
: SplashTicker(nullptr)
|
|
, bInitialized(false)
|
|
, PICOXRHMD(InPICOXRHMD)
|
|
, CustomRenderBridge(InPICOXRHMD->GetCustomRenderBridge())
|
|
, PICOSettings(nullptr)
|
|
, PXRFrame(nullptr)
|
|
, bIsShown(false)
|
|
, bSplashNeedUpdateActiveState(false)
|
|
, bSplashShouldToShow(false)
|
|
, FramesOutstanding(0)
|
|
{
|
|
AddedPXRSplashLayers.Reset();
|
|
PXRLayers_RenderThread_Entry.Reset();
|
|
PXRLayers_RenderThread.Reset();
|
|
PXRLayers_RHIThread.Reset();
|
|
|
|
{
|
|
IStereoLayers::FLayerDesc LayerDesc;
|
|
LayerDesc.QuadSize = FVector2D(0.01f, 0.01f);
|
|
LayerDesc.Priority = 0;
|
|
LayerDesc.PositionType = IStereoLayers::TrackerLocked;
|
|
LayerDesc.Texture = GBlackTexture->TextureRHI;
|
|
BlackLayer = MakeShareable(new FPICOXRStereoLayer(InPICOXRHMD, InPICOXRHMD->NextLayerId++, LayerDesc));
|
|
BlackLayer->bSplashLayer = true;
|
|
BlackLayer->bSplashBlackProjectionLayer = true;
|
|
}
|
|
|
|
PXR_LOGI(PxrUnreal, "Splash FPXRSplash() Construct!");
|
|
}
|
|
|
|
FPXRSplash::~FPXRSplash()
|
|
{
|
|
check(!SplashTicker.IsValid());
|
|
PXR_LOGI(PxrUnreal, "Splash FPXRSplash() Destruct!");
|
|
}
|
|
|
|
void FPXRSplash::ShowLoadingScreen()
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash ShowLoadingScreen!");
|
|
bSplashShouldToShow = true;
|
|
bSplashNeedUpdateActiveState = !bIsShown;
|
|
}
|
|
|
|
void FPXRSplash::HideLoadingScreen()
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash HideLoadingScreen!");
|
|
bSplashShouldToShow = false;
|
|
bSplashNeedUpdateActiveState = bIsShown;
|
|
}
|
|
|
|
bool FPXRSplash::IsPlayingLoadingMovie() const
|
|
{
|
|
if (!bIsShown)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (const FPXRSplashLayer& Splash : AddedPXRSplashLayers)
|
|
{
|
|
if (Splash.Desc.bIsLiveUpdate)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void FPXRSplash::ClearSplashes()
|
|
{
|
|
check(IsInGameThread());
|
|
FScopeLock ScopeLock(&RenderThreadLock);
|
|
AddedPXRSplashLayers.Reset();
|
|
}
|
|
|
|
void FPXRSplash::AddSplash(const FSplashDesc& InSplashDesc)
|
|
{
|
|
FPXRSplashDesc PXRSplashDesc;
|
|
PXRSplashDesc.SplashTransform = InSplashDesc.Transform;
|
|
PXRSplashDesc.SplashQuadSize = InSplashDesc.QuadSize;
|
|
PXRSplashDesc.bNoAlpha = InSplashDesc.bIgnoreAlpha;
|
|
PXRSplashDesc.bIsLiveUpdate = InSplashDesc.bIsDynamic || InSplashDesc.bIsExternal;
|
|
PXRSplashDesc.SplashTextureOffset = InSplashDesc.UVRect.Min;
|
|
PXRSplashDesc.SplashTextureScale = InSplashDesc.UVRect.Max;
|
|
PXRSplashDesc.LoadedTextureRef = InSplashDesc.Texture;
|
|
AddPXRSplashLayers(PXRSplashDesc);
|
|
}
|
|
|
|
void FPXRSplash::InitSplash()
|
|
{
|
|
CheckInGameThread();
|
|
if (!bInitialized)
|
|
{
|
|
Settings = PICOXRHMD->CreateNewSettings();
|
|
PXRFrame = PICOXRHMD->MakeNewGameFrame();
|
|
AddSplashFromPXRSettings();
|
|
PICOXRHMD->InitDevice();
|
|
bInitialized = true;
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::ShutDownSplash()
|
|
{
|
|
check(IsInGameThread());
|
|
|
|
if (bInitialized)
|
|
{
|
|
ExecuteOnRenderThread([this]()
|
|
{
|
|
if (SplashTicker)
|
|
{
|
|
SplashTicker->Unregister();
|
|
SplashTicker = nullptr;
|
|
}
|
|
|
|
ExecuteOnRHIThread([this]()
|
|
{
|
|
AddedPXRSplashLayers.Reset();
|
|
PXRLayers_RenderThread_Entry.Reset();
|
|
PXRLayers_RenderThread.Reset();
|
|
PXRLayers_RHIThread.Reset();
|
|
});
|
|
});
|
|
|
|
if (PostLoadLevelDelegate.IsValid())
|
|
{
|
|
FCoreUObjectDelegates::PostLoadMapWithWorld.Remove(PostLoadLevelDelegate);
|
|
PostLoadLevelDelegate.Reset();
|
|
}
|
|
|
|
bInitialized = false;
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::ReleaseResources_RHIThread()
|
|
{
|
|
for (int32 LayerIndex = 0; LayerIndex < PXRLayers_RenderThread.Num(); LayerIndex++)
|
|
{
|
|
PXRLayers_RenderThread[LayerIndex]->ReleaseResources_RHIThread();
|
|
}
|
|
|
|
for (int32 LayerIndex = 0; LayerIndex < PXRLayers_RHIThread.Num(); LayerIndex++)
|
|
{
|
|
PXRLayers_RHIThread[LayerIndex]->ReleaseResources_RHIThread();
|
|
}
|
|
|
|
PXRLayers_RenderThread.Reset();
|
|
PXRLayers_RHIThread.Reset();
|
|
}
|
|
|
|
void FPXRSplash::SplashTick_RenderThread(float DeltaTime)
|
|
{
|
|
check(IsInRenderingThread());
|
|
|
|
if (!FPICOXRHMDModule::GetPluginWrapper().IsRunning())
|
|
{
|
|
PXR_LOGV(PxrUnreal, "Splash Pxr_IsRunning == false!");
|
|
return;
|
|
}
|
|
|
|
if (FramesOutstanding > 0)
|
|
{
|
|
PXR_LOGV(PxrUnreal, "Splash skipping frame; too many frames outstanding");
|
|
return;
|
|
}
|
|
|
|
RenderSplashFrame_RenderThread(FRHICommandListExecutor::GetImmediateCommandList());
|
|
}
|
|
|
|
void FPXRSplash::AddSplashFromPXRSettings()
|
|
{
|
|
PICOSettings = GetMutableDefault<UPICOXRSettings>();
|
|
check(PICOSettings);
|
|
ClearSplashes();
|
|
for (const FPXRSplashDesc& SplashDesc : PICOSettings->SplashDescs)
|
|
{
|
|
if (SplashDesc.SplashTexturePath.IsValid())
|
|
{
|
|
AddPXRSplashLayers(SplashDesc);
|
|
}
|
|
else
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash AddSplashFromPXRSettings() the TexturePath is null!");
|
|
}
|
|
}
|
|
|
|
if (!PostLoadLevelDelegate.IsValid())
|
|
{
|
|
PostLoadLevelDelegate = FCoreUObjectDelegates::PostLoadMapWithWorld.AddSP(this, &FPXRSplash::OnPostLoadMap);
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::OnPreLoadMap(const FString& MapName)
|
|
{
|
|
if (PICOSettings->bSplashScreenAutoShow)
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash OnPreLoadMap:%s", PLATFORM_CHAR(*MapName));
|
|
if (!bIsShown)
|
|
{
|
|
ToShow();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::OnPostLoadMap(UWorld*)
|
|
{
|
|
if (PICOSettings->bSplashScreenAutoShow)
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash OnPostLoadMap!");
|
|
if (!bSplashShouldToShow)
|
|
{
|
|
HideLoadingScreen();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::BeginTicker()
|
|
{
|
|
check(IsInGameThread());
|
|
if (!SplashTicker.IsValid())
|
|
{
|
|
SplashTicker = MakeShareable(new FSplashTicker_RenderThread(this));
|
|
ExecuteOnRenderThread([this]()
|
|
{
|
|
SplashTicker->Register();
|
|
PXR_LOGI(PxrUnreal, "Splash StartTicker!");
|
|
});
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::EndTicker()
|
|
{
|
|
ExecuteOnRenderThread([this]()
|
|
{
|
|
if (SplashTicker.IsValid())
|
|
{
|
|
SplashTicker->Unregister();
|
|
SplashTicker = nullptr;
|
|
PXR_LOGI(PxrUnreal, "Splash StopTicker!");
|
|
}
|
|
});
|
|
}
|
|
|
|
void FPXRSplash::ToShow()
|
|
{
|
|
check(IsInGameThread());
|
|
ReleaseAllTextures();
|
|
|
|
for (int32 i = 0; i < AddedPXRSplashLayers.Num(); ++i)
|
|
{
|
|
FPXRSplashLayer& SplashLayer = AddedPXRSplashLayers[i];
|
|
if (SplashLayer.Desc.SplashTexturePath.IsValid())
|
|
{
|
|
LoadTexture(SplashLayer);
|
|
}
|
|
if (SplashLayer.Desc.LoadingTextureFromPath && SplashLayer.Desc.LoadingTextureFromPath->IsValidLowLevel())
|
|
{
|
|
SplashLayer.Desc.LoadingTextureFromPath->UpdateResource();
|
|
}
|
|
}
|
|
FlushRenderingCommands();
|
|
|
|
for (int32 i = 0; i < AddedPXRSplashLayers.Num(); ++i)
|
|
{
|
|
FPXRSplashLayer& SplashLayer = AddedPXRSplashLayers[i];
|
|
if (SplashLayer.Desc.LoadingTextureFromPath && SplashLayer.Desc.LoadingTextureFromPath->IsValidLowLevel())
|
|
{
|
|
if (SplashLayer.Desc.LoadingTextureFromPath->GetResource() && SplashLayer.Desc.LoadingTextureFromPath->GetResource()->TextureRHI)
|
|
{
|
|
SplashLayer.Desc.LoadedTextureRef = SplashLayer.Desc.LoadingTextureFromPath->GetResource()->TextureRHI;
|
|
}
|
|
else
|
|
{
|
|
PXR_LOGI(PxrUnreal, "Splash %s - no Resource!", PLATFORM_CHAR(*SplashLayer.Desc.LoadingTextureFromPath->GetDesc()));
|
|
}
|
|
}
|
|
|
|
if (SplashLayer.Desc.LoadedTextureRef)
|
|
{
|
|
const int32 PXRLayerID = PICOXRHMD->NextLayerId++;
|
|
SplashLayer.Layer = MakeShareable(new FPICOXRStereoLayer(PICOXRHMD, PXRLayerID, CreateStereoLayerDescFromPXRSplashDesc(SplashLayer.Desc)));
|
|
SplashLayer.Layer->bSplashLayer = true;
|
|
}
|
|
}
|
|
|
|
{
|
|
FScopeLock ScopeLock(&RenderThreadLock);
|
|
PXRLayers_RenderThread_Entry.Reset();
|
|
for (int32 i = 0; i < AddedPXRSplashLayers.Num(); i++)
|
|
{
|
|
const FPXRSplashLayer& SplashLayer = AddedPXRSplashLayers[i];
|
|
|
|
if (SplashLayer.Layer.IsValid())
|
|
{
|
|
FPICOLayerPtr ClonedLayer = SplashLayer.Layer->CloneMyself();
|
|
PXRLayers_RenderThread_Entry.Add(ClonedLayer);
|
|
}
|
|
}
|
|
if (PXRLayers_RenderThread_Entry.Num() > 0)
|
|
{
|
|
PXRLayers_RenderThread_Entry.Add(BlackLayer->CloneMyself());
|
|
}
|
|
PXRLayers_RenderThread_Entry.Sort(FPICOLayerPtr_SortById());
|
|
}
|
|
|
|
if (PXRLayers_RenderThread_Entry.Num() > 0)
|
|
{
|
|
BeginTicker();
|
|
bIsShown = true;
|
|
}
|
|
else
|
|
{
|
|
PXR_LOGI(PxrUnreal, "No splash layers show!");
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::ToHide()
|
|
{
|
|
check(IsInGameThread());
|
|
PXR_LOGI(PxrUnreal, "Splash Hide!");
|
|
bIsShown = false;
|
|
EndTicker();
|
|
ReleaseAllTextures();
|
|
}
|
|
|
|
void FPXRSplash::AutoShow(bool AutoShowSplash)
|
|
{
|
|
check(IsInGameThread());
|
|
PICOSettings->bSplashScreenAutoShow = AutoShowSplash;
|
|
}
|
|
|
|
void FPXRSplash::AddPXRSplashLayers(const FPXRSplashDesc& Desc)
|
|
{
|
|
check(IsInGameThread());
|
|
PXR_LOGI(PxrUnreal, "Splash AddSplash!");
|
|
FScopeLock ScopeLock(&RenderThreadLock);
|
|
AddedPXRSplashLayers.Add(FPXRSplashLayer(Desc));
|
|
}
|
|
|
|
void FPXRSplash::SwitchActiveSplash_GameThread()
|
|
{
|
|
if (bSplashNeedUpdateActiveState)
|
|
{
|
|
if (bSplashShouldToShow)
|
|
{
|
|
if (!bIsShown)
|
|
{
|
|
ToShow();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (bIsShown)
|
|
{
|
|
ToHide();
|
|
}
|
|
}
|
|
bSplashNeedUpdateActiveState = false;
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::ReleaseAllTextures()
|
|
{
|
|
FScopeLock ScopeLock(&RenderThreadLock);
|
|
for (int32 i = 0; i < AddedPXRSplashLayers.Num(); ++i)
|
|
{
|
|
if (AddedPXRSplashLayers[i].Desc.SplashTexturePath.IsValid())
|
|
{
|
|
ReleaseTexture(AddedPXRSplashLayers[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void FPXRSplash::ReleaseTexture(FPXRSplashLayer& InSplashLayer)
|
|
{
|
|
check(IsInGameThread());
|
|
InSplashLayer.Desc.LoadingTextureFromPath = nullptr;
|
|
InSplashLayer.Desc.LoadedTextureRef = nullptr;
|
|
InSplashLayer.Layer.Reset();
|
|
}
|
|
|
|
void FPXRSplash::LoadTexture(FPXRSplashLayer& InSplashLayer)
|
|
{
|
|
check(IsInGameThread());
|
|
ReleaseTexture(InSplashLayer);
|
|
InSplashLayer.Desc.LoadingTextureFromPath = Cast<UTexture>(InSplashLayer.Desc.SplashTexturePath.TryLoad());
|
|
InSplashLayer.Desc.LoadedTextureRef = nullptr;
|
|
InSplashLayer.Layer.Reset();
|
|
}
|
|
|
|
void FPXRSplash::RenderSplashFrame_RenderThread(FRHICommandListImmediate& RHICmdList)
|
|
{
|
|
CheckInRenderThread();
|
|
|
|
FScopeLock ScopeLock(&RenderThreadLock);
|
|
|
|
FSettingsPtr PXRSettings = Settings->Clone();
|
|
FPXRGameFramePtr SplashFrame = PXRFrame->CloneMyself();
|
|
SplashFrame->FrameNumber = PICOXRHMD->NextGameFrameNumber;
|
|
SplashFrame->predictedDisplayTimeMs = PICOXRHMD->CurrentFramePredictedTime + 1000.0f / PICOXRHMD->DisplayRefreshRate;
|
|
SplashFrame->ShowFlags.Rendering = true;
|
|
SplashFrame->Flags.bHasWaited = PICOXRHMD->WaitedFrameNumber == SplashFrame->FrameNumber ? true : false;
|
|
TArray<FPICOLayerPtr> SplashEntryLayers = PXRLayers_RenderThread_Entry;
|
|
|
|
if (FPICOXRHMDModule::GetPluginWrapper().IsRunning())
|
|
{
|
|
if (PICOXRHMD->WaitedFrameNumber < SplashFrame->FrameNumber)
|
|
{
|
|
PXR_LOGV(PxrUnreal, "Splash WaitFrame %u", SplashFrame->FrameNumber);
|
|
if (PICOXRHMD->bWaitFrameVersion)
|
|
{
|
|
FPICOXRHMDModule::GetPluginWrapper().WaitFrame();
|
|
FPICOXRHMDModule::GetPluginWrapper().GetPredictedDisplayTime(&(PICOXRHMD->CurrentFramePredictedTime));
|
|
SplashFrame->predictedDisplayTimeMs = PICOXRHMD->CurrentFramePredictedTime;
|
|
PXR_LOGV(PxrUnreal, "Splash Pxr_GetPredictedDisplayTime after wait frame:%f", PICOXRHMD->CurrentFramePredictedTime);
|
|
}
|
|
PXR_LOGV(PxrUnreal, "Splash Wait frame return %u", SplashFrame->FrameNumber);
|
|
SplashFrame->Flags.bHasWaited = true;
|
|
}
|
|
if (SplashFrame->Flags.bHasWaited)
|
|
{
|
|
PICOXRHMD->WaitedFrameNumber = SplashFrame->FrameNumber;
|
|
PICOXRHMD->NextGameFrameNumber = SplashFrame->FrameNumber + 1;
|
|
}
|
|
else
|
|
{
|
|
SplashFrame->ShowFlags.Rendering = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
SplashFrame->ShowFlags.Rendering = false;
|
|
}
|
|
|
|
FPlatformAtomics::InterlockedIncrement(&FramesOutstanding);
|
|
|
|
if (SplashFrame->ShowFlags.Rendering)
|
|
{
|
|
PICOXRHMD->UpdateSensorValue(PXRSettings.Get(), SplashFrame.Get());
|
|
}
|
|
|
|
{
|
|
int32 EntryLayer_i = 0;
|
|
int32 Layer_j_RenderThread = 0;
|
|
|
|
while (EntryLayer_i < SplashEntryLayers.Num() && Layer_j_RenderThread < PXRLayers_RenderThread.Num())
|
|
{
|
|
uint32 LayerIdX = SplashEntryLayers[EntryLayer_i]->GetID();
|
|
uint32 LayerIdY = PXRLayers_RenderThread[Layer_j_RenderThread]->GetID();
|
|
|
|
if (LayerIdX < LayerIdY)
|
|
{
|
|
SplashEntryLayers[EntryLayer_i++]->InitPXRLayer_RenderThread(PXRSettings.Get(), CustomRenderBridge, &PICOXRHMD->DelayDeletion, RHICmdList);
|
|
}
|
|
else if (LayerIdX > LayerIdY)
|
|
{
|
|
PICOXRHMD->DelayDeletion.AddLayerToDeferredDeletionQueue(PXRLayers_RenderThread[Layer_j_RenderThread++]);
|
|
}
|
|
else
|
|
{
|
|
SplashEntryLayers[EntryLayer_i++]->InitPXRLayer_RenderThread(PXRSettings.Get(), CustomRenderBridge, &PICOXRHMD->DelayDeletion, RHICmdList, PXRLayers_RenderThread[Layer_j_RenderThread++].Get());
|
|
}
|
|
}
|
|
|
|
while (EntryLayer_i < SplashEntryLayers.Num())
|
|
{
|
|
SplashEntryLayers[EntryLayer_i++]->InitPXRLayer_RenderThread(PXRSettings.Get(), CustomRenderBridge, &PICOXRHMD->DelayDeletion, RHICmdList);
|
|
}
|
|
|
|
while (Layer_j_RenderThread < PXRLayers_RenderThread.Num())
|
|
{
|
|
PICOXRHMD->DelayDeletion.AddLayerToDeferredDeletionQueue(PXRLayers_RenderThread[Layer_j_RenderThread++]);
|
|
}
|
|
}
|
|
|
|
PXRLayers_RenderThread = SplashEntryLayers;
|
|
|
|
for (auto Splash : PXRLayers_RenderThread)
|
|
{
|
|
if (!Splash->bSplashBlackProjectionLayer)
|
|
{
|
|
Splash->PXRLayersCopy_RenderThread(CustomRenderBridge, RHICmdList);
|
|
}
|
|
}
|
|
|
|
CustomRenderBridge->SubmitGPUCommands_RenderThread(RHICmdList);
|
|
|
|
for (int32 i = 0; i < SplashEntryLayers.Num(); i++)
|
|
{
|
|
SplashEntryLayers[i] = SplashEntryLayers[i]->CloneMyself();
|
|
}
|
|
|
|
ExecuteOnRHIThread_DoNotWait([this, PXRSettings, SplashFrame, SplashEntryLayers]()
|
|
{
|
|
PXRLayers_RHIThread = SplashEntryLayers;
|
|
if (SplashFrame->ShowFlags.Rendering && FPICOXRHMDModule::GetPluginWrapper().IsRunning())
|
|
{
|
|
PXR_LOGV(PxrUnreal, "Splash BeginFrame %u", SplashFrame->FrameNumber);
|
|
FPICOXRHMDModule::GetPluginWrapper().BeginFrame();
|
|
if (!PICOXRHMD->bWaitFrameVersion)
|
|
{
|
|
FPICOXRHMDModule::GetPluginWrapper().GetPredictedDisplayTime(&(PICOXRHMD->CurrentFramePredictedTime));
|
|
PXR_LOGV(PxrUnreal, "Splash Pxr_GetPredictedDisplayTime after begin frame:%f", PICOXRHMD->CurrentFramePredictedTime);
|
|
}
|
|
for (int32 LayerIndex = 0; LayerIndex < PXRLayers_RHIThread.Num(); LayerIndex++)
|
|
{
|
|
PXRLayers_RHIThread[LayerIndex]->IncrementSwapChainIndex_RHIThread(CustomRenderBridge);
|
|
}
|
|
}
|
|
|
|
FPlatformAtomics::InterlockedDecrement(&FramesOutstanding);
|
|
|
|
PXRLayers_RHIThread.Sort(FPICOLayerPtr_SortByPriority());
|
|
|
|
if (SplashFrame->ShowFlags.Rendering && FPICOXRHMDModule::GetPluginWrapper().IsRunning())
|
|
{
|
|
PXR_LOGV(PxrUnreal, "Splash EndFrame %u", SplashFrame->FrameNumber);
|
|
for (int32 LayerIndex = 0; LayerIndex < PXRLayers_RHIThread.Num(); LayerIndex++)
|
|
{
|
|
PXRLayers_RHIThread[LayerIndex]->SubmitLayer_RHIThread(PXRSettings.Get(), SplashFrame.Get());
|
|
}
|
|
FPICOXRHMDModule::GetPluginWrapper().EndFrame();
|
|
}
|
|
});
|
|
}
|
|
|
|
IStereoLayers::FLayerDesc FPXRSplash::CreateStereoLayerDescFromPXRSplashDesc(FPXRSplashDesc PXRSplashDesc)
|
|
{
|
|
IStereoLayers::FLayerDesc LayerDesc;
|
|
if (PXRSplashDesc.LoadedTextureRef->GetTextureCube() != nullptr)
|
|
{
|
|
LayerDesc.SetShape<FCubemapLayer>();
|
|
}
|
|
else
|
|
{
|
|
LayerDesc.SetShape<FQuadLayer>();
|
|
}
|
|
|
|
LayerDesc.Transform = PXRSplashDesc.SplashTransform;
|
|
LayerDesc.QuadSize = PXRSplashDesc.SplashQuadSize;
|
|
LayerDesc.UVRect = FBox2D(PXRSplashDesc.SplashTextureOffset, PXRSplashDesc.SplashTextureOffset + PXRSplashDesc.SplashTextureScale);
|
|
LayerDesc.Priority = INT32_MAX - (int32)(PXRSplashDesc.SplashTransform.GetTranslation().X * 1000.f);
|
|
LayerDesc.PositionType = IStereoLayers::TrackerLocked;
|
|
LayerDesc.Texture = PXRSplashDesc.LoadedTextureRef;
|
|
LayerDesc.Flags = IStereoLayers::LAYER_FLAG_QUAD_PRESERVE_TEX_RATIO |
|
|
(PXRSplashDesc.bNoAlpha ? IStereoLayers::LAYER_FLAG_TEX_NO_ALPHA_CHANNEL : 0) |
|
|
(PXRSplashDesc.bIsLiveUpdate ? IStereoLayers::LAYER_FLAG_TEX_CONTINUOUS_UPDATE : 0);
|
|
return LayerDesc;
|
|
}
|