DirectX12 ② 初期化

DirectX12の初期化
言語 : C++
開発環境 : Visual Studio 2020
OS : Windows10
CPU : AMD Ryzen5 3600
RAM : 24.0GB
GPU : NVIDIA GeForce GTX 1050

画面のクリアまで

ヘッダファイル

Dx.h

#pragma once

#include <dxgi1_4.h>
#include <d3d12.h>
#include <wrl/client.h>
#include <cstdint>
#include <iostream>
#include <vector>

#pragma comment(lib, "d3d12.lib")
#pragma comment(lib, "dxgi.lib")

using namespace Microsoft::WRL;

constexpr uint32_t FRAME_BUFFER_COUNT = 2;

class Dx {
public:
    Dx();
    bool Init(uint32_t width, uint32_t height, HWND hwnd);
    void Terminate();

    void BeginRender();
    void EndRender();

    void ResetCmdList();
    void ExcuteCmdList();

    ID3D12Device* GetDevice();
    ID3D12GraphicsCommandList* GetCmdList();

    uint32_t GetWindowWidth();
    uint32_t GetWindowHeight();
    uint32_t GetCurrentBackBufferIndex();

private:
    void Present(uint32_t interval);
    void WaitGPU();

    bool CreateFactory();
    bool CreateDevice();
    bool CreateCommandQueue();
    bool CreateSwapChain();
    bool CreateCommandAllocator();
    bool CreateCommandList();
    bool CreateRenderTarget();
    bool CreateFence();
    bool CreateDepthStencil();

    void CreateViewPort();
    void CreateScissorRect();

private:
    HWND _hwnd;
    uint32_t _width, _height;   //ウィンドウの高さと幅

    ComPtr<IDXGIFactory4> _pFactory;    //ファクトリー
    ComPtr<ID3D12Device> _pDevice;  //デバイス
    ComPtr<ID3D12CommandQueue> _pCmdQueue;  //コマンドキュー
    ComPtr<IDXGISwapChain3> _pSwapChain;    //スワップチェイン
    ComPtr<ID3D12Resource> _pRenderTargets[FRAME_BUFFER_COUNT]; //レンダーターゲット
    ComPtr<ID3D12CommandAllocator> _pCmdAllocator[FRAME_BUFFER_COUNT];  //コマンドアロケーター
    ComPtr<ID3D12GraphicsCommandList> _pCmdList;    //コマンドリスト
    ComPtr<ID3D12DescriptorHeap> _pHeapRTV; //レンダーターゲット用のディスクリプタヒープ
    ComPtr<ID3D12RootSignature> _pRootSignature;    //ルートシグネチャ
    ComPtr<ID3D12PipelineState> _pPipelineState;    //パイプラインステート
    ComPtr<ID3D12Fence> _pFence;    //フェンス
    ComPtr<ID3D12DescriptorHeap> _pHeapDSV; //デプスステンシルビュー用のディスクリプタヒープ
    ComPtr<ID3D12Resource> _pDepthStencilBuffer;    //デプスステンシルバッファ

    uint32_t _currentBackBufferIndex;   //バックバッファーのインデックス
    HANDLE _fenceEvent; //フェンスイベント
    uint64_t _fenceCount[FRAME_BUFFER_COUNT];   //フェンスカウント
    D3D12_CPU_DESCRIPTOR_HANDLE _handleRTV[FRAME_BUFFER_COUNT]; //レンダーターゲットビューのハンドル
    D3D12_CPU_DESCRIPTOR_HANDLE _handleDSV; //デプスステンシルビューのハンドル

    D3D12_VIEWPORT _viewPort;
    D3D12_RECT _scissorRect;

};

extern Dx* dx;  //グローバル変数

コンストラクタと初期化関数

Dx.cpp

Dx* dx;

Dx::Dx() {
    _hwnd = nullptr;
    _currentBackBufferIndex = 0;
    _fenceEvent = nullptr;
    _handleDSV = {};
    _height = 0;
    _width = 0;
    _scissorRect = {};
    _viewPort = {};


    for (uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
        _fenceCount[i] = 0;
        _handleRTV[i] = {};
    }
}


