Assimp triangulation not working

2k views Asked by At

So I've been trying to use Assimp to load models, I want to render them using triangles. So far I've tried loading the test models that come with assimp and if I load an already triangulated model everything works fine. However whenever I try to make assimp triangulate everything it just breaks the mesh completely. Here's the output if I just render a mesh without any settings using triangles, obviously its broken.

https://i.stack.imgur.com/8ituT.png

And if I triangulate it and merge the vertices it ends up looking like this

https://i.stack.imgur.com/N7m9v.png

Finally, calculating bitangents just destroys the mesh completely

Here's the code, I've commented out some of the postprocess settings I've tried

#ifndef MESH_H
#define MESH_H

#include "assimp\scene.h"
#include "assimp\mesh.h"
#include <vector>
#include "main.h"
static enum BUFFER_TYPES
{
    VERTEX_BUFFER,
    TEXCOORD_BUFFER,
    NORMAL_BUFFER,
    INDEX_BUFFER,
    BITANGENT_BUFFER,
    TANGENT_BUFFER
};

//A mesh can have several entries, this struct is used to store them properly
struct Entry
{
    Entry(aiMesh *mesh);
    ~Entry();

    void load(aiMesh *mesh);
    void render();

    //Vertex Array Object
    unsigned int mVAO;
    //Vertex, Normal, Texture, Index Buffer, TODO: add support for more buffers
    unsigned int mVBOs[4];
    //The amount of vertices
    unsigned int mVerticesCount;
};
//The Mesh class
    class Mesh
{
public:
    Mesh(const char* fileName);
    ~Mesh();

    void render();

//All the meshes in the array
std::vector<Entry*> mEntries;

private:
};


#endif

and the .cpp file

#include "Mesh.h"
#include <assimp\Importer.hpp>
#include <assimp\postprocess.h>

