0
\$\begingroup\$

I've followed a tutorial about using Assimp to load models, but the loaded models are incorrectly drawn:

These should be a spheres enter image description here

I've checked my code multiple times but I can't seem to find what I did wrong could someone help me with this problem?

Code: https://github.com/DaanSander/Polygon-Engine/tree/master/Engine/src/geometry

Mesh.h

#pragma once

#include <string>
#include <vector>
#include <sstream>
#include <GL\glew.h>
#include <assimp\scene.h>
#include "../math/Math.h"
#include "../graphics/Shader.h"

namespace engine { namespace geometry {

struct Vertex {
    math::Vector3f position, normal;
    math::Vector2f uvCoord;
};

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

class Mesh {

    GLuint VAO, VBO, EBO;

public:
    std::vector<Vertex*> vertices;
    std::vector<GLuint>  indices;
    std::vector<Texture> textures;

    Mesh(std::vector<Vertex*> vertices, std::vector<GLuint> indices, std::vector<Texture> textures);

    ~Mesh();

    void setupMesh();

    void setupTextures(graphics::Shader* shader);

    GLsizei getVertexCount() { return vertices.size(); };

    inline GLuint getVaoID() { return VAO; }

    inline GLuint getEboID() { return EBO; }
};

}}

Mesh.cpp

#include "Mesh.h"

namespace engine { namespace geometry {

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

        setupMesh();
    }

    Mesh::~Mesh() {
        glDeleteBuffers(1, &VBO);
        glDeleteBuffers(1, &EBO);
        glDeleteVertexArrays(1, &VAO);
    }

    void Mesh::setupMesh() {
        glGenVertexArrays(1, &VAO);
        glGenBuffers(1, &VBO);
        glGenBuffers(1, &EBO);

        glBindVertexArray(VAO);

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

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

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

        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, normal));

        glEnableVertexAttribArray(2);
        glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, uvCoord));

        glBindVertexArray(0);
    }

    void Mesh::setupTextures(graphics::Shader* shader) {
        using namespace std;
        using namespace graphics;
        GLuint diffuseTexureNr = 1;
        GLuint specularTextureNr = 1;
        for (GLuint i = 0; i < textures.size(); i++) {
            glActiveTexture(GL_TEXTURE0 + i);

            stringstream ss;
            string number;
            string name = this->textures[i].type;
            if (name == "texture_diffuse")
                ss << diffuseTexureNr++;
            else if (name == "texture_specular")
                ss << specularTextureNr;

            number = ss.str();

            glUniform1f(shader->getUniformLocation((char*) ("material." + name + number).c_str()), i);
            glBindTexture(GL_TEXTURE_2D, this->textures[i].id);
        }

        glActiveTexture(GL_TEXTURE0);
    }
}}

Model.h

#pragma once

#include <string>
#include <vector>
#include <assimp\Importer.hpp>
#include <assimp\scene.h>
#include <assimp\postprocess.h>

#include "Mesh.h"
#include "..\graphics\Texture.h"

namespace engine { namespace geometry {

class Model {

    std::vector<Mesh> meshes;
    std::string directory;

public:
    Model(GLchar* path);

    inline std::vector<Mesh> getMeshes() { return meshes; }
private:
    void loadModel(std::string path);

    void processNode(aiNode* node, const aiScene* scene);

    Mesh processMesh(aiMesh* mesh, const aiScene* scene);

    std::vector<Texture> loadMaterialTexture(aiMaterial* material, aiTextureType type, std::string typeName);
};


}}

Model.cpp

#include "Model.h"

namespace engine {
namespace geometry {

    Model::Model(GLchar* path) {
        this->loadModel(path);
    }

    void Model::loadModel(std::string path) {
        Assimp::Importer importer;
        const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);

        if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            std::cout << "An error ocurred while loading model at path: " << path << " log: " << importer.GetErrorString() << std::endl;
            return;
        }
        this->directory = path.substr(0, path.find_last_of("/"));

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

    void Model::processNode(aiNode* node, const aiScene* scene) {
        for (int i = 0; i < node->mNumMeshes; i++) {
            aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];
            if (mesh == nullptr) {
                std::cout << "MESH IS NULL" << std::endl;
                system("pause");
            }
            Mesh gMesh = this->processMesh(mesh, scene);
            meshes.push_back(gMesh);
        }

        for (int i = 0; i < node->mNumChildren; i++) {
            if (node->mChildren[i] == nullptr) {
                std::cout << "NODE IS NULL" << std::endl;
                system("pause");
            }
            processNode(node->mChildren[i], scene);
        }
    }

    Mesh Model::processMesh(aiMesh* mesh, const aiScene* scene) {
        using namespace math;
        using namespace std;
        vector<Vertex*> vertices;
        vector<GLuint> indices;
        vector<Texture> textures;

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

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

            vertex.position = vector;

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

            vertex.normal = normal;

            if (mesh->mTextureCoords[0]) {
                Vector2f uvCoord;
                uvCoord.x = mesh->mTextureCoords[0][i].x;
                uvCoord.y = mesh->mTextureCoords[0][i].y;

                vertex.uvCoord = uvCoord;
            } else
                vertex.uvCoord = Vector2f();

            vertices.push_back(&vertex);
        }

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

            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->loadMaterialTexture(material, aiTextureType_DIFFUSE, "texture_diffuse");
            textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());

            vector<Texture> specularMaps = this->loadMaterialTexture(material, aiTextureType_SPECULAR, "texture_specular");
            textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
        }

        return Mesh(vertices, indices, textures);
    }

    std::vector<Texture> Model::loadMaterialTexture(aiMaterial* material, aiTextureType type, std::string typeName) {
        using namespace std;
        vector<Texture> textures;

        for (GLuint i = 0; i < material->GetTextureCount(type); i++) {
            Texture texture;

            aiString str;
            material->GetTexture(type, i, &str);

            graphics::Texture* gTexture = new graphics::Texture(str.C_Str());

            texture.id = gTexture->getTextureID();
            texture.type = typeName;
            texture.path = str;
            textures.push_back(texture);
        }
        return textures;
    }
}}
\$\endgroup\$
  • \$\begingroup\$ Sure @AlexandreVaillancourt! \$\endgroup\$ – Daan Meijer Jan 6 '17 at 17:59
0
\$\begingroup\$

The problem was that I was passing vertices by reference and at the end of the scope it would be deleted.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.