Access color and depth buffer of each frame?

#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

#config

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();	
	}
}
2 Likes