1. 3D Direct Application
1.1 Mesh
1.1.1 File Format - .m3d
1.1.1.1 Header
bool M3DLoader::LoadM3d(const std::string& filename, std::vector<Vertex::PosNormalTexTan2>& vertices,
std::vector<USHORT>& indices, std::vector<MeshGeometry::Subset>& subsets,
std::vector<M3dMaterial>& mats)
- m3d는 3차원 모형의 메시에 대한 자료를 담은 파일 형식
- 사람이 직접 읽고 수정할 수 있도록 보통의 텍스트 형식을 사용
- 실제 응용에서는 이진 형식을 사용하는 것이 메모리 활용면에서 더 효율적임
- 이 형식의 파일은 몇 가지 전역 정보를 담은 시작부로 시작, 자료의 크기를 미리 알수 있게 설정
- 메시가 사용하는 서로 다른 재질 개수, 메시의 정점 & 삼각형 & 뼈대 개수, 메시의 애니메이션 클립 개수
#Materials 2 #Vertices 2258 #Triangles 1674 #Bones 0 #AnimationClips 0
1.1.1.2 Material
void M3DLoader::ReadMaterials(std::ifstream& fin, uint32 numMaterials, std::vector<M3dMaterial>& mats)
- m3d의 파일 시작부 다음 재질 설정들이 나열하는 구역이 나옴
- 주변광, 분산광, 반영광 재질, 적용할 Texture, 알파 절단 적용 여부, 효과이름 등 추가적인 정보도 포함
- 특정 기하구조에 특정한 효과를 적용해야 하는 경우라면 유용할 것
- 어떤 기하구조에서 변위 매핑을 적용, 다른 기하구조는 법선 매핑, 환경 매핑을 적용하는 등을 생각할 수 있음
Ambient: 0.4 0.4 0.4 Diffuse : 0.9 0.9 0.9 Specular 0.4 0.4 0.4 SpecPower : 16
Reflectivity: 0 0 0 AlphaCilp: 0 Effect: Normal DiffuseMap: *.dds NormalMap: *.dds
struct M3dMaterial { Material Mat; bool AlphaClip; std::string EffectTypeName; std::wstring DiffuseMapName; std::wstring NormalMapName; };
1.1.1.3 Subset
void M3DLoader::ReadSubsetTable(std::ifstream& fin,
uint32 numSubsets, std::vector<MeshGeometry::Subset>& subsets)
- m3d 파일이 가정하는 메시는 하나의 부분집합들로 구성
- 메시의 모든 삼각형 중 동일한 재질을 이용해서 렌더링할 수 있는 삼각형들의 집함
- 동일한 재질이란 동일한 Effect, Texture, Render State를 뜻함, 차의 경우 여러 개의 부분집합으로 구성
SubsetID: 0 VertexStart: 0 VertexCount: 1600 FaceStart: 0 FaceCount: 800
SubsetID: 1 VertexStart: 1600 VertexCount: 658 FaceStart: 800 FaceCount: 874
struct Subset
{
Subset() : Id(-1), VertexStart(0), VertexCount(0), FaceStart(0), FaceCount(0) { }
uint32 Id; uint32 VertexStart; uint32 VertexCount; uint32 FaceStart; uint32 FaceCount;
};
1.1.1.4 Vertex & Index
void M3DLoader::ReadVertices(std::ifstream& fin,
uint32 numVertices, std::vector<Vertex::PosNormalTexTan2>& vertices)
void M3DLoader::ReadTriangles(std::ifstream& fin, uint32 numTriangles, std::vector<USHORT>& indices)
- 파일의 마지막 구역은 정점들과 색인들의 목록
Position: 0 0 0 Tangent : 0 0 0 Normal: 0 0 0 Tex-Coords 0 0
Position: 1 1 1 Tangent : 0 0 0 Normal: 0 0 0 Tex-Coords 0 1
...
- m3d 형식의 한가지 한계는 모든 정점의 형식이 동일해야 한다는 것
- 응용 프로그램에 따라서는 이와는 정점 형식이 다른 모형을 사용해야 할 수도 있음
- 유연성을 갖추려면 파일의 형식이 복잡해짐
1.2 Mesh Geometry
1.2.1 Mesh Geometry System
class MeshGeometry;
- 메시 자료를 조직화하기 위해 클래스 하나를 정의하여 사용, 정점 버퍼와 색인 버퍼, 모든 부분집합을 캡슐화
template <typename VertexType>
void MeshGeometry::SetVertices(ComPtr<ID3D11Device> device, const VertexType* vertices, uint32 count);
void MeshGeometry::SetIndices(ComPtr<ID3D11Device> device, const USHORT* indices, uint32 count);
void MeshGeometry::SetSubsetTable(std::vector<Subset>& subsetTable);
- 부분집합 목록 중 둘째 매개변수로 지정된 부분집합에 속하는 삼각형들만 그림
void MeshGeometry::Draw(ComPtr<ID3D11DeviceContext> dc, uint32 subsetId);
uint32 offset = 0;
dc->IASetVertexBuffers(0, 1, _vb.GetAddressOf(), &_vertexStride, &offset);
dc->IASetIndexBuffer(_ib.Get(), _indexBufferFormat, 0);
dc->DrawIndexed(_subsetTable[subsetId].FaceCount * 3, _subsetTable[subsetId].FaceStart * 3, 0);
1.3 Basic Model
class BasicModel;
1.3.1 Basic Model System
- 좀 더 높은 수준에서 기본적인 모형을 대표하는 클래스를 정의하여 사용
- 모형의 기하구조를 담은 Mesh Geometry Instance를 포함, 메시를 그리는 데 필요한 재질들에 대한 정보도 포함
struct BasicModelInstance { shared_ptr<class BasicModel> Model; XMFLOAT4X4 World; };
- 메시의 시스템 메모리 복사본을 유지
- CPU 쪽에서 경계입체 계산이나 선택, 충돌 검출을 수행하기 위해 메시 자료를 읽어야 할 때 필요
BasicModel::BasicModel(ComPtr<ID3D11Device> device,
TextureMgr& texMgr, const std::string& modelFilename, const std::wstring& texturePath);
- M3D Loader를 사용하여 메시 정보를 읽어드려 모든 데이터 저장
M3DLoader m3dLoader;
m3dLoader.LoadM3d(modelFilename, Vertices, Indices, Subsets, mats);
ModelMesh.SetVertices(device, &Vertices[0], Vertices.size());
ModelMesh.SetIndices(device, &Indices[0], Indices.size()); ModelMesh.SetSubsetTable(Subsets);
- 하나의 Texture를 서로 다른 메시들에 적용하는 경우, 중복 방지에 신경 쓰지 않는다면 여러번 적재하는 일 발생
- 중복 방지를 위해 Texture 생성을 관리해주는 TextureMgr 클래스 도입
- 이 클래스는 자료구조를 사용하여 같은 Texture가 두번 적재, 생성되는 일을 방지
std::vector<M3dMaterial> mats; SubsetCount = mats.size();
for (uint32 i = 0; i < SubsetCount; ++i)
{
Mat.push_back(mats[i].Mat);
ComPtr<ID3D11ShaderResourceView> diffuseMapSRV = texMgr.CreateTexture(texturePath + mats[i].DiffuseMapName);
DiffuseMapSRV.push_back(diffuseMapSRV);
ComPtr<ID3D11ShaderResourceView> normalMapSRV = texMgr.CreateTexture(texturePath + mats[i].NormalMapName);
NormalMapSRV.push_back(normalMapSRV);
}
'C++ Algorithm & Study > Game Math & DirectX 11' 카테고리의 다른 글
[Direct11] 47. 3D Direct Application - Character Animation #2 (0) | 2023.07.04 |
---|---|
[Direct11] 46. 3D Direct Application - Character Animation #1 (0) | 2023.07.04 |
[Direct11] 44. 3D Direct Application - Shadow Mapping #2 (0) | 2023.07.03 |
[Direct11] 43. 3D Direct Application - Shadow Mapping #1 (0) | 2023.07.03 |
[Direct11] 42. 3D Direct Application - Particle System #2 (0) | 2023.07.03 |