#Custom Viewport Class
I am posting for you my custom viewport class
I am accessing the color buffer to save a screenshot
Even though the code says PNG I am actually saving it to a .BMP file
DefaultEngine.ini
;~~~ Custom Viewport Client ~~~
GameViewportClientClassName=/Script/VictoryGame.VictoryGameViewport
#.h
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
#include "VictoryGameViewport.generated.h"
UCLASS()
class UVictoryGameViewport : public UGameViewportClient
{
GENERATED_UCLASS_BODY()
//Utility
public:
//Controller
AVictoryGamePlayerController * VictoryPC;
//~~~~~~~~~~~~~ Screen Shots to PNG ~~~~~~~~~~~~~~
//Triggers ScreenShot
bool VictoryDoScreenShot;
//Save Screen Shot to disk as PNG
void SaveScreenShotPNGToDisk(FString TheFileName);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//protected because must only be run from Draw() or causes crash
protected:
void VictoryTakeScreenShot();
//OVERRIDES
public:
virtual void Draw(FViewport* Viewport,FCanvas* SceneCanvas) OVERRIDE;
};
#.cpp
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
#include "VictoryGame.h"
//////////////////////////////////////////////////////////////////////////
// UVictoryGameViewport
UVictoryGameViewport::UVictoryGameViewport(const class FPostConstructInitializeProperties& PCIP)
: Super(PCIP)
{
}
void UVictoryGameViewport::VictoryTakeScreenShot()
{
if (!VictoryPC) return;
if (!Viewport) return;
//~~~~~~~~~~~~~~~~~~~~~~
//get viewport size
FVector2D viewportSize;
GetViewportSize(viewportSize);
//output viewport size, useful for debugging
/*
FString text = "x= ";
text += FString::FromInt(viewportSize.X);
text += "y= ";
text += FString::FromInt(viewportSize.Y);
VictoryPC->ClientMessage(text);
*/
//~~~ Invalid View Port Size ~~~
if (viewportSize.X <= 0 || viewportSize.Y <= 0) return;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Section of Viewport to capture
// entire buffer invalidated if going larger than viewport size
// during readpixels
viewportSize.X--; //actual indicies, not total size
viewportSize.Y--;
//Adjusted Image Size
VictoryPC->BMP_Width = viewportSize.X;
VictoryPC->BMP_Height = viewportSize.Y;
//~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~
//~~~ Empty Color Buffer ~~~
VictoryPC->VictoryScreenShot_ColorBuffer.Empty();
//~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~
//~~~ Reallocate Buffer ~~~
//add uninitialized does not call constructor on the TArray type
//do not use with non-simple data types like FColor FVector etc.
//~~~ Add Zeroed To Ensure Black For No Color Data Parts ~~~
VictoryPC->VictoryScreenShot_ColorBuffer.AddZeroed( viewportSize.X * viewportSize.Y );
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Get Screen Shot!
if (!Viewport->ReadPixels(
VictoryPC->VictoryScreenShot_ColorBuffer,
FReadSurfaceDataFlags(),
FIntRect(1,1,viewportSize.X,viewportSize.Y)
)){
VictoryPC->Optimize("Failed to ReadPixels");
return;
//~~~~~~~~~~~~~~~~~~~~~~~~~
}
//Start Processing Image
VictoryPC->SaveScreenshotToDisk();
}
//Draw
void UVictoryGameViewport::Draw(FViewport * Viewport, FCanvas * SceneCanvas)
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//this line is reaaaaaaaaaaaaaalllly important
Super::Draw(Viewport, SceneCanvas);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//UE_LOG(Victory,Warning,TEXT("VICTORY GAME VIEWPORT Ticking!"));
//Take Screen shot?
if (VictoryDoScreenShot)
{
VictoryDoScreenShot = false;
VictoryTakeScreenShot();
}
}