어제 그렇게 낑낑 대며 assimp를 넣어두고 테스트 코드 같은 것도 하나도 못 만들었다. 오늘은 이제 진짜 3d 모델링을 갖고 오도록 해보자.
역시 doc를 보면서 시작해야겠지.
https://assimp-docs.readthedocs.io/en/latest/usage/use_the_lib.html#
Access by C++ class interface — Asset-Importer-Lib September 2019 documentation
The assimp library can be accessed by both a class or flat function interface. The C++ class interface is the preferred way of interaction: you create an instance of class Assimp::Importer, maybe adjust some settings of it and then call Assimp::Importer::R
assimp-docs.readthedocs.io
doc를 보니 파일 path를 가지고 aiScene을 가지고 올 수가 있다고 한다. aiScene에 해당 모델링 데이터의 모든 정보가 포함되어있으므로 내가 입맛대로 접근하여 사용할 수 있다.
#include "Model.h"
#include <assimp/Importer.hpp> // C++ importer interface
#include <assimp/scene.h> // Output data structure
#include <assimp/postprocess.h> // Post processing flags
Model::Model(Graphics& gfx, const std::string pFile)
:
Bindable(gfx)
{
const std::string pFile;
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(pFile,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
if (!scene) MSG_EXCEPT(importer.GetErrorString());
scene->mMeshes;
for (int i = 0; i < scene->mNumMeshes; ++i)
{
auto mesh = scene->mMeshes[i];
if (mesh->HasFaces())
{
for (int i = 0; i < mesh->mNumVertices; ++i)
{
//여기서 vertex 정보를 들고온다
dx::XMFLOAT3 vertex = { mesh->mVertices->x,mesh->mVertices->y, mesh->mVertices->z };
}
}
}
}
이런 식이다.
아직 모델링 준비를 못해가지고... 그냥 코드 테스트용으로 pFile이라고 선언만 해주었다.
현재 어려운 점은 모델링에는 vertexColor도 있을 것이고 UV도 있고 tangent도 있고 뭐.. 엄청 많은데 이 모든 정보를 vertex에서 가지고 있어야 하는 것인가... 라는 것이다. 선택적으로 취한다면 Model class에 자체적으로 VertexLayout을 보유하고 있어야 할 것이다.
어쩌지... 아무래도 vertexLayout을 가지고 있으며 vertexLayout을 Renderer에게 전달하면 Renderer에서 그에 맞는 InputLayout을 생성하던가 아니면 pre-load된 InputLayout을 가지고 바인딩 하도록 해야할 것 같다.
일단 Model 생성자는 이런 식으로 해주었다. Bone 정보는 아직 애니메이션은 잘 몰라가지고... 일단 제외했다.
Model::Model(Graphics& gfx, const std::string pFile)
:
Bindable(gfx)
{
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(pFile,
aiProcess_CalcTangentSpace |
aiProcess_Triangulate |
aiProcess_JoinIdenticalVertices |
aiProcess_SortByPType);
if (!scene) MSG_EXCEPT(importer.GetErrorString());
for (int i = 0; i < scene->mNumMeshes; ++i)
{
auto mesh = scene->mMeshes[i];
//Create VertexBuffer
std::vector<ElementType> elementtype;
if (mesh->HasPositions) elementtype.push_back(Position3D);
if (mesh->HasVertexColors) elementtype.push_back(ColorRGBA);
if (mesh->HasTextureCoords) elementtype.push_back(Texture2D);
if (mesh->HasNormals) elementtype.push_back(Normal);
//if (mesh->HasBones) elementType에 본 추가
VertexBuffer vertexBuffer = VertexBuffer(VertexLayout(elementtype));
Vertex v = vertexBuffer.Inst();
for (int i = 0; i < mesh->mNumVertices; ++i)
{
if (mesh->HasPositions) v.Get<Position3D>() = { mesh->mVertices[i].x,mesh->mVertices[i].y, mesh->mVertices[i].z };
if (mesh->HasVertexColors) v.Get<ColorRGBA>() = { mesh->mColors[i]->r, mesh->mColors[i]->g, mesh->mColors[i]->b, mesh->mColors[i]->a };
if (mesh->HasTextureCoords) v.Get<Texture2D>() = { mesh->mTextureCoords[i]->x, mesh->mTextureCoords[i]->y };
if (mesh->HasNormals) v.Get<Normal>() = { mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z };
vertexBuffer.Add(v);
}
//Create IndexBuffer
std::vector<UINT> indices;
for (int i = 0; i < mesh->mNumFaces; ++i)
{
for (int j = 0; j < mesh->mFaces[i].mNumIndices; ++j)
{
indices.push_back(mesh->mFaces[i].mIndices[j]);
}
}
//mesh 생성자 호출
meshes.push_back(std::make_unique<Mesh>(gfx, vertexBuffer, &indices));
}
}
이렇게 보니 이중으로 체크해주는 점이 마음에 안든다. vertex에서 Get<>() 함수를 사용할 때 해당 Enum 정보가 들어있는지를 확인하는 함수가 있으면 좋을 것 같다.
대충 이런 식으로 쓰면 좋겠는데.
if(v.Has(Position3D)) v.Get<Position3D>() = 블라블라~~;
음... 결국 똑같이 체크를 해주어야 하지만 그래도 vertex에 어떤 게 있고 없는지 판정하는 함수를 가지고 하는 게 더 안전할 것 같다.
또 이걸 만들어도 문제인 게, InputLayout을 만들려면 VertexShader의 ByteCode를 필요로 하기 때문에 VertexShader에서 정보를 떼와야 한다.
그러면 일일이 가능한 Vertex 조합에 따른 셰이더와 InputLayout을 만들어야 한다는 결론이다. 현재 Position3D, Texture2D, ColorRGB, ColorRGBA, Normal에 Tangent, Bone 정보까지 하면 가능한 가지 수가 무려 2의 7제곱 -1 개 만큼이나 된다. 물론 Position정보는 반드시 포함되므로 빼면 2^6 -1개인데, 아.. 감당 못한다. 현실적으로 저거보다 적은 가지수라고 해도 말이다. 에바;
그냥 통합해서 모든 정보를 저장하고 쓰는 게 차라리 나을 것 같다. 무조건 Position3D,...,Bone 까지 모두 저장하는 Vertex를 만들고, Shader에서 Vertex 정보를 선택해서 쓰는 게 쓸데없는 정보량은 늘 수 있겠으나 내 마음이 편해질 것이다. 역시 사람이 먼저지.
ㅋㅋㅋㅋㅋㅋ 실수로 브렌치를 추가하다가 작업한 게 모두 날아갔다. branch 생성시 커밋되지 않은 파일들 처리를 어떻게 하겠냐고 물어보는데 그냥 ok를 눌렀더니 작업한 걸 모두 취소하겠다가 되어버려서 싹 날아가버렸다... 내일 다시 처음부터 해야겠다.....
'진행과정 기록 > GameEngine' 카테고리의 다른 글
20200204 Model 임포트(Re) 하... (0) | 2020.02.04 |
---|---|
20200204 'dll이 없어 실행할 수 없습니다.' 오류 해결 (0) | 2020.02.04 |
20200202 Assimp(Open Asset Importer) (2) | 2020.02.02 |
20200201 앞으로 할일 (0) | 2020.02.01 |
20200131 Texture, SamplerState (0) | 2020.01.31 |