저번 글에서는 기본적인 큐브를 렌더링 하였다. 이번 글에서는 단순한 큐브가 아닌 모델 파일을 받아 불러오는 방법을 알아보자.
학습을 위해 알아보기 쉬운 txt
파일로 간단한 모델을 불러와보자.
car.txt
VertexCount: 1860
TriangleCount: 1850
VertexList (pos, normal)
{
. . .
}
TriangleList
{
. . .
}
txt
파일을 열어보면 지금까지 DirectX를 공부하며 많이 보았던 익숙한 단어들이 보일것이다. 모델 파일은 기본적으로 우리가 입력 조립기 시점에서 할당해야하는 버텍스의 정보와 인덱스의 정보가 들어가있다.
우리는 모델 파일에서 해당 내용만 잘 골라내어 입력 조립기 시점에 할당시켜주면, 간단하게 모델 렌더링을 할 수 있는 것이다.
오브젝트 렌더링에서 인덱스의 순서가 노말의 방향을 조정한다고 하였는데, 이 노말에 대해 자세히 알아보자.
노말이란 각 정점의 접평면의 수직인 벡터이다.
노말은 각 정점의 접평면이 향하고 있는 방향과도 같기에, 인덱스의 순서를 생각하며 노말의 방향을 맞춰줘야 물체가 제대로 렌더링 되는 것이다.
나중에 조명이 추가된다면, 이 노말을 이용해 입사각과 반사각을 구해 계산할 수 있다.
이제 본격적으로 코드에서 모드를 불러와보자. 기본적인 렌더 파이프라인은 저번에 만든 것을 그대로 사용할 것이기에, 우리는 입력 조립기 시점으로 돌아가 모델 파일을 읽어오고, 버텍스 정보와 인덱스 정보를 입력하는 작업만 해주면 된다.
파일을 읽기 위해서 cpp
의 file stream
을 사용할 것이다. file stream
을 사용하기 위해 fstream
헤더를 먼저 추가해준다.
std::ifstream fin("../Models/car.txt");
if (!fin)
{
MessageBox(0, L"../Models/skull.txt not found.", 0, 0);
return;
}
그 후 std
의 ifstrem
을 이용해, 프로젝트에 넣어준 모델 파일을 불러온다. 그럴 경우는 없겠지만, 후에 디버깅의 편의를 위해 찾아오지 못했을 경우의 예외처리를 해준다.
정보를 읽어오기 이전, 정보를 얻어오기 위해 필요한 변수를 선언해준다.
UINT vCount = 0; // 버텍스 카운트
UINT tCount = 0; // 트라이앵글 카운트
std::vector<Vertex> vertices; // 버텍스의 정보를 담는 벡터
std::vector<std::int32_t> indices; // 인덱스의 정보를 담는 벡터
std::string ignore; // 파일을 읽어올 때 필요없는 값들을 담기위한 쓰레기 변수
파일의 형태를 다시 살펴보면,
VertexCount: [1860] <- vCount
TriangleCount: [1850] <- tCount
VertexList (pos, normal)
{
[. . .] <- position, normal
}
TriangleList
{
[. . .] <- index
}
우리가 읽어와서 변수의 넣어야 할 값들의 위치와 읽지 않고 넘겨야 할 쓰레기값들의 위치를 판단 할 수 있다.
이러한 쓰레기값들은 ignore
변수에 담아 넘겨주고, 읽어야 할 값들만 찾아 변수에 할당해주는 작업을 할 것이다.
fin >> ignore >> vCount; // 버텍스 카운트 읽어오기
fin >> ignore >> tCount; // 트라이앵글 카운트 읽어오기
fin >> ignore >> ignore >> ignore >> ignore;
vertices.resize(vCount); // 버텍스 카운트로 벡터 초기화
indices.resize(3 * tCount); // 인덱스 카운트로 벡터 초기화 ( 1 triangle = 3 index )
for (UINT i = 0; i < vCount; ++i)
{
fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z; // 포지션 정보 읽어오기
fin >> vertices[i].Normal.x >> vertices[i].Normal.y >> vertices[i].Normal.z; // 노말 정보 읽어오기
}
for (UINT i = 0; i < tCount; ++i)
{
fin >> indices[i * 3 + 0] >> indices[i * 3 + 1] >> indices[i * 3 + 2]; // 인덱스 정보 읽어오기
}
fin.close(); // 파일을 모두 읽어준 이후에는 스트림을 닫아줘야 함.
모델을 렌더링 하기 위해 바꿔야 할 부분은 버텍스의 정보와 인덱스의 정보밖에 없기에, 파일을 성공적으로 읽어왔다면, 렌더링을 위한 모든 준비는 끝이 났다.
이후, 기존 작업 그대로 버텍스 버퍼와 인덱스 버퍼를 만들어주고, 렌더링 파이프라인 과정을 따라가면..
성공적으로 자동차 모델을 렌더링 할 수 있다. 아직 조명이 존재하지 않아, 노말 벡터를 사용하지 못하기에 노말 벡터를 컬러값으로 사용하여 자동차가 노말의 값대로 칠해진 모습을 확인 할 수 있다.