微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

直接 X 输入汇编器 - 顶点着色器链接错误

如何解决直接 X 输入汇编器 - 顶点着色器链接错误

我正在学习 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));
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。