C++ Direct3D:尝试绘制三角形,但未显示任何内容

C++ Direct3D:尝试绘制三角形,但未显示任何内容,c++,directx,directx-11,C++,Directx,Directx 11,我正在学习Direct3D11,我试图显示一个三角形,我遵循了所有必要的步骤,但没有显示任何内容。 这是我的密码: #include <Windows.h> #include <dxgi1_4.h> #include <d3d11.h> #include <d3dcompiler.h> #include "Game.h" Game *Game::game = nullptr; Game *Game::GetInstance() { if

我正在学习Direct3D11,我试图显示一个三角形,我遵循了所有必要的步骤,但没有显示任何内容。 这是我的密码:

#include <Windows.h>
#include <dxgi1_4.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include "Game.h"

Game *Game::game = nullptr;

Game *Game::GetInstance()
{
    if (Game::game == nullptr)
        Game::game = new Game();
    return game;
}

Game::Game()
{
}

Game::~Game()
{
}

bool Game::Initialize(HINSTANCE hInstance)
{
    if (InitializeWindow(hInstance))
        return InitializeDirect3D();
    return false;
}

bool Game::InitializeWindow(HINSTANCE hInstance)
{
    WNDCLASS windowClass = {};
    windowClass.hInstance = hInstance;
    windowClass.lpfnWndProc = &WndProc;
    windowClass.lpszClassName = L"wndClass";
    windowClass.lpszMenuName = NULL;
    windowClass.style = CS_HREDRAW | CS_VREDRAW;
    windowClass.cbClsExtra = 0;
    windowClass.cbWndExtra = 0;
    windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    RegisterClass(&windowClass);

    mWindow = CreateWindow(L"wndClass", L"DirectX 12 Engine", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, hInstance, 0);
    if (!mWindow)
    {
        MessageBox(0, L"window creation failed", L"ERROR", MB_OK);
        return false;
    }
    ShowWindow(mWindow, SW_SHOW);
    UpdateWindow(mWindow);

    return true;
}

bool Game::InitializeDirect3D()
{
    HRESULT hr;

    // create the device and the device context
    const D3D_FEATURE_LEVEL featureLevels[] = { D3D_FEATURE_LEVEL_11_0 };
    D3D_FEATURE_LEVEL featureLevel;
    hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, featureLevels, 1, D3D11_SDK_VERSION, &mDevice, &featureLevel, &mDeviceContext);
    if (FAILED(hr))
    {
        MessageBox(mWindow, L"device creation failed", L"ERROR", MB_OK);
        return false;
    }
    if (featureLevel != D3D_FEATURE_LEVEL_11_0)
    {
        MessageBox(mWindow, L"DirectX 11 not supported", L"ERROR", MB_OK);
        return false;
    }

    // query 4X MSAA support
    mDevice->CheckMultisampleQualityLevels(DXGI_FORMAT_R8G8B8A8_UNORM, 4, &m4xMsaaQuality);
    if (m4xMsaaQuality <= 0)
    {
        MessageBox(mWindow, L"4X MSAA not supported", L"ERROR", MB_OK);
        return false;
    }

    // describe and create the swap chain
    DXGI_MODE_DESC modeDesc = {};
    modeDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    modeDesc.Width = mClientWidth;
    modeDesc.Height = mClientHeight;
    modeDesc.RefreshRate.Denominator = 1;
    modeDesc.RefreshRate.Numerator = 60;
    modeDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    swapChainDesc.BufferDesc = modeDesc;
    swapChainDesc.BufferCount = 1;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.Flags = 0;
    swapChainDesc.OutputWindow = mWindow;
    swapChainDesc.Windowed = true;
    swapChainDesc.SampleDesc.Count = 4;
    swapChainDesc.SampleDesc.Quality = m4xMsaaQuality - 1;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

    IDXGIDevice *device = nullptr;
    mDevice->QueryInterface(IID_PPV_ARGS(&device));
    IDXGIAdapter *adapter = nullptr;
    device->GetParent(IID_PPV_ARGS(&adapter));
    IDXGIFactory *factory = nullptr;
    adapter->GetParent(IID_PPV_ARGS(&factory));
    hr = factory->CreateSwapChain(mDevice, &swapChainDesc, &mSwapChain);
    if (FAILED(hr))
    {
        MessageBox(mWindow, L"swap chain creation failed", L"ERROR", MB_OK);
        return false;
    }

    device->Release();
    adapter->Release();
    factory->Release();

    // create the render target view
    ID3D11Texture2D *texture = nullptr;
    mSwapChain->GetBuffer(0, IID_PPV_ARGS(&texture));
    mDevice->CreateRenderTargetView(texture, nullptr, &mRenderTargetView);
    texture->Release();

    // bind render target views to output merger stage of graphics pipeline
    mDeviceContext->OMSetRenderTargets(1, &mRenderTargetView, nullptr);

    // set the viewport
    D3D11_VIEWPORT viewport;
    viewport.TopLeftX = 0.0f;
    viewport.TopLeftY = 0.0f;
    viewport.Width = static_cast<float>(mClientWidth);
    viewport.Height = static_cast<float>(mClientHeight);
    viewport.MinDepth = 0.0f;
    viewport.MaxDepth = 1.0f;
    mDeviceContext->RSSetViewports(1, &viewport);

    CreateShaders();
    CreateBuffers();
    CreateInputLayout();

    return true;
}

bool Game::CreateShaders()
{
    HRESULT hr;

    // compile shaders
    ID3DBlob *error;
    hr = D3DCompileFromFile(L"shaders/VertexShader.hlsl", nullptr, nullptr, "main", "vs_5_0", 0, 0, &mVertexShaderBlob, &error);
    if (FAILED(hr))
    {
        ErrorBox(L"vertex shader compilation failed");
        OutputDebugStringA((LPCSTR)error->GetBufferPointer());
        return false;
    }
    hr = D3DCompileFromFile(L"shaders/PixelShader.hlsl", nullptr, nullptr, "main", "ps_5_0", 0, 0, &mPixelShaderBlob, &error);
    if (FAILED(hr))
    {
        ErrorBox(L"pixel shader compilation failed");
        OutputDebugStringA((LPCSTR)error->GetBufferPointer());
        return false;
    }

    // create shaders
    hr = mDevice->CreateVertexShader(mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), nullptr, &mVertexShader);
    if (FAILED(hr))
    {
        ErrorBox(L"vertex shader creation failed");
        return false;
    }
    hr = mDevice->CreatePixelShader(mPixelShaderBlob->GetBufferPointer(), mPixelShaderBlob->GetBufferSize(), nullptr, &mPixelShader);
    if (FAILED(hr))
    {
        ErrorBox(L"pixel shader creation failed");
        return false;
    }

    return true;
}

bool Game::CreateBuffers()
{
    HRESULT hr;

    // define geometry
    struct Vertex
    {
        float position[3];
    };
    Vertex vertices[] = {
        {-0.5f, -0.5f, 0.0f},
        {-0.5f, 0.5f, 0.0f},
        {0.5f, 0.0f, 0.0f}
    };

    // create vertex buffer
    D3D11_BUFFER_DESC bufferDesc = {};
    bufferDesc.Usage = D3D11_USAGE_DYNAMIC;
    bufferDesc.ByteWidth = sizeof vertices;
    bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
    bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
    bufferDesc.MiscFlags = 0;
    bufferDesc.StructureByteStride = 0;

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

    hr = mDevice->CreateBuffer(&bufferDesc, &data, &mVertexBuffer);
    if (FAILED(hr))
    {
        ErrorBox(L"vertex buffer creation failed");
        return false;
    }

    return true;
}

bool Game::CreateInputLayout()
{
    HRESULT hr;

    // describe input layout
    D3D11_INPUT_ELEMENT_DESC inputLayout[] = {
        {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0},
    };

    // create input layout
    hr = mDevice->CreateInputLayout(inputLayout, 1, mVertexShaderBlob->GetBufferPointer(), mVertexShaderBlob->GetBufferSize(), &mInputLayout);
    if (FAILED(hr))
    {
        ErrorBox(L"input layout creation failed");
        return false;
    }

    return true;
}

int Game::Run()
{
    MSG msg;
    do
    {
        if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE) != 0)
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        else
            Draw();
    } while (msg.message != WM_QUIT);

    return (int)msg.wParam;
}

// custom vertex format
struct Vertex
{
    float position[3];
    unsigned char color[4];
};

