#include "WaveformViewer.h" #include "Async.h" #include "ExecutionTime.h" #include "SlateComputeShader.h" #include "SlatePixelShader.h" #include "Thumbnail.h" #include "Pattern/SamplePattern.h" #include "Pattern/SamplePatternInstance.h" void SWaveformViewer::Construct(const FArguments& InArgs) { Sampler.Load(TEXT("F:\\FL垃圾桶\\Kawaii Anokoga Kiniiranai.mp3")); // Sampler.Load(TEXT("F:\\Sample\\cs1.6\\26_Kick_15_95_SP.wav")); const TArray>& Buffer = Sampler.GetSampleBuffer(); Param.WaveColor = FLinearColor(0.0f, 1.0f, 1.0f, 1.0f).ToFColorSRGB(); Param.BgColor = FLinearColor(0.0f, 0.0f, 0.0f, 0.0f).ToFColorSRGB(); FSlateRenderer* Renderer = FSlateApplication::Get().GetRenderer(); RenderTarget = Renderer->CreateRenderTargetTexture(16, 16, EPixelFormat::PF_R8G8B8A8); RenderTarget->OnResizeDelegate.AddSP(this, &SWaveformViewer::OnResize); if (Renderer->GetRendererAPI() == ERendererAPI::D3D11) { Params = Renderer->CreateComputeShaderParam(ComputeShader); Params->Init(); Params->AddComputeShaderTextureParameter("Result", RenderTarget, 2); Params->AddComputeShaderParam("Samples", Buffer[0].GetData(), Buffer[0].Num(), 0); Params->AddShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool)); ComputeShader = Renderer->CreateComputeShader(TEXT("Arona"), TEXT("WaveformCS")); } else if (Renderer->GetRendererAPI() == ERendererAPI::OpenGL) { ComputeShader = Renderer->CreateComputeShader(TEXT("Arona"), TEXT("WaveformCS")); Params = Renderer->CreateComputeShaderParam(ComputeShader); Params->Init(); Params->AddComputeShaderTextureParameter("Result", RenderTarget, 2); Params->AddComputeShaderParam("Samples", Buffer[0].GetData(), Buffer[0].Num(), 0); Params->AddComputeShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool), 1); } ComputeElement = Renderer->MakeComputeShaderElement(ComputeShader, Params); } void SWaveformViewer::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) { SLeafWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); UpdateTimer += InDeltaTime; if (UpdateTimer > UpdateInterval && bNeedCompute) { UpdateTimer = 0.0f; Async(EAsyncExecution::TaskGraph, [this]() { const FIntPoint& Size = RenderTarget->GetSize(); UpdateTask Task; Task.LineUV = 1.0f / Size.Y; Task.Array = WaveformHandle->GetWaveform(Size.X); Task.Size = Size; UpdateQueue.Enqueue(Task); }); bNeedCompute = false; } } int32 SWaveformViewer::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyCullingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { if (const UpdateTask* UpdateTask = UpdateQueue.Peek()) { Param.LineUV = UpdateTask->LineUV; Params->AddComputeShaderParam("Samples", UpdateTask->Array.GetData(), UpdateTask->Array.Num(), 0); UpdateQueue.Pop(); if (FSlateApplication::Get().GetRenderer()->GetRendererAPI() == ERendererAPI::OpenGL) Params->AddComputeShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool), 1); else Params->AddShaderParam("Params", (bool*)&Param, sizeof(FCSParam) / sizeof(bool)); Params->AddComputeShaderParam("Samples", UpdateTask->Array.GetData(), UpdateTask->Array.Num(), 0); const FIntPoint& Size = UpdateTask->Size; FSlateDrawElement::MakeComputeShaderDispatch(OutDrawElements, LayerId, Size.X , Size.Y, 1, ComputeElement); } LayerId++; RenderTarget->OnDrawViewport(AllottedGeometry, MyCullingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); FSlateDrawElement::MakeViewport(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), RenderTarget, ESlateDrawEffect::None, FLinearColor::White); return LayerId; } void SWaveformViewer::OnResize(const FIntPoint& InSize) const { bNeedCompute = true; }