UE4绘制简单三角形
自定义PrimitiveComponents
组件,使用PrimitiveSceneProxy
渲染。
创建PrimitiveComponents子类
//h
#pragma once
#include "CoreMinimal.h"
#include "Components/PrimitiveComponent.h"
#include "MyTestPrimitiveComponent.generated.h"
/**
*
*/
UCLASS(meta = (BlueprintSpawnableComponent))
class HELLOSLATE_API UMyTestPrimitiveComponent : public UPrimitiveComponent
{
GENERATED_BODY()
virtual class FPrimitiveSceneProxy* CreateSceneProxy() override;
};
//cpp
//override
FPrimitiveSceneProxy* UMyTestPrimitiveComponent::CreateSceneProxy()
{
return new FMyTestPrimSceneProxy(this);
}
创建PrimitiveSceneProxy子类
#include "EngineGlobals.h"
#include "RHI.h"
#include "RenderingThread.h"
#include "RenderResource.h"
#include "VertexFactory.h"
#include "LocalVertexFactory.h"
#include "PrimitiveViewRelevance.h"
#include "PrimitiveSceneProxy.h"
#include "Engine/Engine.h"
#include "MaterialShared.h"
#include "Materials/Material.h"
#include "Engine/CollisionProfile.h"
#include "SceneManagement.h"
#include "DynamicMeshBuilder.h"
#include "UObject/UObjectHash.h"
#include "UObject/UObjectIterator.h"
#include "StaticMeshResources.h"
//顶点缓冲区
//class FTestVertexBuffer :public FVertexBuffer{
//public:
// virtual void InitRHI() override
// {
// FRHIResourceCreateInfo CreateInfo;
// VertexBufferRHI = RHICreateIndexBuffer(sizeof(FDynamicMeshVertex), Verts.Num() * sizeof(FDynamicMeshVertex), BUF_Static, CreateInfo);
//
// void* Buffer = RHILockVertexBuffer(VertexBufferRHI, 0, Verts.Num() * sizeof(FDynamicMeshVertex), RLM_WriteOnly);
// FMemory::Memcpy(Buffer, Verts.GetData(), Verts.Num() * sizeof(FDynamicMeshVertex));
// RHIUnlockVertexBuffer(VertexBufferRHI);
// }
//
// TArray<FDynamicMeshVertex> Verts;
//};
//索引缓冲区
class FTestIndexBuffer : public FIndexBuffer
{
public:
virtual void InitRHI() override
{
FRHIResourceCreateInfo CreateInfo;
IndexBufferRHI = RHICreateIndexBuffer(sizeof(uint32), Indices.Num() * sizeof(uint32), BUF_Static, CreateInfo);
void* Buffer = RHILockIndexBuffer(IndexBufferRHI, 0, Indices.Num() * sizeof(uint32), RLM_WriteOnly);
FMemory::Memcpy(Buffer, Indices.GetData(), Indices.Num() * sizeof(uint32));
RHIUnlockIndexBuffer(IndexBufferRHI);
}
TArray<uint32> Indices;
};
//class FTestLocalVertexFactory :FLocalVertexFactory {
//
//};
/** Represents a UMyTestPrimComponent to the scene manager. */
class FMyTestPrimSceneProxy final : public FPrimitiveSceneProxy
{
public:
//Get-Type-Hash
SIZE_T GetTypeHash() const override
{
static size_t UniquePointer;
return reinterpret_cast<size_t>(&UniquePointer);
}
//PrimitivePoxy
FMyTestPrimSceneProxy(UMyTestPrimitiveComponent* Component)
: FPrimitiveSceneProxy(Component)
, VertexFactory(GetScene().GetFeatureLevel(), "FMyTestPrimSceneProxy")
{
/** Can be set to false to skip some work only needed on lit primitives. */
//设定为false则会跳过一些只被光照图元所需的工作
bWillEverBeLit = false;
//设置顶点信息:(只是一个简单的三角形)
TArray<FDynamicMeshVertex> OutVerts;
FDynamicMeshVertex V0, V1, V2;
V0.Position = FVector(0, 0, 0);
V0.Color = FColor(255, 0, 0);
int32 I0 = OutVerts.Add(V0);
V1.Position = FVector(100, 0, 0);
V1.Color = FColor(0, 255, 0);
int32 I1 = OutVerts.Add(V1);
V2.Position = FVector(0, 100, 0);
V2.Color = FColor(0, 0, 255);
int32 I2 = OutVerts.Add(V2);
IndexBuffer.Indices.Add(I0);
IndexBuffer.Indices.Add(I1);
IndexBuffer.Indices.Add(I2);
//初始化顶点缓冲区属性
VertexBuffers.InitFromDynamicVertex(&VertexFactory, OutVerts);
//初始化索引
// Enqueue initialization of render resource
BeginInitResource(&IndexBuffer);
}
virtual ~FMyTestPrimSceneProxy()
{
VertexBuffers.PositionVertexBuffer.ReleaseResource();
VertexBuffers.StaticMeshVertexBuffer.ReleaseResource();
VertexBuffers.ColorVertexBuffer.ReleaseResource();
IndexBuffer.ReleaseResource();
VertexFactory.ReleaseResource();
}
virtual void GetDynamicMeshElements(const TArray<const FSceneView*>& Views, const FSceneViewFamily& ViewFamily, uint32 VisibilityMap, FMeshElementCollector& Collector) const override
{
QUICK_SCOPE_CYCLE_COUNTER(STAT_MyTestPrimSceneProxy_DrawDynamicElements);
//得到材质
auto MaterialRenderProxy = new FColoredMaterialRenderProxy(
GEngine->ArrowMaterial->GetRenderProxy(),
FLinearColor(0.0f, 1.0f, 1.0f, 1.0f),
"GizmoColor"
);
//设定材质
Collector.RegisterOneFrameMaterialProxy(MaterialRenderProxy);
//针对于每一个View设定mesh顶点
for (int32 ViewIndex = 0; ViewIndex < Views.Num(); ViewIndex++)
{
if (VisibilityMap & (1 << ViewIndex))
{
//申请一块新的内存来存放FMeshBatch
FMeshBatch& Mesh = Collector.AllocateMesh();
//获得第一个元素(也只有一个元素)
FMeshBatchElement& BatchElement = Mesh.Elements[0];
//设定索引缓冲与顶点缓冲
BatchElement.IndexBuffer = &IndexBuffer;
Mesh.VertexFactory = &VertexFactory;
//设定材质
Mesh.MaterialRenderProxy = MaterialRenderProxy;
//设定UniformBuffer
FDynamicPrimitiveUniformBuffer& DynamicPrimitiveUniformBuffer = Collector.AllocateOneFrameResource<FDynamicPrimitiveUniformBuffer>();
DynamicPrimitiveUniformBuffer.Set(GetLocalToWorld(), GetLocalToWorld(), GetBounds(), GetLocalBounds(), true, false, DrawsVelocity(), false);
BatchElement.PrimitiveUniformBufferResource = &DynamicPrimitiveUniformBuffer.UniformBuffer;
//设定索引的范围:
BatchElement.FirstIndex = 0;
BatchElement.NumPrimitives = IndexBuffer.Indices.Num() / 3;
//设定顶点的范围:
BatchElement.MinVertexIndex = 0;
BatchElement.MaxVertexIndex = VertexBuffers.PositionVertexBuffer.GetNumVertices() - 1;
//不使用线框
Mesh.bWireframe = false;
//是否反向剔除
Mesh.ReverseCulling = IsLocalToWorldDeterminantNegative();
//设定图元类型
Mesh.Type = PT_TriangleList;
//设定深度优先级组?
Mesh.DepthPriorityGroup = SDPG_World;
//** Whether view mode overrides can be applied to this mesh eg unlit, wireframe. */
Mesh.bCanApplyViewModeOverrides = false;
//调用FMeshElementCollector的接口AddMesh
Collector.AddMesh(ViewIndex, Mesh);
}
}
}
virtual FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View) const override
{
FPrimitiveViewRelevance Result;
//图元需要被画
Result.bDrawRelevance = IsShown(View) && (View->Family->EngineShowFlags.BillboardSprites);
//有动态的元素(true时GetDynamicMeshElements才会起效)
Result.bDynamicRelevance = true;
return Result;
}
/**
* Called to notify the proxy when its transform has been updated.
* Called in the thread that owns the proxy; game or rendering.
*/
virtual void OnTransformChanged() override
{
Origin = GetLocalToWorld().GetOrigin();
}
virtual uint32 GetMemoryFootprint(void) const override { return(sizeof(*this) + GetAllocatedSize()); }
uint32 GetAllocatedSize(void) const { return(FPrimitiveSceneProxy::GetAllocatedSize()); }
private:
//顶点数据:position,color,texture,tangents
FStaticMeshVertexBuffers VertexBuffers;
//索引数据
FTestIndexBuffer IndexBuffer;
//顶点属性
FLocalVertexFactory VertexFactory;
FVector Origin;
};
网友评论