Source/xsite_ue/MultiViewportCameraActor.cpp
// Called when the game starts or when spawned

Called when the game starts or when spawned
Called when the game starts or when spawned
void AMultiViewportCameraActor::BeginPlay()
{
    bEnabledScreen =
        CaveGameInstance->GetComputerName().ToLower().Equals(this->ClientName.ToLower()) || 
        this->ClientName.Equals(FString("AllClients")) ||
        this->ClientName.Equals("*");
    if (!bEnabledScreen)
    {
        Destroy();
        return;
    }
    ServerScreenAttached_Implementation(CaveGameInstance->GetComputerName(), WindowTitle.ToString());
    CamManager = nullptr;
    if (GetWorld())
    {
        for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator)
        {
            APlayerController *PlayerControllerTemp = Iterator->Get();
            if (PlayerControllerTemp && PlayerControllerTemp->PlayerCameraManager)
            {
                this->PlayerController = PlayerControllerTemp;
                this->CamManager = this->PlayerController->PlayerCameraManager;
            }
        }
    }
    if (CamManager == nullptr)
    {
        GEngine->AddOnScreenDebugMessage(-1, 15.f, FColor::Red,
                                         FString(TEXT("ExtraCamWindow Error: No Player Camera Manager found!")));
        bEnabledScreen = false;
        return;
    }
    FSlateApplication::Get().GetRenderer();
    SAssignNew(ExtraWindow, SWindow)
        .ClientSize(InitialWindowRes)
        .SizingRule(ESizingRule::FixedSize)
        .UseOSWindowBorder(true)
        .Title(FText::FromString(FString::Printf(TEXT("%s - %s"), *WindowTitle.ToString(),
                                                 GetWorld()->IsServer() ? TEXT("Server") : TEXT("Client"))))
        .FocusWhenFirstShown(false)
        .CreateTitleBar(false);
    FSlateApplication::Get().AddWindow(ExtraWindow.ToSharedRef(), true);
    ViewportOverlayWidget = SNew(SOverlay);
    TSharedRef<SGameLayerManager> LayerManagerRef = SNew(SGameLayerManager);
    SGameLayerManager::FArguments arguments = SGameLayerManager::FArguments();
    arguments.SceneViewport(GEngine->GameViewport->GetGameViewport());
    arguments.Visibility(EVisibility::Visible);
    arguments.Cursor(EMouseCursor::None)[ViewportOverlayWidget.ToSharedRef()];
    LayerManagerRef.Get().Construct(arguments);
    LayerManagerRef.Get().SetVisibility(EVisibility::Visible);
    LayerManagerRef.Get().SetCursor(EMouseCursor::None);
    TSharedPtr<SViewport> Viewport = SNew(SViewport)
                                         .RenderDirectlyToWindow(
                                             false) 
                                         .EnableGammaCorrection(false)
                                         .EnableStereoRendering(false) 
                                         .Cursor(EMouseCursor::None)[LayerManagerRef];
    SceneViewport = MakeShareable(new FSceneViewport(GEngine->GameViewport, Viewport));
    Viewport->SetViewportInterface(SceneViewport.ToSharedRef());
    ExtraWindow->SetContent(Viewport.ToSharedRef());
    ExtraWindow->MoveWindowTo(InitialWindowPos);
    ExtraWindow->SetOnWindowClosed(FOnWindowClosed::CreateLambda([this](const TSharedRef<SWindow> &window) {
#ifndef WITH_EDITOR
        if (GetWorld()->IsPlayInEditor() || GetWorld()->IsPlayInPreview())
            return;
        ExtraWindow->RequestDestroyWindow();
        UE_LOG(LogCave, Error, TEXT("Window closed by user. Trying to tear down game instance..."));
        FGenericPlatformMisc::RequestExit(false);
#endif
    }));
    ExtraWindow->ShowWindow();
    SceneViewport->CaptureMouse(false);
    SceneViewport->SetUserFocus(false);
    SceneViewport->LockMouseToViewport(false);
    FSlateApplication::Get().Tick();
    UE_LOG(LogCave, Display, TEXT("[%s] Spawning Extra Window resolution: %s offset: %s"), *WindowTitle.ToString(), *InitialWindowRes.ToString(), *InitialWindowPos.ToString());
    if (this->PlayerController)
    {
        this->PlayerController->ConsoleCommand("r.AllowOcclusionQueries 0");
        if (!GIsEditor) {
            this->PlayerController->ConsoleCommand("Gamma 3"); 
            this->PlayerController->ConsoleCommand("r.DepthOfFieldQuality 0"); 
            this->PlayerController->ConsoleCommand("r.ScreenPercentage 85"); 
            this->PlayerController->ConsoleCommand("r.ssr.quality 0"); 
            this->PlayerController->ConsoleCommand("r.PostProcessingAAQuality 1"); 
        }
        this->PlayerController->ConsoleCommand("r.SceneRenderTargetResizeMethod 2");
    }
    Super::BeginPlay();
}
void AMultiViewportCameraActor :: BeginPlay ( ) { bEnabledScreen = CaveGameInstance -> GetComputerName ( ) . ToLower ( ) . Equals ( this -> ClientName . ToLower ( ) ) || this -> ClientName . Equals ( FString ( " " ) ) || this -> ClientName . Equals ( " " ) ; if ( ! bEnabledScreen ) { Destroy ( ) ; return ; } ServerScreenAttached_Implementation ( CaveGameInstance -> GetComputerName ( ) , WindowTitle . ToString ( ) ) ; CamManager = nullptr ; if ( GetWorld ( ) ) { for ( FConstPlayerControllerIterator Iterator = GetWorld ( ) -> GetPlayerControllerIterator ( ) ; Iterator ; ++ Iterator ) { APlayerController * PlayerControllerTemp = Iterator -> Get ( ) ; if ( PlayerControllerTemp && PlayerControllerTemp -> PlayerCameraManager ) { this -> PlayerController = PlayerControllerTemp ; this -> CamManager = this -> PlayerController -> PlayerCameraManager ; } } } if ( CamManager == nullptr ) { GEngine -> AddOnScreenDebugMessage ( -1 , 15.f , FColor :: Red , FString ( TEXT ( " " ) ) ) ; bEnabledScreen = false ; return ; } FSlateApplication :: Get ( ) . GetRenderer ( ) ; SAssignNew ( ExtraWindow , SWindow ) . ClientSize ( InitialWindowRes ) . SizingRule ( ESizingRule :: FixedSize ) . UseOSWindowBorder ( true ) . Title ( FText :: FromString ( FString :: Printf ( TEXT ( " " ) , * WindowTitle . ToString ( ) , GetWorld ( ) -> IsServer ( ) ? TEXT ( " " ) : TEXT ( " " ) ) ) ) . FocusWhenFirstShown ( false ) . CreateTitleBar ( false ) ; FSlateApplication :: Get ( ) . AddWindow ( ExtraWindow . ToSharedRef ( ) , true ) ; ViewportOverlayWidget = SNew ( SOverlay ) ; TSharedRef < SGameLayerManager > LayerManagerRef = SNew ( SGameLayerManager ) ; SGameLayerManager :: FArguments arguments = SGameLayerManager :: FArguments ( ) ; arguments . SceneViewport ( GEngine -> GameViewport -> GetGameViewport ( ) ) ; arguments . Visibility ( EVisibility :: Visible ) ; arguments . Cursor ( EMouseCursor :: None ) [ ViewportOverlayWidget . ToSharedRef ( ) ] ; LayerManagerRef . Get ( ) . Construct ( arguments ) ; LayerManagerRef . Get ( ) . SetVisibility ( EVisibility :: Visible ) ; LayerManagerRef . Get ( ) . SetCursor ( EMouseCursor :: None ) ; TSharedPtr < SViewport > Viewport = SNew ( SViewport ) . RenderDirectlyToWindow ( false ) . EnableGammaCorrection ( false ) . EnableStereoRendering ( false ) . Cursor ( EMouseCursor :: None ) [ LayerManagerRef ] ; SceneViewport = MakeShareable ( new FSceneViewport ( GEngine -> GameViewport , Viewport ) ) ; Viewport -> SetViewportInterface ( SceneViewport . ToSharedRef ( ) ) ; ExtraWindow -> SetContent ( Viewport . ToSharedRef ( ) ) ; ExtraWindow -> MoveWindowTo ( InitialWindowPos ) ; ExtraWindow -> SetOnWindowClosed ( FOnWindowClosed :: CreateLambda ( [ this ] ( const TSharedRef < SWindow > & window ) { #ifndef WITH_EDITOR if ( GetWorld ( ) -> IsPlayInEditor ( ) || GetWorld ( ) -> IsPlayInPreview ( ) ) return ; ExtraWindow -> RequestDestroyWindow ( ) ; UE_LOG ( LogCave , Error , TEXT ( " " ) ) ; FGenericPlatformMisc :: RequestExit ( false ) ; #endif } ) ) ; ExtraWindow -> ShowWindow ( ) ; SceneViewport -> CaptureMouse ( false ) ; SceneViewport -> SetUserFocus ( false ) ; SceneViewport -> LockMouseToViewport ( false ) ; FSlateApplication :: Get ( ) . Tick ( ) ; UE_LOG ( LogCave , Display , TEXT ( " " ) , * WindowTitle . ToString ( ) , * InitialWindowRes . ToString ( ) , * InitialWindowPos . ToString ( ) ) ; if ( this -> PlayerController ) { this -> PlayerController -> ConsoleCommand ( " " ) ; if ( ! GIsEditor ) { this -> PlayerController -> ConsoleCommand ( " " ) ; this -> PlayerController -> ConsoleCommand ( " " ) ; this -> PlayerController -> ConsoleCommand ( " " ) ; this -> PlayerController -> ConsoleCommand ( " " ) ; this -> PlayerController -> ConsoleCommand ( " " ) ; } this -> PlayerController -> ConsoleCommand ( " " ) ; } Super :: BeginPlay ( ) ; }
Called when the game starts or when spawned
Called when the game starts or when spawned
// This shouldn't be reached in the first place if we are on the wrong client/computer
 // check whether we should spawn this screen on the current machine
 // AMultiViewportCameraActor should only be spawned on the correct clients,
 // Look at CaveController.cpp, there is almost the same statement
 // remove screen mesh from scene, we dont need it anymore
 // kill this actor on the client, it is not needed
 // if we got here, the current screen is active -> message the server for logging
 // Get the player controller
 // this inits the Slate Renderer (that thing responsible for drawing the window)
 // LayerManagerRef.Get().UseScissor(false);
 // true crashes some stuff because HMDs need the rendertarget tex for distortion etc..
 // not displaying on an HMD
 //UE_LOG(LogCave, Warning, TEXT("ViewportClient: %s"), *GEngine->GameViewportClientClassName.ToString());
 // dont do this in editor, otherwise the editor will get killed too
 // the window and some stuff gets initialized by ticking slate, otherwise we get a thread-related crash in packaged builds..
 // IdentifyScreen();
 // r.HZBOcclusion 1 enables Hierarchical Z-Buffer Occlusion (see https://docs.unrealengine.com/en-US/Engine/Rendering/VisibilityCulling/index.html)
 // we do this method to prevent flickering actors (static meshes) caused by aggressive default frustum/occlusion culling
 // whenever an extra window is spawn (with a seperate view frustum than the "main" window) we should make shure to activate this
 // we could also set r.AllowOcclusionQueries=0, but this would probably disable culling all together (which we do not want?)
 //TODO: this is just for performance testing!
 // Edit from server with Cave_Execute "command"
 // https://docs.unrealengine.com/en-US/Engine/Performance/Scalability/ScalabilityReference/index.html
 // our cave is currently really dark
 // we don't want that
 // our cave walls smooth quite a lot of pixels
 // flickering water reflections if we use ssr (screen space reflections)
 // this can lead to shaking screens in very distorted view frustums, apply this on runtime to get rid of shaking
 // if there is more than 1 render target (aka we spawning this extra window), this should be set https://docs.unrealengine.com/en-US/Platforms/MR/MRTroubleshooting/index.html
 // initialize everything before we call base class so that in blueprint beginplay everything is ready
