繁体   English   中英

DirectX11 HLSL着色器未运行

[英]DirectX11 HLSL shaders not running

我完全不喜欢使用DirectX进行3D绘图,所以,我想学习它的基础知识,所以,我尝试使用我在网上偶然发现的每个例子的混合。

我的第一个目标是在屏幕上画几行,但到目前为止,我唯一能够意识到的是用一些不同的颜色清除屏幕......

为了绘制我的2D线,我实际上使用由2015版Visual Studio直接编译的HLSL顶点和像素着色器到cso文件中。 (我最初在使用像素着色器时遇到了问题,但设法发现必须设置其属性)

当我使用Visual Studio图形分析器/调试器时,我可以看到在绘制线条时看起来正确的IA步骤。 但是在这一步之后,我看不到更多,虽然我可以在顶点着色器中逐步调试,但我在位置和颜色参数中看到了正确的值。

VSGA报告

这里的主要问题是:

  • 在像素历史中,我看不到在deviceContext上发出的任何Draw()调用。 我只能看到ClearRenderTarget()
  • 像素着色器显示消息“ 舞台未运行。无输出

我不知道这个过程有什么问题,世界/视图/投影矩阵或depthStencilView是强制性的吗? 我忘了为swapChain和管道提供特定的缓冲区吗? 我试图在rasterState对象中禁用深度,剪刀和剔除,但我不能确定。

我为我的顶点使用了一个结构,它是:

#define LINES_NB 1000
struct Point
{
    float x, y, z, rhw;
    float r, g, b, a;
} lineList[LINES_NB];

最后,这是VERTEX SHADER的代码:

struct VIn
{
    float4 position : POSITION;
    float4 color : COLOR;
};

struct VOut
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

VOut main(VIn input)
{
    VOut output;

    output.position = input.position;
    output.color = input.color;

    return output;
}

我使用以下行编译:

/Zi /E"main" /Od /Fo"E:\PATH\VertexShader.cso" /vs"_5_0" /nologo

PIXEL SHADER的代码如下:

struct PIn
{
    float4 position : SV_POSITION;
    float4 color : COLOR;
};

float4 main(PIn input) : SV_TARGET
{
    return input.color;
}

我使用以下行编译:

/Zi /E"main" /Od /Fo"E:\PATH\PixelShader.cso" /ps"_5_0" /nologo 

这是RASTERIZER STATE创建部分:

D3D11_RASTERIZER_DESC rasterDesc;
rasterDesc.AntialiasedLineEnable = false;
rasterDesc.CullMode = D3D11_CULL_NONE;
rasterDesc.DepthBias = 0;
rasterDesc.DepthBiasClamp = 0.0f;
rasterDesc.DepthClipEnable = false;
rasterDesc.FillMode = D3D11_FILL_WIREFRAME;
rasterDesc.FrontCounterClockwise = true;
rasterDesc.MultisampleEnable = false;
rasterDesc.ScissorEnable = false;
rasterDesc.SlopeScaledDepthBias = 0.0f;

result = _device->CreateRasterizerState(&rasterDesc, &_rasterState);
if (FAILED(result))
{
    OutputDebugString("FAILED TO CREATE RASTERIZER STATE.\n");
    HR(result);
    return -1;
}
_immediateContext->RSSetState(_rasterState);

这是INPUT LAYOUT注册部分(_vertexShaderCode->代码包含vertexShader.cso和_vertexShaderCode-> size的内容,这些内容的大小):

// create the input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

HR(_device->CreateInputLayout(ied, sizeof(ied) / sizeof(D3D11_INPUT_ELEMENT_DESC), _vertexShaderCode->code, _vertexShaderCode->size, &_vertexInputLayout));
_immediateContext->IASetInputLayout(_vertexInputLayout);

变量声明为:

struct Shader
{
    BYTE *code;
    UINT size;
};

ID3D11Device*           _device;
ID3D11DeviceContext*    _immediateContext;
ID3D11RasterizerState*  _rasterState;
ID3D11InputLayout*      _vertexInputLayout;
Shader*                 _vertexShaderCode;
Shader*                 _pixelShaderCode;

我的顶点缓冲区通过调用createLinesBuffer一次,然后,呼吁renderVertice在每drawcall映射它创造:

void        DxDraw::createLinesBuffer(ID3D11Device* device)
{
    D3D11_BUFFER_DESC vertexBufferDesc;
    ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
    vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
    vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    vertexBufferDesc.ByteWidth = sizeof(Point) * LINES_NB;
    std::cout << "buffer size : " << sizeof(Point) * LINES_NB <<     std::endl;
    vertexBufferDesc.MiscFlags = 0;
    vertexBufferDesc.StructureByteStride = 0;

    D3D11_SUBRESOURCE_DATA vertexBufferData;
    ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
    vertexBufferData.pSysMem = lineList;
    std::cout << "lineList : " << lineList << std::endl;
    vertexBufferData.SysMemPitch = 0;
    vertexBufferData.SysMemSlicePitch = 0;

    HR(device->CreateBuffer(&vertexBufferDesc, &vertexBufferData,     &_vertexBuffer));
}

void        DxDraw::renderVertice(ID3D11DeviceContext* ctx, UINT count, D3D11_PRIMITIVE_TOPOLOGY type)
{
    D3D11_MAPPED_SUBRESOURCE ms;
    ZeroMemory(&ms, sizeof(D3D11_MAPPED_SUBRESOURCE));
    // map the buffer   
    HR(ctx->Map(_vertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms));
    // copy the data to it
    memcpy(ms.pData, lineList, sizeof(lineList));
    // unmap it
    ctx->Unmap(_vertexBuffer, NULL);

    // select which vertex buffer to display
    UINT stride = sizeof(Point);
    UINT offset = 0;
    ctx->IASetVertexBuffers(0, 1, &_vertexBuffer, &stride, &offset);

    // select which primtive type we are using
    ctx->IASetPrimitiveTopology(type);

    // draw the vertex buffer to the back buffer
    ctx->Draw(count, 0);
}

这里有很多可能出错的地方,你可以查看:

  • 输入布局是否正确声明? 看起来您的顶点着色器没有任何几何体
  • 你如何声明你的光栅化器舞台? 有时会出现一些问题,如剔除,深度剪裁等。
  • 你的几何结构怎么样? 在将几何应用于输入汇编程序之前,是否应用任何世界/视图/投影变换?
  • 你如何构建顶点缓冲区? 你映射/取消映射吗? 或者也许你为每一个drawcall构建这个?

我不能保证这会有所帮助,但恕我直言所有这一切都值得一试。

至于Pixel Shader的没有输出,它似乎没有任何东西 - 所以必须有一些VS输出或RS以某种方式剪切所有几何(因为剔除,深度测试等)

复制自评论,因为它解决了这个问题。

InputLayout看起来没问题,VertexBuffer看起来也不错。 此时,我会检查实际的顶点坐标。 从截图中看,它看起来像你使用的是非常大的数字,比如x = 271,y = 147.通常情况下,这些位置是通过World-View-Projection转换进行转换的,所以它们最终在<-1.0f; 1.0f >范围。 由于您没有使用任何变换, 我建议您更改lineGenerator函数,以便在<-1.0f中生成几何体; 1.0f> x和y坐标的范围。 例如,如果您当前的x值为271,则将其设为0.271f

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM