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.
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.