void Game::Draw()
{
    const float color[] = { 0.0f, 1.0f, 0.0f, 1.0f };
    mDeviceContext->ClearRenderTargetView(mRenderTargetView, color);

    // set shaders
    mDeviceContext->VSSetShader(mVertexShader, nullptr, 0);
    mDeviceContext->PSSetShader(mPixelShader, nullptr, 0);

    // set vertex buffer
    UINT stride = sizeof(Vertex);
    UINT offset = 0;
    mDeviceContext->IASetVertexBuffers(0, 1, &mVertexBuffer, &stride, &offset);

    // set input layout
    mDeviceContext->IASetInputLayout(mInputLayout);

    // set primitive topology
    mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

    // draw
    mDeviceContext->Draw(3, 0);
    mSwapChain->Present(0, 0);
}

LRESULT CALLBACK Game::GameWndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
    switch (msg)
    {
        case WM_LBUTTONDOWN:
            MessageBox(mWindow, L"left mouse button clicked", L"CLICK", MB_OK);
            return 0;
        case WM_RBUTTONDOWN:
            MessageBox(mWindow, L"right mouse button clicked", L"CLICK", MB_OK);
            return 0;
        case WM_CLOSE:
            if (MessageBox(mWindow, L"are you sure you want to quit?", L"QUIT", MB_YESNO) == IDYES)
                PostQuitMessage(0);
            return 0;
        default: 
            return DefWindowProc(window, msg, wParam, lParam);
    }
}

LRESULT CALLBACK WndProc(HWND window, UINT msg, WPARAM wParam, LPARAM lParam)
{
    return Game::GetInstance()->GameWndProc(window, msg, wParam, lParam);
}

