   Window resize & swap chain
//--------------------------------------------------------------------------------------// File: Tutorial01.cpp//// This application demonstrates creating a Direct3D 10 device//// Copyright (c) Microsoft Corporation. All rights reserved.//--------------------------------------------------------------------------------------#include <windows.h>#include <d3d10.h>#include <d3dx10.h>#include "resource.h"//--------------------------------------------------------------------------------------// Global Variables//--------------------------------------------------------------------------------------HINSTANCEg_hInst = NULL;HWNDg_hWnd = NULL;D3D10_DRIVER_TYPE  g_driverType = D3D10_DRIVER_TYPE_NULL;ID3D10Device* g_pd3dDevice = NULL;IDXGISwapChain*    g_pSwapChain = NULL;ID3D10RenderTargetView* g_pRenderTargetView = NULL;//--------------------------------------------------------------------------------------// Forward declarations//--------------------------------------------------------------------------------------HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );HRESULT InitDevice();void CleanupDevice();LRESULT CALLBACK    WndProc( HWND, UINT, WPARAM, LPARAM );void Render();//--------------------------------------------------------------------------------------// Entry point to the program. Initializes everything and goes into a message processing // loop. Idle time is used to render the scene.//--------------------------------------------------------------------------------------int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow ){    if( FAILED( InitWindow( hInstance, nCmdShow ) ) )   return 0;    if( FAILED( InitDevice() ) )    {   CleanupDevice();   return 0;    }    // Main message loop    MSG msg = {0};    while( WM_QUIT != msg.message )    {   if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )   {  TranslateMessage( &msg );  DispatchMessage( &msg );   }   else   {  Render();   }    }    CleanupDevice();    return ( int )msg.wParam;}//--------------------------------------------------------------------------------------// Register class and create window//--------------------------------------------------------------------------------------HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow ){    // Register class    WNDCLASSEX wcex;    wcex.cbSize = sizeof( WNDCLASSEX );    wcex.style = CS_HREDRAW | CS_VREDRAW;    wcex.lpfnWndProc = WndProc;    wcex.cbClsExtra = 0;    wcex.cbWndExtra = 0;    wcex.hInstance = hInstance;    wcex.hIcon = LoadIcon( hInstance, ( LPCTSTR )IDI_TUTORIAL1 );    wcex.hCursor = LoadCursor( NULL, IDC_ARROW );    wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 );    wcex.lpszMenuName = NULL;    wcex.lpszClassName = L"TutorialWindowClass";    wcex.hIconSm = LoadIcon( wcex.hInstance, ( LPCTSTR )IDI_TUTORIAL1 );    if( !RegisterClassEx( &wcex ) )   return E_FAIL;    // Create window    g_hInst = hInstance;    RECT rc = { 0, 0, 640, 480 };    AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE );    g_hWnd = CreateWindow( L"TutorialWindowClass", L"Direct3D 10 Tutorial 1: Direct3D 10 Basics", WS_OVERLAPPEDWINDOW,  CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance,  NULL );    if( !g_hWnd )   return E_FAIL;    ShowWindow( g_hWnd, nCmdShow );    return S_OK;}//--------------------------------------------------------------------------------------// Called every time the application receives a message//--------------------------------------------------------------------------------------LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ){    PAINTSTRUCT ps;    HDC hdc;    switch( message )    {   case WM_PAINT:  hdc = BeginPaint( hWnd, &ps );  EndPaint( hWnd, &ps );  break;   case WM_DESTROY:  PostQuitMessage( 0 );  break;   default:  return DefWindowProc( hWnd, message, wParam, lParam );    }    return 0;}//--------------------------------------------------------------------------------------// Create Direct3D device and swap chain//--------------------------------------------------------------------------------------HRESULT InitDevice(){    HRESULT hr = S_OK;;    RECT rc;    GetClientRect( g_hWnd, &rc );    UINT width = rc.right - rc.left;    UINT height = rc.bottom - rc.top;    UINT createDeviceFlags = 0;#ifdef _DEBUG    createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG;#endif    D3D10_DRIVER_TYPE driverTypes[] =    {   D3D10_DRIVER_TYPE_HARDWARE,   D3D10_DRIVER_TYPE_REFERENCE,    };    UINT numDriverTypes = sizeof( driverTypes ) / sizeof( driverTypes[0] );    DXGI_SWAP_CHAIN_DESC sd;    ZeroMemory( &sd, sizeof( sd ) );    sd.BufferCount = 1;    sd.BufferDesc.Width = width;    sd.BufferDesc.Height = height;    sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;    sd.BufferDesc.RefreshRate.Numerator = 60;    sd.BufferDesc.RefreshRate.Denominator = 1;    sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;    sd.OutputWindow = g_hWnd;    sd.SampleDesc.Count = 1;    sd.SampleDesc.Quality = 0;    sd.Windowed = TRUE;    for( UINT driverTypeIndex = 0; driverTypeIndex < numDriverTypes; driverTypeIndex++ )    {   g_driverType = driverTypes[driverTypeIndex];   hr = D3D10CreateDeviceAndSwapChain( NULL, g_driverType, NULL, createDeviceFlags,    D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice );   if( SUCCEEDED( hr ) )  break;    }    if( FAILED( hr ) )   return hr;    // Create a render target view    ID3D10Texture2D* pBackBuffer;    hr = g_pSwapChain->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBackBuffer );    if( FAILED( hr ) )   return hr;    hr = g_pd3dDevice->CreateRenderTargetView( pBackBuffer, NULL, &g_pRenderTargetView );    pBackBuffer->Release();    if( FAILED( hr ) )   return hr;    g_pd3dDevice->OMSetRenderTargets( 1, &g_pRenderTargetView, NULL );    // Setup the viewport    D3D10_VIEWPORT vp;    vp.Width = width;    vp.Height = height;    vp.MinDepth = 0.0f;    vp.MaxDepth = 1.0f;    vp.TopLeftX = 0;    vp.TopLeftY = 0;    g_pd3dDevice->RSSetViewports( 1, &vp );    return S_OK;}//--------------------------------------------------------------------------------------// Render the frame//--------------------------------------------------------------------------------------void Render(){    // Just clear the backbuffer    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );    g_pSwapChain->Present( 0, 0 );}//--------------------------------------------------------------------------------------// Clean up the objects we've created//--------------------------------------------------------------------------------------void CleanupDevice(){    if( g_pd3dDevice ) g_pd3dDevice->ClearState();    if( g_pRenderTargetView ) g_pRenderTargetView->Release();    if( g_pSwapChain ) g_pSwapChain->Release();    if( g_pd3dDevice ) g_pd3dDevice->Release();}This code is the first tutorial from Microsoft DirectX 10 SDK. I learned that everytime application window is resized we must recreate swap chain or at least call function ResizeBuffers(...) to properly render on hole window surface. If for example we don't recreate swap chain but only set new viewport, image will cover hole window but it will be stretched.In this example I found only one function that handles rendering//--------------------------------------------------------------------------------------// Render the frame//--------------------------------------------------------------------------------------void Render(){    // Just clear the backbuffer    float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f }; //red,green,blue,alpha    g_pd3dDevice->ClearRenderTargetView( g_pRenderTargetView, ClearColor );    g_pSwapChain->Present( 0, 0 );}If I resize window, program renders color on hole surface.How? In this code buffer size is set only once    sd.BufferDesc.Width = width;    sd.BufferDesc.Height = height;..there is no call ResizeBuffer() anywhere in the codealso viewport size is set only once    D3D10_VIEWPORT vp;    vp.Width = width;    vp.Height = height;Can you explain me why this program works even when I resize application window.   
  Just a note, you don't have to recreate a swapchain when the window is resized, you only need to resizebuffers.This code does not handle the resize correctly so I imagine that the swapchain is doing a stretching blt to cover the window.  The message procedure would have to handle the WM_SIZE message and call resizebuffers on the swapchain.   