DirectX 11 - Initialization (C/C++ & Win32)
How to initialize DirectX 11 and clear the screen.
Updated Jun 26, 2022

main.cpp

#define WIN32_LEAN_AND_MEAN
#define UNICODE
#include <assert.h>
#include <d3d11_1.h>
#include <windows.h>

LRESULT CALLBACK WindowProc(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam) {
    switch(Message) {
        case WM_KEYDOWN: {
            switch(WParam) {
                case 'O': { DestroyWindow(Window); };
            }
        } break;
        case WM_DESTROY: { PostQuitMessage(0); } break;
        
        default: {
            return DefWindowProc(Window, Message, WParam,  LParam);
        }
    }
    
    return 0;
}

int WINAPI wWinMain(HINSTANCE Instance, HINSTANCE PrevInstance, PWSTR CmdLine, int CmdShow) {
    
    WNDCLASS WindowClass = {};
    
    const wchar_t ClassName[] = L"MyWindowClass";
    
    WindowClass.lpfnWndProc = WindowProc;
    WindowClass.hInstance = Instance;
    WindowClass.lpszClassName = ClassName;
    WindowClass.hCursor = LoadCursor(0, IDC_CROSS);
    
    if(!RegisterClass(&WindowClass)) {
        MessageBox(0, L"RegisterClass failed", 0, 0);
        return GetLastError();
    }
    
    HWND Window = CreateWindowEx(0, ClassName, L"Window",
                                 WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                                 CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                                 0, 0, Instance, 0);
    
    if(!Window) {
        MessageBox(0, L"CreateWindowEx failed", 0, 0);
        return GetLastError();
    }
    
    // Device & Context
    
    ID3D11Device *BaseDevice;
    ID3D11DeviceContext *BaseContext;
    
    UINT CreationFlags = 0;
#ifdef _DEBUG
    CreationFlags = D3D11_CREATE_DEVICE_DEBUG;
#endif
    
    D3D_FEATURE_LEVEL FeatureLevels[] = {
        D3D_FEATURE_LEVEL_11_0
    };
    
    HRESULT Result = D3D11CreateDevice(0, D3D_DRIVER_TYPE_HARDWARE, 0,
                                       CreationFlags, FeatureLevels,
                                       ARRAYSIZE(FeatureLevels),
                                       D3D11_SDK_VERSION, &BaseDevice, 0,
                                       &BaseContext);    
    
    if(FAILED(Result)) {
        MessageBox(0, L"D3D11CreateDevice failed", 0, 0);
        return GetLastError();
    }
    
    ID3D11Device1 *Device;
    ID3D11DeviceContext1 *Context;
    
    Result = BaseDevice->QueryInterface(__uuidof(ID3D11Device1), (void **)&Device);
    assert(SUCCEEDED(Result));
    BaseDevice->Release();
    
    Result = BaseContext->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&Context);
    assert(SUCCEEDED(Result));
    BaseContext->Release();
    
    // Swap chain
    
    DXGI_SWAP_CHAIN_DESC1 SwapChainDesc = {};
    
    SwapChainDesc.Width = 0;
    SwapChainDesc.Height = 0;
    SwapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    SwapChainDesc.SampleDesc.Count = 1;
    SwapChainDesc.SampleDesc.Quality = 0;
    SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    SwapChainDesc.BufferCount = 1;
    SwapChainDesc.Scaling = DXGI_SCALING_STRETCH;
    SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    SwapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
    SwapChainDesc.Flags = 0;
    
    IDXGISwapChain1 *SwapChain;
    
    IDXGIDevice2 *DxgiDevice;
    Result = Device->QueryInterface(__uuidof(IDXGIDevice2), (void **)&DxgiDevice);
    assert(SUCCEEDED(Result));
    
    IDXGIAdapter *DxgiAdapter;
    Result = DxgiDevice->GetAdapter(&DxgiAdapter);
    assert(SUCCEEDED(Result));
    DxgiDevice->Release();
    
    IDXGIFactory2 *DxgiFactory;
    Result = DxgiAdapter->GetParent(__uuidof(IDXGIFactory2), (void **)&DxgiFactory);
    assert(SUCCEEDED(Result));
    DxgiAdapter->Release();
    
    Result = DxgiFactory->CreateSwapChainForHwnd(Device, Window,
                                                 &SwapChainDesc, 0, 0, &SwapChain);
    assert(SUCCEEDED(Result));
    DxgiFactory->Release();
    
    // Frame buffer
    
    ID3D11Texture2D *FrameBuffer;
    Result = SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&FrameBuffer);
    assert(SUCCEEDED(Result));
    
    ID3D11RenderTargetView *FrameBufferView;
    Result = Device->CreateRenderTargetView(FrameBuffer, 0, &FrameBufferView);
    assert(SUCCEEDED(Result));
    FrameBuffer->Release();
    
    bool Running = true;
    
    while(Running) {
        MSG Message;
        while(PeekMessage(&Message, nullptr, 0, 0, PM_REMOVE)) {
            if(Message.message == WM_QUIT) Running = false;
            TranslateMessage(&Message);
            DispatchMessage(&Message);
        }
        
        float Color[4] = {0.3f, 0.3f, 0.3f, 1.0f};
        Context->ClearRenderTargetView(FrameBufferView, Color);
        SwapChain->Present(1, 0);
    }
    
    return 0;
}

Build

cl main.cpp /link user32.lib d3d11.lib

build.bat

@echo off

set COMMON_COMPILER_FLAGS=/W4 /wd4100 /Oi /nologo /Fegame.exe

set DEBUG_FLAGS=/Zi /MTd
set RELEASE_FLAGS=/O2

set COMPILER_FLAGS=%COMMON_COMPILER_FLAGS% %DEBUG_FLAGS%
REM set COMPILER_FLAGS=%COMMON_COMPILER_FLAGS% %RELEASE_FLAGS%

set LINKER_FLAGS=/INCREMENTAL:NO /OPT:REF
set LIBS=user32.lib d3d11.lib

cl %COMPILER_FLAGS% main.cpp /link %LINKER_FLAGS% %LIBS%