我正在尝试从几何着色器中流式传输数据,以用作顶点缓冲区以输入到另一个着色器中。但是,这似乎不起作用,并且调试层什么也没告诉我。缓冲区说明有问题吗?
这是我创建输出缓冲区的方法:
D3D11_BUFFER_DESC outputBufferDesc;
ZeroMemory(&outputBufferDesc, sizeof(outputBufferDesc));
outputBufferDesc.ByteWidth = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
outputBufferDesc.Usage = D3D11_USAGE_DEFAULT;
outputBufferDesc.BindFlags = D3D11_BIND_STREAM_OUTPUT;
outputBufferDesc.CPUAccessFlags = 0;
outputBufferDesc.MiscFlags = 0;
outputBufferDesc.StructureByteStride = 0;
result = renderer->CreateBuffer(&outputBufferDesc, NULL, &outputBuffer);
if (result != S_OK)
{
MessageBox(NULL, filename, L"Failed to create stream output buffer", MB_OK);
exit(0);
}
UINT offset[1] = { 0 };
deviceContext->SOSetTargets(1, &outputBuffer, offset);
绘制调用第一个着色器:
deviceContext->VSSetShader(vertexShader, NULL, 0);
deviceContext->PSSetShader(pixelShader, NULL, 0);
deviceContext->GSSetShader(streamOutputGeometryShader, NULL, 0);
// Render the triangle.
deviceContext->DrawIndexed(indexCount, 0, 0);
UINT offset[1] = { 0 };
ID3D11Buffer* pNullBuffer = 0;
deviceContext->SOSetTargets(1, &pNullBuffer, offset);
然后将信息从该缓冲区复制到第二个缓冲区:
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.ByteWidth = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
vertexBufferDesc.StructureByteStride = 0;
result = renderer->CreateBuffer(&vertexBufferDesc, NULL, &vertexBuffer);
if (result != S_OK)
{
MessageBox(NULL, L"Failed to create output mesh vertex buffer", L"Failed", MB_OK);
exit(0);
}
deviceContext->CopyResource(vertexBuffer, buffer);
并在此处使用顶点缓冲区为网格设置输入拓扑:
unsigned int stride;
unsigned int offset;
// Set vertex buffer stride and offset.
stride = sizeof(XMFLOAT4) + 2 * sizeof(XMFLOAT3);
offset = 0;
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
最后,第二个着色器的绘制调用很简单:
deviceContext->DrawAuto();
编辑:在几何着色器中正确计算了几何,但未将其流出。我在下面包含了几何着色器创建代码:
D3D11_SO_DECLARATION_ENTRY SODeclarationEntry[3] =
{
{ 0, "SV_POSITION", 0, 0, 4, 0 },
{ 0, "NORMAL", 0, 0, 3, 0 },
{ 0, "TEXCOORD", 0, 0, 3, 0 }
};
// Create the geometry shader from the buffer.
result = renderer->CreateGeometryShaderWithStreamOutput(geometryShaderBuffer->GetBufferPointer(), geometryShaderBuffer->GetBufferSize(), SODeclarationEntry, _countof(SODeclarationEntry),
NULL, 0, D3D11_SO_NO_RASTERIZED_STREAM, NULL, &streamOutputGeometryShader);
除了实际的顶点数据外,用作流输出阶段目标的缓冲区还保持一些内部状态,以跟踪写入了多少几何图形。DrawAuto()
依靠此信息可以知道要绘制多少几何图形。当仅将顶点数据从流输出缓冲区复制到平原时D3D11_BIND_VERTEX_BUFFER
,此信息将丢失。
文档中的相关报价:
DrawAuto仅在绘图时将一个输入缓冲区绑定为插槽0的IA阶段的输入来工作。应用程序必须使用两个绑定标志D3D11_BIND_VERTEX_BUFFER和D3D11_BIND_STREAM_OUTPUT创建SO缓冲区资源。
我不确定是否应该将数据从一个流输出缓冲区复制到另一个并DrawAuto()
从那里复制。我想这可能有用。但是,根据文档,当前您绝对不能执行任何操作。理想情况下,您只需避免复制数据。如果您确实必须复制数据(无论出于何种原因),我还是建议您首先尝试直接从流式传输的缓冲区中进行绘制,以确保其他所有设置均正确无误,并且只有在可行的情况下,才尝试将其复制到另一个具有两个缓冲区的缓冲区中顶点和流输出绑定标志设置…
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句