D3D11 着色器编译成功,但出现白屏

D3D11 shaders compiles successfully, but I get a white screen

我正在设置 d3d11 来学习基础知识,但遇到了一些问题。我没有任何错误,一切都可以正常编译,但以白色 window 结尾。我在这里错过了什么吗? window 中应该有一个彩色四边形。对于提问中的任何错误,我们深表歉意。这是我第一次 post 来这里。

CPP 文件:

#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <iostream>



struct Vec3
{
    float x, y, z;
};

struct Vertex
{
    Vec3 position;
    Vec3 color;
};


bool running = true;
HWND hwndApp;
LRESULT CALLBACK AppWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY)
    {
        running = false;
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

int main()
{
    WNDCLASSEX appWndClass = { };
    appWndClass.lpfnWndProc = AppWndProc;
    appWndClass.cbSize = sizeof(WNDCLASSEX);
    appWndClass.cbClsExtra = NULL;
    appWndClass.cbWndExtra = NULL;
    appWndClass.hbrBackground = (HBRUSH)COLOR_WINDOW;
    appWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    appWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    appWndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
    appWndClass.style = NULL;
    appWndClass.hInstance = GetModuleHandle(NULL);
    appWndClass.lpszClassName = "AppWndClass";
    appWndClass.lpszMenuName = "";

    RegisterClassEx(&appWndClass);

    hwndApp = CreateWindowEx(
        WS_EX_OVERLAPPEDWINDOW,
        appWndClass.lpszClassName,
        "AppWndClass",
        WS_CAPTION | WS_SYSMENU,
        CW_USEDEFAULT, CW_USEDEFAULT, 1024, 768,
        NULL,
        NULL,
        GetModuleHandle(NULL),
        NULL
    );

    ShowWindow(hwndApp, SW_SHOW);
    UpdateWindow(hwndApp);


    ID3D11Device* d3dDevice = nullptr;
    ID3D11DeviceContext* d3dDeviceContext = nullptr;
    IDXGIDevice* dxgiDevice = nullptr;
    IDXGIAdapter* dxgiAdapter = nullptr;
    IDXGIFactory* dxgiFactory = nullptr;
    IDXGISwapChain* dxgiSwapChain = nullptr;    
    ID3D11RenderTargetView* renderTargetView = nullptr;
    D3D_FEATURE_LEVEL featureLevel;

    D3D_FEATURE_LEVEL featureLevels[] =
    {
        D3D_FEATURE_LEVEL_11_0
    };

    D3D11CreateDevice(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        0,
        featureLevels,
        ARRAYSIZE(featureLevels),
        D3D11_SDK_VERSION,
        &d3dDevice,
        &featureLevel,
        &d3dDeviceContext
    );

    if (d3dDevice == nullptr) return -1;
    if (d3dDeviceContext == nullptr) return -1;

    d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void**)& dxgiDevice);
    dxgiDevice->GetAdapter(&dxgiAdapter);
    dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)& dxgiFactory);









    RECT rc;
    GetClientRect(hwndApp, &rc);

    DXGI_SWAP_CHAIN_DESC swapChainDescription;
    ZeroMemory(&swapChainDescription, sizeof(swapChainDescription));
    swapChainDescription.BufferCount = 1;
    swapChainDescription.BufferDesc.Width = rc.right - rc.left;
    swapChainDescription.BufferDesc.Height = rc.bottom - rc.top;
    swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDescription.BufferDesc.RefreshRate.Numerator = 60;
    swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
    swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDescription.OutputWindow = hwndApp;
    swapChainDescription.SampleDesc.Count = 1;
    swapChainDescription.SampleDesc.Quality = 0;
    swapChainDescription.Windowed = TRUE;


    dxgiFactory->CreateSwapChain(d3dDevice, &swapChainDescription, &dxgiSwapChain);

    ID3D11Texture2D* buffer = nullptr;
    dxgiSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)& buffer);

    if (buffer == nullptr) return -1;

    d3dDevice->CreateRenderTargetView(buffer, nullptr, &renderTargetView);
    buffer->Release();

    if (renderTargetView == nullptr) return -1;














    Vertex vertices[] =
    {
        { -0.5f, -0.5f, 0.0f, 0, 0, 0 },
        { -0.5f, 0.5f, 0.0f, 1, 1, 0 },
        { 0.5f, -0.5f, 0.0f, 0, 0, 1 },
        { 0.5f, 0.5f, 0.0f, 1, 1, 1 }
    };

    UINT sizeVertices = ARRAYSIZE(vertices);


    D3D11_INPUT_ELEMENT_DESC inputElementDescription[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA , 0 },
        { "COLOR", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    };

    UINT sizeInputElementDescription = ARRAYSIZE(inputElementDescription);







    D3D11_BUFFER_DESC bufferDescription = {};
    bufferDescription.Usage = D3D11_USAGE_DEFAULT;
    bufferDescription.ByteWidth = sizeof(Vertex) * sizeVertices;
    bufferDescription.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bufferDescription.CPUAccessFlags = 0;
    bufferDescription.MiscFlags = 0;

    D3D11_SUBRESOURCE_DATA initialData = {};
    initialData.pSysMem = vertices;

    ID3D11Buffer* vertexBuffer;
    d3dDevice->CreateBuffer(&bufferDescription, &initialData, &vertexBuffer);









    void* shaderByteCode = nullptr;
    size_t byteCodeLength = 0;
    ID3DBlob* blobCode = nullptr;
    ID3DBlob* blobErrorMsgs = nullptr;

    //D3DCompileFromFile( L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs );
    if (!SUCCEEDED(D3DCompileFromFile(L"VertexShader.hlsl", nullptr, nullptr, "vsmain", "vs_5_0", 0, 0, &blobCode, &blobErrorMsgs)))
    {
        if (blobErrorMsgs) blobErrorMsgs->Release();
        std::cout << "ERROR COMPILING VERTEXSHADER" << std::endl;
        return false;
    }

    shaderByteCode = blobCode->GetBufferPointer();
    byteCodeLength = blobCode->GetBufferSize();

    ID3D11VertexShader* vertexShader;
    d3dDevice->CreateVertexShader(shaderByteCode, byteCodeLength, nullptr, &vertexShader);
    vertexShader->Release();

    ID3D11InputLayout* inputLayout;
    d3dDevice->CreateInputLayout(inputElementDescription, sizeInputElementDescription, shaderByteCode, byteCodeLength, &inputLayout);

    blobCode->Release();








    void* shaderByteCode2 = nullptr;
    size_t byteCodeLength2 = 0;
    ID3DBlob* blobCode2 = nullptr;
    ID3DBlob* blobErrorMsgs2 = nullptr;

    //D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2);
    if (!SUCCEEDED(D3DCompileFromFile(L"PixelShader.hlsl", nullptr, nullptr, "psmain", "ps_5_0", 0, 0, &blobCode2, &blobErrorMsgs2)))
    {
        if (blobErrorMsgs2) blobErrorMsgs2->Release();
        std::cout << "ERROR COMPILING PIXELSHADER" << std::endl;
        return false;
    }

    shaderByteCode2 = blobCode2->GetBufferPointer();
    byteCodeLength2 = blobCode2->GetBufferSize();

    ID3D11PixelShader* pixelShader;
    d3dDevice->CreatePixelShader(shaderByteCode2, byteCodeLength2, nullptr, &pixelShader);
    pixelShader->Release();

    blobCode2->Release();










    FLOAT clearColor[] = { 0.0, 0.0, 0.0, 1.0 };
    while (running)
    {
        d3dDeviceContext->ClearRenderTargetView(renderTargetView, clearColor);
        d3dDeviceContext->OMSetRenderTargets(1, &renderTargetView, NULL);

        GetClientRect(hwndApp, &rc);

        D3D11_VIEWPORT vp = {};
        vp.Width = rc.right - rc.left;
        vp.Height = rc.bottom - rc.top;
        vp.MinDepth = 0.0f;
        vp.MaxDepth = 1.0f;

        d3dDeviceContext->RSSetViewports(1, &vp);
        d3dDeviceContext->VSSetShader(vertexShader, nullptr, 0);
        d3dDeviceContext->PSSetShader(pixelShader, nullptr, 0);

        UINT stride = sizeof(Vertex);
        UINT offset = 0;
        d3dDeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
        d3dDeviceContext->IASetInputLayout(inputLayout);

        d3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
        d3dDeviceContext->Draw(sizeVertices, 0);




        dxgiSwapChain->Present(true, NULL);

        MSG msg = { 0 };
        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) > 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }


    renderTargetView->Release();
    inputLayout->Release();
    vertexBuffer->Release();
    dxgiDevice->Release();
    dxgiAdapter->Release();
    dxgiFactory->Release();
    d3dDeviceContext->Release();
    d3dDevice->Release();

    return 0;
}

顶点着色器

struct VS_INPUT
{
    float4 position: POSITION;
    float3 color: COLOR;
};

struct VS_OUTPUT
{
    float4 position: SV_POSITION;
    float3 color: COLOR;
};


VS_OUTPUT vsmain(VS_INPUT input)
{
    VS_OUTPUT output = (VS_OUTPUT)0;

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

    return output;
}

像素着色器

struct PS_INPUT
{
    float4 position: SV_POSITION;
    float3 color: COLOR;
};


float4 psmain(PS_INPUT input) : SV_TARGET
{
    return float4(input.color,1.0f);
}

我希望 window 显示多色四边形,但 window 全是白色。

着色器已发布,随后在代码中使用。

vertexShader->Release();
pixelShader->Release();

将着色器的释放移动到程序的末尾解决了这个问题。