【发布时间】:2019-06-26 08:34:06
【问题描述】:
我正在尝试使用SpriteFont 和SpriteBatch 在我的DX11 项目中呈现文本。
在添加代码之前一切正常,但是当未注释代码时,我收到以下错误并且没有任何渲染。
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. Semantic 'TEXCOORD' is defined for mismatched hardware registers between the output stage and input stage. [ EXECUTION ERROR #343: DEVICE_SHADER_LINKAGE_REGISTERINDEX]
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. The input stage requires Semantic/Index (POSITION,0) as input, but it is not provided by the output stage. [ EXECUTION ERROR #342: DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND]
D3D11 ERROR: ID3D11DeviceContext::DrawIndexed: Input Assembler - Vertex Shader linkage error: Signatures between stages are incompatible. The input stage requires Semantic/Index (NORMAL,0) as input, but it is not provided by the output stage. [ EXECUTION ERROR #342: DEVICE_SHADER_LINKAGE_SEMANTICNAME_NOT_FOUND]
我已尝试更改 DeviceContext & Device,但仍然出现同样的错误。
//Draw Text
g_spriteBatch = std::make_unique<SpriteBatch>(g_pImmediateContext);
g_spriteFont = std::make_unique<SpriteFont>(g_pd3dDevice1, L"Data\\game_font.spritefont");
//Render Text
g_spriteBatch->Begin();
//g_spriteFont->DrawString(g_spriteBatch.get(), L"Score: 0", XMFLOAT2(0,0), DirectX::Colors::White);
g_spriteBatch->End();
我尝试过使用不同的设备和 DeviceContext,但仍然是同样的错误。
我一直在尝试许多不同的方法来让它发挥作用。 这就是我的渲染函数目前的样子
更新日期:2019 年 2 月 18 日
void Render() {
float backgroundColour[] = { 0.0f, 0.1f, 0.5f, 0.0f };
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, backgroundColour);
g_pImmediateContext->ClearDepthStencilView(g_depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
g_pImmediateContext->IASetInputLayout(g_pVertexLayout);
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY::D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
g_pImmediateContext->RSSetState(g_rasterState);
g_pImmediateContext->OMSetDepthStencilState(g_depthStencilState, 0);
g_pImmediateContext->VSSetShader(g_pVertexShader, NULL, 0);
g_pImmediateContext->PSSetShader(g_pPixelShader, NULL, 0);
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBuffer, &stride, &offset);
g_pImmediateContext->Draw(3, 0);
//g_pImmediateContext->DrawIndexed(36, 0, 0);
//Draw Text
spriteBatch->Begin();
spriteFont->DrawString(spriteBatch.get(), L"Test", DirectX::XMFLOAT2(0, 0), DirectX::Colors::White);
spriteBatch->End();
//Present our back buffer to the front buffer
g_pSwapChain->Present(0, NULL);
}
运行项目时出现以下错误
D3D11 ERROR: ID3D11DeviceContext::IASetVertexBuffers: A Buffer trying to be bound to slot 0 did not have the appropriate bind flag set at creation time to allow the Buffer to be bound as a VertexBuffer. [ STATE_SETTING ERROR #238: IASETVERTEXBUFFERS_INVALIDBUFFER]
这是存储 tri 数据并设置索引/顶点缓冲区的代码
SimpleVertex vertices[] =
{
SimpleVertex(-0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f),
SimpleVertex( 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 0.0f),
SimpleVertex( 0.5f, -0.5f, 1.0f, 1.0f, 0.0f, 0.0f),
};
D3D11_BUFFER_DESC bd = {};
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * ARRAYSIZE(vertices);
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
bd.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if (FAILED(hr))
{
printf("Failed ro Create Vertex Buffer.");
return hr;
}
我已将D3D11_BIND_INDEX_BUFFER 更改为D3D11_BIND_VERTEX_BUFFER 并发生同样的错误。
在此之后,也会产生以下警告。
D3D11 WARNING: ID3D11DeviceContext::Draw: Vertex Buffer at the input vertex slot 0 is not big enough for what the Draw*() call expects to traverse. This is OK, as reading off the end of the Buffer is defined to return 0. However the developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #356: DEVICE_DRAW_VERTEX_BUFFER_TOO_SMALL]
D3D11 WARNING: ID3D11DeviceContext::Draw: The size of the Constant Buffer at slot 0 of the Vertex Shader unit is too small (64 bytes provided, 192 bytes, at least, expected). This is OK, as out-of-bounds reads are defined to return 0. It is also possible the developer knows the missing data will not be used anyway. This is only a problem if the developer actually intended to bind a sufficiently large Constant Buffer for what the shader expects. [ EXECUTION WARNING #351: DEVICE_DRAW_CONSTANT_BUFFER_TOO_SMALL]
D3D11 WARNING: ID3D11DeviceContext::Draw: Input vertex slot 0 has stride 24 which is less than the minimum stride logically expected from the current Input Layout (32 bytes). This is OK, as hardware is perfectly capable of reading overlapping data. However the developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #355: DEVICE_DRAW_VERTEX_BUFFER_STRIDE_TOO_SMALL]
【问题讨论】:
-
问题似乎是在绘制立方体时发生错误。
spriteBatch函数似乎导致着色器链接器错误。g_pImmediateContext->DrawIndexed(36, 0, 0);此行出现错误。 -
在绘制立方体时,是否设置了所有需要的状态?您可能缺少匹配立方体所需的输入布局或顶点着色器。
-
在渲染中没有精灵绘制函数的情况下,立方体可以很好地绘制:
spriteBatch->Begin(); spriteFont->DrawString(spriteBatch.get(), L"TEXT PLACEHOLDER", XMFLOAT2(1.0f, 1.0f)); spriteBatch->End();这会删除设置/状态,因此需要再次设置输入布局和顶点缓冲区。我也将一些状态转移到了渲染函数中。虽然这有效,但 FPS 似乎下降了。在场景中有两个立方体时,深度缓冲区似乎停止工作,其中立方体 2 似乎总是与立方体 1 重叠。 -
是的,你需要在绘制之前设置所有需要的状态。上面文档的链接列出了
SpriteBatch更改的所有状态,其中包括任何绘图都需要的输入布局和顶点着色器。一般来说,您不应该假设设置了任何状态,并且在帧的开头设置了渲染目标和视口/剪刀。然后在每次绘制调用之前,您可以更改所需的任何状态。旧版ID3DXFont所做的“捕获和恢复”状态非常缓慢。