void ErrorBox(wchar_t *message)
{
    MessageBox(Game::GetInstance()->mWindow, message, L"ERROR", MB_OK);
}
#包括
#包括
#包括
#包括
#包括“Game.h”
Game*Game::Game=nullptr;
Game*Game::GetInstance()
{
如果(游戏::游戏==nullptr)
游戏::游戏=新游戏();
回归游戏;
}
Game::Game()
{
}
游戏::~Game()
{
}
bool游戏::初始化(HINSTANCE HINSTANCE)
{
if(初始化为INDOW(hInstance))
返回initializedDirect3D();
返回false;
}
bool游戏::初始化窗口(HINSTANCE HINSTANCE)
{
WNDCLASS windowClass={};
windowClass.hInstance=hInstance;
windowClass.lpfnWndProc=&WndProc;
windowClass.lpszClassName=L“wndClass”;
windowClass.lpszMenuName=NULL;
windowClass.style=CS_HREDRAW | CS_VREDRAW;
windowClass.cbClsExtra=0;
windowClass.cbWndExtra=0;
windowClass.hCursor=LoadCursor(空,IDC_箭头);
windowClass.hIcon=加载图标(空,IDI_应用程序);
windowClass.hbrBackground=(HBRUSH)GetStockObject(灰色画笔);
RegisterClass(&windowClass);
mWindow=CreateWindow(L“wndClass”,L“DirectX 12引擎”,WS_重叠窗口,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,0,0,hInstance,0);
如果(!mWindow)
{
消息框(0,L“窗口创建失败”,L“错误”,MB_OK);
返回false;
}
展示窗口(mWindow、SW_SHOW);
更新窗口(mWindow);
返回true;
}
布尔游戏::InitializeDirect3D()
{
HRESULT-hr;
//创建设备和设备上下文
常量D3D_特征层特征层[]={D3D_特征层11_0};
D3D_特征级特征级;
hr=D3D11CreateDevice(nullptr、D3D驱动程序、类型硬件、0、D3D11、创建设备、调试、功能级别、1、D3D11、SDK版本、&mDevice、&featureLevel、&mDeviceContext);
如果(失败(小时))
{
MessageBox(mWindows,L“设备创建失败”,L“错误”,MB_OK);
返回false;
}
如果(功能级别!=D3D\U功能级别\U 11\U 0)
{
MessageBox(mWindows,L“不支持DirectX 11”,L“错误”,MB_OK);
返回false;
}
//查询4X MSAA支持
mDevice->CheckMultisampleQualityLevels(DXGI_格式_R8G8B8A8_UNORM、4和m4xMsaaQuality);
if(M4XMSAA质量查询接口(IID_PPV_参数和设备));
IDXGIAdapter*适配器=空PTR;
设备->获取父级(IID_PPV_参数(&adapter));
IDXGIFactory*工厂=空PTR;
适配器->获取父级(IID_PPV_参数(&factory));
hr=工厂->创建SwapChain(mDevice和swapChainDesc和mSwapChain);
如果(失败(小时))
{
MessageBox(mWindows,L“交换链创建失败”,L“错误”,MB_OK);
返回false;
}
设备->释放();
适配器->释放();
工厂->发布();
//创建渲染目标视图
ID3D11Texture2D*纹理=空PTR;
mSwapChain->GetBuffer(0,IID_PPV_参数(&texture));
mDevice->CreateRenderTargetView(纹理、nullptr和mRenderTargetView);
纹理->释放();
//将渲染目标视图绑定到图形管道的输出合并阶段
mDeviceContext->OMSetRenderTargets(1,&mRenderTargetView,nullptr);
//设置视口
D3D11_视口;
viewport.TopLeftX=0.0f;
viewport.TopLeftY=0.0f;
viewport.Width=静态投影(mClientWidth);
viewport.Height=静态投影(mClientHeight);
viewport.MinDepth=0.0f;
viewport.MaxDepth=1.0f;
mDeviceContext->RSSETViewport(1,视口和视口);
CreateShaders();
CreateBuffers();
CreateInputLayout();
返回true;
}
bool游戏::CreateShaders()
{
HRESULT-hr;
//编译着色器
ID3DBlob*错误;
hr=D3DCompileFromFile(L“shaders/VertexShader.hlsl”、nullptr、nullptr、“main”、“vs_5_0”、0、0和mVertexShaderBlob、&error);
如果(失败(小时))
{
ErrorBox(L“顶点着色器编译失败”);
OutputDebugStringA((LPCSTR)错误->GetBufferPointer());
返回false;
}
hr=D3DCompileFromFile(L“shaders/PixelShader.hlsl”、nullptr、nullptr、main、ps_5_0、0、0和mPixelShaderBlob、&error);
如果(失败(小时))
{
ErrorBox(L“像素着色器编译失败”);
OutputDebugStringA((LPCSTR)错误->GetBufferPointer());
返回false;
}
//创建着色器
hr=mDevice->CreateVertexShader(mVertexShaderBlob->GetBufferPointer(),mVertexShaderBlob->GetBufferSize(),nullptr,&mVertexShader);
如果(失败(小时))
{
ErrorBox(L“顶点着色器创建失败”);
返回false;
}
hr=mDevice->CreatePixelShader(mPixelShaderBlob->GetBufferPointer(),mPixelShaderBlob->GetBufferSize(),nullptr,&mPixelShader);
如果(失败(小时))
{
ErrorBox(L“像素着色器创建失败”);
返回false;
}
返回true;
}
bool游戏::CreateBuffers()
{
HRESULT-hr;
//定义几何图形
结构顶点
{
浮动位置[3];
};
顶点[]={
{-0.5f,-0.5f,0.0f},
{-0.5f,0.5f,0.0f},
{0.5f,0.0f,0.0f}
};
//创建顶点缓冲区
D3D11_BUFFER_DESC bufferDesc={};
bufferDesc.Usage=D3D11\u Usage\u DYNAMIC;
bufferDesc.ByteWidth=顶点的大小;
bufferDesc.CPUAccessFlags=D3D11\u CPU\u访问\u写入;
bufferDesc.BindFlags=D3D11_BIND_VERTEX_BUFFER;
bufferDesc.miscsflags=0;
bufferDesc.StructureByteStride=0;
D3D11_子资源_数据数据={};
data.psysem=顶点;
hr=mDevice->CreateBuffer(&bufferDesc,&data,&mVertexBuffer);
如果(失败(小时))
{
ErrorBox(L“顶点缓冲区创建失败”);
返回false;
}
返回true;
}
布尔游戏::CreateInputLayout()
{
HRESULT-hr;
//描述输入布局
D3D11_输入_元素_描述输入布局[]={
{“位置”,0,DXGI_格式_R32G32B32_浮点,0,0,D3D11_输入_逐顶点_数据,0},
};
//创建输入布局
hr=mDevice->CreateInputLayout(inputLayout,1,mVertexShaderBlob->GetBufferPointer(),mVertexShaderBlob
ID3D11RasterizerState* rs = 0;
D3D11_RASTERIZER_DESC r;
r.AntialiasedLineEnable = false;
r.CullMode = D3D11_CULL_BACK;
r.DepthBias = 0;
r.DepthBiasClamp = 0.0f;
r.DepthClipEnable = true;
r.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID;
r.FrontCounterClockwise = true;
r.MultisampleEnable = false;
r.ScissorEnable = false;
r.SlopeScaledDepthBias = 0.0f;
/*if (FAILED(*/device->CreateRasterizerState(&r,&rs);
d3dcontext->RSSetState(rs);