@author:白袍小道
随缘查看
前言:
绘制相关类
MeshCompoent |
模型组件 |
FVertexBuffer |
顶点缓冲区封装 |
FIndexBuffer |
顶点索引缓冲区封装 |
FRHIResourceCreateInfo |
资源创建描述,分装了底层(DX,OPENGL)的资源(如缓冲区)的描述 |
FMemory |
C++内存操作封装 |
RHIUnlockIndexBuffer |
???????? |
FPrimitiveSceneProxy |
为渲染线程映射 UPrimitiveComponent 状态。 划分为子类以支持不同类型的基元(骨架、刚体、BSP 等) 实现某些非常重要的函数. |
FSceneView |
单个视图到一个 FScene 的引擎代表。 通过对 FSceneRenderer::Render 的不同调用的不同视图来渲染(多编辑器视口) 通过对 FSceneRenderer::Render 的同一调用中的多个视图来渲染(分屏游戏)。 为每个帧构建新视图 |
FSceneViewFamily |
一组视图进入一个场景,该场景有不同的视图转换和所有者角色,所以有个管理(维护) |
FMeshElementCollector |
|
FDynamicMeshBuilder |
绘制规则
- Constructor : 从给定的顶点工厂(vertex factory)和材质着色器列表(material shader map)找出适当的着色器,并存储他们的引用。
其中材质着色器可以看GlobalShader的管理部分【值得参考类比和学习】。
- CreateBoundShaderState : 为绘制规则(Drawing Policy)创建绑定到RHI的着色器状态。
- Matches/Compare : 提供了排序该drawing policy和渲染列表(draw lists)中其他drawing policy的函数,Matches 必须比较 DrawShared 依赖的所有因素。
- DrawShared : 设置在从 Matches 返回 True 的绘制规则之间一致的 RHI 状态。例如,大多数绘制规则会为材质和顶点工厂排序,因此着色器参数只依赖可以设置的材质,并且可以绑定特定于该顶点工厂的顶点缓冲区。应尽可能在此处设置状态,而非在 SetMeshRenderState 设置,因为 DrawShared 在静态渲染路径中调用较少。
- SetMeshRenderState : 设置特定于此网格体的 RHI 状态,或 DrawShared 中未设置的状态。这比 DrawShared 调用的次数多得多,因此此处性能非常重要。
- DrawMesh : 实际发出 RHI 绘制调用
参考源码及其说明
DZCPP_CustomMeshComponent_01.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include “CoreMinimal.h”
#include “Components/MeshComponent.h”
#include <VertexFactory.h>
#include “ContentExamples.h”
#include “DynamicMeshBuilder.h”
#include “DZCPP_CustomMeshComponent_01.generated.h”
/**
*
*/
UCLASS(ClassGroup=Experimental,meta = (BlueprintSpawnableComponent))
class CONTENTEXAMPLES_API UDZCPP_CustomMeshComponent_01 : public UMeshComponent
{
GENERATED_BODY()
public:
virtual FPrimitiveSceneProxy * CreateSceneProxy() override;
TArray<int32> Indices;
TArray<FVector> Vertices;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Materials)
UMaterial * TheMaterial;
UDZCPP_CustomMeshComponent_01();
};
DZCPP_CustomMeshComponent_01.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include “DZCPP_CustomMeshComponent_01.h”
class FMyVertexBuffer : public FVertexBuffer
{
public:
TArray<FVector> Vertices;
virtual void InitRHI() override
{
FRHIResourceCreateInfo CreateInfo;
VertexBufferRHI = RHICreateVertexBuffer(Vertices.Num()
* sizeof(FVector), BUF_Static, CreateInfo);
void* VertexBufferData =
RHILockVertexBuffer(VertexBufferRHI, 0, Vertices.Num()
* sizeof(FVector), RLM_WriteOnly);
FMemory::Memcpy(VertexBufferData, Vertices.GetData(),
Vertices.Num() * sizeof(FVector));
RHIUnlockVertexBuffer(VertexBufferRHI);
}
};
class FMyIndexBuffer : public FIndexBuffer
{
public:
TArray<int32> Indices;
virtual void InitRHI() override
{
FRHIResourceCreateInfo CreateInfo;
IndexBufferRHI = RHICreateIndexBuffer(sizeof(int32),
Indices.Num() * sizeof(int32), BUF_Static, CreateInfo);
void* Buffer = RHILockIndexBuffer(IndexBufferRHI, 0,
Indices.Num() * sizeof(int32), RLM_WriteOnly);
FMemory::Memcpy(Buffer, Indices.GetData(),
Indices.Num() * sizeof(int32));
RHIUnlockIndexBuffer(IndexBufferRHI);
}
};
class FMySceneProxy : public FPrimitiveSceneProxy
{
private:
TArray<FDynamicMeshVertex> Vertices;
TArray<int32> Indices;
FMyVertexBuffer VertexBuffer;
FMyIndexBuffer IndexBuffer;
public:
UPROPERTY()
UMaterial* TheMaterial;
FMySceneProxy(UDZCPP_CustomMeshComponent_01* Component) :FPrimitiveSceneProxy(Component), Indices(Component->Indices), TheMaterial(Component->TheMaterial)
{
//VertexBuffer = FMyVertexBuffer();
//IndexBuffer = FMyIndexBuffer();
//for (FVector Vertex : Component->Vertices)
//{
//Vertices.Add(FDynamicMeshVertex(Component
//->GetComponentLocation() + Vertex));
//}
}
//FPrimitiveViewRelevance GetViewRelevance(const FSceneView* View)
//{
//FPrimitiveViewRelevance Result;
//Result.bDynamicRelevance = true;
//Result.bDrawRelevance = true;
//Result.bNormalTranslucencyRelevance = true;
//return Result;
//}
//void GetDynamicMeshElements(const TArray<const
//FSceneView*>& Views, const FSceneViewFamily& ViewFamily,
//uint32 VisibilityMap, FMeshElementCollector& Collector)
//{
//for (int32 ViewIndex = 0; ViewIndex < Views.Num();
//ViewIndex++)
//{
//FDynamicMeshBuilder MeshBuilder;
//if (Vertices.Num() == 0)
//{
//return;
//}
//MeshBuilder.AddVertices(Vertices);
//MeshBuilder.AddTriangles(Indices);
//}
//}
//void FMySceneProxy::OnActorPositionChanged()
//{
//VertexBuffer.ReleaseResource();
//IndexBuffer.ReleaseResource();
//}
//uint32 FMySceneProxy::GetMemoryFootprint(void)
//{
//return sizeof(*this);
//}
virtual ~FMySceneProxy() {};
};
FPrimitiveSceneProxy* UDZCPP_CustomMeshComponent_01::CreateSceneProxy()
{
FPrimitiveSceneProxy* proxy = nullptr;
//fmysceneproxy * childproxy = new fmysceneproxy(this);
//proxy = childproxy;
return proxy;
}
UDZCPP_CustomMeshComponent_01::UDZCPP_CustomMeshComponent_01()
{
/*static ConstructorHelpers::FObjectFinder<UMaterial>Material(TEXT(“Material’/Engine/BasicShapes/BasicShapeMaterial'”));
if (Material.Object != NULL)
{
TheMaterial = (UMaterial*)Material.Object;
}
Vertices.Add(FVector(10, 0, 0));
Vertices.Add(FVector(0, 10, 0));
Vertices.Add(FVector(0, 0, 10));
Indices.Add(0);
Indices.Add(1);
Indices.Add(2);*/
}