Entry::Entry(aiMesh *mesh)
{

mVBOs[VERTEX_BUFFER] = NULL;
mVBOs[TEXCOORD_BUFFER] = NULL;
mVBOs[NORMAL_BUFFER] = NULL;
mVBOs[INDEX_BUFFER] = NULL;
mVBOs[BITANGENT_BUFFER] = NULL;
mVBOs[TANGENT_BUFFER] = NULL;
//Generate our vertex arrays
glGenVertexArrays(1, &mVAO);
//Bind our vertex arrays
glBindVertexArray(mVAO);

//Each face has 3 vertices
//mVerticesCount = mesh->mNumFaces * 3;
mVerticesCount = mesh->mNumVertices;

//Check whether the mesh has any positions 
if (mesh->HasPositions())
{
    float *vertices = new float[mesh->mNumVertices * 3];
    for (int i = 0; i < mesh->mNumVertices; ++i)
    {
        vertices[i * 3] = mesh->mVertices[i].x;
        vertices[i * 3 + 1] = mesh->mVertices[i].y;
        vertices[i * 3 + 2] = mesh->mVertices[i].z;
    }

    glGenBuffers(1, &mVBOs[VERTEX_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mVBOs[VERTEX_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(0);

    delete vertices;
}


if (mesh->HasTextureCoords(0))
{
    float *texCoords = new float[mesh->mNumVertices * 2];
    for (int i = 0; i < mesh->mNumVertices; ++i)
    {
        texCoords[i * 2] = mesh->mTextureCoords[0][i].x;
        texCoords[i * 2 + 1] = mesh->mTextureCoords[0][i].y;
    }

    glGenBuffers(1, &mVBOs[TEXCOORD_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mVBOs[TEXCOORD_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, 2 * mesh->mNumVertices * sizeof(GLfloat), texCoords, GL_STATIC_DRAW);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(1);

    delete texCoords;
}

if (mesh->HasNormals())
{
    float *normals = new float[mesh->mNumVertices * 3];
    for (int i = 0; i < mesh->mNumVertices; ++i)
    {
        normals[i * 3] = mesh->mNormals[i].x;
        normals[i * 3 + 1] = mesh->mNormals[i].y;
        normals[i * 3 + 2] = mesh->mNormals[i].z;
    }

    glGenBuffers(1, &mVBOs[NORMAL_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mVBOs[NORMAL_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), normals, GL_STATIC_DRAW);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(2);

    delete normals;
}

if (mesh->HasFaces())
{
    unsigned int *indices = new unsigned int[mesh->mNumFaces * 3];
    for (int i = 0; i < mesh->mNumFaces; ++i)
    {
    indices[i * 3] = mesh->mFaces[i].mIndices[0];
    indices[i * 3 + 1] = mesh->mFaces[i].mIndices[1];
    indices[i * 3 + 2] = mesh->mFaces[i].mIndices[2];
    }

    glGenBuffers(1, &mVBOs[INDEX_BUFFER]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mVBOs[INDEX_BUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3 * mesh->mNumFaces * sizeof(GLuint), indices, GL_STATIC_DRAW);

    glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(3);

    delete indices;
}

if (mesh->HasTangentsAndBitangents())
{
    float *bitangents = new float[mesh->mNumVertices * 3];
    for (int i = 0; i < mesh->mNumVertices; ++i)
    {
        bitangents[i * 3] = mesh->mBitangents[i].x;
        bitangents[i * 3 + 1] = mesh->mBitangents[i].y;
        bitangents[i * 3 + 2] = mesh->mBitangents[i].z;
    }

    glGenBuffers(1, &mVBOs[BITANGENT_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mVBOs[BITANGENT_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), bitangents, GL_STATIC_DRAW);

    glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(4);

    delete bitangents;

    float *tangents = new float[mesh->mNumVertices * 3];
    for (int i = 0; i < mesh->mNumVertices; ++i)
    {
        tangents[i * 3] = mesh->mTangents[i].x;
        tangents[i * 3 + 1] = mesh->mTangents[i].y;
        tangents[i * 3 + 2] = mesh->mTangents[i].z;
    }

    glGenBuffers(1, &mVBOs[TANGENT_BUFFER]);
    glBindBuffer(GL_ARRAY_BUFFER, mVBOs[TANGENT_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, 3 * mesh->mNumVertices * sizeof(GLfloat), tangents, GL_STATIC_DRAW);

    glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(5);

    delete tangents;
}


glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);


}
Entry::~Entry()
{
    if (mVBOs[VERTEX_BUFFER])
        glDeleteBuffers(1, &mVBOs[VERTEX_BUFFER]);
    if (mVBOs[TEXCOORD_BUFFER])
        glDeleteBuffers(1, &mVBOs[TEXCOORD_BUFFER]);
    if (mVBOs[NORMAL_BUFFER])
        glDeleteBuffers(1, &mVBOs[NORMAL_BUFFER]);
    if (mVBOs[INDEX_BUFFER])
    glDeleteBuffers(1, &mVBOs[INDEX_BUFFER]);
    if (mVBOs[BITANGENT_BUFFER])
        glDeleteBuffers(1, &mVBOs[BITANGENT_BUFFER]);
    if (mVBOs[TANGENT_BUFFER])
        glDeleteBuffers(1, &mVBOs[TANGENT_BUFFER]);

    glDeleteVertexArrays(1, &mVAO);
}
void Entry::render()
{
    /*glBindVertexArray(mVAO);
    glDrawElements(GL_TRIANGLES, mVerticesCount, GL_UNSIGNED_INT, NULL);
    glBindVertexArray(0);*/
    glBindVertexArray(mVAO);
    glDrawArrays(GL_TRIANGLES, 0, mVerticesCount);
    glBindVertexArray(0);
}
Mesh::Mesh(const char* fileName)
{
    Assimp::Importer importer;
    //const aiScene* scene = importer.ReadFile(fileName,aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices | aiProcess_SortByPType);
//const aiScene* scene = importer.ReadFile(fileName, aiProcessPreset_TargetRealtime_Quality);
const aiScene* scene = importer.ReadFile(fileName, aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_JoinIdenticalVertices);

//importer.ApplyPostProcessing()
/*ASSIMP_API const aiScene* aiApplyPostProcessing(const aiScene * pScene,
unsigned int pFlags);*/


//aiApplyPostProcessing


if (!scene)
    printf("There was an error loading mesh: %s\n", importer.GetErrorString());

for (int i = 0; i < scene->mNumMeshes; ++i)
    mEntries.push_back(new Entry(scene->mMeshes[i]));
}
    Mesh::~Mesh()
{
    for (int i = 0; i < mEntries.size(); ++i)
        delete mEntries.at(i);

    mEntries.clear();
}
void Mesh::render()
{
    for (int i = 0; i < mEntries.size(); ++i)
        mEntries.at(i)->render();
}
1

There are 1 answers

0
KimKulling On

You have to check our delete-ops by the way. For instance you creates indoces with new[] and deleted it with delete indices.