void FUMGViewportClient::Draw(FViewport* InViewport, FCanvas* Canvas) { FViewport* ViewportBackup = Viewport; Viewport = InViewport ? InViewport : Viewport; // Determine whether we should use world time or real time based on the scene. float TimeSeconds; float RealTimeSeconds; float DeltaTimeSeconds; const bool bIsRealTime = true; UWorld* World = GWorld; if ( ( GetScene() != World->Scene ) || ( bIsRealTime == true ) ) { // Use time relative to start time to avoid issues with float vs double TimeSeconds = FApp::GetCurrentTime() - GStartTime; RealTimeSeconds = FApp::GetCurrentTime() - GStartTime; DeltaTimeSeconds = FApp::GetDeltaTime(); } else { TimeSeconds = World->GetTimeSeconds(); RealTimeSeconds = World->GetRealTimeSeconds(); DeltaTimeSeconds = World->GetDeltaSeconds(); } // Setup a FSceneViewFamily/FSceneView for the viewport. FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( Canvas->GetRenderTarget(), GetScene(), EngineShowFlags) .SetWorldTimes(TimeSeconds, DeltaTimeSeconds, RealTimeSeconds) .SetRealtimeUpdate(bIsRealTime)); ViewFamily.EngineShowFlags = EngineShowFlags; //UpdateLightingShowFlags(ViewFamily.EngineShowFlags); //ViewFamily.ExposureSettings = ExposureSettings; //ViewFamily.LandscapeLODOverride = LandscapeLODOverride; FSceneView* View = CalcSceneView(&ViewFamily); //SetupViewForRendering(ViewFamily, *View); FSlateRect SafeFrame; View->CameraConstrainedViewRect = View->UnscaledViewRect; //if ( CalculateEditorConstrainedViewRect(SafeFrame, Viewport) ) //{ // View->CameraConstrainedViewRect = FIntRect(SafeFrame.Left, SafeFrame.Top, SafeFrame.Right, SafeFrame.Bottom); //} if ( IsAspectRatioConstrained() ) { // Clear the background to black if the aspect ratio is constrained, as the scene view won't write to all pixels. Canvas->Clear(FLinearColor::Black); } Canvas->Clear(BackgroundColor); GetRendererModule().BeginRenderingViewFamily(Canvas, &ViewFamily); // Remove temporary debug lines. // Possibly a hack. Lines may get added without the scene being rendered etc. if ( World->LineBatcher != NULL && ( World->LineBatcher->BatchedLines.Num() || World->LineBatcher->BatchedPoints.Num() ) ) { World->LineBatcher->Flush(); } if ( World->ForegroundLineBatcher != NULL && ( World->ForegroundLineBatcher->BatchedLines.Num() || World->ForegroundLineBatcher->BatchedPoints.Num() ) ) { World->ForegroundLineBatcher->Flush(); } //FCanvas* DebugCanvas = Viewport->GetDebugCanvas(); //UDebugDrawService::Draw(ViewFamily.EngineShowFlags, Viewport, View, DebugCanvas); // //FlushRenderingCommands(); Viewport = ViewportBackup; }
void FJavascriptUMGViewportClient::Draw(FViewport* InViewport, FCanvas* Canvas) { FViewport* ViewportBackup = Viewport; Viewport = InViewport ? InViewport : Viewport; // Determine whether we should use world time or real time based on the scene. float TimeSeconds; float RealTimeSeconds; float DeltaTimeSeconds; const bool bIsRealTime = true; UWorld* World = GWorld; if ((GetScene() != World->Scene) || (bIsRealTime == true)) { // Use time relative to start time to avoid issues with float vs double TimeSeconds = FApp::GetCurrentTime() - GStartTime; RealTimeSeconds = FApp::GetCurrentTime() - GStartTime; DeltaTimeSeconds = FApp::GetDeltaTime(); } else { TimeSeconds = World->GetTimeSeconds(); RealTimeSeconds = World->GetRealTimeSeconds(); DeltaTimeSeconds = World->GetDeltaSeconds(); } // Setup a FSceneViewFamily/FSceneView for the viewport. FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( Canvas->GetRenderTarget(), GetScene(), EngineShowFlags) .SetWorldTimes(TimeSeconds, DeltaTimeSeconds, RealTimeSeconds) .SetRealtimeUpdate(bIsRealTime)); ViewFamily.EngineShowFlags = EngineShowFlags; //UpdateLightingShowFlags(ViewFamily.EngineShowFlags); //ViewFamily.ExposureSettings = ExposureSettings; //ViewFamily.LandscapeLODOverride = LandscapeLODOverride; FSceneView* View = CalcSceneView(&ViewFamily); //SetupViewForRendering(ViewFamily, *View); FSlateRect SafeFrame; View->CameraConstrainedViewRect = View->UnscaledViewRect; //if ( CalculateEditorConstrainedViewRect(SafeFrame, Viewport) ) //{ // View->CameraConstrainedViewRect = FIntRect(SafeFrame.Left, SafeFrame.Top, SafeFrame.Right, SafeFrame.Bottom); //} if (IsAspectRatioConstrained()) { // Clear the background to black if the aspect ratio is constrained, as the scene view won't write to all pixels. Canvas->Clear(FLinearColor::Black); } Canvas->Clear(BackgroundColor); // workaround for hacky renderer code that uses GFrameNumber to decide whether to resize render targets --GFrameNumber; GetRendererModule().BeginRenderingViewFamily(Canvas, &ViewFamily); Viewport = ViewportBackup; }
void UBlendSpaceThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas) { UBlendSpaceBase* BlendSpace = Cast<UBlendSpaceBase>(Object); if (BlendSpace != nullptr) { if (ThumbnailScene == nullptr) { ThumbnailScene = new FBlendSpaceThumbnailScene(); } if (ThumbnailScene->SetBlendSpace(BlendSpace)) { FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues(RenderTarget, ThumbnailScene->GetScene(), FEngineShowFlags(ESFIM_Game)) .SetWorldTimes(FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime)); ViewFamily.EngineShowFlags.DisableAdvancedFeatures(); ViewFamily.EngineShowFlags.MotionBlur = 0; ViewFamily.EngineShowFlags.LOD = 0; ThumbnailScene->GetView(&ViewFamily, X, Y, Width, Height); GetRendererModule().BeginRenderingViewFamily(Canvas, &ViewFamily); ThumbnailScene->SetBlendSpace(nullptr); } } }
void UStaticMeshThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas) { UStaticMesh* StaticMesh = Cast<UStaticMesh>(Object); if (StaticMesh != nullptr && !StaticMesh->IsPendingKill()) { if ( ThumbnailScene == nullptr ) { ThumbnailScene = new FStaticMeshThumbnailScene(); } ThumbnailScene->SetStaticMesh(StaticMesh); ThumbnailScene->GetScene()->UpdateSpeedTreeWind(0.0); FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues( RenderTarget, ThumbnailScene->GetScene(), FEngineShowFlags(ESFIM_Game) ) .SetWorldTimes(FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime)); ViewFamily.EngineShowFlags.DisableAdvancedFeatures(); ViewFamily.EngineShowFlags.MotionBlur = 0; ViewFamily.EngineShowFlags.LOD = 0; ThumbnailScene->GetView(&ViewFamily, X, Y, Width, Height); GetRendererModule().BeginRenderingViewFamily(Canvas,&ViewFamily); ThumbnailScene->SetStaticMesh(nullptr); } }
void UMaterialFunctionThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas) { UMaterialFunction* MatFunc = Cast<UMaterialFunction>(Object); if (MatFunc != nullptr) { if ( ThumbnailScene == nullptr ) { ThumbnailScene = new FMaterialThumbnailScene(); } UMaterial* PreviewMaterial = MatFunc->GetPreviewMaterial(); if( PreviewMaterial ) { PreviewMaterial->ThumbnailInfo = MatFunc->ThumbnailInfo; ThumbnailScene->SetMaterialInterface( PreviewMaterial ); FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues( RenderTarget, ThumbnailScene->GetScene(), FEngineShowFlags(ESFIM_Game) ) .SetWorldTimes(FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime)); ViewFamily.EngineShowFlags.DisableAdvancedFeatures(); ViewFamily.EngineShowFlags.MotionBlur = 0; ThumbnailScene->GetView(&ViewFamily, X, Y, Width, Height); if (ViewFamily.Views.Num() > 0) { GetRendererModule().BeginRenderingViewFamily(Canvas,&ViewFamily); } ThumbnailScene->SetMaterialInterface(nullptr); } } }
void FTileRenderer::DrawTile(FRHICommandListImmediate& RHICmdList, const class FSceneView& View, const FMaterialRenderProxy* MaterialRenderProxy, bool bNeedsToSwitchVerticalAxis, float X, float Y, float SizeX, float SizeY, float U, float V, float SizeU, float SizeV, bool bIsHitTesting, const FHitProxyId HitProxyId, const FColor InVertexColor) { FMaterialTileVertex DestVertex[4]; // create verts if (bNeedsToSwitchVerticalAxis) { DestVertex[0].Initialize(X + SizeX, View.ViewRect.Height() - (Y + SizeY), U + SizeU, V + SizeV); DestVertex[1].Initialize(X, View.ViewRect.Height() - (Y + SizeY), U, V + SizeV); DestVertex[2].Initialize(X + SizeX, View.ViewRect.Height() - Y, U + SizeU, V); DestVertex[3].Initialize(X, View.ViewRect.Height() - Y, U, V); } else { DestVertex[0].Initialize(X + SizeX, Y, U + SizeU, V); DestVertex[1].Initialize(X, Y, U, V); DestVertex[2].Initialize(X + SizeX, Y + SizeY, U + SizeU, V + SizeV); DestVertex[3].Initialize(X, Y + SizeY, U, V + SizeV); } DestVertex[0].Color = InVertexColor.DWColor(); DestVertex[1].Color = InVertexColor.DWColor(); DestVertex[2].Color = InVertexColor.DWColor(); DestVertex[3].Color = InVertexColor.DWColor(); // update the FMeshBatch FMeshBatch& Mesh = GTileMesh.MeshElement; Mesh.UseDynamicData = true; Mesh.DynamicVertexData = DestVertex; Mesh.MaterialRenderProxy = MaterialRenderProxy; GetRendererModule().DrawTileMesh(RHICmdList, View, Mesh, bIsHitTesting, HitProxyId); }
void FSceneViewStateReference::Allocate() { check(!Reference); Reference = GetRendererModule().AllocateViewState(); GlobalListLink = TLinkedList<FSceneViewStateReference*>(this); GlobalListLink.Link(GetSceneViewStateList()); }
void FSceneViewStateReference::AllocateAll() { for(TLinkedList<FSceneViewStateReference*>::TIterator ViewStateIt(FSceneViewStateReference::GetSceneViewStateList());ViewStateIt;ViewStateIt.Next()) { FSceneViewStateReference* ViewStateReference = *ViewStateIt; ViewStateReference->Reference = GetRendererModule().AllocateViewState(); } }
/** Restores systems that need references to classes in the renderer module. */ void RestoreReferencesToRendererModuleClasses( const TMap<UWorld*, bool>& WorldsToUpdate, const TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData, const TScopedPointer<TArray<uint8> >& GlobalShaderData, const TMap<FShaderType*, FString>& ShaderTypeNames, const TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames) { FlushShaderFileCache(); // Initialize cached shader type data InitializeShaderTypes(); IRendererModule& RendererModule = GetRendererModule(); FSceneViewStateReference::AllocateAll(); // Recreate all renderer scenes for (TMap<UWorld*, bool>::TConstIterator It(WorldsToUpdate); It; ++It) { UWorld* World = It.Key(); RendererModule.AllocateScene(World, World->RequiresHitProxies(), It.Value(), World->FeatureLevel); for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); Level->InitializeRenderingResources(); } } // Restore FShaders from the serialized memory blobs // Shader maps may still not be complete after this due to code changes picked up in the recompile RestoreGlobalShaderMap(GRHIShaderPlatform_DEPRECATED, *GlobalShaderData); UMaterial::RestoreMaterialShadersFromMemory(GRHIShaderPlatform_DEPRECATED, ShaderMapToSerializedShaderData); FMaterialShaderMap::FixupShaderTypes(GRHIShaderPlatform_DEPRECATED, ShaderTypeNames, VertexFactoryTypeNames); TArray<FShaderType*> OutdatedShaderTypes; TArray<const FVertexFactoryType*> OutdatedFactoryTypes; FShaderType::GetOutdatedTypes(OutdatedShaderTypes, OutdatedFactoryTypes); // Recompile any missing shaders UMaterialInterface::IterateOverActiveFeatureLevels([&](ERHIFeatureLevel::Type FeatureLevel) { auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel]; BeginRecompileGlobalShaders(OutdatedShaderTypes, ShaderPlatform); UMaterial::UpdateMaterialShaders(OutdatedShaderTypes, OutdatedFactoryTypes, ShaderPlatform); }); // Block on global shader jobs FinishRecompileGlobalShaders(); }
void UWorldThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas) { UWorld* World = Cast<UWorld>(Object); if (World != nullptr && World->Scene) { FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues( RenderTarget, World->Scene, FEngineShowFlags(ESFIM_All0) ) .SetWorldTimes(FApp::GetCurrentTime() - GStartTime, FApp::GetDeltaTime(), FApp::GetCurrentTime() - GStartTime)); ViewFamily.EngineShowFlags.SetDiffuse(true); ViewFamily.EngineShowFlags.SetSkeletalMeshes(true); ViewFamily.EngineShowFlags.SetTranslucency(true); ViewFamily.EngineShowFlags.SetBillboardSprites(true); ViewFamily.EngineShowFlags.SetLOD(true); ViewFamily.EngineShowFlags.SetMaterials(true); ViewFamily.EngineShowFlags.SetStaticMeshes(true); ViewFamily.EngineShowFlags.SetLandscape(true); ViewFamily.EngineShowFlags.SetGame(true); ViewFamily.EngineShowFlags.SetBSP(true); ViewFamily.EngineShowFlags.SetRendering(true); ViewFamily.EngineShowFlags.SetPaper2DSprites(true); if ( !bUseUnlitScene ) { ViewFamily.EngineShowFlags.SetSpecular(true); ViewFamily.EngineShowFlags.SetLighting(true); ViewFamily.EngineShowFlags.SetDirectLighting(true); ViewFamily.EngineShowFlags.SetIndirectLightingCache(true); ViewFamily.EngineShowFlags.SetDeferredLighting(true); ViewFamily.EngineShowFlags.SetDirectionalLights(true); ViewFamily.EngineShowFlags.SetGlobalIllumination(true); ViewFamily.EngineShowFlags.SetPointLights(true); ViewFamily.EngineShowFlags.SetSpotLights(true); ViewFamily.EngineShowFlags.SetSkyLighting(true); ViewFamily.EngineShowFlags.SetReflectionEnvironment(true); } GetView(World, &ViewFamily, X, Y, Width, Height); if (ViewFamily.Views.Num() > 0) { GetRendererModule().BeginRenderingViewFamily(Canvas, &ViewFamily); } } }
void ULevelThumbnailRenderer::Draw(UObject* Object, int32 X, int32 Y, uint32 Width, uint32 Height, FRenderTarget* RenderTarget, FCanvas* Canvas) { ULevel* Level = Cast<ULevel>(Object); if (Level != nullptr) { FSceneViewFamilyContext ViewFamily( FSceneViewFamily::ConstructionValues( RenderTarget, Level->OwningWorld->Scene, FEngineShowFlags(ESFIM_Game) ) .SetWorldTimes(GCurrentTime - GStartTime,GDeltaTime,GCurrentTime - GStartTime) ); ViewFamily.EngineShowFlags.DisableAdvancedFeatures(); ViewFamily.EngineShowFlags.MotionBlur = 0; ViewFamily.EngineShowFlags.Lighting = 1; ViewFamily.EngineShowFlags.PostProcessing = 0; GetView(Level, &ViewFamily, X, Y, Width, Height); if (ViewFamily.Views.Num() > 0) { GetRendererModule().BeginRenderingViewFamily(Canvas, &ViewFamily); } } }
void UOffAxisGameViewportClient::Draw(FViewport* InViewport, FCanvas* SceneCanvas) { //Valid SceneCanvas is required. Make this explicit. check(SceneCanvas); FCanvas* DebugCanvas = InViewport->GetDebugCanvas(); // Create a temporary canvas if there isn't already one. static FName CanvasObjectName(TEXT("CanvasObject")); UCanvas* CanvasObject = GetCanvasByName(CanvasObjectName); CanvasObject->Canvas = SceneCanvas; // Create temp debug canvas object static FName DebugCanvasObjectName(TEXT("DebugCanvasObject")); UCanvas* DebugCanvasObject = GetCanvasByName(DebugCanvasObjectName); DebugCanvasObject->Canvas = DebugCanvas; DebugCanvasObject->Init(InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, NULL); const bool bScaledToRenderTarget = GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport); if (bScaledToRenderTarget) { // Allow HMD to modify screen settings GEngine->HMDDevice->UpdateScreenSettings(Viewport); } if (DebugCanvas) { DebugCanvas->SetScaledToRenderTarget(bScaledToRenderTarget); } if (SceneCanvas) { SceneCanvas->SetScaledToRenderTarget(bScaledToRenderTarget); } bool bUIDisableWorldRendering = false; FViewElementDrawer GameViewDrawer; // create the view family for rendering the world scene to the viewport's render target FSceneViewFamilyContext ViewFamily(FSceneViewFamily::ConstructionValues( InViewport, GetWorld()->Scene, EngineShowFlags) .SetRealtimeUpdate(true)); // Allow HMD to modify the view later, just before rendering if (GEngine->HMDDevice.IsValid() && GEngine->IsStereoscopic3D(InViewport)) { ISceneViewExtension* HmdViewExt = GEngine->HMDDevice->GetViewExtension(); if (HmdViewExt) { ViewFamily.ViewExtensions.Add(HmdViewExt); HmdViewExt->ModifyShowFlags(ViewFamily.EngineShowFlags); } } ESplitScreenType::Type SplitScreenConfig = GetCurrentSplitscreenConfiguration(); EngineShowFlagOverride(ESFIM_Game, (EViewModeIndex)ViewModeIndex, ViewFamily.EngineShowFlags, NAME_None, SplitScreenConfig != ESplitScreenType::None); TMap<ULocalPlayer*, FSceneView*> PlayerViewMap; FAudioDevice* AudioDevice = GEngine->GetAudioDevice(); bool bReverbSettingsFound = false; FReverbSettings ReverbSettings; class AAudioVolume* AudioVolume = nullptr; for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PlayerController = *Iterator; if (PlayerController) { ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player); if (LocalPlayer) { const bool bEnableStereo = GEngine->IsStereoscopic3D(InViewport); int32 NumViews = bEnableStereo ? 2 : 1; for (int i = 0; i < NumViews; ++i) { // Calculate the player's view information. FVector ViewLocation; FRotator ViewRotation; EStereoscopicPass PassType = !bEnableStereo ? eSSP_FULL : ((i == 0) ? eSSP_LEFT_EYE : eSSP_RIGHT_EYE); FSceneView* View = LocalPlayer->CalcSceneView(&ViewFamily, ViewLocation, ViewRotation, InViewport, &GameViewDrawer, PassType); if (mOffAxisMatrixSetted) UpdateProjectionMatrix(View, mOffAxisMatrix); if (View) { if (View->Family->EngineShowFlags.Wireframe) { // Wireframe color is emissive-only, and mesh-modifying materials do not use material substitution, hence... View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f); View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f); } else if (View->Family->EngineShowFlags.OverrideDiffuseAndSpecular) { View->DiffuseOverrideParameter = FVector4(GEngine->LightingOnlyBrightness.R, GEngine->LightingOnlyBrightness.G, GEngine->LightingOnlyBrightness.B, 0.0f); View->SpecularOverrideParameter = FVector4(.1f, .1f, .1f, 0.0f); } else if (View->Family->EngineShowFlags.ReflectionOverride) { View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f); View->SpecularOverrideParameter = FVector4(1, 1, 1, 0.0f); View->NormalOverrideParameter = FVector4(0, 0, 1, 0.0f); View->RoughnessOverrideParameter = FVector2D(0.0f, 0.0f); } if (!View->Family->EngineShowFlags.Diffuse) { View->DiffuseOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f); } if (!View->Family->EngineShowFlags.Specular) { View->SpecularOverrideParameter = FVector4(0.f, 0.f, 0.f, 0.f); } View->CameraConstrainedViewRect = View->UnscaledViewRect; // If this is the primary drawing pass, update things that depend on the view location if (i == 0) { // Save the location of the view. LocalPlayer->LastViewLocation = ViewLocation; PlayerViewMap.Add(LocalPlayer, View); // Update the listener. if (AudioDevice != NULL) { FVector Location; FVector ProjFront; FVector ProjRight; PlayerController->GetAudioListenerPosition(/*out*/ Location, /*out*/ ProjFront, /*out*/ ProjRight); FTransform ListenerTransform(FRotationMatrix::MakeFromXY(ProjFront, ProjRight)); ListenerTransform.SetTranslation(Location); ListenerTransform.NormalizeRotation(); bReverbSettingsFound = true; FReverbSettings PlayerReverbSettings; FInteriorSettings PlayerInteriorSettings; class AAudioVolume* PlayerAudioVolume = GetWorld()->GetAudioSettings(Location, &PlayerReverbSettings, &PlayerInteriorSettings); if (AudioVolume == nullptr || (PlayerAudioVolume != nullptr && PlayerAudioVolume->Priority > AudioVolume->Priority)) { AudioVolume = PlayerAudioVolume; ReverbSettings = PlayerReverbSettings; } uint32 ViewportIndex = PlayerViewMap.Num() - 1; AudioDevice->SetListener(ViewportIndex, ListenerTransform, (View->bCameraCut ? 0.f : GetWorld()->GetDeltaSeconds()), PlayerAudioVolume, PlayerInteriorSettings); } } // Add view information for resource streaming. IStreamingManager::Get().AddViewInformation(View->ViewMatrices.ViewOrigin, View->ViewRect.Width(), View->ViewRect.Width() * View->ViewMatrices.ProjMatrix.M[0][0]); GetWorld()->ViewLocationsRenderedLastFrame.Add(View->ViewMatrices.ViewOrigin); } } } } } if (bReverbSettingsFound) { AudioDevice->SetReverbSettings(AudioVolume, ReverbSettings); } // Update level streaming. GetWorld()->UpdateLevelStreaming(); // Draw the player views. if (!bDisableWorldRendering && !bUIDisableWorldRendering && PlayerViewMap.Num() > 0) { GetRendererModule().BeginRenderingViewFamily(SceneCanvas, &ViewFamily); } // Clear areas of the rendertarget (backbuffer) that aren't drawn over by the views. { // Find largest rectangle bounded by all rendered views. uint32 MinX = InViewport->GetSizeXY().X, MinY = InViewport->GetSizeXY().Y, MaxX = 0, MaxY = 0; uint32 TotalArea = 0; for (int32 ViewIndex = 0; ViewIndex < ViewFamily.Views.Num(); ++ViewIndex) { const FSceneView* View = ViewFamily.Views[ViewIndex]; FIntRect UpscaledViewRect = View->UnscaledViewRect; MinX = FMath::Min<uint32>(UpscaledViewRect.Min.X, MinX); MinY = FMath::Min<uint32>(UpscaledViewRect.Min.Y, MinY); MaxX = FMath::Max<uint32>(UpscaledViewRect.Max.X, MaxX); MaxY = FMath::Max<uint32>(UpscaledViewRect.Max.Y, MaxY); TotalArea += FMath::TruncToInt(UpscaledViewRect.Width()) * FMath::TruncToInt(UpscaledViewRect.Height()); } // To draw black borders around the rendered image (prevents artifacts from post processing passes that read outside of the image e.g. PostProcessAA) { int32 BlackBorders = 0; // FMath::Clamp(CVarSetBlackBordersEnabled.GetValueOnGameThread(), 0, 10); if (ViewFamily.Views.Num() == 1 && BlackBorders) { MinX += BlackBorders; MinY += BlackBorders; MaxX -= BlackBorders; MaxY -= BlackBorders; TotalArea = (MaxX - MinX) * (MaxY - MinY); } } // If the views don't cover the entire bounding rectangle, clear the entire buffer. if (ViewFamily.Views.Num() == 0 || TotalArea != (MaxX - MinX)*(MaxY - MinY) || bDisableWorldRendering) { SceneCanvas->DrawTile(0, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false); } else { // clear left if (MinX > 0) { SceneCanvas->DrawTile(0, 0, MinX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false); } // clear right if (MaxX < (uint32)InViewport->GetSizeXY().X) { SceneCanvas->DrawTile(MaxX, 0, InViewport->GetSizeXY().X, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false); } // clear top if (MinY > 0) { SceneCanvas->DrawTile(MinX, 0, MaxX, MinY, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false); } // clear bottom if (MaxY < (uint32)InViewport->GetSizeXY().Y) { SceneCanvas->DrawTile(MinX, MaxY, MaxX, InViewport->GetSizeXY().Y, 0.0f, 0.0f, 1.0f, 1.f, FLinearColor::Black, NULL, false); } } } // Remove temporary debug lines. if (GetWorld()->LineBatcher != NULL) { GetWorld()->LineBatcher->Flush(); } if (GetWorld()->ForegroundLineBatcher != NULL) { GetWorld()->ForegroundLineBatcher->Flush(); } // Draw FX debug information. if (GetWorld()->FXSystem) { GetWorld()->FXSystem->DrawDebug(SceneCanvas); } // Render the UI. { //SCOPE_CYCLE_COUNTER(STAT_UIDrawingTime); // render HUD bool bDisplayedSubtitles = false; for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { APlayerController* PlayerController = *Iterator; if (PlayerController) { ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player); if (LocalPlayer) { FSceneView* View = PlayerViewMap.FindRef(LocalPlayer); if (View != NULL) { // rendering to directly to viewport target FVector CanvasOrigin(FMath::TruncToFloat(View->UnscaledViewRect.Min.X), FMath::TruncToInt(View->UnscaledViewRect.Min.Y), 0.f); CanvasObject->Init(View->UnscaledViewRect.Width(), View->UnscaledViewRect.Height(), View); // Set the canvas transform for the player's view rectangle. SceneCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin)); CanvasObject->ApplySafeZoneTransform(); // Render the player's HUD. if (PlayerController->MyHUD) { //SCOPE_CYCLE_COUNTER(STAT_HudTime); DebugCanvasObject->SceneView = View; PlayerController->MyHUD->SetCanvas(CanvasObject, DebugCanvasObject); if (GEngine->IsStereoscopic3D(InViewport)) { check(GEngine->StereoRenderingDevice.IsValid()); GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, SceneCanvas, CanvasObject, Viewport); PlayerController->MyHUD->PostRender(); SceneCanvas->PopTransform(); GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, SceneCanvas, CanvasObject, Viewport); PlayerController->MyHUD->PostRender(); SceneCanvas->PopTransform(); // Reset the canvas for rendering to the full viewport. CanvasObject->Reset(); CanvasObject->SizeX = View->UnscaledViewRect.Width(); CanvasObject->SizeY = View->UnscaledViewRect.Height(); CanvasObject->SetView(NULL); CanvasObject->Update(); } else { PlayerController->MyHUD->PostRender(); } // Put these pointers back as if a blueprint breakpoint hits during HUD PostRender they can // have been changed CanvasObject->Canvas = SceneCanvas; DebugCanvasObject->Canvas = DebugCanvas; // A side effect of PostRender is that the playercontroller could be destroyed if (!PlayerController->IsPendingKill()) { PlayerController->MyHUD->SetCanvas(NULL, NULL); } } if (DebugCanvas != NULL) { DebugCanvas->PushAbsoluteTransform(FTranslationMatrix(CanvasOrigin)); UDebugDrawService::Draw(ViewFamily.EngineShowFlags, InViewport, View, DebugCanvas); DebugCanvas->PopTransform(); } CanvasObject->PopSafeZoneTransform(); SceneCanvas->PopTransform(); // draw subtitles if (!bDisplayedSubtitles) { FVector2D MinPos(0.f, 0.f); FVector2D MaxPos(1.f, 1.f); GetSubtitleRegion(MinPos, MaxPos); uint32 SizeX = SceneCanvas->GetRenderTarget()->GetSizeXY().X; uint32 SizeY = SceneCanvas->GetRenderTarget()->GetSizeXY().Y; FIntRect SubtitleRegion(FMath::TruncToInt(SizeX * MinPos.X), FMath::TruncToInt(SizeY * MinPos.Y), FMath::TruncToInt(SizeX * MaxPos.X), FMath::TruncToInt(SizeY * MaxPos.Y)); // We need a world to do this FSubtitleManager::GetSubtitleManager()->DisplaySubtitles(SceneCanvas, SubtitleRegion, GetWorld()->GetAudioTimeSeconds()); } } } } } //ensure canvas has been flushed before rendering UI SceneCanvas->Flush_GameThread(); if (DebugCanvas != NULL) { DebugCanvas->Flush_GameThread(); } // Allow the viewport to render additional stuff PostRender(DebugCanvasObject); // Render the console. if (ViewportConsole) { if (GEngine->IsStereoscopic3D(InViewport)) { GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, Viewport); ViewportConsole->PostRender_Console(DebugCanvasObject); #if !UE_BUILD_SHIPPING if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid()) { GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_LEFT_EYE); } #endif DebugCanvas->PopTransform(); GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, Viewport); ViewportConsole->PostRender_Console(DebugCanvasObject); #if !UE_BUILD_SHIPPING if (DebugCanvas != NULL && GEngine->HMDDevice.IsValid()) { GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_RIGHT_EYE); } #endif DebugCanvas->PopTransform(); // Reset the canvas for rendering to the full viewport. DebugCanvasObject->Reset(); DebugCanvasObject->SizeX = Viewport->GetSizeXY().X; DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y; DebugCanvasObject->SetView(NULL); DebugCanvasObject->Update(); } else { ViewportConsole->PostRender_Console(DebugCanvasObject); } } } // Grab the player camera location and orientation so we can pass that along to the stats drawing code. FVector PlayerCameraLocation = FVector::ZeroVector; FRotator PlayerCameraRotation = FRotator::ZeroRotator; { for (FConstPlayerControllerIterator Iterator = GetWorld()->GetPlayerControllerIterator(); Iterator; ++Iterator) { (*Iterator)->GetPlayerViewPoint(PlayerCameraLocation, PlayerCameraRotation); } } if (GEngine->IsStereoscopic3D(InViewport)) { GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_LEFT_EYE, DebugCanvas, DebugCanvasObject, InViewport); DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation); DebugCanvas->PopTransform(); GEngine->StereoRenderingDevice->PushViewportCanvas(eSSP_RIGHT_EYE, DebugCanvas, DebugCanvasObject, InViewport); DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation); DebugCanvas->PopTransform(); // Reset the canvas for rendering to the full viewport. DebugCanvasObject->Reset(); DebugCanvasObject->SizeX = Viewport->GetSizeXY().X; DebugCanvasObject->SizeY = Viewport->GetSizeXY().Y; DebugCanvasObject->SetView(NULL); DebugCanvasObject->Update(); #if !UE_BUILD_SHIPPING if (GEngine->HMDDevice.IsValid()) { GEngine->HMDDevice->DrawDebug(DebugCanvasObject, eSSP_FULL); } #endif } else { DrawStatsHUD(GetWorld(), InViewport, DebugCanvas, DebugCanvasObject, DebugProperties, PlayerCameraLocation, PlayerCameraRotation); } }
void UGameEngine::Tick( float DeltaSeconds, bool bIdleMode ) { SCOPE_CYCLE_COUNTER(STAT_GameEngineTick); NETWORK_PROFILER(GNetworkProfiler.TrackFrameBegin()); int32 LocalTickCycles=0; CLOCK_CYCLES(LocalTickCycles); // ----------------------------------------------------- // Non-World related stuff // ----------------------------------------------------- if( DeltaSeconds < 0.0f ) { #if (UE_BUILD_SHIPPING && WITH_EDITOR) // End users don't have access to the secure parts of UDN. Regardless, they won't // need the warning because the game ships with AMD drivers that address the issue. UE_LOG(LogEngine, Fatal,TEXT("Negative delta time!")); #else // Send developers to the support list thread. UE_LOG(LogEngine, Fatal,TEXT("Negative delta time! Please see https://udn.epicgames.com/lists/showpost.php?list=ue3bugs&id=4364")); #endif } // Tick the module manager IHotReloadInterface* HotReload = IHotReloadInterface::GetPtr(); if(HotReload != nullptr) { HotReload->Tick(); } if (!IsRunningDedicatedServer() && !IsRunningCommandlet()) { // Clean up the game viewports that have been closed. CleanupGameViewport(); } // If all viewports closed, time to exit. if(GIsClient && GameViewport == NULL ) { UE_LOG(LogEngine, Log, TEXT("All Windows Closed") ); FPlatformMisc::RequestExit( 0 ); return; } if ( GameViewport != NULL ) { // Decide whether to drop high detail because of frame rate. QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_SetDropDetail); GameViewport->SetDropDetail(DeltaSeconds); } // Update subsystems. { // This assumes that UObject::StaticTick only calls ProcessAsyncLoading. StaticTick(DeltaSeconds, !!GAsyncLoadingUseFullTimeLimit, GAsyncLoadingTimeLimit / 1000.f); } // ----------------------------------------------------- // Begin ticking worlds // ----------------------------------------------------- FName OriginalGWorldContext = NAME_None; for (int32 i=0; i < WorldList.Num(); ++i) { if (WorldList[i].World() == GWorld) { OriginalGWorldContext = WorldList[i].ContextHandle; break; } } for (int32 WorldIdx = 0; WorldIdx < WorldList.Num(); ++WorldIdx) { FWorldContext &Context = WorldList[WorldIdx]; if (Context.World() == NULL) { continue; } GWorld = Context.World(); // Tick all travel and Pending NetGames (Seamless, server, client) { QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_TickWorldTravel); TickWorldTravel(Context, DeltaSeconds); } if (!IsRunningDedicatedServer() && !IsRunningCommandlet()) { QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_CheckCaptures); // Only update reflection captures in game once all 'always loaded' levels have been loaded // This won't work with actual level streaming though if (Context.World()->AreAlwaysLoadedLevelsLoaded()) { // Update sky light first because it's considered direct lighting, sky diffuse will be visible in reflection capture indirect specular USkyLightComponent::UpdateSkyCaptureContents(Context.World()); UReflectionCaptureComponent::UpdateReflectionCaptureContents(Context.World()); } } if (!bIdleMode) { // Tick the world. GameCycles=0; CLOCK_CYCLES(GameCycles); Context.World()->Tick( LEVELTICK_All, DeltaSeconds ); UNCLOCK_CYCLES(GameCycles); } // Issue cause event after first tick to provide a chance for the game to spawn the player and such. if( Context.World()->bWorldWasLoadedThisTick ) { Context.World()->bWorldWasLoadedThisTick = false; const TCHAR* InitialExec = Context.LastURL.GetOption(TEXT("causeevent="),NULL); ULocalPlayer* GamePlayer = Context.OwningGameInstance ? Context.OwningGameInstance->GetFirstGamePlayer() : NULL; if( InitialExec && GamePlayer ) { UE_LOG(LogEngine, Log, TEXT("Issuing initial cause event passed from URL: %s"), InitialExec); GamePlayer->Exec( GamePlayer->GetWorld(), *(FString("CAUSEEVENT ") + InitialExec), *GLog ); } Context.World()->bTriggerPostLoadMap = true; } // Tick the viewports. if ( GameViewport != NULL && !bIdleMode ) { SCOPE_CYCLE_COUNTER(STAT_GameViewportTick); GameViewport->Tick(DeltaSeconds); } UpdateTransitionType(Context.World()); // fixme: this will only happen once due to the static bool, but still need to figure out how to handle this for multiple worlds if (FPlatformProperties::SupportsWindowedMode()) { // Hide the splashscreen and show the game window static bool bFirstTime = true; if ( bFirstTime ) { bFirstTime = false; FPlatformSplash::Hide(); if ( GameViewportWindow.IsValid() ) { GameViewportWindow.Pin()->ShowWindow(); FSlateApplication::Get().RegisterGameViewport( GameViewportWidget.ToSharedRef() ); } } } if (!bIdleMode && !IsRunningDedicatedServer() && !IsRunningCommandlet()) { // Render everything. RedrawViewports(); } // Block on async loading if requested. if (Context.World()->bRequestedBlockOnAsyncLoading) { BlockTillLevelStreamingCompleted(Context.World()); Context.World()->bRequestedBlockOnAsyncLoading = false; } // streamingServer if( GIsServer == true ) { SCOPE_CYCLE_COUNTER(STAT_UpdateLevelStreaming); Context.World()->UpdateLevelStreaming(); } // Update Audio. This needs to occur after rendering as the rendering code updates the listener position. if (FAudioDevice* AudioDevice = Context.World()->GetAudioDevice()) { AudioDevice->Update(!Context.World()->IsPaused()); } if( GIsClient ) { // IStreamingManager is updated outside of a world context. For now, assuming it needs to tick here, before possibly calling PostLoadMap. // Will need to take another look when trying to support multiple worlds. // Update resource streaming after viewports have had a chance to update view information. Normal update. { QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_IStreamingManager); IStreamingManager::Get().Tick( DeltaSeconds ); } if ( Context.World()->bTriggerPostLoadMap ) { Context.World()->bTriggerPostLoadMap = false; // Turns off the loading movie (if it was turned on by LoadMap) and other post-load cleanup. QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_IStreamingManager); PostLoadMap(); } } UNCLOCK_CYCLES(LocalTickCycles); TickCycles=LocalTickCycles; // See whether any map changes are pending and we requested them to be committed. QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_ConditionalCommitMapChange); ConditionalCommitMapChange(Context); } // ---------------------------- // End per-world ticking // ---------------------------- // Restore original GWorld*. This will go away one day. if (OriginalGWorldContext != NAME_None) { QUICK_SCOPE_CYCLE_COUNTER(STAT_UGameEngine_Tick_GetWorldContextFromHandleChecked); GWorld = GetWorldContextFromHandleChecked(OriginalGWorldContext).World(); } // rendering thread commands { ENQUEUE_UNIQUE_RENDER_COMMAND_TWOPARAMETER( TickRenderingTimer, bool, bPauseRenderingRealtimeClock, GPauseRenderingRealtimeClock, float, DeltaTime, DeltaSeconds, { if(!bPauseRenderingRealtimeClock) { // Tick the GRenderingRealtimeClock, unless it's paused GRenderingRealtimeClock.Tick(DeltaTime); } GetRendererModule().TickRenderTargetPool(); }); }