어떤 버그인지는 바로 전 포스트에 정리해 뒀으니 이쪽을 참고하면 될 듯 하고..
https://ayurik152.tistory.com/13
DirectX12 인덱스 버퍼 데이터 버그 디버깅 중..
정말 골치아픈 버그가 생겼고, 지금 얘 때문에 2주 정도 진전이 없다. 코드상에 문제가 전혀 없어보이기 때문인데다 PIX를 사용한 런타임 디버깅을 얼마 전에 알았기 때문이다. 지금 엔진 테스
ayurik152.tistory.com
웃기게도 포스트를 올리고 1시간쯤 더 코드를 리뷰하다가 원인을 발견했다. 이전에 엔진에서 바로 사용할 수 있도록 기본적인 도형들을 만들어둔다고 했었는데.. 얘네도 당연히 메시니까 버퍼를 만들어줘야한다.
void ResourceManager::CreateDefaultResources()
{
//==========Shader==========
D3D_SHADER_MACRO skinnedDefines[] =
{
"SKINNED", "1", NULL, NULL
};
auto stdVS = make_shared<Shader>(L"Default.hlsl", nullptr, ShaderType::VS);
Add<Shader>(L"standardVS", stdVS);
auto skinnedVS = make_shared<Shader>(L"Default.hlsl", skinnedDefines, ShaderType::VS);
Add<Shader>(L"skinnedVS", skinnedVS);
auto opaquePS = make_shared<Shader>(L"Default.hlsl", nullptr, ShaderType::PS);
Add<Shader>(L"opaquePS", opaquePS);
//==========Texture==========
auto tex = make_shared<Texture>(L"white1x1.dds");
Add<Texture>(L"Tex_Default", tex);
//==========Material==========
auto defaultMat = make_shared<Material>("Default", 0, 0, -1);
Add<Material>(L"Mat_Default", defaultMat);
//==========Mesh==========
shared_ptr<Mesh> boxMesh = make_shared<Mesh>();
boxMesh->CreateBasicCube();
Add<Mesh>(L"Mesh_BasicBox", boxMesh);
shared_ptr<Mesh> sphereMesh = make_shared<Mesh>();
sphereMesh->CreateBasicSphere();
Add<Mesh>(L"Mesh_BasicSphere", sphereMesh);
shared_ptr<Mesh> quadMesh = make_shared<Mesh>();
quadMesh->CreateBasicQuad();
Add<Mesh>(L"Mesh_BasicQuad", quadMesh);
}
이게 엔진에서 기본적으로 준비해두는 리소스들이다. 여기서 마지막 Mesh 주석 이후의 세 가지가 기본 도형들의 메시 데이터 생성부인데 저 CreateBasic~~() 메소드들을 조금 자세히 들여다보자.
void Mesh::CreateBasicCube()
{
CreateBasicCube(1.5f, 1.5f, 1.5f, 3);
}
void Mesh::CreateBasicCube(float width, float height, float depth, UINT numSubdivisions)
{
shared_ptr<Geometry> geo = GeometryGenerator::CreateBox(width, height, depth, numSubdivisions);
shared_ptr<SubMesh> subMesh = make_shared<SubMesh>(geo);
subMesh->CreateBuffer();
_submeshes.push_back(subMesh);
}
void Mesh::CreateBasicSphere()
{
return CreateBasicSphere(1.0f, 3);
}
void Mesh::CreateBasicSphere(float radius, UINT numSubdivisions)
{
shared_ptr<Geometry> geo = GeometryGenerator::CreateGeosphere(radius, numSubdivisions);
shared_ptr<SubMesh> subMesh = make_shared<SubMesh>(geo);
subMesh->CreateBuffer();
_submeshes.push_back(subMesh);
}
void Mesh::CreateBasicQuad()
{
shared_ptr<Geometry> geo = GeometryGenerator::CreateQuad();
shared_ptr<SubMesh> subMesh = make_shared<SubMesh>(geo);
subMesh->CreateBuffer();
_submeshes.push_back(subMesh);
}
대강 이런식이다. 오버로드를 통해서 오브젝트의 수치를 정할건지 프리셋을 따를건지 고를 수 있도록 구현해뒀는데, 지금 중요한건 그게 아니다. 각 메소드를 살펴보면 두번째 줄에서 서브메시를 생성하고 그 다음 줄에서 버퍼를 생성하고 있다. 얘네도 메시니까 당연히 버퍼를 생성해줘야되는게 맞다. 근데 난 저 코드들을 보고 순간 번쩍이면서 생각난 것이 있다. 난 외부 리소스를 불러들였을 때 수동으로 버퍼를 만들어 준 적이 없는데?
SubMesh 클래스의 생성자를 한 번 살펴보도록 하자.
SubMesh::SubMesh()
{
_material = RESOURCE->Get<Material>(L"Mat_Default");
}
SubMesh::SubMesh(shared_ptr<Geometry> geo) : _geometry(geo)
{
_material = RESOURCE->Get<Material>(L"Mat_Default");
CreateBuffer();
}
생성자에 기하구조를 파라미터로 넘겨서 서브메시를 생성하는 경우 CreateBuffer()를 수행해서 자체적으로 버퍼를 만들고 있음을 알 수 있다. 뭐야 그럼 기본도형들은 버퍼를 두번 중복해서 생성하는거네,,,? 이걸 알자마자 수동으로 버퍼를 만들어주던 코드를 주석처리했고, 문제는 말끔히 사라졌다.

혹시 몰라서 기본도형 메시를 여러개 생성해서 검증도 해봤지만 문제는 없었다. 드디어 이 지옥같은 디버깅이 끝났다.. 해방감도 느껴지지만 한편으로는 터무니없는 이유라 좀 허무하기도 하다,, 얼른 SkinnedMesh를 구현하도록 하자.
'공부 > DirectX12' 카테고리의 다른 글
| 툰 셰이딩에서 얼굴 명암 처리에 대해서 (0) | 2025.04.04 |
|---|---|
| 앞으로의 개발 목표 정리 (0) | 2025.03.29 |
| DirectX12 인덱스 버퍼 데이터 버그 디버깅 중.. (0) | 2025.03.23 |
| DirectX12에서의 Descriptor Heap 크기에 대해 (0) | 2025.03.09 |
| DirectX에서의 회전 작업(LookAt 메소드 구현)에 대해서 (0) | 2025.02.14 |