问题描述
我正在学习 Direct X 并尝试在屏幕上绘制一个基本的三角形。我有一个简单的顶点着色器和像素着色器。
顶点着色器:
float4 main( float2 pos : POSITION) : SV_Position
{
return float4(pos.x,pos.y,0.0f,1.0f);
}
像素着色器:
float4 main() : SV_Target
{
return float4(1.0f,1.0f,1.0f);
}
Error: ID3D11DeviceContext::Draw: 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.
我的渲染代码:
void renderer_draw_triangle()
{
struct vertex
{
float x;
float y;
};
const struct vertex vertices[] =
{
{0.0f,0.5f},{0.5f,-0.5f},{-0.5f,};
const UINT stride = sizeof(struct vertex);
const UINT offset = 0u;
ID3D11Buffer *vertex_buffer;
D3D11_BUFFER_DESC bd = {
.BindFlags = D3D11_BIND_VERTEX_BUFFER,.Usage = D3D11_USAGE_IMMUTABLE,.cpuAccessFlags = 0u,.MiscFlags = 0u,.ByteWidth = sizeof(vertices),.StructureByteStride = stride};
D3D11_SUBRESOURCE_DATA sd = {.pSysMem = vertices};
CHECK_ERROR(device->lpVtbl->CreateBuffer(device,&bd,&sd,&vertex_buffer));
context->lpVtbl->IASetVertexBuffers(context,0u,1u,&vertex_buffer,&stride,&offset);
ID3D11VertexShader *vertexShader;
ID3DBlob *blob;
CHECK_DX_ERROR(D3DReadFiletoBlob(L"../Engine/build/shaders/VertexShader.cso",&blob));
CHECK_DX_ERROR(device->lpVtbl->CreateVertexShader(device,blob->lpVtbl->GetBufferPointer(blob),blob->lpVtbl->GetBufferSize(blob),NULL,&vertexShader));
context->lpVtbl->VSSetShader(context,vertexShader,0u);
ID3D11PixelShader *pixelShader;
CHECK_DX_ERROR(D3DReadFiletoBlob(L"../Engine/build/shaders/PixelShader.cso",&blob));
CHECK_DX_ERROR(device->lpVtbl->CreatePixelShader(device,&pixelShader));
context->lpVtbl->PSSetShader(context,pixelShader,0u);
ID3D11InputLayout *input_layout;
const D3D11_INPUT_ELEMENT_DESC inputs[] =
{
{"POSITION",dxgi_FORMAT_R32G32_FLOAT,D3D11_INPUT_PER_VERTEX_DATA,0},};
CHECK_DX_ERROR(device->lpVtbl->CreateInputLayout(device,inputs,ASIZE(inputs),&input_layout));
CHECK_DX_ERROR(context->lpVtbl->IASetInputLayout(context,input_layout));
context->lpVtbl->OMSetrendertargets(context,&target,NULL);
context->lpVtbl->IASetPrimitivetopology(context,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D11_VIEWPORT vp = {.Width = 800,.Height = 600,.MinDepth = 0,.MaxDepth = 1,.TopLeftX = 0,.TopLeftY = 0};
context->lpVtbl->RSSetViewports(context,&vp);
CHECK_DX_ERROR(context->lpVtbl->Draw(context,ASIZE(vertices),0u));
}
它说它在输入层中找不到语义,但我已经重读了一百万次代码,但无法弄清楚出了什么问题。语义显然在输入元素描述数组中。我很确定输入层已正确绑定。任何人都可以提供任何帮助吗?
解决方法
POSITION
是旧版 Direct3D 9 名称,SV_Position
是 Direct3D 10+ 语义。欢迎您使用任一,但您必须保持一致。
IOW:如果您在着色器中使用 SV_Position
(这是首选),那么您需要在 SV_Position
输入布局结构中使用 D3D11_INPUT_ELEMENT_DESC
。
事实证明我必须在顶点着色器之前创建像素着色器。我不确定为什么,但它有效。
void renderer_draw_triangle()
{
struct vertex
{
float x;
float y;
};
const struct vertex vertices[] =
{
{0.0f,0.5f},{0.5f,-0.5f},{-0.5f,};
const UINT stride = sizeof(struct vertex);
const UINT offset = 0u;
ID3D11Buffer *vertex_buffer;
D3D11_BUFFER_DESC bd = {
.BindFlags = D3D11_BIND_VERTEX_BUFFER,.Usage = D3D11_USAGE_IMMUTABLE,.CPUAccessFlags = 0u,.MiscFlags = 0u,.ByteWidth = sizeof(vertices),.StructureByteStride = stride};
D3D11_SUBRESOURCE_DATA sd = {.pSysMem = vertices};
CHECK_ERROR(device->lpVtbl->CreateBuffer(device,&bd,&sd,&vertex_buffer));
context->lpVtbl->IASetVertexBuffers(context,0u,1u,&vertex_buffer,&stride,&offset);
ID3DBlob *blob;
ID3D11PixelShader *pixelShader;
CHECK_DX_ERROR(D3DReadFileToBlob(L"../Engine/build/shaders/PixelShader.cso",&blob));
CHECK_DX_ERROR(device->lpVtbl->CreatePixelShader(device,blob->lpVtbl->GetBufferPointer(blob),blob->lpVtbl->GetBufferSize(blob),NULL,&pixelShader));
context->lpVtbl->PSSetShader(context,pixelShader,0u);
ID3D11VertexShader *vertexShader;
CHECK_DX_ERROR(D3DReadFileToBlob(L"../Engine/build/shaders/VertexShader.cso",&blob));
CHECK_DX_ERROR(device->lpVtbl->CreateVertexShader(device,&vertexShader));
context->lpVtbl->VSSetShader(context,vertexShader,0u);
ID3D11InputLayout *input_layout;
const D3D11_INPUT_ELEMENT_DESC inputs[] =
{
{"POSITION",DXGI_FORMAT_R32G32_FLOAT,D3D11_INPUT_PER_VERTEX_DATA,0},};
CHECK_DX_ERROR(device->lpVtbl->CreateInputLayout(device,inputs,ASIZE(inputs),&input_layout));
CHECK_DX_ERROR(context->lpVtbl->IASetInputLayout(context,input_layout));
context->lpVtbl->OMSetRenderTargets(context,&target,NULL);
context->lpVtbl->IASetPrimitiveTopology(context,D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
D3D11_VIEWPORT vp = {.Width = 800,.Height = 600,.MinDepth = 0,.MaxDepth = 1,.TopLeftX = 0,.TopLeftY = 0};
context->lpVtbl->RSSetViewports(context,&vp);
CHECK_DX_ERROR(context->lpVtbl->Draw(context,ASIZE(vertices),0u));
}