3D 모델을로드하는 것과 같은 삶을 살았습니다. 그 때문에 나는 Assimp를 사용하려고했습니다.assimp로 3D 모델을로드 할 수 없습니다.
슬프게도 나는 아무 결과도 얻을 수 없었습니다. 메쉬 클래스를 작동시킬 수 있었고 수동으로 데이터를 채워서 큐브를 만들 수있었습니다. 하지만 내 모델 클래스는 작동하지 않는 것 같습니다.
Assimp 오류의 종류를 반환하지 않은, 그래서 나는 (I 아마 한)
디버거에 따르면, 데이터가 성공적으로 채워졌다 내가 잘못하지 않았다 Assimp의 마음에 (주 같아요 "모드를 "그 외에는
, 코드가 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;
그래서 저는 수동으로 큐브를 설정하고 OpenGL에서 잘 렌더링했습니다. 따라서 다음에는 수백 KB의 복잡한 라이브러리를 다운로드하고 파일에서 복잡한 모델을로드하려고 시도했지만 작동하지 않았습니다. 나는 그것을 디버깅했지만 실마리를 얻지 못했다 ... : 예. 나는 한 발 뒤로 물을 것이다. 나는 AssImp가 특정 OpenGL 튜토리얼에서 언급 된 것을 기억합니다. 나는 그들을 따라갈 것이지만 ** 또한 샘플 데이터를 사용한다. 아마도 AssImp는 불확실성으로 인해 모델을 읽을 수 없습니다. 3D 파일 형식에 대해 google을 사용하고 혼자서 간단한 것을 구현해보십시오. (일부는 정말 간단합니다.) – Scheff
간단한 3D 파일 형식 : [AC3D] (https://www.inivis.com/)에서는 [AC3D 파일 형식] (https://www.inivis.com/ac3d)을 사용합니다. /man/ac3dfileformat.html) 나는 당신의 요구에 충분히 간단하고 강력 할 것이라고 생각한다. 소프트웨어 자체는 샘플을 제공합니다 (필자가 자체 로더 구현을 테스트하는 데 사용함). 파일 형식은 ASCII 형식이므로 사람이 읽을 수 있습니다. 따라서 테스트/디버깅이 쉬워집니다. – Scheff
'vertices'와'indices'의 값을 확인 했습니까? 그들이해야 할 일이 무엇입니까? 텍스처가 올바르게로드되었는지 (CodeXL, renderdoc 등의 OpenGL 디버거에서 확인).우리가 사용하고있는 데이터 나 렌더링 방법을 알려주지 않으면 무엇이 잘못 될지 어떻게 알 수 있습니까? – BDL