2017-11-28 23 views
-1

3D 모델을로드하는 것과 같은 삶을 살았습니다. 그 때문에 나는 Assimp를 사용하려고했습니다.assimp로 3D 모델을로드 할 수 없습니다.

슬프게도 나는 아무 결과도 얻을 수 없었습니다. 메쉬 클래스를 작동시킬 수 있었고 수동으로 데이터를 채워서 큐브를 만들 수있었습니다. 하지만 내 모델 클래스는 작동하지 않는 것 같습니다.

Assimp 오류의 종류를 반환하지 않은, 그래서 나는 (I 아마 한)

디버거에 따르면, 데이터가 성공적으로 채워졌다 내가 잘못하지 않았다 Assimp의 마음에 (주 같아요 "모드를 "그 외에는

enter image description here

, 코드가 this에서 영감을 모델의 이름)이며, 가장 큰 차이는 텍스처 로딩 (I 텍스처를로드 theSFML 라이브러리를 사용)과에 정말 메쉬 로딩에서 약간의 비트, 로직 s 똑같은 말.

#ifndef MODEL_H 
#define MODEL_H 

#include "Mesh.h" 
#include "ressourceManager/TextureManager.h" 

#include <iostream> 
#include <string> 


#include <assimp/Importer.hpp> 
#include <assimp/scene.h> 
#include <assimp/postprocess.h> 


using namespace std; 

class Model 
{ 
    public: 
     Model(const string &path); 
     void Draw(Shader &shader); 

    private: 
     vector<Mesh> meshes; 

     string directory; 

     void loadModel(const 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); 

}; 

#endif // MODEL_H 

model.cpp :

#include "Model.h" 


Model::Model(const string &path) 
{ 

    loadModel(path); 
} 

void Model::Draw(Shader &shader) 
{ 
    for(Mesh mesh: meshes) 
     mesh.draw(shader); 

} 

void Model::loadModel(const 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); 

} 

void Model::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); 

} 

Mesh Model::processMesh(aiMesh* mesh, const aiScene* scene) 
{ 

    vector<Vertex> vertices; 
    vector<GLuint> indices; 
    vector<Texture> textures; 

    for(unsigned int i = 0; i < mesh->mNumVertices; i++){ 
     Vertex vertex; 

     glm::vec3 vector; 

     vector.x = mesh->mVertices[i].x; 
     vector.y = mesh->mVertices[i].y; 
     vector.z = mesh->mVertices[i].z; 
     vertex.pos = vector; 

     vector.x = mesh->mNormals[i].x; 
     vector.y = mesh->mNormals[i].y; 
     vector.z = mesh->mNormals[i].z; 
     vertex.normal = vector; 

     if(mesh->mTextureCoords[0]){ 
      glm::vec2 vec; 
      vec.x = mesh->mTextureCoords[0][i].x; 
      vec.y = mesh->mTextureCoords[0][i].y; 
      vertex.texCoord = vec; 

     }else 
      vertex.texCoord = glm::vec2(0.0f, 0.0f); 


     vertices.push_back(vertex); 
    } 

    for (GLuint i = 0; i < mesh->mNumFaces; i++){ 
     aiFace face = mesh->mFaces[i]; 
     for (GLuint j = 0; j < face.mNumIndices; j++) 
      indices.push_back(face.mIndices[j]); 
    } 

    if(mesh->mMaterialIndex >= 0){ 
     aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex]; 

     vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse"); 
     textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end()); 

     // 2. Specular maps 
     vector<Texture> specularMaps = this->loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular"); 
     textures.insert(textures.end(), specularMaps.begin(), specularMaps.end()); 
    } 

    return Mesh(vertices, indices, textures); 
} 

vector<Texture> Model::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 = *RessourceManager::TextureManager::get(directory + "/" + str.C_Str()); 
     texture.type = typeName; 
     texture.path = str; 
     textures.push_back(texture); 
    } 
    return textures; 
} 

textureManager.h (내가 사용하는 것은 텍스처를로드하기 위해) :

#ifndef TEXTUREMANAGER_H 
#define TEXTUREMANAGER_H 

#include <unordered_map> 
#include <memory> 
#include <GL/glew.h> 