bool Dx::Init(uint32_t width, uint32_t height, HWND hwnd) {
    HRESULT hResult;
#if defined(DEBUG) || defined(_DEBUG)
    {
        ComPtr<ID3D12Debug> debug;
        hResult = D3D12GetDebugInterface(IID_PPV_ARGS(debug.GetAddressOf()));

        if (SUCCEEDED(hResult)) {
            debug->EnableDebugLayer();
        }
    }
#endif

    _hwnd = hwnd;
    _width = width;
    _height = height;

    if (!CreateFactory()) {
        return false;
    }

    if (!CreateDevice()) {
        return false;
    }
    
    if (!CreateCommandQueue()) {
        return false;
    }

    if (!CreateSwapChain()) {
        return false;
    }

    if (!CreateCommandAllocator()) {
        return false;
    }

    if (!CreateCommandList()) {
        return false;
    }

    if (!CreateRenderTarget()) {
        return false;
    }

    if (!CreateDepthStencil()) {
        return false;
    }

    if (!CreateFence()) {
        return false;
    }

    CreateViewPort();
    CreateScissorRect();
    
    _pCmdList->Close(); 
    
    return true;
}

バイスの作成(NVIDIAのグラボを使用する場合)

Dx.cpp

//DXGIファクトリーの作成
bool Dx::CreateFactory() {
    HRESULT hResult;
    hResult = CreateDXGIFactory1(IID_PPV_ARGS(_pFactory.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create DXGIFactory" << std::endl;
        return false;
    }
    return true;
}

//デバイスの作成
bool Dx::CreateDevice() {
    HRESULT hResult;

    //アダプター列挙
    std::vector <IDXGIAdapter*> adapters;
    IDXGIAdapter* tmpAdapter = nullptr;
    for (uint32_t i = 0; _pFactory->EnumAdapters(i, &tmpAdapter) != DXGI_ERROR_NOT_FOUND; ++i) {
        adapters.push_back(tmpAdapter);
    }


    //アダプターの選択
    for (auto adpt : adapters) {
        DXGI_ADAPTER_DESC adesc = {};
        adpt->GetDesc(&adesc);
        std::wstring strDesc = adesc.Description;
        //NVIDIAのグラボを探す
        if (strDesc.find(L"NVIDIA") != std::string::npos) {
            tmpAdapter = adpt;
            break;
        }
    }

    //フィーチャレベル列挙
    D3D_FEATURE_LEVEL levels[] = {
        D3D_FEATURE_LEVEL_12_1,
        D3D_FEATURE_LEVEL_12_0,
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
    };

    //デバイスの作成
    //フィーチャーレベルを探す
    for (D3D_FEATURE_LEVEL l : levels) {
        hResult = D3D12CreateDevice(tmpAdapter, l, IID_PPV_ARGS(&_pDevice));
        if (hResult == S_OK) {
            break;
        }
    }
    if (hResult != S_OK) {
        std::cout << "Failed to create Device" << std::endl;
        return false;
    }

    tmpAdapter->Release(); //使い終わったらリリース

    return true;
}

バイスの作成(グラボを指定しない場合)

Dx.cpp

//DXGIファクトリーの作成
bool Dx::CreateFactory() {
    HRESULT hResult;
    hResult = CreateDXGIFactory1(IID_PPV_ARGS(_pFactory.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create DXGIFactory" << std::endl;
        return false;
    }
    return true;
}

//デバイスの作成
bool Dx::CreateDevice() {
    HRESULT hResult;

    //フィーチャレベル列挙
    D3D_FEATURE_LEVEL levels[] = {
        D3D_FEATURE_LEVEL_12_1,
        D3D_FEATURE_LEVEL_12_0,
        D3D_FEATURE_LEVEL_11_1,
        D3D_FEATURE_LEVEL_11_0,
    };

    //デバイスの作成
    //フィーチャーレベルを探す
    for (D3D_FEATURE_LEVEL l : levels) {
        hResult = D3D12CreateDevice(nullptr, l, IID_PPV_ARGS(&_pDevice));
        if (hResult == S_OK) {
            break;
        }
    }
    if (hResult != S_OK) {
        std::cout << "Failed to create Device" << std::endl;
        return false;
    }

    return true;
}

コマンドキューの作成

Dx.cpp

//コマンドキューの作成
bool Dx::CreateCommandQueue() {
    D3D12_COMMAND_QUEUE_DESC cmdQueueDesc = {};
    cmdQueueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
    cmdQueueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_NORMAL;
    cmdQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
    cmdQueueDesc.NodeMask = 0;

    HRESULT hResult = _pDevice->CreateCommandQueue(&cmdQueueDesc, IID_PPV_ARGS(_pCmdQueue.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create CommnadQueue" << std::endl;
        return false;
    }

    return true;
}

スワップチェインの作成

Dx.cpp

//スワップチェインの作成
bool Dx::CreateSwapChain() {
    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    swapChainDesc.BufferDesc.Width = _width;
    swapChainDesc.BufferDesc.Height = _height;
    swapChainDesc.BufferDesc.RefreshRate.Numerator = 60;
    swapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
    swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
    swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.BufferCount = FRAME_BUFFER_COUNT;
    swapChainDesc.OutputWindow = _hwnd;
    swapChainDesc.Windowed = TRUE;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

    ComPtr<IDXGISwapChain> swapChain;
    HRESULT hResult = _pFactory->CreateSwapChain(_pCmdQueue.Get(), &swapChainDesc, swapChain.GetAddressOf());
    if (FAILED(hResult)) {
        std::cout << "Failed to create IDXGISwapChain" << std::endl;
        return false;
    }

    //IDXGISwapChain3を取得
    hResult = swapChain.As(&_pSwapChain);
    if (FAILED(hResult)) {
        std::cout << "Failed to get IDXGISwapChain3" << std::endl;
        return false;
    }

    //バックバッファ番号を取得
    _currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();

    swapChain.Reset();  //解放

    return true;
}

コマンドアロケータの作成

Dx.cpp

//コマンドアロケータの作成
bool Dx::CreateCommandAllocator() {
    HRESULT hResult;
    for (uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
        hResult = _pDevice->CreateCommandAllocator(
            D3D12_COMMAND_LIST_TYPE_DIRECT,
            IID_PPV_ARGS(_pCmdAllocator[i].GetAddressOf()));
        if (FAILED(hResult)) {
            std::cout << "Failed to create CommandAllocator" << std::endl;
            return false;
        }
    }

    return true;
}

コマンドリストの作成

Dx.cpp

//コマンドリストの作成
bool Dx::CreateCommandList() {
    HRESULT hResult = _pDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, _pCmdAllocator[_currentBackBufferIndex].Get(), nullptr, IID_PPV_ARGS(_pCmdList.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create CommandList" << std::endl;
        return false;
    }
    return true;
}

レンダーターゲットビューの作成

Dx.cpp

//レンダーターゲットビューの作成
bool Dx::CreateRenderTarget() {
    //ディスクリプタヒープの作成
    D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
    heapDesc.NumDescriptors = FRAME_BUFFER_COUNT;
    heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
    heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    heapDesc.NodeMask = 0;

    HRESULT hResult = _pDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(_pHeapRTV.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create DescriptorHeap" << std::endl;
        return false;
    }

    D3D12_CPU_DESCRIPTOR_HANDLE handle = _pHeapRTV->GetCPUDescriptorHandleForHeapStart();
    uint32_t incrementSize = _pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

    for (uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
        hResult = _pSwapChain->GetBuffer(i, IID_PPV_ARGS(_pRenderTargets[i].GetAddressOf()));
        if (FAILED(hResult)) {
            std::cout << "Failed to get RenderTargets" << std::endl;
            return false;
        }

        D3D12_RENDER_TARGET_VIEW_DESC viewDesc = {};
        viewDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
        viewDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D;
        viewDesc.Texture2D.MipSlice = 0;
        viewDesc.Texture2D.PlaneSlice = 0;

        _pDevice->CreateRenderTargetView(_pRenderTargets[i].Get(), &viewDesc, handle);

        _handleRTV[i] = handle;
        handle.ptr += incrementSize;
    }

    return true;
}

フェンスの作成

Dx.cpp

//フェンスの作成
bool Dx::CreateFence() {
    for (uint32_t i = 0; i < FRAME_BUFFER_COUNT; i++) {
        _fenceCount[i] = 0;
    }
    HRESULT hResult = _pDevice->CreateFence(_fenceCount[_currentBackBufferIndex], D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(_pFence.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create Fence" << std::endl;
        return false;
    }

    _fenceCount[_currentBackBufferIndex]++;

    //イベントの作成
    _fenceEvent = CreateEvent(nullptr, false, false, nullptr);
    if (_fenceEvent == nullptr) {
        return false;
    }

    return true;
}

デプスステンシルビューの作成

Dx.cpp

//デプスステンシルビューの作成
bool Dx::CreateDepthStencil() {
    D3D12_HEAP_PROPERTIES heapProp = {};
    heapProp.Type = D3D12_HEAP_TYPE_DEFAULT;
    heapProp.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
    heapProp.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    heapProp.CreationNodeMask = 1;
    heapProp.VisibleNodeMask = 1;

    D3D12_RESOURCE_DESC desc = {};
    desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
    desc.Alignment = 0;
    desc.Width = _width;
    desc.Height = _height;
    desc.DepthOrArraySize = 1;
    desc.MipLevels = 1;
    desc.Format = DXGI_FORMAT_D32_FLOAT;
    desc.SampleDesc.Count = 1;
    desc.SampleDesc.Quality = 0;
    desc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    desc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;

    D3D12_CLEAR_VALUE clearValue;
    clearValue.Format = DXGI_FORMAT_D32_FLOAT;
    clearValue.DepthStencil.Depth = 1.0f;
    clearValue.DepthStencil.Stencil = 0;

    HRESULT hResult = _pDevice->CreateCommittedResource(&heapProp, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_DEPTH_WRITE, &clearValue, IID_PPV_ARGS(_pDepthStencilBuffer.GetAddressOf()));
    if (FAILED(hResult)) {
        std::cout << "Failed to create DepthStencilBuffer" << std::endl;
        return false;
    }

    D3D12_DESCRIPTOR_HEAP_DESC heapDesc = {};
    heapDesc.NumDescriptors = 1;
    heapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV;
    heapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
    heapDesc.NodeMask = 0;

    hResult = _pDevice->CreateDescriptorHeap(&heapDesc, IID_PPV_ARGS(&_pHeapDSV));
    if (FAILED(hResult)) {
        std::cout << "Failed to create DescriptorHeap for DepthStencilView " << std::endl;
        return false;
    }

    D3D12_CPU_DESCRIPTOR_HANDLE handle = _pHeapDSV->GetCPUDescriptorHandleForHeapStart();
    uint32_t incrementSize = _pDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_DSV);

    D3D12_DEPTH_STENCIL_VIEW_DESC viewDesc = {};
    viewDesc.Format = DXGI_FORMAT_D32_FLOAT;
    viewDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
    viewDesc.Texture2D.MipSlice = 0;
    viewDesc.Flags = D3D12_DSV_FLAG_NONE;

    _pDevice->CreateDepthStencilView(_pDepthStencilBuffer.Get(), &viewDesc, handle);
    _handleDSV = handle;

    return true;
}

ビューポート、シザー矩形の作成

Dx.cpp

//ビューポートの作成
void Dx::CreateViewPort() {
    _viewPort.TopLeftX = 0;
    _viewPort.TopLeftY = 0;
    _viewPort.Width = static_cast<float>(_width);
    _viewPort.Height = static_cast<float>(_height);
    _viewPort.MinDepth = 0.0f;
    _viewPort.MaxDepth = 1.0f;
}

//シザー矩形の作成
void Dx::CreateScissorRect() {
    _scissorRect.left = 0;
    _scissorRect.right = _width;
    _scissorRect.top = 0;
    _scissorRect.bottom = _height;
}

終了処理

Dx.cpp

//終了処理
void Dx::Terminate() {
    WaitGPU();

    if (_fenceEvent != nullptr) {
        CloseHandle(_fenceEvent);
        _fenceEvent = nullptr;
    }

    _pHeapRTV.Reset();
}

//GPUの処理待機
void Dx::WaitGPU() {
    //シグナル処理
    _pCmdQueue->Signal(_pFence.Get(), _fenceCount[_currentBackBufferIndex]);
    //イベントを設定
    _pFence->SetEventOnCompletion(_fenceCount[_currentBackBufferIndex], _fenceEvent);
    //待機処理
    WaitForSingleObjectEx(_fenceEvent, INFINITE, false);

    _fenceCount[_currentBackBufferIndex]++;
}

レンダリング

Dx.cpp

//描画開始
void Dx::BeginRender() {
    //コマンドの記録開始
    _pCmdAllocator[_currentBackBufferIndex]->Reset();
    _pCmdList->Reset(_pCmdAllocator[_currentBackBufferIndex].Get(), nullptr);

    //リソースバリア
    D3D12_RESOURCE_BARRIER barrier = {};
    barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.pResource = _pRenderTargets[_currentBackBufferIndex].Get();
    barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
    barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
    barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    _pCmdList->ResourceBarrier(1, &barrier);

    //レンダーターゲットの設定
    _pCmdList->OMSetRenderTargets(1, &_handleRTV[_currentBackBufferIndex], false, &_handleDSV);

    //クリアカラー(赤)
    float clearColor[] = { 1.0f, 0.0f, 0.0f, 1.0f };

    //レンダーターゲットビューをクリア
    _pCmdList->ClearRenderTargetView(_handleRTV[_currentBackBufferIndex], clearColor, 0, nullptr);

    //デプスステンシルバッファクリア
    _pCmdList->ClearDepthStencilView(_handleDSV, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);

    //ビューポートとシザー矩形をセット
    _pCmdList->RSSetViewports(1, &_viewPort);
    _pCmdList->RSSetScissorRects(1, &_scissorRect);

}

//描画終了
void Dx::EndRender() {
    //リソースバリア
    D3D12_RESOURCE_BARRIER barrier = {};
    barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.pResource = _pRenderTargets[_currentBackBufferIndex].Get();
    barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
    barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
    barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
    _pCmdList->ResourceBarrier(1, &barrier);

    //コマンドリストを閉じる
    _pCmdList->Close();

    //コマンドを実行
    ID3D12CommandList* ppCmdLists[] = { _pCmdList.Get() };
    _pCmdQueue->ExecuteCommandLists(1, ppCmdLists);

    //画面に表示
    Present(1);
}

//コマンドリストのリセット
void Dx::ResetCmdList() {
    //_pCmdAllocator->Reset();
    _pCmdList->Reset(_pCmdAllocator->Get(), nullptr);
}

//コマンドリストの実行
void Dx::ExcuteCmdList() {
    ID3D12CommandList* ppCmdLists[] = { _pCmdList.Get() };
    _pCmdQueue->ExecuteCommandLists(1, ppCmdLists);

    //シグナル処理
    uint64_t currentValue = _fenceCount[_currentBackBufferIndex];
    _pCmdQueue->Signal(_pFence.Get(), currentValue);

    if (_pFence->GetCompletedValue() != currentValue) {
        auto event = CreateEvent(nullptr, false, false, nullptr);
        _pFence->SetEventOnCompletion(currentValue, event);
        WaitForSingleObject(event, INFINITE);
        CloseHandle(event);
    }

    _pCmdAllocator[_currentBackBufferIndex]->Reset();
    _pCmdList->Reset(_pCmdAllocator[_currentBackBufferIndex].Get(), nullptr);
}

//表示
void Dx::Present(uint32_t interval) {
    //画面に表示
    _pSwapChain->Present(interval, 0);

    //シグナル処理
    uint64_t currentValue = _fenceCount[_currentBackBufferIndex];
    _pCmdQueue->Signal(_pFence.Get(), currentValue);

    //バックバッファ番号を更新
    _currentBackBufferIndex = _pSwapChain->GetCurrentBackBufferIndex();


    //描画待機
    if (_pFence->GetCompletedValue() < _fenceCount[_currentBackBufferIndex]) {
        _pFence->SetEventOnCompletion(_fenceCount[_currentBackBufferIndex], _fenceEvent);
        WaitForSingleObjectEx(_fenceEvent, INFINITE, false);
    }

    _fenceCount[_currentBackBufferIndex] = currentValue + 1;
}

getter関数

Dx.cpp

//デバイスの取得
ID3D12Device* Dx::GetDevice() {
    return _pDevice.Get();
}

//コマンドリストの取得
ID3D12GraphicsCommandList* Dx::GetCmdList() {
    return _pCmdList.Get();
}

//ウィンドウの高さの取得
uint32_t Dx::GetWindowWidth() {
    return _width;
}

//ウィンドウの幅の取得
uint32_t Dx::GetWindowHeight() {
    return _height;
}

//バックバッファのインデックスを取得
uint32_t Dx::GetCurrentBackBufferIndex() {
    return _currentBackBufferIndex;
}

実行結果

クリアカラーで赤を指定しているため、赤い画面が表示されている。

参考資料

書籍

サイト

qiita.com

learn.microsoft.com