Updated Aug 3, 2021

DirectX 11 - Initialization (C/C++ & Win32)

How to initialize DirectX 11 and clear the screen.

Code (main.cpp)

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

LRESULT CALLBACK 
window_proc(HWND window, 
            UINT message, 
            WPARAM w_param, 
            LPARAM l_param)
{
    switch(message)
    {
        case WM_KEYDOWN:
        {
            switch(w_param)
            {
                case 'O':
                {
                    DestroyWindow(window);
                };
            }
        } break;
        
        case WM_DESTROY:
        {
            PostQuitMessage(0);
        } break;
        
        default:
        {
            return DefWindowProc(window, 
                                 message, 
                                 w_param, 
                                 l_param);
        }
    }
    
    return 0;
}

int WINAPI 
wWinMain(HINSTANCE instance, 
         HINSTANCE prev_instance, 
         PWSTR cmd_line, 
         int cmd_show)
{
    // window creation
    
    WNDCLASS window_class = {};
    
    const wchar_t class_name[] = L"MyWindowClass";
    
    window_class.lpfnWndProc = window_proc;
    window_class.hInstance = instance;
    window_class.lpszClassName = class_name;
    window_class.hCursor = LoadCursor(0, IDC_CROSS);
    
    if(!RegisterClass(&window_class))
    {
        MessageBox(0, L"RegisterClass failed", 0, 0);
        return GetLastError();
    }
    
    HWND window = CreateWindowEx(0,
                                 class_name,
                                 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();
    }
    
    // dx device & context
    
    ID3D11Device *base_device;
    ID3D11DeviceContext *base_context;
    
    UINT creation_flags = 0;
#ifdef _DEBUG
    creation_flags = D3D11_CREATE_DEVICE_DEBUG;
#endif
    
    D3D_FEATURE_LEVEL feature_levels[] = {
        D3D_FEATURE_LEVEL_11_0
    };
    
    HRESULT result = D3D11CreateDevice(0,
                                       D3D_DRIVER_TYPE_HARDWARE,
                                       0,
                                       creation_flags,
                                       feature_levels,
                                       ARRAYSIZE(feature_levels),
                                       D3D11_SDK_VERSION,
                                       &base_device,
                                       0,
                                       &base_context
                                       );
    
    if(FAILED(result))
    {
        MessageBox(0, L"D3D11CreateDevice failed", 0, 0);
        return GetLastError();
    }
    
    ID3D11Device1 *device;
    ID3D11DeviceContext1 *context;
    
    result = base_device->QueryInterface(__uuidof(ID3D11Device1), (void **)&device);
    assert(SUCCEEDED(result));
    base_device->Release();
    
    result = base_context->QueryInterface(__uuidof(ID3D11DeviceContext1), (void **)&context);
    assert(SUCCEEDED(result));
    base_context->Release();
    
    // swap chain
    
    DXGI_SWAP_CHAIN_DESC1 swap_chain_desc = {};
    
    swap_chain_desc.Width = 0;
    swap_chain_desc.Height = 0;
    swap_chain_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
    swap_chain_desc.SampleDesc.Count = 1;
    swap_chain_desc.SampleDesc.Quality = 0;
    swap_chain_desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swap_chain_desc.BufferCount = 1;
    swap_chain_desc.Scaling = DXGI_SCALING_STRETCH;
    swap_chain_desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    swap_chain_desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
    swap_chain_desc.Flags = 0;
    
    IDXGISwapChain1 *swap_chain;
    
    IDXGIDevice2 * dxgi_device;
    result = device->QueryInterface(__uuidof(IDXGIDevice2), (void **)&dxgi_device);
    assert(SUCCEEDED(result));
    
    IDXGIAdapter * dxgi_adapter;
    result = dxgi_device->GetAdapter(&dxgi_adapter);
    assert(SUCCEEDED(result));
    dxgi_device->Release();
    
    IDXGIFactory2 * dxgi_factory;
    result = dxgi_adapter->GetParent(__uuidof(IDXGIFactory2), (void **)&dxgi_factory);
    assert(SUCCEEDED(result));
    dxgi_adapter->Release();
    
    result = dxgi_factory->CreateSwapChainForHwnd(device,
                                                  window,
                                                  &swap_chain_desc,
                                                  0,
                                                  0,
                                                  &swap_chain
                                                  );
    assert(SUCCEEDED(result));
    dxgi_factory->Release();
    
    // frame buffer view
    
    ID3D11Texture2D *frame_buffer;
    result = swap_chain->GetBuffer(0,
                                   __uuidof(ID3D11Texture2D),
                                   (void **)&frame_buffer
                                   );
    assert(SUCCEEDED(result));
    
    ID3D11RenderTargetView *frame_buffer_view;
    result = device->CreateRenderTargetView(frame_buffer,
                                            0,
                                            &frame_buffer_view
                                            );
    assert(SUCCEEDED(result));
    frame_buffer->Release();
    
    // loop
    
    bool running = true;
    
    while(running)
    {
        MSG msg;
        while(PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
        {
            if(msg.message == WM_QUIT) running = false;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        
        float color[4] = {0.3f, 0.3f, 0.3f, 1.0};
        
        context->ClearRenderTargetView(frame_buffer_view, color);
        
        swap_chain->Present(1, 0);
    }
    
    return 0;
}

Build script (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%