我的矢量声明/循环/东西有问题,但我不确定它是什么

时间:2013-11-22 03:19:58

标签: c++ vector windows-phone-8 reference direct3d

我原本只是在我的游戏中为小行星(立方体)使用一组缓冲区的单一声明。它运作得很好。

我想创建一个缓冲区向量,以显示多个小行星。当我将缓冲区的声明更改为向量时,一切都崩溃了......

编译器没有抱怨,但在运行时我得到:

Unhandled exception at 0x71879C01 (Msvcr110d.dll) in Game.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

输出日志:

First-chance exception at 0x770D277C in Game.exe: Microsoft C++ exception: std::out_of_range at memory location 0x014A90CC.
The thread 0x8f4 has exited with code 0 (0x0).
First-chance exception at 0x770D277C in Game.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x770D277C in Game.exe: Microsoft C++ exception: std::out_of_range at memory location 0x014A9E10.
Unhandled exception at 0x712D9C01 (Msvcr110d.dll) in Game.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.

我已经宣布了我的缓冲区:

// Asteroid Buffers 
vector<Microsoft::WRL::ComPtr<ID3D11Buffer>> asteroidVertexBuffers;
vector<Microsoft::WRL::ComPtr<ID3D11Buffer>> asteroidIndexBuffers;
vector<uint32> asteroidIndexCounts;

我预留了三个缓冲区的插槽:

int asteroidCount = 3;

asteroidVertexBuffers.reserve( asteroidCount );
asteroidIndexBuffers.reserve( asteroidCount );
asteroidIndexCounts.reserve( asteroidCount );

我迭代并将缓冲区推入顶点:

    for( int a = 0; a < asteroidCount; a++ )
    {
        D3D11_SUBRESOURCE_DATA asteroidVertexBufferData = {0};
        asteroidVertexBufferData.pSysMem = asteroidVertices;
        asteroidVertexBufferData.SysMemPitch = 0;
        asteroidVertexBufferData.SysMemSlicePitch = 0;
        CD3D11_BUFFER_DESC asteroidVertexBufferDesc(sizeof(asteroidVertices), D3D11_BIND_VERTEX_BUFFER);
        DX::ThrowIfFailed(
            m_d3dDevice->CreateBuffer(
                &asteroidVertexBufferDesc,
                &asteroidVertexBufferData,
                &asteroidVertexBuffers.at( a )
                )
            );

        // Runtime Crash here

        asteroidIndexCounts.at( a ) = ARRAYSIZE(asteroidIndices);

        D3D11_SUBRESOURCE_DATA asteroidIndexBufferData = {0};
        asteroidIndexBufferData.pSysMem = asteroidIndices;
        asteroidIndexBufferData.SysMemPitch = 0;
        asteroidIndexBufferData.SysMemSlicePitch = 0;
        CD3D11_BUFFER_DESC asteroidIndexBufferDesc(sizeof(asteroidIndices), D3D11_BIND_INDEX_BUFFER);
        DX::ThrowIfFailed(
            m_d3dDevice->CreateBuffer(
                &asteroidIndexBufferDesc,
                &asteroidIndexBufferData,
                &asteroidIndexBuffers.at( a )
                )
            );
    }

可能有用的备注


更新:认为我发现了问题(以及重新分配的内存)

认为我发现了这个问题。我只是注意到第一个和第二个参数上的_IN是内存的引用,它意味着它也需要是一个内存向量...我会纠正它,看它是否有效。

更新::我错了或我做错了......