namespace RessourceManager{ 
    class TextureManager 
     { 
      public: 
       TextureManager(); 
       static std::shared_ptr<GLuint> get(const std::string& name); 
       static void removeUnused(); 
      private: 
       static std::unordered_map<std::string, std::shared_ptr<GLuint>> p_textureIDs; 
     }; 
    } 

    #endif // TEXTUREMANAGER_H 

여기에 코드

model.h에게있어

textureManager .cpp

#include "TextureManager.h" 
#include "SFML/Graphics.hpp" 
#include <iostream> 
namespace RessourceManager{ 
    TextureManager::TextureManager() 
    { 

    } 

    std::shared_ptr<GLuint> TextureManager::get(const std::string& name) 
    { 
     const auto i = p_textureIDs.find(name); 
     if(i != p_textureIDs.end()) 
      return i->second; 
     else{ 
      std::shared_ptr<GLuint> p_textureID = std::make_shared<GLuint>(); 

      glGenTextures(1, p_textureID.get()); 


      sf::Image image; 
      image.loadFromFile(name); 

      glBindTexture(GL_TEXTURE_2D, *p_textureID.get()); 
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.getSize().x, image.getSize().y, 0, GL_RGBA, GL_UNSIGNED_BYTE, image.getPixelsPtr()); 
      glGenerateMipmap(GL_TEXTURE_2D); 

      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); 
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

      glBindTexture(GL_TEXTURE_2D, 0); 

      p_textureIDs.insert({name, p_textureID}); 
      std::cout << "new texture created" << std::endl; 
      return p_textureID; 
     } 
    } 

    void TextureManager::removeUnused() 
    { 
     for(auto i = p_textureIDs.begin(); i != p_textureIDs.end();) 
      if(i->second.unique()) 
       i = p_textureIDs.erase(i); 
      else 
       ++i; 
    } 


    std::unordered_map<std::string, std::shared_ptr<GLuint>> TextureManager::p_textureIDs; 
+0

그래서 저는 수동으로 큐브를 설정하고 OpenGL에서 잘 렌더링했습니다. 따라서 다음에는 수백 KB의 복잡한 라이브러리를 다운로드하고 파일에서 복잡한 모델을로드하려고 시도했지만 작동하지 않았습니다. 나는 그것을 디버깅했지만 실마리를 얻지 못했다 ... : 예. 나는 한 발 뒤로 물을 것이다. 나는 AssImp가 특정 OpenGL 튜토리얼에서 언급 된 것을 기억합니다. 나는 그들을 따라갈 것이지만 ** 또한 샘플 데이터를 사용한다. 아마도 AssImp는 불확실성으로 인해 모델을 읽을 수 없습니다. 3D 파일 형식에 대해 google을 사용하고 혼자서 간단한 것을 구현해보십시오. (일부는 정말 간단합니다.) – Scheff

+0

간단한 3D 파일 형식 : [AC3D] (https://www.inivis.com/)에서는 [AC3D 파일 형식] (https://www.inivis.com/ac3d)을 사용합니다. /man/ac3dfileformat.html) 나는 당신의 요구에 충분히 간단하고 강력 할 것이라고 생각한다. 소프트웨어 자체는 샘플을 제공합니다 (필자가 자체 로더 구현을 테스트하는 데 사용함). 파일 형식은 ASCII 형식이므로 사람이 읽을 수 있습니다. 따라서 테스트/디버깅이 쉬워집니다. – Scheff

+0

'vertices'와'indices'의 값을 확인 했습니까? 그들이해야 할 일이 무엇입니까? 텍스처가 올바르게로드되었는지 (CodeXL, renderdoc 등의 OpenGL 디버거에서 확인).우리가 사용하고있는 데이터 나 렌더링 방법을 알려주지 않으면 무엇이 잘못 될지 어떻게 알 수 있습니까? – BDL

답변

0

데이터를 성공적으로로드했습니다.

올바른 방법으로 모델에보기를 설정해야합니다. 어쩌면 당신이 이미 그렇게했지만 귀하의 예제에서 그 코드를 탐지 할 수 없었습니다.

간단한 큐브의 경우 위치 (0 | 0 | 0)를 배치하면이 원점을 볼 수 있습니다. glm을 사용하여 올바른 행렬을 계산할 수 있습니다. 예 : here을 찾을 수 있습니다.

한 점 확인 : 꼭짓점 및 조각 셰이더도 제대로 설정 되었습니까?