我使用C++为DirectX 11项目编写了一个网格加载程序,我决定使用assimp,因为我在学习OpenGL时获得了使用API的经验。该加载程序处理较小的网格没有问题,但当顶点数量达到一定阈值时,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).与original mesh相反。
一开始我试着:
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;
}
顶点缓冲区和索引缓冲区创建方法为:
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);
}
我也试过加载文件中的所有模型,并为每个模型创建单独的网格对象,然后绘制每个对象,但我仍然得到了相同的结果。任何帮助都将非常感谢。如果有任何更多的信息或代码片段需要,我总是很乐意提供。
1条答案
按热度按时间dxpyg8gm1#
我发现了问题,它在我的索引缓冲区类中
count变量是unsigned short,所以索引的数量被限制在65535(所谓的“剪切阈值”),将其改为unsigned int就解决了这个问题。