code
This commit is contained in:
@ -0,0 +1,188 @@
|
||||
// ------------------------------------------------
|
||||
// Copyright Joe Marshall 2024- All Rights Reserved
|
||||
// ------------------------------------------------
|
||||
//
|
||||
// Attaches to a static mesh, and allows the vertex data
|
||||
// to be passed into the vulkanimpl for rendering
|
||||
// ------------------------------------------------
|
||||
#pragma once
|
||||
|
||||
#include "Engine/StaticMesh.h"
|
||||
#include "Engine/StaticMeshActor.h"
|
||||
#include "IMediaEventSink.h"
|
||||
#include "MediaObjectPool.h"
|
||||
#include "MediaPlayer.h"
|
||||
#include "MediaPlayerFacade.h"
|
||||
#include "MediaSampleSink.h"
|
||||
|
||||
#include "Logging/StructuredLog.h"
|
||||
|
||||
#include "IVulkanVertexData.h"
|
||||
|
||||
#include "RendererInterface.h"
|
||||
|
||||
#include "DirectVideoMeshRenderer.generated.h"
|
||||
|
||||
class AndroidVulkanTextureSample;
|
||||
|
||||
class FRendererSceneViewExt;
|
||||
|
||||
class FRawStaticIndexBuffer;
|
||||
struct FStaticMeshVertexBuffers;
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogDirectVideoMeshRenderer, Log, All);
|
||||
|
||||
UCLASS(Blueprintable, ClassGroup = (Rendering, Common),
|
||||
hidecategories = (Object, Activation, "Components|Activation"), ShowCategories = (Mobility),
|
||||
editinlinenew, meta = (BlueprintSpawnableComponent))
|
||||
class VULKANVIDEOMESHCOMPONENT_API UDirectVideoMeshRendererComponent : public UActorComponent
|
||||
{
|
||||
friend class FRendererSceneViewExt;
|
||||
GENERATED_BODY()
|
||||
public:
|
||||
UDirectVideoMeshRendererComponent();
|
||||
~UDirectVideoMeshRendererComponent();
|
||||
|
||||
void HandlePlayerMediaEvent(EMediaSampleSinkEvent Event);
|
||||
|
||||
void DeInit();
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components|DirectVideo")
|
||||
UMediaPlayer *LinkedPlayer;
|
||||
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components|DirectVideo")
|
||||
bool HideMeshWhileWeHaveVideo;
|
||||
|
||||
// FMediaTextureSampleSink (called indirectly from _TextureSink)
|
||||
virtual bool Enqueue(const TSharedRef<IMediaTextureSample, ESPMode::ThreadSafe> &Sample);
|
||||
virtual int32 Num() const
|
||||
{
|
||||
if (CurrentSample.IsValid())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
virtual void RequestFlush()
|
||||
{
|
||||
CurrentSample.Reset();
|
||||
PreparedSample.Reset();
|
||||
}
|
||||
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
protected:
|
||||
// draw to a command list (which is already in a render pass with outputs set up)
|
||||
void DrawToCommandList(FRHICommandList &RHICmdList, FSceneView &InView);
|
||||
// load mesh, update matrices, create vulkan images (must be outside render pass)
|
||||
void DoWorkOutsideRenderPass(FRHICommandList &RHICmdList, FSceneViewFamily &InViewFamily);
|
||||
|
||||
void UpdateVisibility();
|
||||
|
||||
class _TextureSink : public FMediaTextureSampleSink
|
||||
{
|
||||
public:
|
||||
_TextureSink(UDirectVideoMeshRendererComponent *InOwner)
|
||||
{
|
||||
Owner = InOwner;
|
||||
FlushCount = 0;
|
||||
EventDelegate =
|
||||
OnMediaSampleSinkEvent().AddRaw(this, &_TextureSink::ReceiveEventHandler);
|
||||
}
|
||||
|
||||
virtual ~_TextureSink()
|
||||
{
|
||||
OnMediaSampleSinkEvent().Remove(EventDelegate);
|
||||
}
|
||||
virtual bool Enqueue(
|
||||
const TSharedRef<IMediaTextureSample, ESPMode::ThreadSafe> &Sample) override
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Enqueue");
|
||||
auto POwner = Owner.Get();
|
||||
if (POwner != NULL)
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Enqueue2");
|
||||
return POwner->Enqueue(Sample);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
virtual int32 Num() const override
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Num");
|
||||
auto POwner = Owner.Get();
|
||||
if (POwner != NULL)
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Num2");
|
||||
return POwner->Num();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
virtual void RequestFlush() override
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Flush");
|
||||
|
||||
FlushCount += 1;
|
||||
auto POwner = Owner.Get();
|
||||
if (POwner != NULL)
|
||||
{
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "Flush2");
|
||||
POwner->RequestFlush();
|
||||
}
|
||||
}
|
||||
|
||||
void ReceiveEventHandler(EMediaSampleSinkEvent Event, const FMediaSampleSinkEventData &Data)
|
||||
{
|
||||
int iEvent = (int)Event;
|
||||
UE_LOGFMT(LogDirectVideoMeshRenderer, Verbose, "On event:{1}", iEvent);
|
||||
auto POwner = Owner.Get();
|
||||
if (POwner != NULL)
|
||||
{
|
||||
POwner->HandlePlayerMediaEvent(Event);
|
||||
}
|
||||
}
|
||||
|
||||
TWeakObjectPtr<UDirectVideoMeshRendererComponent> Owner;
|
||||
int FlushCount;
|
||||
|
||||
FDelegateHandle EventDelegate;
|
||||
};
|
||||
|
||||
void Initialize();
|
||||
|
||||
void GetMeshObject();
|
||||
bool ConstructMeshFromRenderData(const FStaticMeshVertexBuffers &VertexBuffers,
|
||||
const FRawStaticIndexBuffer &IndexBuffer);
|
||||
void GetShaderInfo(const FSceneView *InView, float *m44, float *vp44,
|
||||
float *pre_view_translation);
|
||||
virtual void TickComponent(float DeltaTime, ELevelTick TickType,
|
||||
FActorComponentTickFunction *ThisTickFunction) override;
|
||||
|
||||
virtual void Serialize(FArchive &Ar) override;
|
||||
|
||||
UPROPERTY()
|
||||
bool HasMesh;
|
||||
// raw mesh data as passed to RenderToMesh
|
||||
// we save this in UObject::Serialize so that
|
||||
// we don't need to load it from the mesh at
|
||||
// runtime
|
||||
UPROPERTY()
|
||||
TArray<float> PositionsAsFloats; // x,y,z,u,v (floats)
|
||||
|
||||
// vertexData is not a UStruct because we pass it through to
|
||||
// native android code
|
||||
TArray<VertexData> Positions; // x,y,z,u,v (floats)
|
||||
|
||||
UPROPERTY()
|
||||
TArray<uint32> Indices; // index buffer for mesh (uint32)
|
||||
|
||||
TSharedPtr<_TextureSink> TextureSink;
|
||||
|
||||
TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> CurrentSample;
|
||||
TSharedPtr<IMediaTextureSample, ESPMode::ThreadSafe> PreparedSample;
|
||||
|
||||
TWeakPtr<FMediaPlayerFacade, ESPMode::ThreadSafe> Facade;
|
||||
|
||||
TObjectPtr<AStaticMeshActor> MeshActor;
|
||||
|
||||
TSharedPtr<FRendererSceneViewExt, ESPMode::ThreadSafe> ExtensionHolder;
|
||||
|
||||
bool Initialized;
|
||||
};
|
Reference in New Issue
Block a user