
3Dã¢ãã«ã¯ã©ã¹
ãããè¢ããŸãããAssimpã®ããŒã¿èªã¿èŸŒã¿ãšããŒã¿å€æã³ãŒããæ±ããžã£ã³ã°ã«ã«é£ã³èŸŒã¿ãŸãããïŒ ãã®ã¬ãã¹ã³ã®ã¿ã¹ã¯ã¯ãå¥ã®ã¯ã©ã¹ãäœæããããšã§ããããã¯ãå€ãã®ããªãŽã³ã¡ãã·ã¥ãå«ãã¢ãã«å šäœã§ãããå Žåã«ãã£ãŠã¯è€æ°ã®ãµããªããžã§ã¯ãã§æ§æãããŸãã æšè£œã®ãã«ã³ããŒãã¿ã¯ãŒãããšãã°ããŒã«ã®ãã建ç©ã¯ãåŒãç¶ãåäžã®ã¢ãã«ãšããŠããŒããããŸãã Assimpã䜿çšããŠãããŒã¿ãããŒãããååã®ã¬ãã¹ã³ã®Meshã¿ã€ãã®å€ãã®ãªããžã§ã¯ãã«å€æããŸãã
å
容
ããŒã1.ã¯ããã«
ããŒã2.åºæ¬çãªç §æ
ããŒã3. 3Dã¢ãã«ãããŠã³ããŒããã
ããŒã4.é«åºŠãªOpenGLæ©èœ
ããŒã5.é«åºŠãªç §æ
ããŒã6. PBR
- Opengl
- ãŠã£ã³ããŠäœæ
- ããã«ã¡ã¯ãŠã£ã³ããŠ
- ããã«ã¡ã¯ãã©ã€ã¢ã³ã°ã«
- ã·ã§ãŒããŒ
- ãã¯ã¹ãã£ãŒ
- å€æ
- 座æšç³»
- ã«ã¡ã©
ããŒã2.åºæ¬çãªç §æ
ããŒã3. 3Dã¢ãã«ãããŠã³ããŒããã
ããŒã4.é«åºŠãªOpenGLæ©èœ
- 深床ãã¹ã
- ã¹ãã³ã·ã«ãã¹ã
- è²æ··å
- é¡ã®ã¯ãªããã³ã°
- ãã¬ãŒã ãããã¡
- ãã¥ãŒããã¯ã«ãŒã
- é«åºŠãªããŒã¿åŠç
- é«åºŠãªGLSL
- 幟äœåŠã·ã§ãŒããŒ
- ã€ã³ã¹ã¿ã³ã¹å
- ã¹ã ãŒãžã³ã°
ããŒã5.é«åºŠãªç §æ
- é«åºŠãªç §æã Blinn-Fongã¢ãã«ã
- ã¬ã³ãè£æ£
- ã·ã£ããŠã«ãŒã
- å šæ¹åã·ã£ããŠããã
- æ³ç·ãããã³ã°
- èŠå·®ãããã³ã°
- HDR
- ãã«ãŒã
- é 延ã¬ã³ããªã³ã°
- SSAO
ããŒã6. PBR
ç«ã®å°»å°ŸãåŒã£åŒµããªãããã«ããŸããã-Modelã¯ã©ã¹ã®æ§é ãç解ããŸãã
class Model { public: /* */ Model(char *path) { loadModel(path); } void Draw(Shader shader); private: /* */ vector<Mesh> meshes; string directory; /* */ void loadModel(string path); void processNode(aiNode *node, const aiScene *scene); Mesh processMesh(aiMesh *mesh, const aiScene *scene); vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName); };
ã芧ã®ãšãããã¯ã©ã¹ã«ã¯Meshåã®ãªããžã§ã¯ãã®ãã¯ãã«ãå«ãŸããŠãããã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¢ãã«ãã¡ã€ã«ãžã®ãã¹ãæå®ããå¿ èŠããããŸãã äž¡æ¹ã®èªã¿èŸŒã¿ã¯ã³ã³ã¹ãã©ã¯ã¿ãŒã§çŽæ¥è¡ããããã«ããŒã¡ãœããloadModelã䜿çšããŸãã ãã¹ãŠã®ãã©ã€ããŒãã¡ãœããã¯ãAssimpããŒã¿ã€ã³ããŒãããã»ã¹ã®äžéšã§äœæ¥ãã責任ãããã以äžã§è©³çŽ°ã«æ€èšããŸãã
Drawã¡ãœããã¯ç°¡åã§ããããªãŽã³ã¡ãã·ã¥ã®ãªã¹ããå埩åŠçãããããã®Drawã¡ãœãããåŒã³åºããŸãã
void Draw(Shader shader) { for(unsigned int i = 0; i < meshes.size(); i++) meshes[i].Draw(shader); }
OpenGLã«3Dã¢ãã«ãã€ã³ããŒããã
ãŸããAssimpã«å¿ èŠãªããããŒãã¡ã€ã«ãæå¹ã«ããŸãã
#include <assimp/Importer.hpp> #include <assimp/scene.h> #include <assimp/postprocess.h>
ã³ã³ã¹ãã©ã¯ã¿ãŒã§åŒã³åºãããæåã®ã¡ãœããã¯loadModelã§ã ãããã¯ãã©ã€ãã©ãªã䜿çšããŠãã¢ãã«ãAssimpã®çšèªã§ã·ãŒã³ãªããžã§ã¯ããšåŒã°ããæ§é ã«ããŒãããŸãã ã»ã¯ã·ã§ã³ã®æåã®ã¬ãã¹ã³ãæãåºããŠãã ãã-ã·ãŒã³ãªããžã§ã¯ãã¯Assimpã®ããŒã¿éå±€ã®ã«ãŒããªããžã§ã¯ãã§ããããšãããããŸãã å®æããã·ãŒã³ãªããžã§ã¯ããååŸãããšããã«ãå¿ èŠãªãã¹ãŠã®ã¢ãã«ããŒã¿ã«ã¢ã¯ã»ã¹ã§ããŸãã
Assimp APIã®æ³šç®ãã¹ãç¹æ§ã¯ãããŸããŸãªåœ¢åŒã®ããŒãã®ç¹æ®æ§ãšæè¡ç詳现ããã®æœè±¡åã§ãã ãã¹ãŠã®ããŠã³ããŒãã¯1åã®åŒã³åºãã§è¡ãããŸãã
Assimp::Importer importer; const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);
æåã«ã Importerã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã次ã«ã ReadFileãåŒã³åºãããã¢ãã«ãã¡ã€ã«ãžã®ãã¹ãã©ã¡ãŒã¿ãŒãšåŸåŠççšã®ãã©ã°ã®ãªã¹ããæå®ãããŸãã åçŽãªããŒã¿ã®ããŒãã«å ããŠãAPIã§ã¯ãã€ã³ããŒããããããŒã¿ã«å¯ŸããŠAssimpã«è¿œå ã®åŠçã匷å¶ãããã©ã°ãæå®ã§ããŸãã aiProcess_Triangulateãèšå®ãããšãã¢ãã«ã«äžè§åœ¢ã§æ§æãããŠããªããªããžã§ã¯ããããå Žåãã©ã€ãã©ãªã¯ãã®ãããªãªããžã§ã¯ããäžè§åœ¢ã®ã°ãªããã«å€æããŸãã aiProcess_FlipUVsãã©ã°ã¯ãå¿ èŠã«å¿ããŠoY軞ã«æ²¿ã£ããã¯ã¹ãã£åº§æšã®å転ãã¢ã¯ãã£ãã«ããŸãïŒ ãã¯ã¹ãã£ãã¥ãŒããªã¢ã«ããåŠãã ããã«ãOpenGLã§ã¯ãã»ãšãã©ãã¹ãŠã®ç»åãoY軞ã«æ²¿ã£ãŠå転ãããããããã®ãã©ã°ã¯ãã¹ãŠãæ£ããä¿®æ£ããã®ã«åœ¹ç«ã¡ãŸãïŒã ããã«äŸ¿å©ãªãªãã·ã§ã³ãããã€ããããŸãã
- aiProcess_GenNormals ïŒãœãŒã¹ããŒã¿ã«äœããªãå Žåãé ç¹ã®æ³ç·ãèšç®ããŸãã
- aiProcess_SplitLargeMesââhes ïŒå€§ããªããªãŽã³ã¡ãã·ã¥ãå°ããªã¡ãã·ã¥ã«åå²ããŸããããã¯ãã¬ã³ããŒã§åŠçãããå€ã®æ°ã«å¶éãããå Žåã«äŸ¿å©ã§ãã
- aiProcess_OptimizeMeshes ïŒéã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸã-å€ãã®ã°ãªããã1ã€ã®å€§ããªã°ãªããã«ã¹ãããããŠãã¬ã³ããªã³ã°ã®åŒã³åºãæ°ãæé©åããŸãã
ã©ã€ãã©ãªAPIã«ã¯ãããã«å€ãã®åŠçãªãã·ã§ã³ãå«ãŸããŠããŸã ã ã¢ãã«èªäœã®ããŒãã¯é©ãã»ã©ç°¡åã§ãã çµæã®ã·ãŒã³ãªããžã§ã¯ãããããŒã¿ãæœåºãããããã¡ãã·ã¥ãªããžã§ã¯ãã«å€æããäœæ¥ã¯ãããå°ãè€éã§ãã
loadModelã¡ãœããã®å®å šãªãªã¹ãïŒ
void loadModel(string path) { Assimp::Importer import; const aiScene *scene = import.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { cout << "ERROR::ASSIMP::" << import.GetErrorString() << endl; return; } directory = path.substr(0, path.find_last_of('/')); processNode(scene->mRootNode, scene); }
ããŒãåŸãã·ãŒã³ãªããžã§ã¯ããšã·ãŒã³ã®ã«ãŒãããŒããžã®éãŒããã€ã³ã¿ãŒãããã³è¿ãããããŒã¿ã®äžå®å šæ§ãå ±åããã¹ããŒã¿ã¹ãã©ã°ããã§ãã¯ããŸãã ãããã®ã€ãã³ãã¯ãããããã€ã³ããŒããªããžã§ã¯ãGetErrorStringã®ã¡ãœããããååŸãã説æãå«ããšã©ãŒã¡ãã»ãŒãžã®åºåã«ã€ãªãããããã«é¢æ°ãçµäºããŸãã ãŸãããã¡ã€ã«ãžã®ãã«ãã¹ããããã£ã¬ã¯ããªãžã®ãã¹ãåé¢ããŸãã
ãã¹ãŠããšã©ãŒãªãå®è¡ãããå Žåãã«ãŒãããŒããååž°çãªã¡ãœããprocessNodeã«æž¡ãããšã«ãããã·ãŒã³ã®ããŒãã®åŠçã«é²ã¿ãŸãã ååž°çãªåŠç圢åŒã¯ãã·ãŒã³éå±€ã«ãšã£ãŠæãããªããã«éžæãããŸããçŸåšã®ããŒããåŠçããåŸããã®åå«ãããã°ãããåŠçããå¿ èŠããããŸãã ååž°é¢æ°ã¯ããã€ãã®åŠçãå®è¡ããããã€ãã®æ¡ä»¶ïŒçµäºæ¡ä»¶ïŒã«éåãããŸã§ãå€æŽããããã©ã¡ãŒã¿ãŒã§èªèº«ãåŒã³åºããŸãã ç§ãã¡ã®å Žåããã®ãããªæ¡ä»¶ã¯ãåŠçã®ããã®æ°ããããŒãããªãããšã§ãã
ãæ°ä»ãã®ãšãããAssimpããŒã¿æ§é ã¯ãåããŒããããªãŽã³ã¡ãã·ã¥ã€ã³ããã¯ã¹ã®ã»ãããæ ŒçŽããŠããããšãåæãšããŠããããããã¯å®éã«ã·ãŒã³ãªããžã§ã¯ãã«æ ŒçŽãããŸãã ãããã£ãŠãåããŒããšãã®åå«ã«ã€ããŠãããŒãã«ä¿åãããŠããã¡ãã·ã¥ã®ã€ã³ããã¯ã¹ã®ãªã¹ãã䜿çšããŠãããªãŽã³ã¡ãã·ã¥ã®ããŒã¿ãéžæããå¿ èŠããããŸãã processNodeã¡ãœããã®ãªã¹ãã以äžã«ç€ºããŸãã
void processNode(aiNode *node, const aiScene *scene) { // ( ) for(unsigned int i = 0; i < node->mNumMeshes; i++) { aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; meshes.push_back(processMesh(mesh, scene)); } // for(unsigned int i = 0; i < node->mNumChildren; i++) { processNode(node->mChildren[i], scene); } }
ãŸã ãçŸåšã®ããŒãã®ã€ã³ããã¯ã¹ã䜿çšããŠã mmeshesé åããã·ãŒã³ãªããžã§ã¯ããååŸããããšã«ãããAssimpã¡ãã·ã¥ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãååŸããŸãã 次ã«ã aiMeshãªããžã§ã¯ã㯠processMeshã¡ãœããã䜿çšããŠMeshã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«å€æããã ã¡ãã·ã¥ãªã¹ãã«ä¿åãããŸãã
ããŒãã®ãã¹ãŠã®ããªãŽã³ã¡ãã·ã¥ãåãåã£ãåŸãåå«ã®ãªã¹ãã調ã¹ãŠãæ¢ã«åãprocessNodeãå®è¡ããŸãã åå«ãªã¹ãããªããªããšãã¡ãœããã¯çµäºããŸãã
æ°é ãã®ããèªè ã¯ãããŒãå ã®ã€ã³ããã¯ã¹ãæ··ä¹±ããããšãªããã·ãŒã³ãªããžã§ã¯ãã«æ ŒçŽãããŠããé åãåçŽã«èª¿ã¹ãããšã§ã°ãªããã®ãªã¹ããååŸã§ããããšã«æ°ä»ãã§ãããã ãã ãã䜿çšãããããè€éãªæ¹æ³ã¯ãããªãŽã³ã¡ãã·ã¥éã®èŠªåé¢ä¿ã確ç«ããæ©èœã«ãã£ãŠæ£åœåãããŸãã ååž°ãã¹ã䜿çšãããšãç¹å®ã®ãªããžã§ã¯ãéã§åæ§ã®é¢ä¿ã確ç«ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³äŸïŒè»ãªã©ã®ããããå€æå移åã¢ãã«ã 移åãããšãã¯ããã¹ãŠã®äŸåéšåïŒãšã³ãžã³ãã¹ãã¢ãªã³ã°ãã€ãŒã«ãã¿ã€ã€ãªã©ïŒã移åããå¿ èŠããããŸãã ãªããžã§ã¯ãã®åæ§ã®ã·ã¹ãã ã¯ã芪åéå±€ãšããŠç°¡åã«äœæã§ããŸãã
çŸæç¹ã§ã¯ãã®ãããªã·ã¹ãã ã¯äœ¿çšããŠããŸããããå°æ¥ãããªãŽã³ã¡ãã·ã¥ã管çããããã®æ©èœãè¿œå ãããå Žåã¯ããã®ã¢ãããŒãã«åŸãããšããå§ãããŸãã æçµçã«ããããã®é¢ä¿ã¯ããã®ã¢ãã«ãäœæããã¢ããªã³ã°ã¢ãŒãã£ã¹ãã«ãã£ãŠç¢ºç«ãããŸãã
次ã®ã¹ãããã¯ãAssimpããŒã¿ãåã«äœæããMeshã¯ã©ã¹ã®åœ¢åŒã«å€æããããšã§ãã
AssimpãMeshã«å€æ
aiMeshãªããžã§ã¯ããå éšåœ¢åŒã«çŽæ¥å€æããããšã¯ãããã»ã©è² æ ã«ã¯ãªããŸããã å¿ èŠãªããªãŽã³ã¡ãã·ã¥ã®ãªããžã§ã¯ãã®å±æ§ãèªã¿åãã Meshã¿ã€ãã®ãªããžã§ã¯ãã«ä¿åããã ãã§ååã§ãã processMeshã¡ãœããã®ã¹ã±ã«ãã³ã以äžã«ç€ºããŸãã
Mesh processMesh(aiMesh *mesh, const aiScene *scene) { vector<Vertex> vertices; vector<unsigned int> indices; vector<Texture> textures; for(unsigned int i = 0; i < mesh->mNumVertices; i++) { Vertex vertex; // , ... vertices.push_back(vertex); } // ... // if(mesh->mMaterialIndex >= 0) { ... } return Mesh(vertices, indices, textures); }
åŠçã¯ãé ç¹ãã€ã³ããã¯ã¹ã®èªã¿åãããããªã¢ã«ããŒã¿ã®ååŸã®3ã€ã®ã¹ãããã«åæžãããŸãã åä¿¡ããããŒã¿ã¯ã ã¡ãã·ã¥ãªããžã§ã¯ãã®äœæã«äœ¿çšããã3ã€ã®å®£èšããããã¯ã¿ãŒã®ããããã«æ ŒçŽãããè¿ãããŸãã
é ç¹ããŒã¿ã®ååŸã¯ç°¡åã§ãã é ç¹æ§é äœã宣èšãããã®ã€ã³ã¹ã¿ã³ã¹ãååŠçã¹ãããã§é ç¹é åã«è¿œå ããŸãã ã«ãŒãã¯ãä¿åãããé ç¹ããŒã¿ããªããªããŸã§å®è¡ãããŸãïŒå€mesh-> mNumVerticesã«ãã£ãŠæ±ºå®ãããŸãïŒã ã«ãŒãã®æ¬äœã§ã¯ãããšãã°ãé ç¹ã®äœçœ®ãªã©ã®é¢é£ããŒã¿ãæ§é äœãã£ãŒã«ãã«å ¥åããŸãã
glm::vec3 vector; vector.x = mesh->mVertices[i].x; vector.y = mesh->mVertices[i].y; vector.z = mesh->mVertices[i].z; vertex.Position = vector;
Assimpã¯ãå éšããŒã¿åã«æ å ±ãä¿åãããããã¿ã€ãvec3ã®ãã«ããŒãªããžã§ã¯ãã宣èšããŸããããã¯ãglmã«ãã£ãŠå®£èšãããåã«çŽæ¥å€æããããšã¯ã§ããŸããã
Assimpã®é ç¹äœçœ®ã®é åã¯åã«mVerticesãšåŒã°ããããã¯ããçŽæçã§ã¯ãããŸããã
æ³ç·ã®å Žåãããã»ã¹ã¯åæ§ã§ãïŒ
vector.x = mesh->mNormals[i].x; vector.y = mesh->mNormals[i].y; vector.z = mesh->mNormals[i].z; vertex.Normal = vector;
èªã¿åããã¯ã¹ãã£åº§æšãã©ã®ããã«èŠããããã§ã«æšæž¬ããŸãããïŒ Assimpã¯ãé ç¹ãæ倧8ã»ããã®ãã¯ã¹ãã£åº§æšãæã€å¯èœæ§ãæ³å®ããŠããŸãã ãã®ãããªå¯ã¯å¿ èŠãããŸãããæåã®ã»ããã®ããŒã¿ãååŸããã ãã§ååã§ãã ãããŠåæã«ãåé¡ã®ã°ãªãããååçã«ãã¯ã¹ãã£åº§æšãæã£ãŠãããã©ããããã§ãã¯ããããšã¯çŽ æŽãããããšã§ãïŒ
if(mesh->mTextureCoords[0]) // ? { glm::vec2 vec; vec.x = mesh->mTextureCoords[0][i].x; vec.y = mesh->mTextureCoords[0][i].y; vertex.TexCoords = vec; } else vertex.TexCoords = glm::vec2(0.0f, 0.0f);
ãã®æç¹ã§ã®é ç¹æ§é ã®ã€ã³ã¹ã¿ã³ã¹ã¯ãé ç¹ã®å¿ é å±æ§ãå®å šã«åããŠãããä¿åã®ããã«é ç¹é åã«éä¿¡ã§ããŸãã ãã®ããã»ã¹ã¯ãããªãŽã³ã¡ãã·ã¥ã®é ç¹ã®æ°ã«å¿ããŠç¹°ãè¿ãããŸãã
ææ°
Assimpã©ã€ãã©ãªã¯ãåããªãŽã³ã¡ãã·ã¥ãé¢ã®é åãå«ããã®ãšããŠå®çŸ©ããŸããåé¢ã¯ç¹å®ã®ããªããã£ãã«ãã£ãŠè¡šãããŸãã ç§ãã¡ã®å Žåããããã¯åžžã«äžè§åœ¢ã§ãïŒã€ã³ããŒããªãã·ã§ã³aiProcess_Triangulateã®ãããã§ã ïŒã é¢èªäœã«ã¯ããã®é¢ã®ããªããã£ãã®æç»ã«äœ¿çšãããé ç¹ãšé åºã瀺ãã€ã³ããã¯ã¹ã®ãªã¹ããå«ãŸããŠããŸãã ãããã£ãŠãé¢ã®ãªã¹ãã調ã¹ãŠããã¹ãŠã®ã€ã³ããã¯ã¹ããŒã¿ãèªã¿åãããšãã§ããŸãã
for(unsigned int i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; for(unsigned int j = 0; j < face.mNumIndices; j++) indices.push_back(face.mIndices[j]); }
å€åŽã®ã«ãŒããå®äºãããšãOpenGL glDrawElementsããã·ãŒãžã£ã䜿çšããŠã°ãªããã衚瀺ããã®ã«ååãªã€ã³ããã¯ã¹ã®å®å šãªãªã¹ããæå ã«ãããŸãã ãã ããã¬ãã¹ã³ãå®äºããããã«ããããªã¢ã«ãåŠçããŠã¢ãã«ã«è©³çŽ°ãè¿œå ããŸãã
çŽ æ
ã¡ãã·ã¥ãªããžã§ã¯ãã¯ã ã·ãŒã³ãªããžã§ã¯ãã®mMaterialsé åã«å®éã«ä¿åãããŠãããªããžã§ã¯ãã®ãããªã¢ã«ã®ã¿ãã€ã³ããã¯ã¹ã§åç §ããŸãã ãããã£ãŠããããªã¢ã«ãã°ãªããã«å²ãåœãŠãããŠããå Žåããããªã¢ã«ããŒã¿ã¯ãã®ã€ã³ããã¯ã¹ã«ãã£ãŠååŸã§ããŸãã
if(mesh->mMaterialIndex >= 0) { aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; vector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse"); textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end()); vector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"); textures.insert(textures.end(), specularMaps.begin(), specularMaps.end()); }
ãŸãã ãŠãããŒã¹ãªããžã§ã¯ãã®mMaterialsé åããaiMaterialãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒãååŸããŸãã 次ã«ãæ¡æ£ãã¯ã¹ãã£ããã³/ãŸãã¯é¡é¢å æ²¢ãã¯ã¹ãã£ãããŒãããŸãã ãããªã¢ã«ãªããžã§ã¯ãã«ã¯ãåã¿ã€ãã®ãã¯ã¹ãã£ãžã®ãã¹ã®é åãå«ãŸããŠããŸãã ãã¯ã¹ãã£ã®åã¿ã€ãã«ã¯ãæ¥é èŸaiTextureType_ãæã€ç¬èªã®èå¥åããããŸãã è£å©ã¡ãœããloadMaterialTexturesã¯ããããªã¢ã«ãªããžã§ã¯ãããæœåºããã察å¿ããã¿ã€ãã®ãã¯ã¹ãã£ãå«ãTextureãªããžã§ã¯ãã®ãã¯ãã«ãè¿ããŸãã ãããã®ãã¯ãã«ã®ããŒã¿ã¯ãã¢ãã«ãªããžã§ã¯ãã®äžè¬çãªãã¯ã¹ãã£é åã«æ ŒçŽãããŸãã
ã«ãŒãå ã®loadMaterialTexturesé¢æ°ã¯ãæå®ãããã¿ã€ãã®ãã¹ãŠã®ãã¯ã¹ãã£ãééãããã¡ã€ã«ãã¹ãèªã¿åããOpenGLãã¯ã¹ãã£ãããŒãããŠçæããå¿ èŠãªæ å ±ãTextureæ§é äœã®ã€ã³ã¹ã¿ã³ã¹ã«ä¿åããŸãã
vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName) { vector<Texture> textures; for(unsigned int i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); Texture texture; texture.id = TextureFromFile(str.C_Str(), directory); texture.type = typeName; texture.path = str; textures.push_back(texture); } return textures; }
ãŸãã GetTextureCountãåŒã³åºãããšã§ãã¯ã¹ãã£ã®æ°ããã§ãã¯ããã察象ã®ãã¯ã¹ãã£ã®ã¿ã€ããæž¡ãããŸãã 次ã«ã GetTextureã¡ãœããã䜿çšããŠãã¯ã¹ãã£ãã¡ã€ã«ãžã®ãã¹ãèªã¿åãããŸãããã®ã¡ãœããã¯ã aiStringåã®æååãšããŠçµæãè¿ããŸãã å¥ã®ãã«ããŒé¢æ°TextureFromFileã¯ããã®èå¥åãè¿ãããšã§ãçŽæ¥ãã¡ã€ã«ã®ããŒããšãã¯ã¹ãã£çæïŒSOILã©ã€ãã©ãªã䜿çšïŒãå®è¡ããŸãã ãã®é¢æ°ãã©ã®ããã«èŠããã®ãããããªãå Žåã¯ãèšäºã®æåŸã«ããå®å šãªããã°ã©ã ã³ãŒãã§ãã®å šæãèŠã€ããããšãã§ããŸãã
ãã®ã³ãŒãã§ã¯ãã¢ãã«ãã¡ã€ã«ã«ä¿åãããŠãããã¯ã¹ãã£ãã¡ã€ã«ãžã®ãã¹ã®æ§è³ªã«é¢ããä»®å®ãããããšã«æ³šæããŠãã ããã ãããã®ãã¹ã¯ãã¢ãã«ãã¡ã€ã«ãå«ããã©ã«ããŒã«çžå¯Ÿçã§ãããšèããŠããŸãã ãã®å Žåã以åã«ä¿åããããã©ã«ããŒãžã®ãã¹ãã¢ãã«ïŒ loadModelã¡ãœããã§å®è¡ïŒãšãã¯ã¹ãã£ãžã®ãã¹ïŒãããã£ãŠããã©ã«ããŒãžã®ãã¹ãGetTextureã«è»¢éãããŸãïŒãšããŒãžããããšã«ããããã¯ã¹ãã£ãã¡ã€ã«ãžã®ãã«ãã¹ãååŸã§ããŸãã
äžéšã®ã¢ãã«ã¯ã絶察圢åŒã§ãããã¯ãŒã¯ã¹ãã¢ã®ãã¯ã¹ãã£ãã¹ã«ããŠã³ããŒãã§ããŸããããã«ããããã·ã³ã§æããã«åé¡ãçºçããŸãã ãããããšãã£ã¿ãŒã䜿çšããŠããã¯ã¹ãã£ãã¹ãé çªã«äžŠã¹ãå¿ èŠããããŸãã
ããŠãAssimpã䜿çšããŠã¢ãã«ãã€ã³ããŒãããããšã«é¢ãããã¹ãŠã®ããã«æããŸããïŒ
å€§å¹ ãªæé©å
ããã§ããªãã æé©åã®æ©äŒã¯éãããŸãŸã§ãïŒå¿ é ã§ã¯ãããŸãããïŒã å€ãã®ã·ãŒã³ã§ã¯ãäžéšã®ãªããžã§ã¯ãã¯ç¹å®ã®æ°ã®ãã¯ã¹ãã£ãåå©çšã§ããŸãã è±åŽå²©ã®ãã¯ã¹ãã£ãå£ã«äœ¿çšãããŠãã家ãæ³åããŠãã ããã ããããåããã¯ã¹ãã£ãŒã¯åºã倩äºãé段ã«æé©ã§ãããããŒãã«ãé ãã®å°ããªäºæžã«ãæé©ã§ãã ãã¡ã€ã«ãããã¯ã¹ãã£ãããŒãããã®ã¯æã軜éãªæé ã§ã¯ãªããçŸåšã®å®è£ ã§ã¯ããã®ãããªãã¡ã€ã«ããã§ã«ããŒããããŠããå Žåã§ããåã¡ãã·ã¥ã®ãã¯ã¹ãã£ãªããžã§ã¯ããåå¥ã«ããŒãããã³äœæããŸãã ãã®ãããªèŠèœãšãã¯ãã¢ãã«ãã¡ã€ã«ã®èªã¿èŸŒã¿ã®å®è£ ã«ãããããã«ããã¯ã«ãªãããããªããŸãã
æé©åãšããŠãæ¢ã«ããŒãããããã¯ã¹ãã£ã®åå¥ã®ãªã¹ããäœæãããããModelãªããžã§ã¯ãã®ã¹ã³ãŒãã«ä¿æããŸããå¥ã®ãã¯ã¹ãã£ãããŒããããšããããŒãããããã¯ã¹ãã£ã®ãªã¹ãã«ãã®ååšããã§ãã¯ããŸãã ããã«ãããè€è£œã®èšç®èœåãé©åã«ç¯çŽã§ããŸãã ãã ããéè€ããã§ãã¯ããã«ã¯ããã¯ã¹ãã£ãžã®ãã¹ããã¯ã¹ãã£æ§é ã«ä¿åããå¿ èŠããããŸãã
struct Texture { unsigned int id; string type; aiString path; // };
æ¢ã«ããŒãããããã¯ã¹ãã£ã®ãªã¹ãã¯ã Modelã¯ã©ã¹ã®ãã©ã€ããŒãå€æ°ãšããŠå®£èšããããã¯ãã«ãšããŠãã©ãŒããããããŸãïŒ
vector<Texture> textures_loaded;
ãããŠã loadMaterialTexturesã¡ãœããã§ã¯ ããã®ãã¯ãã«ã§ããŒãããããã¯ã¹ãã£ã®ãã¹ã®çºçãæ€çŽ¢ããã³ããŒãããå ŽåãããŒããã¹ããããããã§ã«ããŒãããããã¯ã¹ãã£ã®èå¥åãçŸåšã®ããªãŽã³ã¡ãã·ã¥ã®ãã¯ã¹ãã£é åã«çœ®ãæããŸãã
vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName) { vector<Texture> textures; for(unsigned int i = 0; i < mat->GetTextureCount(type); i++) { aiString str; mat->GetTexture(type, i, &str); bool skip = false; for(unsigned int j = 0; j < textures_loaded.size(); j++) { if(std::strcmp(textures_loaded[j].path.C_Str(), str.C_Str()) == 0) { textures.push_back(textures_loaded[j]); skip = true; break; } } if(!skip) { // â Texture texture; texture.id = TextureFromFile(str.C_Str(), directory); texture.type = typeName; texture.path = str; textures.push_back(texture); // textures_loaded.push_back(texture); } } return textures; }
ã§ããïŒ ç§ãã¡ã¯æ®éçãªã ãã§ãªãããã®ã¿ã¹ã¯ã«éåžžã«è¿ éã«å¯Ÿå¿ããæé©åãããã¢ãã«èªã¿èŸŒã¿ã·ã¹ãã ãæã«ããŠããŸãã
Assimpã®äžéšã®ããŒãžã§ã³ã¯èããé ããªãããããã°ããŒãžã§ã³ãšããŠãã«ãããããããããžã§ã¯ãã®ãããã°ãã«ãã§äœ¿çšãããŸãã ãã®åäœãçºçããå Žåã¯ããªãªãŒã¹ãã«ãã䜿çšããŠã¿ãŠãã ããã
æé©åãå«ãå®å šãªãœãŒã¹ã³ãŒãã¯ãã¡ãã«ãããŸã ã
ã³ã³ãã-ããŠã³ïŒ
ããŠãããã®3Dã¢ãŒãã£ã¹ãã«ãã£ãŠéçºãããæ¬ç©ã®ã¢ãã«ãæŠå Žã§ãã¹ãããã²ãã®äžã®ãããã¯ãŒã¯Kulibinã«ãã£ãŠå¥è·¡çã«å€æãããããšãªããã·ã¹ãã ããã¹ããããšãã§ãïŒãã ãããããã®ã³ã³ãããŒã¯ããããŸã§ã«èŠãäžã§æé«ã®ãã¥ãŒãã®äžéšã§ãããšèªããŠããŸããïŒ ããã§ãã¹ãŠã®å声ãåŸãããšãæãã§ããªãã®ã§ãç§ã¯ä»ã®äººã ã®åµé æ§ã«ç®ãåããŸãïŒå®éšã¢ãã«ã¯ãCrytekã®Crysisã·ã¥ãŒã¿ãŒã®ãããã¯ãããžãŒã¹ãŒãã§ã ïŒãã®å Žåãtf3dm.comããããŠã³ããŒããããä»ã®ã¢ãã«ãåäœããŸãïŒã ã¢ãã«ã¯ã.objãã¡ã€ã«ãšãæ¡æ£ããã©ãŒãã¯ã¹ãã£ãããã³æ³ç·ãããäžã®ããŒã¿ãå«ãè£å©.mtlã®åœ¢åŒã§æºåãããŸãã ããããã¢ãã«ãããŠã³ããŒãã§ããŸãïŒãããã«å€æŽãããŠããŸãïŒã ãŸãããã¹ãŠã®ãã¯ã¹ãã£ãã¢ãã«ãã©ã«ããŒã«ããããšãæãåºããŸãã
ã¢ãã«ãã¡ã€ã«ã®å€æŽã§ã¯ããã¯ã¹ãã£ãžã®ãã¹ããå ã®ãã¡ã€ã«ã«ä¿åãããŠãã絶察ãã¹ã§ã¯ãªããçžå¯Ÿãã¹ã«å€æŽããŸãã
ã³ãŒãã§ã¯ãModelã®ã€ã³ã¹ã¿ã³ã¹ã宣èšããã¢ãã«ãã¡ã€ã«ãžã®ãã¹ãã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŸãã æ£åžžã«ããŒãããããšãã¡ã€ã³ããã°ã©ã ã«ãŒãã§Drawã¡ãœãããåŒã³åºããŠã¢ãã«ã衚瀺ãããŸãã å®éãããã ãã§ãïŒ ãããã¡ã®éžæãé ç¹å±æ§ãžã®ãã€ã³ã¿ã®å²ãåœãŠãOpenGLããã·ãŒãžã£ãä»ããã¬ã³ããªã³ã°ã®åŒã³åºãã«æ··ä¹±ã¯ãããŸãã-1è¡ã§ååã§ãã ãã©ã°ã¡ã³ããã¢ãã«ã®æ¡æ£ãã¯ã¹ãã£ã®è²ã®ã¿ãçæããã·ã§ãŒããŒã®åçŽãªã»ãããäœæããããã ãã«æ®ããŸãã çµæã¯æ¬¡ã®ããã«ãªããŸãã

å®å šãªãœãŒã¹ã³ãŒãã¯ãã¡ãã§ãã
é¡é¢åå°ãããã®äœ¿çšãšå¯Ÿå¿ããã¬ãã¹ã³ã®ç §æèšç®ã¢ãã«ãæ¥ç¶ãã2ã€ã®å æºãå°å ¥ããããšã«ãããé©ãã¹ãçµæãåŸãããšãã§ããŸãã

ãããç§ã®æãã容åšã®è€éãã®çµæã§ããããšãèªããããåŸãŸããã Assimpã䜿çšãããšããããã¯ãŒã¯äžã§å©çšå¯èœãªæ°åã®ã¢ãã«ã®ã»ãŒãã¹ãŠãããŠã³ããŒãã§ããŸãã è€æ°ã®åœ¢åŒã®ã¢ãã«ãç¡æã§ããŠã³ããŒãã§ãããªãœãŒã¹ã¯ãããŸããã ãã¡ããããã¹ãŠã®ã¢ãã«ãæ£åžžã«ããŒãããããããã¯ã¹ãã£ãžã®ãã¹ãæ£ãããªãã£ãããååãšããŠAssimpã§ãµããŒããããŠããªã圢åŒã«ãªãããšã¯ãããŸããã
ã泚æ ããã -ukïŒoïŒãªã³ã«ãŒãä»ããŠé§åããããªãªãžãã«ãžã®ãªã³ã¯ããaã³ããŸãã Hubroparserã¯ãå ã®URLã®éåžžã®ãªã³ã¯ãèªèããããšãæåŠããŸããã