void SCaptureRegionWidget::Activate(bool bCurrentCaptureRegionIsFullViewport) { SetVisibility(EVisibility::Visible); OriginalCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion; bIgnoreExistingCaptureRegion = bCurrentCaptureRegionIsFullViewport; }
FReply SCaptureRegionWidget::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if (IsEnabled() && MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton) { FVector2D ViewportPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition; FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion; switch (CurrentState) { case State_Dragging: { BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Inactive; bIgnoreExistingCaptureRegion = false; break; } case State_XAxisResize: { ViewportPosition.Y = CurrentCaptureRegion.Max.Y; BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Inactive; break; } case State_YAxisResize: { ViewportPosition.X = CurrentCaptureRegion.Max.X; BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Inactive; break; } case State_Moving: { CurrentState = State_Inactive; //OnCaptureRegionChanged.ExecuteIfBound(CurrentCaptureRegion); SendUpdatedCaptureRegion(); break; } case State_Inactive: { break; } default: { check(false); break; } } return FReply::Handled(); } else { return FReply::Unhandled(); } }
void SCaptureRegionWidget::BuildNewCaptureRegion(const FVector2D& InPointA, const FVector2D& InPointB) { FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion; CurrentCaptureRegion.Min = FIntPoint(FMath::Min((int32)InPointA.X, (int32)InPointB.X), FMath::Min((int32)InPointA.Y, (int32)InPointB.Y)); CurrentCaptureRegion.Max = FIntPoint(FMath::Max((int32)InPointA.X, (int32)InPointB.X), FMath::Max((int32)InPointA.Y, (int32)InPointB.Y)); //OnCaptureRegionChanged.ExecuteIfBound(CurrentCaptureRegion); SendUpdatedCaptureRegion(); }
bool UAutomationBlueprintFunctionLibrary::TakeAutomationScreenshotInternal(const FString& Name, FIntPoint Resolution) { // Fallback resolution if all else fails for screenshots. uint32 ResolutionX = 1280; uint32 ResolutionY = 720; // First get the default set for the project. UAutomationTestSettings const* AutomationTestSettings = GetDefault<UAutomationTestSettings>(); if ( AutomationTestSettings->DefaultScreenshotResolution.GetMin() > 0 ) { ResolutionX = (uint32)AutomationTestSettings->DefaultScreenshotResolution.X; ResolutionY = (uint32)AutomationTestSettings->DefaultScreenshotResolution.Y; } // If there's an override resolution, use that instead. if ( Resolution.GetMin() > 0 ) { ResolutionX = (uint32)Resolution.X; ResolutionY = (uint32)Resolution.Y; } else { // Failing to find an override, look for a platform override that may have been provided through the // device profiles setup, to configure the CVars for controlling the automation screenshot size. int32 OverrideWidth = CVarAutomationScreenshotResolutionWidth.GetValueOnGameThread(); int32 OverrideHeight = CVarAutomationScreenshotResolutionHeight.GetValueOnGameThread(); if ( OverrideWidth > 0 ) { ResolutionX = (uint32)OverrideWidth; } if ( OverrideHeight > 0 ) { ResolutionY = (uint32)OverrideHeight; } } // Force all mip maps to load before taking the screenshot. UTexture::ForceUpdateTextureStreaming(); #if (WITH_DEV_AUTOMATION_TESTS || WITH_PERF_AUTOMATION_TESTS) FAutomationScreenshotTaker* TempObject = new FAutomationScreenshotTaker(GEngine->GameViewport->OnScreenshotCaptured(), Name); #endif FHighResScreenshotConfig& Config = GetHighResScreenshotConfig(); if ( Config.SetResolution(ResolutionX, ResolutionY, 1.0f) ) { GEngine->GameViewport->GetGameViewport()->TakeHighResScreenShot(); return true; } return false; }
void SCaptureRegionWidget::Deactivate(bool bKeepChanges) { if (GetVisibility() != EVisibility::Hidden) { SetVisibility(EVisibility::Hidden); bIgnoreExistingCaptureRegion = false; if (!bKeepChanges) { GetHighResScreenshotConfig().UnscaledCaptureRegion = OriginalCaptureRegion; } } }
bool ASceneCaptureToDiskCamera::SaveCaptureToDisk(const FString &FilePath) const { TArray<FColor> OutBMP; if (!ReadPixels(OutBMP)) { return false; } for (FColor &color : OutBMP) { color.A = 255; } const FIntPoint DestSize(GetImageSizeX(), GetImageSizeY()); FString ResultPath; FHighResScreenshotConfig &HighResScreenshotConfig = GetHighResScreenshotConfig(); return HighResScreenshotConfig.SaveImage(FilePath, OutBMP, DestSize, &ResultPath); }
void AShaderPluginDemoCharacter::SaveRenderTargetToDisk(UTextureRenderTarget2D* InRenderTarget, FString Filename, bool debug) { FTextureRenderTargetResource* RTResource = InRenderTarget->GameThread_GetRenderTargetResource(); FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm); ReadPixelFlags.SetLinearToGamma(true); TArray<FColor> OutBMP; RTResource->ReadPixels(OutBMP, ReadPixelFlags); FIntRect SourceRect; FIntPoint DestSize(InRenderTarget->GetSurfaceWidth(), InRenderTarget->GetSurfaceHeight()); FString ResultPath; FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig(); if (HighResScreenshotConfig.SaveImage(FPaths::GameSavedDir() + TEXT("Screenshots/") + Filename, OutBMP, DestSize, &ResultPath) && debug) { UE_LOG(LogFPChar, Warning, TEXT("Screenshot saved to: %s"), *ResultPath); } }
FReply SCaptureRegionWidget::OnMouseButtonDown( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if (IsEnabled() && MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton) { FVector2D ViewportPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition; FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion; switch (PotentialInteraction) { case PI_DrawNewCaptureRegion: { DragStartPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition; BuildNewCaptureRegion(DragStartPosition, DragStartPosition); CurrentState = State_Dragging; break; } case PI_ResizeBL: { DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y); BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Dragging; break; } case PI_ResizeTL: { DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Max.Y); BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Dragging; break; } case PI_ResizeBR: { DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y); BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Dragging; break; } case PI_ResizeTR: { DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y); BuildNewCaptureRegion(ViewportPosition, DragStartPosition); CurrentState = State_Dragging; break; } case PI_ResizeBottom: { DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y); CurrentState = State_YAxisResize; break; } case PI_ResizeTop: { DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y); CurrentState = State_YAxisResize; break; } case PI_ResizeLeft: { DragStartPosition = FVector2D(CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y); CurrentState = State_XAxisResize; break; } case PI_ResizeRight: { DragStartPosition = FVector2D(CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y); CurrentState = State_XAxisResize; break; } case PI_MoveExistingRegion: { DragStartPosition = ViewportPosition; CurrentState = State_Moving; break; } } return FReply::Handled(); } else { return FReply::Unhandled(); } }
void SCaptureRegionWidget::SendUpdatedCaptureRegion() { GetHighResScreenshotConfig().TargetViewport->Invalidate(); }
FReply SCaptureRegionWidget::OnMouseMove( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if (IsEnabled()) { FVector2D ViewportPosition = MouseEvent.GetScreenSpacePosition() - MyGeometry.AbsolutePosition; FIntRect& CurrentCaptureRegion = GetHighResScreenshotConfig().UnscaledCaptureRegion; switch (CurrentState) { case State_Dragging: { BuildNewCaptureRegion(ViewportPosition, DragStartPosition); break; } case State_Moving: { FVector2D Delta = ViewportPosition - DragStartPosition; DragStartPosition = ViewportPosition; CurrentCaptureRegion += FIntPoint((int32)Delta.X, (int32)Delta.Y); //OnCaptureRegionChanged.ExecuteIfBound(CurrentCaptureRegion); SendUpdatedCaptureRegion(); break; } case State_XAxisResize: { ViewportPosition.Y = CurrentCaptureRegion.Max.Y; BuildNewCaptureRegion(ViewportPosition, DragStartPosition); break; } case State_YAxisResize: { ViewportPosition.X = CurrentCaptureRegion.Max.X; BuildNewCaptureRegion(ViewportPosition, DragStartPosition); break; } case State_Inactive: { if (CurrentCaptureRegion.Area() > 0 && !bIgnoreExistingCaptureRegion) { // Common tests bool bWithinXRangeOfExistingRegion = ViewportPosition.X >= CurrentCaptureRegion.Min.X && ViewportPosition.X <= CurrentCaptureRegion.Max.X; bool bWithinYRangeOfExistingRegion = ViewportPosition.Y >= CurrentCaptureRegion.Min.Y && ViewportPosition.Y <= CurrentCaptureRegion.Max.Y; // Distance away from an edge which we consider intersecting const float EdgeDistance = 5; // Check if we're over the corners if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Min.Y)).Size() < EdgeDistance) { this->Cursor = EMouseCursor::ResizeSouthEast; PotentialInteraction = PI_ResizeTL; } else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Min.X, CurrentCaptureRegion.Max.Y)).Size() < EdgeDistance) { this->Cursor = EMouseCursor::ResizeSouthWest; PotentialInteraction = PI_ResizeBL; } else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Min.Y)).Size() < EdgeDistance) { this->Cursor = EMouseCursor::ResizeSouthWest; PotentialInteraction = PI_ResizeTR; } else if ((ViewportPosition - FVector2D((float)CurrentCaptureRegion.Max.X, CurrentCaptureRegion.Max.Y)).Size() < EdgeDistance) { this->Cursor = EMouseCursor::ResizeSouthEast; PotentialInteraction = PI_ResizeBR; } else if (FMath::Abs((float)CurrentCaptureRegion.Min.X - ViewportPosition.X) < EdgeDistance && bWithinYRangeOfExistingRegion) { this->Cursor = EMouseCursor::ResizeLeftRight; PotentialInteraction = PI_ResizeLeft; } else if (FMath::Abs((float)CurrentCaptureRegion.Max.X - ViewportPosition.X) < EdgeDistance && bWithinYRangeOfExistingRegion) { this->Cursor = EMouseCursor::ResizeLeftRight; PotentialInteraction = PI_ResizeRight; } else if (FMath::Abs((float)CurrentCaptureRegion.Min.Y - ViewportPosition.Y) < EdgeDistance && bWithinXRangeOfExistingRegion) { this->Cursor = EMouseCursor::ResizeUpDown; PotentialInteraction = PI_ResizeTop; } else if (FMath::Abs((float)CurrentCaptureRegion.Max.Y - ViewportPosition.Y) < EdgeDistance && bWithinXRangeOfExistingRegion) { this->Cursor = EMouseCursor::ResizeUpDown; PotentialInteraction = PI_ResizeBottom; } else if (CurrentCaptureRegion.Contains(FIntPoint((int32)ViewportPosition.X, (int32)ViewportPosition.Y))) { this->Cursor = EMouseCursor::CardinalCross; PotentialInteraction = PI_MoveExistingRegion; } else { this->Cursor = EMouseCursor::Crosshairs; PotentialInteraction = PI_DrawNewCaptureRegion; } } else { this->Cursor = EMouseCursor::Crosshairs; PotentialInteraction = PI_DrawNewCaptureRegion; } break; } default: { check(false); break; } } return FReply::Handled(); } else { return FReply::Unhandled(); } }
void FSceneView::EndFinalPostprocessSettings(const FSceneViewInitOptions& ViewInitOptions) { { static const auto CVarMobileMSAA = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); if(CVarMobileMSAA ? CVarMobileMSAA->GetValueOnGameThread() > 1 : false) { // Turn off various features which won't work with mobile MSAA. FinalPostProcessSettings.DepthOfFieldScale = 0.0f; FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.BloomQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.BloomIntensity = 0.0f; } } if(!Family->EngineShowFlags.Bloom) { FinalPostProcessSettings.BloomIntensity = 0.0f; } if(!Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.LPVIntensity = 0.0f; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.DepthOfFieldQuality")); int Value = CVar->GetValueOnGameThread(); if(Value <= 0) { FinalPostProcessSettings.DepthOfFieldScale = 0.0f; } } if(!Family->EngineShowFlags.DepthOfField) { FinalPostProcessSettings.DepthOfFieldScale = 0; } if(!Family->EngineShowFlags.Vignette) { FinalPostProcessSettings.VignetteIntensity = 0; FinalPostProcessSettings.VignetteColor = FLinearColor(0.0f, 0.0f, 0.0f); } if(!Family->EngineShowFlags.Grain) { FinalPostProcessSettings.GrainIntensity = 0; FinalPostProcessSettings.GrainJitter = 0; } if(!Family->EngineShowFlags.CameraImperfections) { FinalPostProcessSettings.BloomDirtMaskIntensity = 0; } if(!Family->EngineShowFlags.AmbientCubemap) { FinalPostProcessSettings.ContributingCubemaps.Empty(); } if(!Family->EngineShowFlags.LensFlares) { FinalPostProcessSettings.LensFlareIntensity = 0; } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarExposureOffset.GetValueOnGameThread(); FinalPostProcessSettings.AutoExposureBias += Value; } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.ScreenPercentage")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.ScreenPercentage = Value; } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) { float Value = CVarSSRMaxRoughness.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.ScreenSpaceReflectionMaxRoughness = Value; } } #endif { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionStaticFraction")); float Value = CVar->GetValueOnGameThread(); if(Value >= 0.0) { FinalPostProcessSettings.AmbientOcclusionStaticFraction = Value; } } if(!Family->EngineShowFlags.ScreenPercentage || bIsSceneCapture || bIsReflectionCapture) { FinalPostProcessSettings.ScreenPercentage = 100; } if(!Family->EngineShowFlags.AmbientOcclusion) { FinalPostProcessSettings.AmbientOcclusionIntensity = 0; } { static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataFloat(TEXT("r.AmbientOcclusionRadiusScale")); float Scale = FMath::Clamp(CVar->GetValueOnGameThread(), 0.1f, 5.0f); FinalPostProcessSettings.AmbientOcclusionRadius *= Scale; } { float Scale = FMath::Clamp(CVarSSAOFadeRadiusScale.GetValueOnGameThread(), 0.01f, 50.0f); FinalPostProcessSettings.AmbientOcclusionDistance *= Scale; } { float Value = FMath::Clamp(CVarMotionBlurScale.GetValueOnGameThread(), 0.0f, 50.0f); FinalPostProcessSettings.MotionBlurAmount *= Value; } { float Value = CVarMotionBlurMax.GetValueOnGameThread(); if(Value >= 0.0f) { FinalPostProcessSettings.MotionBlurMax = FMath::Min(FinalPostProcessSettings.MotionBlurMax, Value); } } { float Value = CVarSceneColorFringeMax.GetValueOnGameThread(); if (Value >= 0.0f) { FinalPostProcessSettings.SceneFringeIntensity = FMath::Min(FinalPostProcessSettings.SceneFringeIntensity, Value); } } if (!Family->EngineShowFlags.Lighting || !Family->EngineShowFlags.GlobalIllumination) { FinalPostProcessSettings.IndirectLightingColor = FLinearColor(0,0,0,0); FinalPostProcessSettings.IndirectLightingIntensity = 0.0f; } // Anti-Aliasing { const auto FeatureLevel = GetFeatureLevel(); static const auto CVar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.PostProcessAAQuality")); static auto* MobileHDRCvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileHDR")); static auto* MobileMSAACvar = IConsoleManager::Get().FindTConsoleVariableDataInt(TEXT("r.MobileMSAA")); static uint32 MSAAValue = GShaderPlatformForFeatureLevel[FeatureLevel] == SP_OPENGL_ES2_IOS ? 1 : MobileMSAACvar->GetValueOnGameThread(); int32 Quality = FMath::Clamp(CVar->GetValueOnGameThread(), 0, 6); if( !Family->EngineShowFlags.PostProcessing || !Family->EngineShowFlags.AntiAliasing || Quality <= 0 // Disable antialiasing in GammaLDR mode to avoid jittering. || (FeatureLevel == ERHIFeatureLevel::ES2 && MobileHDRCvar->GetValueOnGameThread() == 0) || (FeatureLevel <= ERHIFeatureLevel::ES3_1 && (MSAAValue > 1))) { FinalPostProcessSettings.AntiAliasingMethod = AAM_None; } if( FinalPostProcessSettings.AntiAliasingMethod == AAM_TemporalAA) { if( !Family->EngineShowFlags.TemporalAA || !Family->bRealtimeUpdate || Quality < 3 ) { FinalPostProcessSettings.AntiAliasingMethod = AAM_FXAA; } } } if (AllowDebugViewmodes()) { ConfigureBufferVisualizationSettings(); } #if WITH_EDITOR FHighResScreenshotConfig& Config = GetHighResScreenshotConfig(); // Pass highres screenshot materials through post process settings FinalPostProcessSettings.HighResScreenshotMaterial = Config.HighResScreenshotMaterial; FinalPostProcessSettings.HighResScreenshotMaskMaterial = Config.HighResScreenshotMaskMaterial; FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = NULL; // If the highres screenshot UI is open and we're not taking a highres screenshot this frame if (Config.bDisplayCaptureRegion && !GIsHighResScreenshot) { // Only enable the capture region effect if the capture region is different from the view rectangle... if ((Config.UnscaledCaptureRegion != ViewRect) && (Config.UnscaledCaptureRegion.Area() > 0) && (State != NULL)) { // ...and if this is the viewport associated with the highres screenshot UI auto ConfigViewport = Config.TargetViewport.Pin(); if (ConfigViewport.IsValid() && Family && Family->RenderTarget == ConfigViewport->GetViewport()) { static const FName ParamName = "RegionRect"; FLinearColor NormalizedCaptureRegion; // Normalize capture region into view rectangle NormalizedCaptureRegion.R = (float)Config.UnscaledCaptureRegion.Min.X / (float)ViewRect.Width(); NormalizedCaptureRegion.G = (float)Config.UnscaledCaptureRegion.Min.Y / (float)ViewRect.Height(); NormalizedCaptureRegion.B = (float)Config.UnscaledCaptureRegion.Max.X / (float)ViewRect.Width(); NormalizedCaptureRegion.A = (float)Config.UnscaledCaptureRegion.Max.Y / (float)ViewRect.Height(); // Get a MID for drawing this frame and push the capture region into the shader parameter FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial = State->GetReusableMID(Config.HighResScreenshotCaptureRegionMaterial); FinalPostProcessSettings.HighResScreenshotCaptureRegionMaterial->SetVectorParameterValue(ParamName, NormalizedCaptureRegion); } } } #endif // WITH_EDITOR // Upscaling or Super sampling { float LocalScreenPercentage = FinalPostProcessSettings.ScreenPercentage; float Fraction = 1.0f; // apply ScreenPercentage if (LocalScreenPercentage != 100.f) { Fraction = FMath::Clamp(LocalScreenPercentage / 100.0f, 0.1f, 4.0f); } // Window full screen mode with upscaling bool bFullscreen = false; if (GEngine && GEngine->GameViewport && GEngine->GameViewport->GetWindow().IsValid()) { bFullscreen = GEngine->GameViewport->GetWindow()->GetWindowMode() != EWindowMode::Windowed; } check(Family->RenderTarget); if (bFullscreen) { // CVar mode 2 is fullscreen with upscale if(GSystemResolution.WindowMode == EWindowMode::WindowedFullscreen) { // FIntPoint WindowSize = Viewport->GetSizeXY(); FIntPoint WindowSize = Family->RenderTarget->GetSizeXY(); // allow only upscaling float FractionX = FMath::Clamp((float)GSystemResolution.ResX / WindowSize.X, 0.1f, 4.0f); float FractionY = FMath::Clamp((float)GSystemResolution.ResY / WindowSize.Y, 0.1f, 4.0f); // maintain a pixel aspect ratio of 1:1 for easier internal computations Fraction *= FMath::Max(FractionX, FractionY); } } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) if(CVarScreenPercentageEditor.GetValueOnAnyThread() == 0) { bool bNotInGame = GEngine && GEngine->GameViewport == 0; if(bNotInGame) { Fraction = 1.0f; } } #endif // Upscale if needed if (Fraction != 1.0f) { // compute the view rectangle with the ScreenPercentage applied const FIntRect ScreenPercentageAffectedViewRect = ViewInitOptions.GetConstrainedViewRect().Scale(Fraction); SetScaledViewRect(ScreenPercentageAffectedViewRect); } } }