2015-11-23 115 views
1

我有一个函数,基本上创建不同的实例缓冲区到一个数组中,供我在我的DrawIndexedInstanced调用中使用。DX11丢失实例缓冲区数据

但是,当我将顶点缓冲区和实例缓冲区传递给着色器时,当着色器使用它时,我的实例数据完全丢失,因此我的对象都没有被重新定位,因此都在同一个地方渲染。

我一直在寻找这个小时,并且从字面上找不到任何有用的东西。

创建顶点着色器输入布局:

D3D11_INPUT_ELEMENT_DESC solidColorLayout[] = 
{ 
    //Vertex Buffer 
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 
    { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, 

    //Instance buffer 
    { "INSTANCEPOS", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 0, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, 
    { "INSTANCEROT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 12, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, 
    { "INSTANCESCA", 0, DXGI_FORMAT_R32G32B32_FLOAT, 1, 24, D3D11_INPUT_PER_INSTANCE_DATA, 1 }, 
    { "INSTANCETEX", 0, DXGI_FORMAT_R32_FLOAT, 1, 36, D3D11_INPUT_PER_INSTANCE_DATA, 1 } 
}; 

创建实例缓冲液(称为每帧多次,以创建所有必需的缓冲液):

void GameManager::CreateInstanceBuffer(ID3D11Buffer** buffer, Mesh* mesh, std::vector<Instance> instances) 
{ 

    D3D11_BUFFER_DESC instBuffDesc; 
    ZeroMemory(&instBuffDesc, sizeof(instBuffDesc)); 

    instBuffDesc.Usage = D3D11_USAGE_DEFAULT; 
    instBuffDesc.ByteWidth = sizeof(Instance) * instances.size(); 
    instBuffDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
    instBuffDesc.CPUAccessFlags = 0; 
    instBuffDesc.MiscFlags = 0; 
    instBuffDesc.StructureByteStride = 0; 

    int i = sizeof(Instance); 

    D3D11_SUBRESOURCE_DATA instData; 
    ZeroMemory(&instData, sizeof(instData)); 

    instData.pSysMem = &instances; 
    instData.SysMemPitch = 0; 
    instData.SysMemSlicePitch = 0; 

    CheckFailWithError(dxManager.GetDevice()->CreateBuffer(&instBuffDesc, &instData, buffer), 
     "An error occurred whilst building an instance buffer", 
     "[GameManager]"); 


    meshBuffers.push_back(mesh->GetBuffer(VERTEX_BUFFER)); 
} 

的绘图命令:

dxManager.GetContext()->DrawIndexedInstanced(instanceIndexCounts[buffer], instanceCounts[buffer], 0, 0, 0); 

着色器:

cbuffer cbChangesEveryFrame : register(b0) 
{ 
    matrix worldMatrix; 
}; 
cbuffer cbNeverChanges : register(b1) 
{ 
    matrix viewMatrix; 
}; 
cbuffer cbChangeOnResize : register(b2) 
{ 
    matrix projMatrix; 
}; 

struct VS_Input 
{ 
    float4 pos : POSITION; 
    float2 tex0 : TEXCOORD0; 

    float4 instancePos : INSTANCEPOS; 
    float4 instanceRot : INSTANCEROT; 
    float4 instanceSca : INSTANCESCA; 
    float instanceTex : INSTANCETEX; 
}; 

PS_Input VS_Main(VS_Input vertex) 
{ 
    PS_Input vsOut = (PS_Input)0; 
    vsOut.pos = mul(vertex.pos + vertex.instancePos, worldMatrix); 
    vsOut.pos = mul(vsOut.pos, viewMatrix); 
    vsOut.pos = mul(vsOut.pos, projMatrix); 
    vsOut.tex0 = vertex.tex0; 
    return vsOut; 
} 

我已经使用Visual Studio内置的图形调试器。最初它似乎是将顶点着色器中的变量重新分配给前端,但是从AlignedByteOffset中删除APPEND_ALIGNED_ELEMENT已修复该问题,但每个实例数据似乎已损坏且未收到。

如果还有其他东西需要告诉我,我会根据需要更新帖子。

回答

3

问题在于你的subresource数据。

instData.pSysMem = &instances; 

您没有指定从哪个偏移量读取内存。尝试使用

instData.pSysMem = &instances[0]; 

instData.pSysMem = &instances.at(0); 

这明确从何处开始读取内存,并希望解决您的问题。

+1

3个角色...你告诉我我已经花了2个夜晚来狩猎这个问题,还有3个角色?!非常感谢!它工作完美,有点合理。 –

+0

**指针...必须爱它们!**指向矢量的指针与指向该矢量中数据的指针不同。这就像指向一个拿东西的东西,而不是直接指向某件东西。他们两个完全不同的东西。 – CodeAngry

+0

这不像'void *'那么多。由于任何指针都可以隐式转换为指向'void'的指针,因此类型系统无法帮助您在这里出错。正是出于这个原因,我通常在'void'指针的周围放置了一个最小类型安全的C++包装器。 – legalize