1. 도형 예제를, GeometryGenerator::CreateSphere 대신 GeometryGeneartor::CreateGeosphere를 사용하도록 수정하고, 세부 수준을 0, 1, 2, 3으로 바꿔보자.
3. 8장의 두개골 메시를 적재해서 렌더링해보자.
8장의 연습문제 'LitColumns' 예제 폴더의 Models/Skull.txt는 정점 목록과 색인 목록이 들어있다.
일단 이 두개골의 정점과 색인을 읽어서 정점 버퍼와 색인 버퍼를 만들어야 한다. 그 후, 기하구조 보조 구조체인 MeshGeometry를 채워서 멤버 데이터인 Geometries에 집어넣는다.
void ShapesApp::BuildSkullGeometry()
{
std::ifstream fin("Models/skull.txt");
if (!fin)
{
MessageBox(0, L"Models/skull.txt not found.", 0, 0);
return;
}
UINT vcount = 0;
UINT tcount = 0;
std::string ignore;
fin >> ignore >> vcount;
fin >> ignore >> tcount;
fin >> ignore >> ignore >> ignore >> ignore;
std::vector<Vertex> vertices(vcount);
for (UINT i = 0; i < vcount; ++i)
{
fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;
fin >> ignore >> ignore >> ignore;
// fin >> vertices[i].Color.x >> vertices[i].Color.y >> vertices[i].Color.z;
}
fin >> ignore;
fin >> ignore;
fin >> ignore;
std::vector<std::int32_t> indices(3 * tcount);
for (UINT i = 0; i < tcount; ++i)
{
fin >> indices[i * 3 + 0] >> indices[i * 3 + 1] >> indices[i * 3 + 2];
}
fin.close();
auto vbByteSize = vertices.size() * sizeof(Vertex); // auto로 받는게 편하다.
auto ibByteSize = indices.size() * sizeof(UINT);
auto geo = std::make_unique<MeshGeometry>();
geo->Name = "skull";
ThrowIfFailed(D3DCreateBlob(vbByteSize, &geo->VertexBufferCPU));
CopyMemory(geo->VertexBufferCPU->GetBufferPointer(), vertices.data(), vbByteSize);
ThrowIfFailed(D3DCreateBlob(ibByteSize, &geo->IndexBufferCPU));
CopyMemory(geo->IndexBufferCPU->GetBufferPointer(), indices.data(), ibByteSize);
geo->VertexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
mCommandList.Get(), vertices.data(), vbByteSize, geo->VertexBufferUploader);
geo->IndexBufferGPU = d3dUtil::CreateDefaultBuffer(md3dDevice.Get(),
mCommandList.Get(), indices.data(), ibByteSize, geo->IndexBufferUploader);
geo->VertexByteStride = sizeof(Vertex);
geo->VertexBufferByteSize = static_cast<UINT>(vbByteSize);
geo->IndexFormat = DXGI_FORMAT_R32_UINT; // IndexFormat에 주의
geo->IndexBufferByteSize = static_cast<UINT>(ibByteSize);
SubmeshGeometry skullmesh;
skullmesh.IndexCount = static_cast<UINT>(indices.size());
skullmesh.StartIndexLocation = 0;
skullmesh.BaseVertexLocation = 0;
geo->DrawArgs["skull"] = skullmesh;
mGeometries[geo->Name] = std::move(geo);
}
그리고 집어넣은 데이터로 렌더 항목을 만든다.
void ShapesApp::BuildRenderItems()
{
...
auto skullRitem = std::make_unique<RenderItem>();
XMStoreFloat4x4(&skullRitem->World, XMMatrixTranslation(0.0f, 2.0f, 0.0f));
skullRitem->ObjCBIndex = 2;
skullRitem->Geo = mGeometries["skull"].get();
skullRitem->PrimitiveType = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
skullRitem->IndexCount = skullRitem->Geo->DrawArgs["skull"].IndexCount;
skullRitem->StartIndexLocation = skullRitem->Geo->DrawArgs["skull"].StartIndexLocation;
skullRitem->BaseVertexLocation = skullRitem->Geo->DrawArgs["skull"].BaseVertexLocation;
mAllRitems.push_back(std::move(skullRitem));
// 두개골이 렌더 항목에 추가되어 인덱스가 3부터 시작
UINT objCBIndex = 3;
// 총 5번 원기둥과 구를 각각 2개씩 추가하여 총 각각 10개씩 mAllRitems에 넣어진다.
for(int i = 0; i < 5; ++i)
{
// 원기둥과 구 입력
}
}
'그래픽스 > DirectX 12' 카테고리의 다른 글
[DirectX 12 3D게임 입문] Chapter 9 : 텍스처 적용 (3) | 2023.11.30 |
---|---|
[DirectX 12 3D게임 입문] Chapter 8.16 : 조명 - 연습문제 (0) | 2023.11.29 |
[DirectX 12 3D게임 입문] Chapter 6.13: Direct3D의 그리기 연산 - 연습문제 (0) | 2023.11.16 |
[DirectX 12 3D게임 입문] Chapter 5.7 ~ 5.12: 렌더링 파이프라인 - 테셀레이션 단계들 ~ 출력 병합기 단계 (1) | 2023.11.14 |
[DirectX 12 3D게임 입문] Chapter 5.6: 렌더링 파이프라인 - 정점 셰이더 단계 (1) | 2023.11.13 |