gpt4 book ai didi

c++ - 尝试在 DirectX 11 中加载 Obj 文件时 vector 下标超出范围

转载 作者:行者123 更新时间:2023-11-28 02:54:50 28 4
gpt4 key购买 nike

当我尝试加载没有法线或纹理坐标的 Obj 文件时,我得到一个超出范围的 vector 下标。如果我加载一个包含法线和纹理坐标的 obj 文件,那么一切正常。所以我只是问如何修改我的代码以加载没有法线和纹理坐标的 obj 文件。

这是我存储 VERTEX 数据的结构

struct VERTEX
{
XMFLOAT3 position;
XMFLOAT3 normal;
XMFLOAT2 texcoord;
};

这些顶点用于存储数据

std::vector<XMFLOAT3> m_position;
std::vector<XMFLOAT2> m_texCoords;
std::vector<XMFLOAT3> m_normals;
std::vector<VERTEX> m_vertices;
std::vector<DWORD> m_Indices;
VERTEX vertex;

这就是我阅读面部线条的方式。这一切都很好,但我不确定这是否是我的程序在没有法线和纹理坐标的情况下加载 obj 文件时中断的原因。

        else if (strcmp(buffer, "f") == 0)
{
int fPosition, fTexCoord, fNormal; //data of a single vertex

for (int iFace = 0; iFace < 3; iFace++)
{
ZeroMemory(&vertex, sizeof(VERTEX));
file >> fPosition;
vertex.position = m_position[fPosition - 1];

if (file.peek() == '/')
{
file.ignore();

if (file.peek() != '/')
{
file >> fTexCoord;
vertex.texcoord = m_texCoords[fTexCoord - 1];
}

if (file.peek() == '/')
{
file.ignore();
file >> fNormal;
vertex.normal = m_normals[fNormal -1];
}

m_vertices.push_back(vertex);
m_Indices.push_back(m_vertices.size() - 1);

}
}
}

最后这就是我设置顶点缓冲区的方式

D3D11_INPUT_ELEMENT_DESC vertlayout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 36, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

ID3D11Device* pDevice = m_shader->GetDevice();
ID3DBlob* pVSBlob = m_shader->GetVSBlob();

pDevice->CreateInputLayout(vertlayout, ARRAYSIZE(vertlayout), pVSBlob->GetBufferPointer(),
pVSBlob->GetBufferSize(), &m_vertexLayout);

D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(VERTEX)* m_vertices.size();
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;

D3D11_SUBRESOURCE_DATA initData;
ZeroMemory(&initData, sizeof(initData));
initData.pSysMem = &m_vertices[0]; //This is where it breaks

pDevice->CreateBuffer(&bd, &initData, &m_vertexBuffer);

bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(DWORD)* m_Indices.size();
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
initData.pSysMem = &m_Indices[0]; //and it breaks here too

pDevice->CreateBuffer(&bd, &initData, &m_indexBuffer);

正如评论所说,在 initData.pSysMem = &m_vertices[0];initData.pSysMem = &m_Indices[0]; 的行中,我的程序将中断我会得到 vector 下标超出范围的错误。如果我从 &m_vertices 和 &m_Indices 中删除 [0],它不会中断,但不会呈现任何内容。

我只想知道如何让我的 obj 加载器加载不需要始终具有所有 4 个顶点、法线、纹理坐标和面的 obj 文件。

最佳答案

一般情况

您无法仅通过猜测找出您的应用程序崩溃的原因。而你不需要。作为程序员,我们有很好的工具来解决这些问题。因此,一般建议:学习使用调试器

具体问题

你的载体是空的。
当您尝试访问不存在的第一个元素(m_vertices[0]m_Indices[0])时,您会得到这个断言失败(因为您处于 Debug模式;在 Release模式下它将静默触发未定义的行为)。

如何检查

当程序执行在这些行上中断时,检查“调用堆栈”窗口,看看您在哪个函数中。找到你的一个函数,它在堆栈中最高,然后单击它。检查“Locals”、“Auto”或“Watch”窗口(菜单“Debug”->“Windows”)以查看范围内的 vector 和其他变量的内容。放置断点并在需要时重启应用。

如何修复

在程序的前面设置断点,看看为什么你的 vector 是空的。逐行移动,逐个函数,使用“Step into”和“Step over”,观察变量,直到找到错误源。

如果那里有空 vector 是有效的,您可以创建分支以避免访问其内容的代码路径:

if(!m_vertices.empty())
{
// Create buffers with data
}
else
{
// Create empty buffers or report an error
}`

希望对您有所帮助。

关于c++ - 尝试在 DirectX 11 中加载 Obj 文件时 vector 下标超出范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22254544/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com