diff options
| -rw-r--r-- | .gitignore | 13 | ||||
| -rw-r--r-- | d3d11-resize-draw/d3d11-resize-draw.slnx | 7 | ||||
| -rw-r--r-- | d3d11-resize-draw/d3d11-resize-draw.vcxproj | 146 | ||||
| -rw-r--r-- | d3d11-resize-draw/d3d11-resize-draw.vcxproj.filters | 27 | ||||
| -rw-r--r-- | d3d11-resize-draw/main.cpp | 469 | ||||
| -rw-r--r-- | d3d11-resize-draw/shader.hlsl | 30 |
6 files changed, 688 insertions, 4 deletions
@@ -1,5 +1,10 @@ -.DS_Store -.cache -.vs +*.DS_Store +*.cache +*.cso +*.exe +*.pdb +*.vcxproj.user +*.vs bin -build
\ No newline at end of file +build +d3d11-re.*
\ No newline at end of file diff --git a/d3d11-resize-draw/d3d11-resize-draw.slnx b/d3d11-resize-draw/d3d11-resize-draw.slnx new file mode 100644 index 0000000..49bfd17 --- /dev/null +++ b/d3d11-resize-draw/d3d11-resize-draw.slnx @@ -0,0 +1,7 @@ +<Solution> + <Configurations> + <Platform Name="x64" /> + <Platform Name="x86" /> + </Configurations> + <Project Path="d3d11-resize-draw.vcxproj" Id="53c908fe-a2be-4c82-8088-06bda7620da6" /> +</Solution> diff --git a/d3d11-resize-draw/d3d11-resize-draw.vcxproj b/d3d11-resize-draw/d3d11-resize-draw.vcxproj new file mode 100644 index 0000000..8da36ae --- /dev/null +++ b/d3d11-resize-draw/d3d11-resize-draw.vcxproj @@ -0,0 +1,146 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <VCProjectVersion>18.0</VCProjectVersion> + <Keyword>Win32Proj</Keyword> + <ProjectGuid>{53c908fe-a2be-4c82-8088-06bda7620da6}</ProjectGuid> + <RootNamespace>d3d11resizedraw</RootNamespace> + <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v145</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v145</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v145</PlatformToolset> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v145</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level4</WarningLevel> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <ConformanceMode>true</ConformanceMode> + <LanguageStandard>stdcpp20</LanguageStandard> + </ClCompile> + <Link> + <SubSystem>Windows</SubSystem> + <GenerateDebugInformation>true</GenerateDebugInformation> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="main.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="shader.hlsl"> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Pixel</ShaderType> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Pixel</ShaderType> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Pixel</ShaderType> + <ShaderType Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Pixel</ShaderType> + <FileType>Document</FileType> + </None> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project>
\ No newline at end of file diff --git a/d3d11-resize-draw/d3d11-resize-draw.vcxproj.filters b/d3d11-resize-draw/d3d11-resize-draw.vcxproj.filters new file mode 100644 index 0000000..887115c --- /dev/null +++ b/d3d11-resize-draw/d3d11-resize-draw.vcxproj.filters @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Source Files"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions> + </Filter> + <Filter Include="Header Files"> + <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier> + <Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions> + </Filter> + <Filter Include="Resource Files"> + <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier> + <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="main.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="shader.hlsl"> + <Filter>Source Files</Filter> + </None> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/d3d11-resize-draw/main.cpp b/d3d11-resize-draw/main.cpp new file mode 100644 index 0000000..aa5ff88 --- /dev/null +++ b/d3d11-resize-draw/main.cpp @@ -0,0 +1,469 @@ +// -------------------------------------------------------------------------------- +// Direct3D 11 demo comparing various methods of drawing while resizing +// +// ref: https://gist.github.com/d7samurai/261c69490cce0620d0bfc93003cd1052 +// +// SPDX-License-Identifier: 0BSD +// -------------------------------------------------------------------------------- + +#define ACTIVE_METHOD 3 + +// -------------------------------------------------------------------------------- +// Method 1: Don't do anything special. This is just to highlight the problem. +// -------------------------------------------------------------------------------- +// #define ACTIVE_METHOD 1 + +// -------------------------------------------------------------------------------- +// Method 2: Set CS_VREDRAW | CS_HREDRAW and render in WM_PAINT. +// +// This is visually perfect, but some functions can't be called from inside +// WM_PAINT. For example, creating a modal dialog box with MessageBoxW() or +// assert() will block the message loop. When this happens, the app will hang or +// crash. +// -------------------------------------------------------------------------------- + +// -------------------------------------------------------------------------------- +// Method 3: Render during resize with WM_TIMER. +// +// This is a well-known workaround that has been generally proven safe. This is +// what sokol_app.h does. +// +// If you use WM_TIMER alone, there is a small gap at the side of the window when +// resizing, but it's barely visible. +// +// If you draw on WM_TIMER and WM_SIZE, there is no bar, but there may be redundant +// draw calls. +// +// Creating dialogs in WM_TIMER and WM_SIZE doesn't seem to be an issue. +// -------------------------------------------------------------------------------- + +#if !defined(ACTIVE_METHOD) || ACTIVE_METHOD < 1 || ACTIVE_METHOD > 3 +# error ACTIVE_METHOD not set +#endif + +#include <cmath> +#include <cstdio> +#include <d3d11.h> +#include <d3dcompiler.h> + +#pragma comment(lib, "d3d11.lib") +#pragma comment(lib, "d3dcompiler.lib") + +// -------------------------------------------------------------------------------- +// Shared code +// -------------------------------------------------------------------------------- + +#define Assert(expr) do { if (!(expr)) { __debugbreak(); } } while (0); +#define HR(hr) do { HRESULT hr_ = (hr); Assert(SUCCEEDED(hr_)); } while (0); + +struct CBuffer +{ + FLOAT color[4]; + FLOAT rot[16]; +}; + +static struct +{ + HWND hwnd; + IDXGISwapChain* d3dswp; + ID3D11Device* d3ddev; + ID3D11DeviceContext* d3dctx; + ID3D11RenderTargetView* d3drtv; + UINT vstride; + UINT voffset; + ID3D11Buffer* vbuf_quad; + ID3D11Buffer* ibuf_quad; + UINT ibuf_quad_count; + ID3D11VertexShader* vs; + ID3D11PixelShader* ps; + ID3D11InputLayout* vlayout; + ID3D11Buffer* cbuf; + FLOAT vp_w; + FLOAT vp_h; +} G = { 0 }; + +static void CreateDemoWindow(UINT class_style, WNDPROC wndproc) +{ + WNDCLASSW wcl = { .style = class_style, .lpfnWndProc = wndproc, .hInstance = GetModuleHandleW(0), .lpszClassName = L"d3d11-resize-draw"}; + RegisterClassW(&wcl); + + G.hwnd = CreateWindowExW(0, wcl.lpszClassName, wcl.lpszClassName, WS_OVERLAPPEDWINDOW, 0, 0, 1024, 768, 0, 0, 0, 0); + Assert(G.hwnd); +} + +static void DestroyRenderTarget() +{ + if (G.d3drtv) { + G.d3drtv->Release(); + G.d3drtv = 0; + } +} + +static void CreateRenderTarget() +{ + Assert(!G.d3drtv); + ID3D11Texture2D* tex; + HR(G.d3dswp->GetBuffer(0, IID_PPV_ARGS(&tex))); + HR(G.d3ddev->CreateRenderTargetView(tex, 0, &G.d3drtv)); + tex->Release(); +} + +static void SetupD3D11() +{ + DXGI_SWAP_CHAIN_DESC swap_chain_desc = { + .BufferDesc = { .Format = DXGI_FORMAT_R8G8B8A8_UNORM, }, + .SampleDesc = { .Count = 1, }, + .BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT, + .BufferCount = 2, + .OutputWindow = G.hwnd, + .Windowed = TRUE, + .SwapEffect = DXGI_SWAP_EFFECT_DISCARD, + }; + D3D_FEATURE_LEVEL feature_levels[] = { D3D_FEATURE_LEVEL_11_0 }; + + HR(D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, feature_levels, ARRAYSIZE(feature_levels), D3D11_SDK_VERSION, &swap_chain_desc, &G.d3dswp, &G.d3ddev, 0, &G.d3dctx)); + + // Vertex shader + { + ID3DBlob* blob; + HR(D3DCompileFromFile(L"shader.hlsl", 0, 0, "VsMain", "vs_5_0", 0, 0, &blob, nullptr)); + HR(G.d3ddev->CreateVertexShader(blob->GetBufferPointer(), blob->GetBufferSize(), 0, &G.vs)); + + D3D11_INPUT_ELEMENT_DESC idesc[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + HR(G.d3ddev->CreateInputLayout(idesc, ARRAYSIZE(idesc), blob->GetBufferPointer(), blob->GetBufferSize(), &G.vlayout)); + blob->Release(); + } + // Pixel shader + { + ID3DBlob* blob; + HR(D3DCompileFromFile(L"shader.hlsl", 0, 0, "PsMain", "ps_5_0", 0, 0, &blob, nullptr)); + HR(G.d3ddev->CreatePixelShader(blob->GetBufferPointer(), blob->GetBufferSize(), 0, &G.ps)); + blob->Release(); + } + + struct Vertex { FLOAT p[2]; FLOAT t[2]; }; + G.vstride = sizeof(Vertex); + G.voffset = 0; + + // Quad vertex buffer + { + Vertex vdata[] = { + { { -1.0f, +1.0f }, { 0.0f, 0.0f } }, + { { +1.0f, +1.0f }, { 1.0f, 0.0f } }, + { { +1.0f, -1.0f }, { 1.0f, 1.0f } }, + { { -1.0f, -1.0f }, { 0.0f, 1.0f } }, + }; + D3D11_BUFFER_DESC bdesc = { .ByteWidth = sizeof(vdata), .Usage = D3D11_USAGE_IMMUTABLE, .BindFlags = D3D11_BIND_VERTEX_BUFFER }; + D3D11_SUBRESOURCE_DATA sdata = { .pSysMem = vdata }; + HR(G.d3ddev->CreateBuffer(&bdesc, &sdata, &G.vbuf_quad)); + } + // Quad index buffer + { + UINT16 idata[] = { + 0, 1, 2, + 0, 2, 3, + }; + D3D11_BUFFER_DESC bdesc = { .ByteWidth = sizeof(idata), .Usage = D3D11_USAGE_IMMUTABLE, .BindFlags = D3D11_BIND_INDEX_BUFFER }; + D3D11_SUBRESOURCE_DATA sdata = { .pSysMem = idata }; + HR(G.d3ddev->CreateBuffer(&bdesc, &sdata, &G.ibuf_quad)); + G.ibuf_quad_count = ARRAYSIZE(idata); + } + + // Constant buffer + { + D3D11_BUFFER_DESC bdesc = { .ByteWidth = sizeof(CBuffer), .Usage = D3D11_USAGE_DYNAMIC, .BindFlags = D3D11_BIND_CONSTANT_BUFFER , .CPUAccessFlags = D3D11_CPU_ACCESS_WRITE }; + HR(G.d3ddev->CreateBuffer(&bdesc, 0, &G.cbuf)); + } +} + +static void MakeRotationZ(FLOAT angle, FLOAT* out) +{ + FLOAT c = cosf(angle); + FLOAT s = sinf(angle); + + out[ 0] = c; out[ 1] = -s; out[ 2] = 0; out[ 3] = 0; + out[ 4] = s; out[ 5] = c; out[ 6] = 0; out[ 7] = 0; + out[ 8] = 0; out[ 9] = 0; out[10] = 1; out[11] = 0; + out[12] = 0; out[13] = 0; out[14] = 0; out[15] = 1; +} + +static void MakeScale(FLOAT s, FLOAT* out) +{ + ZeroMemory(out, sizeof(FLOAT) * 16); + out[ 0] = s; + out[ 5] = s; + out[10] = 1.0f; + out[15] = 1.0f; +} + +static void MulMat4(const FLOAT* A, const FLOAT* B, FLOAT* out) +{ + FLOAT r[16]; + for (UINT row = 0; row < 4; row++) { + for (UINT col = 0; col < 4; col++) { + r[row * 4 + col] = A[row * 4 + 0] * B[0 * 4 + col] + A[row * 4 + 1] * B[1 * 4 + col] + A[row * 4 + 2] * B[2 * 4 + col] + A[row * 4 + 3] * B[3 * 4 + col]; + } + } + memcpy(out, r, sizeof(r)); +} + +static void MakeTransform(FLOAT r, FLOAT s, FLOAT* out) +{ + FLOAT ms[16]; + FLOAT mr[16]; + MakeScale(s, ms); + MakeRotationZ(r, mr); + MulMat4(mr, ms, out); +} + +static void DrawD3D11() +{ + RECT rc; GetClientRect(G.hwnd, &rc); + D3D11_VIEWPORT vp = { .Width = (FLOAT)(rc.right - rc.left), .Height = (FLOAT)(rc.bottom - rc.top), .MaxDepth = 1.0f }; + G.d3dctx->RSSetViewports(1, &vp); + + FLOAT clear[4] = { 0.1f, 0.1f, 0.1f, 1.0f }; + G.d3dctx->OMSetRenderTargets(1, &G.d3drtv, 0); + G.d3dctx->ClearRenderTargetView(G.d3drtv, clear); + + G.d3dctx->VSSetShader(G.vs, 0, 0); + G.d3dctx->PSSetShader(G.ps, 0, 0); + G.d3dctx->VSSetConstantBuffers(0, 1, &G.cbuf); + G.d3dctx->PSSetConstantBuffers(0, 1, &G.cbuf); + + G.d3dctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + G.d3dctx->IASetInputLayout(G.vlayout); + G.d3dctx->IASetVertexBuffers(0, 1, &G.vbuf_quad, &G.vstride, &G.voffset); + G.d3dctx->IASetIndexBuffer(G.ibuf_quad, DXGI_FORMAT_R16_UINT, 0); + + // Quad 1 + { + D3D11_MAPPED_SUBRESOURCE mapped; + HR(G.d3dctx->Map(G.cbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + CBuffer* cb = (CBuffer*)mapped.pData; + + cb->color[0] = 1.0f; + cb->color[1] = 0.0f; + cb->color[2] = 0.0f; + cb->color[3] = 1.0f; + + MakeTransform(0.0f, 1.0f, cb->rot); + + G.d3dctx->Unmap(G.cbuf, 0); + G.d3dctx->DrawIndexed(G.ibuf_quad_count, 0, 0); + } + + // Quad 2 + { + D3D11_MAPPED_SUBRESOURCE mapped; + HR(G.d3dctx->Map(G.cbuf, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped)); + CBuffer* cb = (CBuffer*)mapped.pData; + + cb->color[0] = 0.0f; + cb->color[1] = 1.0f; + cb->color[2] = 0.0f; + cb->color[3] = 1.0f; + + MakeTransform((FLOAT)GetTickCount64() / 1e3f, 0.5f, cb->rot); + + G.d3dctx->Unmap(G.cbuf, 0); + G.d3dctx->DrawIndexed(G.ibuf_quad_count, 0, 0); + } + + HR(G.d3dswp->Present(1, 0)); + + SHORT key = GetAsyncKeyState('A'); + if ((key & 0x8000) && (key & 0x1)) { + MessageBoxW(G.hwnd, L"This is an example dialog", L"d3d11-resize-draw", MB_OK); + } +} + +static void ResizeD3D11(LPARAM lparam) +{ + DestroyRenderTarget(); + HR(G.d3dswp->ResizeBuffers(0, LOWORD(lparam), HIWORD(lparam), DXGI_FORMAT_UNKNOWN, 0)); + CreateRenderTarget(); +} + +static void SpewMsg(const char* fmt, ...) +{ + char buf[512]; + va_list va; + va_start(va, fmt); + vsnprintf(buf, sizeof(buf), fmt, va); + va_end(va); + + OutputDebugStringA(buf); OutputDebugStringA("\n"); +} + +static void SpewWndProc(HWND hwnd, UINT msg, WPARAM, LPARAM) +{ + switch (msg) { + case WM_SIZE: { + SpewMsg("WM_SIZE hwnd=%p", hwnd); + } break; + case WM_PAINT: { + SpewMsg("WM_PAINT hwnd=%p", hwnd); + } break; + } +} +#define SPEW_WNDPROC() SpewWndProc(hwnd, msg, wparam, lparam); + +// -------------------------------------------------------------------------------- +// Method 1: Don't do anything special. This is just to highlight the problem. +// -------------------------------------------------------------------------------- +#if ACTIVE_METHOD == 1 + +static LRESULT WINAPI Method1_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + SPEW_WNDPROC(); + switch (msg) { + case WM_SIZE: { + if (wparam != SIZE_MINIMIZED) { + ResizeD3D11(lparam); + } + DrawD3D11(); + return 0; + } break; + case WM_DESTROY: { + PostQuitMessage(0); + return 0; + } break; + } + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + CreateDemoWindow(CS_CLASSDC, Method1_WndProc); + SetupD3D11(); + CreateRenderTarget(); + ShowWindow(G.hwnd, SW_SHOW); + + BOOL running = TRUE; + while (running) { + MSG msg; + while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + if (msg.message == WM_QUIT) { + running = FALSE; + } + } + + DrawD3D11(); + } +} + +#endif // ACTIVE_METHOD == 1 + +// -------------------------------------------------------------------------------- +// Method 2: Set CS_VREDRAW | CS_HREDRAW and render in WM_PAINT. +// -------------------------------------------------------------------------------- +#if ACTIVE_METHOD == 2 + +static LRESULT WINAPI Method1_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + SPEW_WNDPROC(); + switch (msg) { + case WM_SIZE: { + if (wparam != SIZE_MINIMIZED) { + ResizeD3D11(lparam); + } + return 0; + } break; + case WM_DESTROY: { + PostQuitMessage(0); + return 0; + } break; + case WM_PAINT: { + DrawD3D11(); + return 0; + } break; + } + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + CreateDemoWindow(CS_CLASSDC | CS_HREDRAW | CS_VREDRAW, Method1_WndProc); + SetupD3D11(); + CreateRenderTarget(); + ShowWindow(G.hwnd, SW_SHOW); + + BOOL running = TRUE; + while (running) { + MSG msg; + while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + if (msg.message == WM_QUIT) { + running = FALSE; + } + } + } +} + +#endif // ACTIVE_METHOD == 2 + +// -------------------------------------------------------------------------------- +// Method 3: Render during resize with WM_TIMER. +// -------------------------------------------------------------------------------- +#if ACTIVE_METHOD == 3 + +static LRESULT WINAPI Method1_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + SPEW_WNDPROC(); + switch (msg) { + case WM_SIZE: { + if (wparam != SIZE_MINIMIZED) { + ResizeD3D11(lparam); + } +#if 1 + DrawD3D11(); +#endif + return 0; + } break; + case WM_DESTROY: { + PostQuitMessage(0); + return 0; + } break; + case WM_ENTERSIZEMOVE: { + SetTimer(hwnd, 1, USER_TIMER_MINIMUM, 0); + } break; + case WM_EXITSIZEMOVE: { + KillTimer(hwnd, 1); + } break; + case WM_TIMER: { + DrawD3D11(); + } break; + } + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +int WINAPI WinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ LPSTR, _In_ int) +{ + CreateDemoWindow(CS_CLASSDC, Method1_WndProc); + SetupD3D11(); + CreateRenderTarget(); + ShowWindow(G.hwnd, SW_SHOW); + + BOOL running = TRUE; + while (running) { + MSG msg; + while (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + if (msg.message == WM_QUIT) { + running = FALSE; + } + } + + DrawD3D11(); + } +} + +#endif // ACTIVE_METHOD == 3 diff --git a/d3d11-resize-draw/shader.hlsl b/d3d11-resize-draw/shader.hlsl new file mode 100644 index 0000000..8a942e8 --- /dev/null +++ b/d3d11-resize-draw/shader.hlsl @@ -0,0 +1,30 @@ +struct VertexDesc +{ + float2 p : POSITION; + float2 t : TEXCOORD0; +}; + +struct PixelDesc +{ + float4 p : SV_POSITION; + float2 t : TEXCOORD0; +}; + +cbuffer Params : register(b0) +{ + float4 u_color; + float4x4 u_rot; +}; + +PixelDesc VsMain(VertexDesc v) +{ + PixelDesc p; + p.p = mul(u_rot, float4(v.p.x, v.p.y, 0.0f, 1.0f)); + p.t = v.t; + return p; +} + +float4 PsMain(PixelDesc p) : SV_Target +{ + return u_color; +} |