AssImp не загружает файлы OBJ - PullRequest
       34

AssImp не загружает файлы OBJ

0 голосов
/ 24 февраля 2020

Я использую AssImp для загрузки модели, созданной в Blender и экспортированной в формат файла .obj. И GLFW, GLEW и GLM для рендеринга загруженной модели. Моя проблема в том, что сейчас AssImp даже не загружает модель, и я просто получаю сообщение об ошибке ERROR::ASSIMP::Unable to open file "MyFile.obj". Это класс, который я использую, чтобы импортировать модель и позже нарисовать ее.

#pragma once

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <vector>

#include <GL/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <SOIL2/SOIL2.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "MeinMesh.h"


using namespace std;

GLint TextureFromFile(const char* path, string directory);

class Model
{
public:
    //Konstruktor mit pfad zum Model aufrufen
    Model(const GLchar* path)
    {
        this->loadModel(path);
    }
    // Modell zeichnen
    void Draw(Shader shader)
    {
        for (GLuint i = 0; i < this->meshes.size(); i++) 
        {
            this->meshes[i].Draw(shader);
        }
    }

private:
    //Daten für das Modell
    vector<Mesh> meshes;
    string directory;
    vector<Texture> textures_loaded;

    void loadModel(string path)
    {
        //Datei mit Assimp auslesen
        Assimp::Importer importer;
        const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);

        if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
        {
            cout << "ERROR::ASSIMP::" << importer.GetErrorString() << endl;
            return;
        }

        this->directory = path.substr(0, path.find_last_of('/'));

        this->processNode(scene->mRootNode, scene);
    }

    void processNode(aiNode* node, const aiScene* scene)
    {
        for (GLuint i = 0; i < node->mNumMeshes; i++)
        {
            aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];

            this->meshes.push_back(this->processMesh(mesh, scene));
        }

        for (GLuint i = 0; i < node->mNumChildren; i++)
        {
            this->processNode(node->mChildren[i], scene);
        }
    }

    Mesh processMesh(aiMesh* mesh, const aiScene* scene)
    {
        vector<Vertex> vertices;
        vector<GLuint> indices;
        vector<Texture> textures;

        for (GLuint 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.Position = 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.TexCoords = vec;
            }
            else
            {
                vertex.TexCoords = 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());

            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> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName)
    {
        vector<Texture> textures;

        for ( GLuint i=0; i < mat->GetTextureCount(type); i++ )
        {
            aiString str;
            mat->GetTexture(type, i, &str);

            GLboolean skip = false;

            //Textur wurde bereits geladen => überspringen 
            for (GLuint j = 0; j < textures_loaded.size(); j++)
            {
                if (textures_loaded[j].path == str)
                {
                    textures.push_back(textures_loaded[j]);
                    skip = true;

                    break;
                }
            }

            //Texture wurde noch nicht geladen
            if (!skip)
            {
                Texture texture;
                texture.id = TextureFromFile(str.C_Str(), this->directory);
                texture.type = typeName;
                texture.path = str;
                textures.push_back(texture);

                this->textures_loaded.push_back(texture);
            }
        }
        return textures;
    }
};

GLint TextureFromFile(const char* path, string directory)
{
    string filename = string(path);
    filename = directory + '/' + filename;
    GLuint textureID;
    glGenTextures( 1, &textureID );
    int width, height;
    unsigned char* image = SOIL_load_image(filename.c_str(), &width, &height, 0, SOIL_LOAD_RGB);

    glBindTexture(GL_TEXTURE_2D, textureID);
    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
    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);

    SOIL_free_image_data(image);
    return textureID;
}

Это код, который я использую для настройки Me sh, составляющего мои Модели. Хотя я получаю предупреждение из этого файла, в котором говорится, что переменная «Texture :: id» не инициализируется, хотя она явно.

#pragma once

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>

#include "Shader.h"
#include <gl/glew.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <assimp/types.h>

using namespace std;

struct Vertex
{
    glm::vec3 Position;
    glm::vec3 Normal;
    glm::vec2 TexCoords;
};

struct Texture
{
    GLuint id;
    string type;
    aiString path;
};

