簡體   English   中英

嘗試在DirectX 11中加載Obj文件時,向量下標超出范圍

[英]Vector subscript out of range when trying to load Obj files in DirectX 11

當我嘗試加載沒有法線或紋理坐標的Obj文件時,我得到的矢量下標超出范圍。 如果我加載一個具有法線和紋理坐標的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]; ,我的程序會中斷,我會得到矢量下標超出范圍錯誤。 如果我從&m_vertices和&m_Indices中刪除[0],它將不會中斷,但不會渲染任何內容。

我只想知道如何讓我的obj加載器加載obj文件,它們不需要總是包含所有4個頂點,法線,紋理坐標和面。

一般來說

你無法通過猜測找出你的應用程序崩潰的原因。 你不需要。 作為程序員,我們有很好的工具來解決這些問題。 所以,一般建議: 學會使用你的調試器

具體問題

你的載體是空的。
當您嘗試訪問不存在的第一個元素( m_vertices[0]m_Indices[0] )時,會導致此斷言失敗 (因為您處於調試模式;在釋放模式下,它將靜默觸發未定義的行為)。

怎么檢查

當程序執行在這些行上中斷時,請選中“調用堆棧”窗口,以查看您的功能。 找到一個在堆棧中最高的函數並單擊它。 選中“Locals”,“Auto”或“Watch”窗口(菜單“Debug” - >“Windows”),查看向量內容和范圍內的其他變量。 如果需要,放置斷點並重啟應用程序。

怎么修

在程序的早期設置斷點,以查看向量為空的原因。 逐行移動,逐個功能,使用“Step into”和“Step over”,觀察變量,直到你會發現錯誤來源。

如果在那里有空向量是有效的,你可以創建分支以避免訪問它的內容的代碼路徑:

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

希望能幫助到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM