三角形未出现在 DirectX 11 应用程序中

问题描述 投票:0回答:1

我正在尝试渲染一个简单的三角形,但问题是除了三角形不渲染之外一切正常:

#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <string>

#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")

using namespace DirectX;

// Vertex shader source code
const std::string vertexShaderSource = R"(
    float4 main(float4 pos : POSITION) : SV_Position
    {
        return pos;
    }
)";

// Pixel shader source code
const std::string pixelShaderSource = R"(
    float4 main() : SV_Target
    {
        return float4(0.0f, 1.0f, 0.7f, 1.0f);
    }
)";

#define CHECK_HR_ERROR(msg) if (FAILED(hr)) MessageBox(nullptr, msg, L"Error", MB_ICONERROR)

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    }

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

int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow)
{
    // Create the window
    const wchar_t* windowClassName = L"DirectX11WindowClass";
    const wchar_t* windowTitle = L"DirectX 11 Application";
    const int windowWidth = 800;
    const int windowHeight = 600;

    WNDCLASSEX wcex = {};
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = WindowProc;
    wcex.hInstance = hInstance;
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.lpszClassName = windowClassName;

    RegisterClassEx(&wcex);

    RECT rc = { 0, 0, windowWidth, windowHeight };
    AdjustWindowRect(&rc, WS_OVERLAPPEDWINDOW, false);

    HWND hwnd = CreateWindowEx(
        0,
        windowClassName,
        windowTitle,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT,
        rc.right - rc.left, rc.bottom - rc.top,
        nullptr,
        nullptr,
        hInstance,
        nullptr
    );

    if (!hwnd)
        return -1;

    ShowWindow(hwnd, nCmdShow);

    // Initialize DirectX
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferDesc.Width = windowWidth;
    swapChainDesc.BufferDesc.Height = windowHeight;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = hwnd;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.Windowed = true;

    ID3D11Device* device = nullptr;
    ID3D11DeviceContext* deviceContext = nullptr;
    IDXGISwapChain* swapChain = nullptr;
    ID3D11RenderTargetView* renderTargetView = nullptr;

    HRESULT hr = D3D11CreateDeviceAndSwapChain(
        nullptr,
        D3D_DRIVER_TYPE_HARDWARE,
        nullptr,
        0,
        nullptr,
        0,
        D3D11_SDK_VERSION,
        &swapChainDesc,
        &swapChain,
        &device,
        nullptr,
        &deviceContext
    );
    CHECK_HR_ERROR(L"failed to create the device, deviceContext and swapChain!");

    // Create the render target view
    ID3D11Texture2D* backBuffer = nullptr;
    hr = swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(&backBuffer));
    CHECK_HR_ERROR(L"failed to get the back buffer!");

    hr = device->CreateRenderTargetView(backBuffer, nullptr, &renderTargetView);
    CHECK_HR_ERROR(L"failed to create the render target view!");
    backBuffer->Release();

    D3D11_VIEWPORT viewport = {};
    viewport.Width = static_cast<float>(windowWidth);
    viewport.Height = static_cast<float>(windowHeight);
    viewport.MinDepth = 0.0f;
    viewport.MaxDepth = 1.0f;
    viewport.TopLeftX = 0.0f;
    viewport.TopLeftY = 0.0f;

    deviceContext->RSSetViewports(1, &viewport);

    // Set the render target
    deviceContext->OMSetRenderTargets(1, &renderTargetView, nullptr);

    // Create the vertex buffer
    struct VertexType
    {
        XMFLOAT4 position;
    };

    VertexType vertices[] =
    {
        { XMFLOAT4(-0.5f, -0.5f, 0.0f, 1.0f) },
        { XMFLOAT4(0.5f, -0.5f, 0.0f, 1.0f) },
        { XMFLOAT4(0.0f, 0.5f, 0.0f, 1.0f) }
    };

    D3D11_BUFFER_DESC vertexBufferDesc = {};
    vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
    vertexBufferDesc.ByteWidth = sizeof(VertexType) * 3; // sizeof(vertices)
    vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    vertexBufferDesc.CPUAccessFlags = 0;

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

    ID3D11Buffer* vertexBuffer = nullptr;
    hr = device->CreateBuffer(&vertexBufferDesc, &vertexData, &vertexBuffer);
    CHECK_HR_ERROR(L"failed to create the vertex buffer!");

    // Set the vertex buffer
    UINT stride = sizeof(VertexType);
    UINT offset = 0;
    deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);

    // Set the primitive topology
    deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // Create the vertex shader
    ID3DBlob* vertexShaderBlob = nullptr;
    D3DCompile(vertexShaderSource.c_str(), vertexShaderSource.length(), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr);
    CHECK_HR_ERROR(L"failed to compile the vertex shader!");

    ID3D11VertexShader* vertexShader = nullptr;
    hr = device->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &vertexShader);
    CHECK_HR_ERROR(L"failed to create the vertex shader!");

    deviceContext->VSSetShader(vertexShader, nullptr, 0);

    D3D11_INPUT_ELEMENT_DESC inputLayoutDesc[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
    };

    ID3D11InputLayout* inputLayout = nullptr;
    hr = device->CreateInputLayout(inputLayoutDesc, _countof(inputLayoutDesc), vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &inputLayout);
    CHECK_HR_ERROR(L"failed to create the input layout!");

    deviceContext->IASetInputLayout(inputLayout);

    // Create the pixel shader
    ID3DBlob* pixelShaderBlob = nullptr;
    hr = D3DCompile(pixelShaderSource.c_str(), pixelShaderSource.length(), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr);
    CHECK_HR_ERROR(L"failed to compile the pixel shader!");

    ID3D11PixelShader* pixelShader = nullptr;
    hr = device->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &pixelShader);
    CHECK_HR_ERROR(L"failed to create the pixel shader!");

    deviceContext->PSSetShader(pixelShader, nullptr, 0);

    // Main message loop
    MSG msg = {};
    while (msg.message != WM_QUIT)
    {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
        {
            // Render the frame
            float clearColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };
            deviceContext->ClearRenderTargetView(renderTargetView, clearColor);
            deviceContext->Draw(3, 0);
            swapChain->Present(1, 0);
        }
    }

    // Cleanup
    vertexBuffer->Release();
    vertexShaderBlob->Release();
    vertexShader->Release();
    pixelShaderBlob->Release();
    pixelShader->Release();
    renderTargetView->Release();
    swapChain->Release();
    deviceContext->Release();
    device->Release();

    return static_cast<int>(msg.wParam);
}
c++ directx directx-11
1个回答
0
投票

您无需告诉 DirectX 三角形的顶点索引是什么。对于三角形,您可以按照以下方法修复它:

将其添加到您的初始化代码中:

UINT indices[] =
{
  2,1,0 // order is important!
};

D3D11_BUFFER_DESC indexBufferDesc = {};
indexBufferDesc.ByteWidth = sizeof(indices);
indexBufferDesc.Usage = D3D11_USAGE_IMMUTABLE;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;

D3D11_SUBRESOURCE_DATA indexData = { indices };
ID3D11Buffer* indexBuffer;
hr = device->CreateBuffer(&indexBufferDesc, &indexData, &indexBuffer);
CHECK_HR_ERROR(L"failed to create the index buffer!");

deviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);

将您的 Draw 调用替换为以下调用:

deviceContext->DrawIndexed(ARRAYSIZE(indices), 0, 0);

但是您可以保持所有代码和绘制调用不变,只需反转三角形顶点 (0,1,2 => 2,1,0),如下所示:

VertexType vertices[] =
{
    { XMFLOAT4(0.0f, 0.5f, 0.0f, 1.0f) },
    { XMFLOAT4(0.5f, -0.5f, 0.0f, 1.0f) },
    { XMFLOAT4(-0.5f, -0.5f, 0.0f, 1.0f) },
};
© www.soinside.com 2019 - 2024. All rights reserved.