class Mesh
{
public:
    vector<Vertex> vertices;
    vector<GLuint> indices;
    vector<Texture> textures;

    Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<Texture> textures)
    {
        this->vertices = vertices;
        this->indices = indices;
        this->textures = textures;

        this->SetupMesh();
    }

    void Draw(Shader shader)
    {
        GLuint diffuseNr = 1;
        GLuint specularNr = 1;

        for (GLuint i = 0; i < this->textures.size(); i++)
        {
            glActiveTexture(GL_TEXTURE + i);

            stringstream ss;
            string number;
            string name = this->textures[i].type;

            if ("texture_diffuse" == name)
            {
                ss << diffuseNr++;
            }
            else if ("texture_specular" == name)
            {
                ss << specularNr++;
            }

            number = ss.str();

            glUniform1i(glGetUniformLocation(shader.Program, (name + number).c_str()), i);
            glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
        }

        //Draw the Mesh
        glBindVertexArray(this->VAO);
        glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);
        glBindVertexArray(0);

        for ( GLuint i = 0; i < this-> textures.size(); i++)
        {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, 0);
        }
    }

private:
    GLuint VAO, VBO, EBO;

    void SetupMesh()
    {
        glGenVertexArrays( 1, &this->VAO);
        glGenBuffers( 1, &this->VBO);
        glGenBuffers(1, &this->EBO);

        glBindVertexArray(this->VAO);

        glBindBuffer(GL_ARRAY_BUFFER, this->VBO);
        glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &this->vertices[0], GL_STATIC_DRAW);

        glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, this->EBO );
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);

        //Vertex Positionen
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);

        //Vertex Normals
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof( Vertex, Normal));

        //Vertex Texture coordinates
        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof( Vertex,TexCoords ));

        glBindVertexArray(0);

    }
};

И это класс, который я использую для открытия и позже Заполните окно, вызвав его из моего главного окна. cpp

#include "MeinMesh.h"
#include "Shader.h"
#include "Model.h"

#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>

#include <iostream>

OpenWindow::OpenWindow(const std::string& title, unsigned int width, unsigned int height)
    :m_Title(title), m_Width(width), m_Height(height), m_Window(nullptr)
{
    /* GLFW initialisieren */
    if (!glfwInit())
        return;

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_COMPAT_PROFILE);

    /* Erschaffen des des Windows und Context */
    m_Window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);

    if (!m_Window)
    {
        glfwTerminate();
        return;
    }

    glfwMakeContextCurrent(m_Window);

    /* Initialiesieren der GLEW Lib*/
     glewExperimental = GL_TRUE;
     GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        /*Glew konnte nicht initialisiert werden*/
        fprintf(stderr, "error: %s\n", glewGetErrorString(err));
        std::cout << "GLEW konnte nicht gestartet werden";
    }

    //Viewport einrichten
    glViewport(0, 0, width, height);

    //Depth enable
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl;
    std::cout << glGetString(GL_VENDOR) << std::endl;

}


/* Getting Infos about the Window*/
std::string OpenWindow::GetTitle() const
{
    return m_Title;
}

unsigned int OpenWindow::GetWidth() const
{
    return m_Width;
}

unsigned int OpenWindow::GetHeight()const
{
    return m_Height;
}

// Drawing in the Window
void OpenWindow::Show()
{   //Setup Shader

    glm::mat4 projection;
    projection = glm::perspective(45.0f, (GLfloat)m_Width / (GLfloat)m_Height, 0.1f, 1000.0f);

    Shader myShader("core.vs", "core.frag");

    Model Castle("Burg und Rammbock.obj");
    Model ram("Rammbock.obj");

    bool close = false;
    while (!glfwWindowShouldClose(m_Window) )
    {
        //Render
        // Colourbuffer leeren
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


        myShader.StartShader();

        //Projection Matrix
        glm::mat4 model;
        glm::mat4 view;
        view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));

        GLint modelLoc = glGetUniformLocation(myShader.Program, "model");
        GLint viewLoc = glGetUniformLocation(myShader.Program, "view");
        GLint projectionLoc = glGetUniformLocation(myShader.Program, "projection");

        glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
        glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
        glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

        // Zeichnen der Modelle
        Castle.Draw(myShader);
        ram.Draw(myShader);

        //Screen Buffer wechseln
        glfwSwapBuffers(m_Window);

    }

    glfwTerminate();
}

Я добавил файлы для моделей в проект, и AssImp правильно скомпилирован. Я пытался использовать разные форматы файлов и UTF8 и UTF16, я исключил файлы .obj из сборки, но независимо от того, что я сделал, AssImp не может загрузить файлы.

...