void AssimpTool::Init()
{
shared_ptr<Converter> converter = make_shared<Converter>();
converter->ReadAssetFile(L"Tank/Tank.fbx"); // FBX -> 메모리
converter->ExportMaterialData(L"Tank/Tank"); // Material → XML 저장
converter->ExportModelData(L"Tank/Tank"); // Model → Binary 저장
}
ReadAssetFile로 FBX를 메모리로 읽고ExportMaterialData: XML로 저장 (텍스처/머티리얼 정보)ExportModelData: .mesh 바이너리로 저장 (정점/인덱스/Bone 정보 포함)// FileUtils::Write
template<typename T>
void Write(const T& data)
{
DWORD numOfBytes = 0;
assert(::WriteFile(_handle, &data, sizeof(T), (LPDWORD)&numOfBytes, nullptr));
}
.mesh 파일로 저장 시 Bone, Mesh, Vertex, Index 등 순서에 맞게 직렬화void Model::ReadModel(wstring filename)
{
// .mesh 파일 로드
file->Open(fullPath, FileMode::Read);
// 1. Bone 정보 읽기
// 2. Mesh 정보 읽기
// - Vertex / Index Buffer 세팅
}
이때
VertexBuffer,IndexBuffer,Geometry<ModelVertexType>를 구성하여 GPU에 전달할 준비를 마친다.
void Model::ReadMaterial(wstring filename)
{
// .xml에서 텍스처 정보 추출
auto texture = RESOURCES->GetOrAddTexture(textureStr, fullPath);
material->SetDiffuseMap(texture);
}
SetDiffuseMap 등으로 등록void Model::BindCacheInfo()
{
// Mesh에 Material, Bone 캐싱
// Bone 계층 구조 연결 (parent, children)
}
void ModelRenderer::Update()
{
RENDER->PushTransformData(...);
for (auto& mesh : meshes)
{
mesh->material->Update();
_shader->DrawIndexed(...);
}
}
ModelRenderer는 복수의 Mesh와 Material을 처리함void StaticMeshDemo::CreateTank()
{
shared_ptr<Model> m1 = make_shared<Model>();
m1->ReadModel(L"Tank/Tank");
m1->ReadMaterial(L"Tank/Tank");
_obj = make_shared<GameObject>();
_obj->AddComponent(make_shared<ModelRenderer>(_shader));
_obj->GetModelRenderer()->SetModel(m1);
}
Tank.mesh, Tank.xml 파일을 로드해 셋팅cbuffer BoneBuffer
{
matrix BoneTransform[MAX_MODEL_TRANSFORMS];
};
output.position = mul(input.position, BoneTransform[BoneIndex]);
Model, Material, Bone, Mesh 데이터를 올바르게 구성하고