This commit is contained in:
2025-07-14 22:24:27 +08:00
parent daacc18ecf
commit 4af19ef574
7722 changed files with 72086 additions and 0 deletions

View File

@ -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;
};