728x90
Types.h (모델 관련 구조체들 정의 된곳)
더보기
#pragma once
#include "stdafx.h"
struct asBone
{
int Index;
string Name;
int Parent;
Matrix Transform;
};
struct asMeshPart
{
string MaterialName;
//DPCall에서 사용하기 위함
UINT StartVertex;
UINT VertexCount;
UINT StartIndex;
UINT IndexCount;
};
struct asMesh
{
int BoneIndex;
vector<Model::VertexModel> Vertices;
vector<UINT> indices;
vector<asMeshPart*> MeshParts;
};
struct asMaterial
{
string Name;
Color Ambient;
Color Diffuse;
Color Specular;
Color Emissive;
string DiffuseFile;
string SpecularFile;
string NormalFile;
};
Converter.cpp, h (fbx읽어서 바이너리 형태로 만들고 읽고 머티리얼 등 만들고 쓰기)
더보기


코드는 저 5개의 함수 관련만
void Converter::ExportMaterial(wstring savePath, bool bOverWrite)
{
savePath = L"../../_Textures/" + savePath + L".material";
if (bOverWrite == false) //덮어 쓰기 관련 false x / true o
{
if (Path::ExistFile(savePath) == true) return;
}
ReadMaterialData();
WriteMaterialData(savePath);
}
void Converter::ReadMaterialData()
{
//ai 타입을 as로 변환 하는 과정
for (UINT i = 0; i < scene->mNumMaterials; i++)
{
aiMaterial* srcMaterial = scene->mMaterials[i];
//미사용 머티리얼이면 아래 내용 제외
if (FoundMaterialData(srcMaterial) == false) continue;
//이름 가져오기
asMaterial* material = new asMaterial();
material->Name = srcMaterial->GetName().C_Str();
//컬러별 가져오기
aiColor3D color;
srcMaterial->Get(AI_MATKEY_COLOR_AMBIENT, color);
material->Ambient = Color(color.r, color.g, color.b, 1.0f);
srcMaterial->Get(AI_MATKEY_COLOR_DIFFUSE, color);
material->Diffuse = Color(color.r, color.g, color.b, 1.0f);
srcMaterial->Get(AI_MATKEY_COLOR_SPECULAR, color);
material->Specular = Color(color.r, color.g, color.b, 1.0f);
srcMaterial->Get(AI_MATKEY_COLOR_EMISSIVE, color);
material->Emissive = Color(color.r, color.g, color.b, 1.0f);
//디자인 경로별 저장
aiString file;
srcMaterial->GetTexture(aiTextureType_DIFFUSE, 0, &file);
material->DiffuseFile = file.C_Str();
srcMaterial->GetTexture(aiTextureType_SPECULAR, 0, &file);
material->SpecularFile = file.C_Str();
srcMaterial->GetTexture(aiTextureType_NORMALS, 0, &file);
material->NormalFile = file.C_Str();
//머티리얼 저장
materials.push_back(material);
}
}
bool Converter::FoundMaterialData(aiMaterial * material)
{
string materialName = material->GetName().C_Str();
bool bFound = false;
for (asMesh* mesh : meshes)
{
for (asMeshPart* part : mesh->MeshParts)
{
if (part->MaterialName == materialName) return true;
}
}
return false;
}
//Xml 만드는 곳 + 텍스쳐 뽑기
void Converter::WriteMaterialData(wstring savePath)
{
string folder = String::ToString(Path::GetDirectoryName(savePath));
string file = String::ToString(Path::GetFileName(savePath));
Path::CreateFolders(folder);
Xml::XMLDocument* document = new Xml::XMLDocument();
Xml::XMLDeclaration* decl = document->NewDeclaration();
document->LinkEndChild(decl);
Xml::XMLElement* root = document->NewElement("Materials");
root->SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
root->SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
document->LinkEndChild(root);
for (asMaterial* material : materials)
{
Xml::XMLElement* node = document->NewElement("Material");
root->LinkEndChild(node);
Xml::XMLElement* element = NULL;
element = document->NewElement("Name");
element->SetText(material->Name.c_str());
node->LinkEndChild(element);
element = document->NewElement("DiffuseFile");
element->SetText(WriteTexture(folder, material->DiffuseFile).c_str());
node->LinkEndChild(element);
element = document->NewElement("SpecularFile");
element->SetText(WriteTexture(folder, material->SpecularFile).c_str());
node->LinkEndChild(element);
element = document->NewElement("NormalFile");
element->SetText(WriteTexture(folder, material->NormalFile).c_str());
node->LinkEndChild(element);
element = document->NewElement("Ambient");
element->SetAttribute("R", material->Ambient.r);
element->SetAttribute("G", material->Ambient.g);
element->SetAttribute("B", material->Ambient.b);
element->SetAttribute("A", material->Ambient.a);
node->LinkEndChild(element);
element = document->NewElement("Diffuse");
element->SetAttribute("R", material->Diffuse.r);
element->SetAttribute("G", material->Diffuse.g);
element->SetAttribute("B", material->Diffuse.b);
element->SetAttribute("A", material->Diffuse.a);
node->LinkEndChild(element);
element = document->NewElement("Specular");
element->SetAttribute("R", material->Specular.r);
element->SetAttribute("G", material->Specular.g);
element->SetAttribute("B", material->Specular.b);
element->SetAttribute("A", material->Specular.a);
node->LinkEndChild(element);
element = document->NewElement("Emissive");
element->SetAttribute("R", material->Emissive.r);
element->SetAttribute("G", material->Emissive.g);
element->SetAttribute("B", material->Emissive.b);
element->SetAttribute("A", material->Emissive.a);
node->LinkEndChild(element);
}
document->SaveFile((folder + file).c_str());
SafeDelete(document);
}
//텍스처 뽑기
string Converter::WriteTexture(string saveFolder, string file)
{
if (file.length() < 1) return "";
string fileName = Path::GetFileName(file);
const aiTexture* texture = scene->GetEmbeddedTexture(file.c_str());
string path = "";
//일방적인 file(fbx)에서 뽑고 따로 저장 할때 (내장)
if (texture != NULL)
{
path = saveFolder + Path::GetFileNameWithoutExtension(file) + ".png";
BinaryWriter* w = new BinaryWriter(String::ToWString(path));
w->Byte(texture->pcData, texture->mWidth);
SafeDelete(w);
}
else
{//디자인이 별도로 폴더 같은거 만들때 해당 결로 들어가서 뽑기 (외장)
string directory = String::ToString(Path::GetDirectoryName(this->file));
string origin = directory + file;
String::Replace(&origin, "\\", "/");
//하위 파일이 없으면 return
if (Path::ExistFile(origin) == false) return "";
path = saveFolder + fileName;
CopyFileA(origin.c_str(), path.c_str(), FALSE);
//덮어쓰기
String::Replace(&path, "../../_Textures/", "");
}
return Path::GetFileName(path);
}
헤더도 해당만 추가 시키면됨
public:
void ExportMaterial(wstring savePath, bool bOverWrite = true);
private:
void ReadMaterialData(); //ai -> as 형태로
bool FoundMaterialData(aiMaterial* material); //미사용 마테리얼 제외
void WriteMaterialData(wstring savePath); //.xml로 저장하는 역할
string WriteTexture(string saveFolder, string file); //실제로 파일 저장하는곳
private:
vector<struct asMaterial*> materials;
ExportFile.cpp (모델 파일을 Converter를 이용해서 만들기위한 클래스)
더보기


이런 형태로 생성
실행 결과
더보기



_Textures 폴더 안에 정상적으로 머티리얼 전용 폴더가 생성

Kachujin파일 열면 이렇게 Texture 파일을 읽어서 만들어줌
보충
FBX 파일 내부적으로 있는 것들은 "사운드, 조명, 카메라, material..." 이외 여러가지 있다
material Color 안에는 "Ambient, DiffuseMap, NormalMap, SpecularMap, Emissive" 있고 Textures 파일과
Xml 매칭 해서 색상을 입히고 Shader를 통해서 추가적인 옵션을 부여
'DirectX > DirectX 3D_(구)' 카테고리의 다른 글
20_ModelAnimation (0) | 2021.07.26 |
---|---|
19_ModelMaterial [2/2] (0) | 2021.07.19 |
18_ModelEditor [2/2] (0) | 2021.07.14 |
18_ModelEditor [1/2] (0) | 2021.07.13 |
17_Framework (Transform, PerFrame, Renderer) (0) | 2021.07.13 |