UE4绘制简单三角形(三)
运行时动态生成StaticMesh,并对StaticMesh的三角形面指定不同的材质。
Code
FStaticMeshSection
指定了Static Mesh中一组三角形,它们拥有同一个材质。
UStaticMeshComponent* mesh = NewObject<UStaticMeshComponent>(this);
mesh->SetFlags(RF_Transient);
UStaticMesh* pStaticMesh = NewObject<UStaticMesh>(mesh);
mesh->SetStaticMesh(pStaticMesh);
pStaticMesh->NeverStream = true;
//静态网格Mesh
FStaticMeshRenderData* RenderData = new FStaticMeshRenderData();
RenderData->AllocateLODResources(1);
FStaticMeshLODResources& LODResources = RenderData->LODResources[0];
TArray<uint32> indices;
indices.SetNum(6);
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 0;
indices[4] = 2;
indices[5] = 3;
TArray<FStaticMeshBuildVertex> StaticMeshBuildVertices;
StaticMeshBuildVertices.SetNum(4);
FStaticMeshBuildVertex& vertex0 = StaticMeshBuildVertices[0];
vertex0.Position = FVector(0, 0, 0);
vertex0.Color = FColor(255, 0, 0);
vertex0.UVs[0] = FVector2D(0, 0);
vertex0.TangentX = FVector(0, 1, 0);
vertex0.TangentY = FVector(1, 0, 0);
vertex0.TangentY = FVector(0, 0, 1);
FStaticMeshBuildVertex& vertex1 = StaticMeshBuildVertices[1];
vertex1.Position = FVector(100, 0, 0);
vertex1.Color = FColor(255, 0, 0);
vertex1.UVs[0] = FVector2D(1, 0);
vertex1.TangentX = FVector(0, 1, 0);
vertex1.TangentY = FVector(1, 0, 0);
vertex1.TangentY = FVector(0, 0, 1);
FStaticMeshBuildVertex& vertex2 = StaticMeshBuildVertices[2];
vertex2.Position = FVector(0, 100, 0);
vertex2.Color = FColor(255, 0, 0);
vertex2.UVs[0] = FVector2D(1, 0);
vertex2.TangentX = FVector(0, 1, 0);
vertex2.TangentY = FVector(1, 0, 0);
vertex2.TangentY = FVector(0, 0, 1);
FStaticMeshBuildVertex& vertex3 = StaticMeshBuildVertices[3];
vertex3.Position = FVector(-100, 0, 0);
vertex3.Color = FColor(255, 0, 0);
vertex3.UVs[0] = FVector2D(1, 0);
vertex3.TangentX = FVector(0, 1, 0);
vertex3.TangentY = FVector(1, 0, 0);
vertex3.TangentY = FVector(0, 0, 1);
LODResources.bHasColorVertexData = false;
FBoxSphereBounds BoundingBoxAndSphere;
BoundingBoxAndSphere.Origin = FVector(0, 0, 0);
BoundingBoxAndSphere.SphereRadius = 200.0f;
RenderData->Bounds = BoundingBoxAndSphere;
LODResources.VertexBuffers.PositionVertexBuffer.Init(StaticMeshBuildVertices);
FColorVertexBuffer& ColorVertexBuffer =
LODResources.VertexBuffers.ColorVertexBuffer;
LODResources.VertexBuffers.StaticMeshVertexBuffer.Init(
StaticMeshBuildVertices, 1);
LODResources.IndexBuffer.SetIndices(
indices,
EIndexBufferStride::Type::AutoDetect);
LODResources.bHasDepthOnlyIndices = false;
LODResources.bHasReversedIndices = false;
LODResources.bHasReversedDepthOnlyIndices = false;
FStaticMeshLODResources::FStaticMeshSectionArray& Sections =
LODResources.Sections;
FStaticMeshSection& section1 = Sections.AddDefaulted_GetRef();
section1.bEnableCollision = false;
section1.NumTriangles = 1;
section1.FirstIndex = 0;
section1.MinVertexIndex = 0;
section1.MaxVertexIndex = StaticMeshBuildVertices.Num() - 1;
//Material'/Game/mat/red.red'
UMaterial* Material1 = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("Material'/Game/mat/red.red'"));
UMaterialInstanceDynamic* MaterialInstance1 = UMaterialInstanceDynamic::Create(Material1, nullptr);
MaterialInstance1->AddToRoot();
MaterialInstance1->TwoSided = true;
FName pMateraialName = pStaticMesh->AddMaterial(MaterialInstance1);
int32 idx = pStaticMesh->GetMaterialIndex(pMateraialName);
section1.MaterialIndex = idx;
FStaticMeshSection& section2 = Sections.AddDefaulted_GetRef();
section2.bEnableCollision = false;
section2.NumTriangles = 1;
section2.FirstIndex = 3;
section2.MinVertexIndex = 0;
section2.MaxVertexIndex = StaticMeshBuildVertices.Num() - 1;
Material'/Game/mat/green.green'
UMaterial* Material2 = (UMaterial*)StaticLoadObject(UMaterial::StaticClass(), nullptr, TEXT("Material'/Game/mat/green.green'"));
UMaterialInstanceDynamic* MaterialInstance2 = UMaterialInstanceDynamic::Create(Material2, nullptr);
MaterialInstance2->AddToRoot();
MaterialInstance2->TwoSided = true;
FName pMateraialName2 = pStaticMesh->AddMaterial(MaterialInstance2);
idx = pStaticMesh->GetMaterialIndex(pMateraialName2);
section1.MaterialIndex = idx;
pStaticMesh->RenderData = TUniquePtr<FStaticMeshRenderData>(RenderData);
pStaticMesh->InitResources();
pStaticMesh->CalculateExtendedBounds();
pStaticMesh->RenderData->ScreenSize[0].Default = 1.0f;
pStaticMesh->CreateBodySetup();
mesh->SetMobility(EComponentMobility::Movable);
//附加替换RootComponent
mesh->SetupAttachment(this->RootComponent);
mesh->RegisterComponent();
Result