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\$
1
  • \$\begingroup\$ Sure @AlexandreVaillancourt! \$\endgroup\$ Jan 6, 2017 at 17:59

1 Answer 1

0
\$\begingroup\$

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

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .