我原本只是在我的游戏中为小行星(立方体)使用一组缓冲区的单一声明。它运作得很好。
我想创建一个缓冲区向量,以显示多个小行星。当我将缓冲区的声明更改为向量时,一切都崩溃了......
编译器没有抱怨,但在运行时我得到:
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
pszFunction包含:
std::vector<class Microsoft::WRL::ComPtr<struct ID3D11Buffer>,class std::allocator<class Microsoft::WRL::ComPtr<struct ID3D11Buffer> > >::operator []
答案 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”的第三个参数。
答案 2 :(得分:0)
调整大小而不是保留:
int asteroidCount = 3;
asteroidVertexBuffers.resize( asteroidCount );
asteroidIndexBuffers.resize( asteroidCount );
asteroidIndexCounts.resize( asteroidCount );