简体   繁体   English

DirectX11 HLSL着色器未运行

[英]DirectX11 HLSL shaders not running

I am totally noob to 3D drawing using DirectX so, I wanted to learn the very basics of it and so, I attempted to use a mix of every example I stumbled upon through the web. 我完全不喜欢使用DirectX进行3D绘图,所以,我想学习它的基础知识,所以,我尝试使用我在网上偶然发现的每个例子的混合。

My first objective is to simply draw a few lines on the screen but so far, the only thing I was able to realize is to clear the screen with some varying color... 我的第一个目标是在屏幕上画几行,但到目前为止,我唯一能够意识到的是用一些不同的颜色清除屏幕......

In order to draw my 2D lines, I actually use HLSL vertex and pixel shaders compiled directly by the 2015 version of Visual Studio into cso files. 为了绘制我的2D线,我实际上使用由2015版Visual Studio直接编译的HLSL顶点和像素着色器到cso文件中。 (I initially had trouble with the pixel shader but managed to find that its properties have to be set ) (我最初在使用像素着色器时遇到了问题,但设法发现必须设置其属性)

When I use the Visual Studio Graphics Analyzer/Debugger, I can see the IA step which seems to be correct as the lines are drawn. 当我使用Visual Studio图形分析器/调试器时,我可以看到在绘制线条时看起来正确的IA步骤。 But after this step, I can't see anything more although I can debug step by step in the vertex shader and I see the correct values in position and color parameters. 但是在这一步之后,我看不到更多,虽然我可以在顶点着色器中逐步调试,但我在位置和颜色参数中看到了正确的值。

VSGA报告

The main issues, here, are: 这里的主要问题是:

  • In pixel history, I can't see any Draw() call issued on the deviceContext. 在像素历史中,我看不到在deviceContext上发出的任何Draw()调用。 I can only see ClearRenderTarget() 我只能看到ClearRenderTarget()
  • The pixel shader displays the message " Stage did not run. No ouput " 像素着色器显示消息“ 舞台未运行。无输出

I don't know what is wrong in the process, are the world/view/projection matrices or the depthStencilView mandatory? 我不知道这个过程有什么问题,世界/视图/投影矩阵或depthStencilView是强制性的吗? Did I forgot to provide a specific buffer to the swapChain and pipeline? 我忘了为swapChain和管道提供特定的缓冲区吗? I tried to disable depth, scissor, and culling in the rasterState object but I can't be sure. 我试图在rasterState对象中禁用深度,剪刀和剔除,但我不能确定。

I use a structure for my vertices which is : 我为我的顶点使用了一个结构,它是:

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

Finally, here is the code for the VERTEX SHADER : 最后,这是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;
}

Which I compile with the following line : 我使用以下行编译:

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

And the code for the PIXEL SHADER is the following: PIXEL SHADER的代码如下:

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

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

Which I compile with the following line: 我使用以下行编译:

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

This is the RASTERIZER STATE creation part: 这是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);

And this is the INPUT LAYOUT registration part (_vertexShaderCode->code contains the contents of vertexShader.cso and _vertexShaderCode->size, the size of those contents): 这是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);

Where variables are declared as: 变量声明为:

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

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

My VERTEX BUFFER is created by calling createLinesBuffer once, and then, calling renderVertice for mapping it at every drawcall: 我的顶点缓冲区通过调用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);
}

There are many things that might have gone wrong here, potentially you can check: 这里有很多可能出错的地方,你可以查看:

  • is Input Layout properly declared? 输入布局是否正确声明? It looks like your Vertex Shader doesn't get any geometry 看起来您的顶点着色器没有任何几何体
  • how do you declare your Rasterizer Stage? 你如何声明你的光栅化器舞台? Sometime there might be some issues, like culling, depth clipping, etc. 有时会出现一些问题,如剔除,深度剪裁等。
  • how does your geometry look like? 你的几何结构怎么样? Do you apply any world/view/projection transformation before applying geometry to Input Assembler? 在将几何应用于输入汇编程序之前,是否应用任何世界/视图/投影变换?
  • how do you construct your Vertex Buffer? 你如何构建顶点缓冲区? Do you Map/Unmap it? 你映射/取消映射吗? Or maybe you construct this for every drawcall? 或者也许你为每一个drawcall构建这个?

I cannot guarantee that this will help, but IMHO all of this is worth checking out. 我不能保证这会有所帮助,但恕我直言所有这一切都值得一试。

As for no output from Pixel Shader, it seems that nothing was feeded to it - so there must be something either with VS output or RS clipped all the geometry somehow (because of culling, depth testing, etc.) 至于Pixel Shader的没有输出,它似乎没有任何东西 - 所以必须有一些VS输出或RS以某种方式剪切所有几何(因为剔除,深度测试等)

Copied from comment, since it solved the issue. 复制自评论,因为它解决了这个问题。

InputLayout looks OK, VertexBuffer looks ok either. InputLayout看起来没问题,VertexBuffer看起来也不错。 At this point, I would check actual vertex coordinates. 此时,我会检查实际的顶点坐标。 From your screenshot, it lookl like you're using pretty big numbers, like x = 271, y = 147. Normally, those position are transformed via World-View-Projection transformation, so they end up in <-1.0f;1.0f> range. 从截图中看,它看起来像你使用的是非常大的数字,比如x = 271,y = 147.通常情况下,这些位置是通过World-View-Projection转换进行转换的,所以它们最终在<-1.0f; 1.0f >范围。 Since you're not using any transformations, I would recommend to change your lineGenerator function so it generates geometry in <-1.0f; 由于您没有使用任何变换, 我建议您更改lineGenerator函数,以便在<-1.0f中生成几何体; 1.0f> range for x and y coordinates. 1.0f> x和y坐标的范围。 For example, if your current x value is 271, make it 0.271f 例如,如果您当前的x值为271,则将其设为0.271f

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

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