c++directxgame-developmentdirectx-11assimp

Mesh loaded with Assimp displaying partial amount of vertices?


I was writing a mesh loader for a DirectX 11 project using C++, and I decided to use assimp because of the experience I gained with the API while learning OpenGL. The loader has no issues dealing with smaller meshes, but when the amount of vertices a certain threshold, it completely breaks, displaying only a few vertices (it doesn't show the star on the Cerberus model and its even worse on higher detail meshes). as opposed to the original mesh.

At first I tried:

struct Vertex
{
    struct {
        float x, y, z;
    } position;
    struct {
        float x, y, z;
    } normal;
    struct
    {
        float u, v;
    } TexCoord;
    Vertex(float px, float py, float pz, float nx, float ny, float nz, float u, float v)
        : position{ px, py, pz },normal{nx, ny, nz}, TexCoord{u, v}
    {
    }
    Vertex(){}
};
class Mesh {
    public:
        Mesh(){}
        int Create(const char* filepath);
        inline VertexBuffer* GetVertexBuffer() { return &m_VertexBuffer; }
        inline IndexBuffer* GetIndexBuffer() { return &m_IndexBuffer; }
        inline void DestroyMesh() { m_VertexBuffer.ShutDown(); m_IndexBuffer.ShutDown(); };
    private:
        static BufferLayout layout[];
        std::vector<Vertex> m_vertices;
        std::vector<unsigned int> m_indices;
        VertexBuffer m_VertexBuffer;
        IndexBuffer m_IndexBuffer;
    };
}
int Mesh::Create(const char* filepath)
{
    Assimp::Importer imp;
    const aiScene* pScene = imp.ReadFile(filepath, aiProcess_Triangulate |aiProcess_JoinIdenticalVertices);
        
    const aiMesh* pmesh = pScene->mMeshes[0];
    m_vertices.reserve(pmeshes->mNumVertices);
    m_indices.reserve(pmeshes->mNumFaces * 3);  
    for (unsigned int j = 0; j < pmeshes->mNumVertices; j++)
    {
        m_vertices.push_back(Vertex(
            pmeshes->mVertices[j].x, pmeshes->mVertices[j].y, pmeshes->mVertices[j].z,
            pmeshes->mNormals[j].x, pmeshes->mNormals[j].y, pmeshes->mNormals[j].z,
            pmeshes->mTextureCoords[0][j].x, pmeshes->mTextureCoords[0][j].y
            ));
    }
    for (unsigned int i = 0; i < pmeshes->mNumFaces; i++)
    {
        const auto& face = pmeshes->mFaces[i];
        for (unsigned int j = 0; j < face.mNumIndices; j++)
            m_indices.push_back(face.mIndices[j]);
    }
    m_VertexBuffer.Create(m_vertices.data(), sizeof(Vertex) * pmeshes->mNumVertices, sizeof(Vertex));
    m_IndexBuffer.Create(m_indices.data(), sizeof(unsigned int) * pmeshes->mNumFaces * 3, sizeof(unsigned int));
    imp.FreeScene();
    return 0;
}

The Vertex and Index Buffer Creation methods were:

void VertexBuffer::Create(const void* vertices, unsigned int size, unsigned int stride)
{
    D3D11_BUFFER_DESC bd = {};
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    bd.ByteWidth = size;
    D3D11_SUBRESOURCE_DATA sd = {};
    sd.pSysMem = vertices;
    RendererBase::Getd3dDevice()->CreateBuffer(&bd, &sd, &pVertexBuffer);
}
IndexBuffer::Create(const void* indices, unsigned int size, unsigned int stride)
{
        count = size/stride;
    D3D11_BUFFER_DESC bd = {};
    bd.Usage = D3D11_USAGE_DEFAULT;
    bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
    bd.CPUAccessFlags = 0;
    bd.MiscFlags = 0;
    bd.ByteWidth = size;
    D3D11_SUBRESOURCE_DATA sd = {};
    sd.pSysMem = indices;
    RendererBase::Getd3dDevice()->CreateBuffer(&bd, &sd, &pIndexBuffer);
}

I also tried loading all models in the file and creating separate mesh objects for each, then drawing each one, but I still got the same results. any help will be very much appreciated. If there is any more information or code snippets needed, I'm always happy to provide.


Solution

  • I found out the issue, it was in my index buffer class

    class IndexBuffer
    {
    public:
        IndexBuffer();
        void ShutDown();
        void Bind();
        void UnBind();
        static IndexBuffer* Create(const void* indices, unsigned int size, unsigned int stride);
        void Create(const void* indices, unsigned int size, unsigned int stride);
        inline unsigned int GetCount() { return count; }
    private:
        unsigned short count;
        ID3D11Buffer* pIndexBuffer = NULL;
    };
    

    The count variable was an unsigned short, so the amount of indices drawn was limited to 65535 (the so-called "clipping threshold"). Changing this to an unsigned int solved the problem.