我为新类型添加了一些向量,然后将它们全部插入到我的代码中:

    int asteroidCount = 3;

    asteroidVertexBuffersData.reserve( asteroidCount );
    asteroidVertexBuffersDesc.reserve( asteroidCount );
    asteroidVertexBuffers.reserve( asteroidCount );
    asteroidIndexBuffers.reserve( asteroidCount );
    asteroidIndexCounts.reserve( asteroidCount );

    for( int a = 0; a < asteroidCount; a++ )
    {
        D3D11_SUBRESOURCE_DATA asteroidVertexBufferData = {0};
        asteroidVertexBuffersData.push_back( asteroidVertexBufferData );

        asteroidVertexBuffersData.at(a).pSysMem = asteroidVertices;
        asteroidVertexBuffersData.at(a).SysMemPitch = 0;
        asteroidVertexBuffersData.at(a).SysMemSlicePitch = 0;

        CD3D11_BUFFER_DESC asteroidVertexBufferDesc(sizeof(asteroidVertices), D3D11_BIND_VERTEX_BUFFER);
        asteroidVertexBuffersDesc.push_back( asteroidVertexBufferDesc );
        DX::ThrowIfFailed(
            m_d3dDevice->CreateBuffer(
                &asteroidVertexBuffersDesc.at(a),
                &asteroidVertexBuffersData.at(a),
                &asteroidVertexBuffers.at(a)
                )
            );

它抛出同样的错误:'(

更新::我走过了失败过程,发现了以下有趣的部分和bobs

enter image description here

pszFunction包含:

   std::vector<class Microsoft::WRL::ComPtr<struct ID3D11Buffer>,class std::allocator<class Microsoft::WRL::ComPtr<struct ID3D11Buffer> > >::operator []

3 个答案:

答案 0 :(得分:0)

在不知道您正在使用哪个Direct3D版本或如何创建设备的情况下,很难知道您哪里出错了。其他参数之一可能不正确并导致错误。

您不希望引用您想要其地址的向量中的项,因为第3个参数需要ID3D11Buffer**,它是指针的指针。

这是一个有效的小例子。如果您的使用情况不同,请编辑问题以包含一个像这样的小型自包含示例,以便我们能够看到足够的答案。

#include <Windows.h>
#include <d3d11.h>
#include <DirectXMath.h>
#include <iostream>
#include <vector>

using DirectX::XMFLOAT3;

#pragma comment(lib, "d3d11.lib")

int main()
{
    ID3D11Device* device = NULL;
    if(FAILED(D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &device, NULL, NULL)))
    {
        std::cerr << "Device creation Failed!\n";
        return 0;
    }

    struct SimpleVertexCombined
    {
        XMFLOAT3 Pos;
        XMFLOAT3 Col;
    };

    SimpleVertexCombined verticesCombo[] =
    {
        XMFLOAT3(0.0f, 0.5f, 0.5f),
        XMFLOAT3(0.0f, 0.0f, 0.5f),
        XMFLOAT3(0.5f, -0.5f, 0.5f),
        XMFLOAT3(0.5f, 0.0f, 0.0f),
        XMFLOAT3(-0.5f, -0.5f, 0.5f),
        XMFLOAT3(0.0f, 0.5f, 0.0f),
    };

    D3D11_BUFFER_DESC bufferDesc;
    bufferDesc.Usage = D3D11_USAGE_DEFAULT;
    bufferDesc.ByteWidth = sizeof(SimpleVertexCombined)* 3;
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.CPUAccessFlags = 0;
    bufferDesc.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA InitData;
    InitData.pSysMem = verticesCombo;
    InitData.SysMemPitch = 0;
    InitData.SysMemSlicePitch = 0;

    std::vector<ID3D11Buffer*> VertexBuffers(1);

    HRESULT hr = device->CreateBuffer(&bufferDesc, &InitData, &VertexBuffers[0]);
    if(SUCCEEDED(hr))
    {
        std::cout << "CreateBuffer Success! - Buffer = 0x" << VertexBuffers[0] << "\n";
    }
    else
    {
        std::cout << "CreateBuffer Failure!\n";
    }
    return 0;
}

答案 1 :(得分:0)

vector :: at()的返回值类型是REFERENCE本身。所以我认为你应该使用“asteroidVertexBuffers.at(a)”作为方法“CreateBuffer”的第三个参数。

请参阅:http://www.cplusplus.com/reference/vector/vector/at/

答案 2 :(得分:0)

调整大小而不是保留:

    int asteroidCount = 3;

    asteroidVertexBuffers.resize( asteroidCount );
    asteroidIndexBuffers.resize( asteroidCount );
    asteroidIndexCounts.resize( asteroidCount );