DirectX11 マルチスクリーン2

画面の初期化

スワップチェインとレンダーターゲットをモニターの数だけ生成する.できればモニターの数を自動で取得して初期化をしたかったが,めんどくさそうだったのでやめた.

モニターの情報を保持する構造体を作成

struct SCREEN {
    int32_t X;
    int32_t Y;
    int32_t Width;
    int32_t Height;
    HWND Hwnd;
};

スワップチェインの生成

const uint32_t MONITOR_NUM = 4;
IDXGISwapChain* _pSwapChains[4];
ID3D11Texture2D* _pRenderTargets[4];
ID3D11RenderTargetView* _pRenderTargetViews[4];
bool DxManager::CreateSwapChain(SCREEN monitor, uint32_t index) {
    HRESULT hResult = S_OK;
    DXGI_MODE_DESC modeDesc = {};
    modeDesc.Width = monitor.Width;
    modeDesc.Height = monitor.Height;
    modeDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
    modeDesc.RefreshRate.Numerator = 60;
    modeDesc.RefreshRate.Denominator = 1;
    modeDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
    modeDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

    DXGI_SWAP_CHAIN_DESC swapChainDesc = {};
    ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
    swapChainDesc.BufferCount = 2;
    swapChainDesc.BufferDesc = modeDesc;
    swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDesc.OutputWindow = monitor.Hwnd;
    swapChainDesc.SampleDesc.Count = 1;
    swapChainDesc.SampleDesc.Quality = 0;
    swapChainDesc.Windowed = true;
    swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    swapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

    hResult = _pFactory->CreateSwapChain(_pDevice.Get(), &swapChainDesc, &_pSwapChains[index]);
    if (FAILED(hResult)) {
        return false;
    }

    _pAdapter->Release();
    _pFactory->Release();
    

    hResult = _pSwapChains[index]->GetBuffer(0, IID_PPV_ARGS(&_pRenderTargets[index]));
    if (FAILED(hResult)) {
        return false;
    }

    hResult = _pDevice->CreateRenderTargetView(_pRenderTargets[index], nullptr, &_pRenderTargetViews[index]);
    if (FAILED(hResult)) {
        return false;
    }

    _viewport.Width = static_cast<float>(monitor.Width);
    _viewport.Height = static_cast<float>(monitor.Height);
    _viewport.MinDepth = 0.0f;
    _viewport.MaxDepth = 1.0f;
    _viewport.TopLeftX = 0;
    _viewport.TopLeftY = 0;
    
    

    return true;
}

レンダリング

void DxManager::BeginRender() {
    for (uint32_t i = 0; i < MONITOR_NUM; i++){
        _pDeviceContext->OMSetRenderTargets(1, &_pRenderTargetViews[i], nullptr);
        _pDeviceContext->RSSetViewports(1, &_viewport);

        float clearColor[4] = { 1.0f, 0.0f, 0.0f, 0.0f };
        _pDeviceContext->ClearRenderTargetView(_pRenderTargetViews[i], clearColor);
    }
}

void DxManager::EndRender() {
    for (uint32_t i = 0; i < MONITOR_NUM; i++) {
        _pSwapChains[i]->Present(1, 0);
    }
}