Examples: DirectX11 example application handles window resizing.

This commit is contained in:
ocornut 2015-03-09 14:51:10 +00:00
parent 866fa95aaa
commit 66a5837ba8
3 changed files with 119 additions and 86 deletions

View File

@ -13,7 +13,6 @@
// Data // Data
static INT64 g_Time = 0; static INT64 g_Time = 0;
static INT64 g_TicksPerSecond = 0; static INT64 g_TicksPerSecond = 0;
static bool g_FontTextureLoaded = false;
static HWND g_hWnd = 0; static HWND g_hWnd = 0;
static ID3D11Device* g_pd3dDevice = NULL; static ID3D11Device* g_pd3dDevice = NULL;
@ -26,6 +25,7 @@ static ID3D11Buffer* g_pVertexConstantBuffer = NULL;
static ID3D10Blob * g_pPixelShaderBlob = NULL; static ID3D10Blob * g_pPixelShaderBlob = NULL;
static ID3D11PixelShader* g_pPixelShader = NULL; static ID3D11PixelShader* g_pPixelShader = NULL;
static ID3D11SamplerState* g_pFontSampler = NULL; static ID3D11SamplerState* g_pFontSampler = NULL;
static ID3D11ShaderResourceView*g_pFontTextureView = NULL;
static ID3D11BlendState* g_blendState = NULL; static ID3D11BlendState* g_blendState = NULL;
struct CUSTOMVERTEX struct CUSTOMVERTEX
@ -180,7 +180,7 @@ LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
return 0; return 0;
} }
void ImGui_ImplDX11_InitFontsTexture() static void ImGui_ImplDX11_InitFontsTexture()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
@ -190,6 +190,7 @@ void ImGui_ImplDX11_InitFontsTexture()
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
// Create DX11 texture // Create DX11 texture
{
D3D11_TEXTURE2D_DESC texDesc; D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = width; texDesc.Width = width;
@ -216,14 +217,15 @@ void ImGui_ImplDX11_InitFontsTexture()
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = texDesc.MipLevels; srvDesc.Texture2D.MipLevels = texDesc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0; srvDesc.Texture2D.MostDetailedMip = 0;
ID3D11ShaderResourceView* font_texture_view = NULL; g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &g_pFontTextureView);
g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &font_texture_view);
pTexture->Release(); pTexture->Release();
}
// Store our identifier // Store our identifier
io.Fonts->TexID = (void *)font_texture_view; io.Fonts->TexID = (void *)g_pFontTextureView;
// Create texture sampler // Create texture sampler
{
D3D11_SAMPLER_DESC samplerDesc; D3D11_SAMPLER_DESC samplerDesc;
ZeroMemory(&samplerDesc, sizeof(samplerDesc)); ZeroMemory(&samplerDesc, sizeof(samplerDesc));
samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
@ -236,9 +238,15 @@ void ImGui_ImplDX11_InitFontsTexture()
samplerDesc.MaxLOD = 0.f; samplerDesc.MaxLOD = 0.f;
g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler);
} }
}
static bool InitDirect3DState() bool ImGui_ImplDX11_CreateDeviceObjects()
{ {
if (!g_pd3dDevice)
return false;
if (g_pVB)
ImGui_ImplDX11_InvalidateDeviceObjects();
// Create the vertex shader // Create the vertex shader
{ {
static const char* vertexShader = static const char* vertexShader =
@ -351,21 +359,35 @@ static bool InitDirect3DState()
return false; return false;
} }
ImGui_ImplDX11_InitFontsTexture();
return true; return true;
} }
void ImGui_ImplDX11_InvalidateDeviceObjects()
{
if (!g_pd3dDevice)
return;
if (g_pFontSampler) { g_pFontSampler->Release(); g_pFontSampler = NULL; }
if (g_pFontTextureView) { g_pFontTextureView->Release(); ImGui::GetIO().Fonts->TexID = 0; }
if (g_pVB) { g_pVB->Release(); g_pVB = NULL; }
if (g_blendState) { g_blendState->Release(); g_blendState = NULL; }
if (g_pPixelShader) { g_pPixelShader->Release(); g_pPixelShader = NULL; }
if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; }
if (g_pVertexConstantBuffer) { g_pVertexConstantBuffer->Release(); g_pVertexConstantBuffer = NULL; }
if (g_pInputLayout) { g_pInputLayout->Release(); g_pInputLayout = NULL; }
if (g_pVertexShader) { g_pVertexShader->Release(); g_pVertexShader = NULL; }
if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; }
}
bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context) bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context)
{ {
g_hWnd = (HWND)hwnd; g_hWnd = (HWND)hwnd;
g_pd3dDevice = device; g_pd3dDevice = device;
g_pd3dDeviceContext = device_context; g_pd3dDeviceContext = device_context;
if (!InitDirect3DState())
{
IM_ASSERT(0);
return false;
}
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond))
return false; return false;
if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time))
@ -398,28 +420,17 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex
void ImGui_ImplDX11_Shutdown() void ImGui_ImplDX11_Shutdown()
{ {
if (g_pd3dDeviceContext) g_pd3dDeviceContext->ClearState(); ImGui_ImplDX11_InvalidateDeviceObjects();
if (g_pFontSampler) g_pFontSampler->Release();
if (ID3D11ShaderResourceView* font_texture_view = (ID3D11ShaderResourceView*)ImGui::GetIO().Fonts->TexID)
font_texture_view->Release();
if (g_pVB) g_pVB->Release();
if (g_blendState) g_blendState->Release();
if (g_pPixelShader) g_pPixelShader->Release();
if (g_pPixelShaderBlob) g_pPixelShaderBlob->Release();
if (g_pVertexConstantBuffer) g_pVertexConstantBuffer->Release();
if (g_pInputLayout) g_pInputLayout->Release();
if (g_pVertexShader) g_pVertexShader->Release();
if (g_pVertexShaderBlob) g_pVertexShaderBlob->Release();
ImGui::Shutdown(); ImGui::Shutdown();
g_pd3dDevice = NULL;
g_pd3dDeviceContext = NULL;
g_hWnd = (HWND)0;
} }
void ImGui_ImplDX11_NewFrame() void ImGui_ImplDX11_NewFrame()
{ {
if (!g_FontTextureLoaded) if (!g_pVB)
ImGui_ImplDX11_InitFontsTexture(); ImGui_ImplDX11_CreateDeviceObjects();
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();

View File

@ -5,10 +5,13 @@ struct ID3D11Device;
struct ID3D11DeviceContext; struct ID3D11DeviceContext;
bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context); bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context);
void ImGui_ImplDX11_InitFontsTexture();
void ImGui_ImplDX11_Shutdown(); void ImGui_ImplDX11_Shutdown();
void ImGui_ImplDX11_NewFrame(); void ImGui_ImplDX11_NewFrame();
// Use if you want to reset your rendering device without losing ImGui state.
void ImGui_ImplDX11_InvalidateDeviceObjects();
bool ImGui_ImplDX11_CreateDeviceObjects();
// Handler for Win32 messages, update mouse/keyboard data. // Handler for Win32 messages, update mouse/keyboard data.
// You may or not need this for your implementation, but it can serve as reference for handling inputs. // You may or not need this for your implementation, but it can serve as reference for handling inputs.
// Commented out to avoid dragging dependencies on <windows.h> types. You can copy the extern declaration in your code. // Commented out to avoid dragging dependencies on <windows.h> types. You can copy the extern declaration in your code.

View File

@ -1,5 +1,4 @@
// ImGui - standalone example application for DirectX 11 // ImGui - standalone example application for DirectX 11
// TODO: Allow resizing the application window.
#include <imgui.h> #include <imgui.h>
#include "imgui_impl_dx11.h" #include "imgui_impl_dx11.h"
@ -14,7 +13,29 @@ static ID3D11DeviceContext* g_pd3dDeviceContext = NULL;
static IDXGISwapChain* g_pSwapChain = NULL; static IDXGISwapChain* g_pSwapChain = NULL;
static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; static ID3D11RenderTargetView* g_mainRenderTargetView = NULL;
HRESULT InitDeviceD3D(HWND hWnd) void CreateRenderTarget()
{
DXGI_SWAP_CHAIN_DESC sd;
g_pSwapChain->GetDesc(&sd);
// Create the render target
ID3D11Texture2D* pBackBuffer;
D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
render_target_view_desc.Format = sd.BufferDesc.Format;
render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView);
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
pBackBuffer->Release();
}
void CleanupRenderTarget()
{
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = NULL; }
}
HRESULT CreateDeviceD3D(HWND hWnd)
{ {
// Setup swap chain // Setup swap chain
DXGI_SWAP_CHAIN_DESC sd; DXGI_SWAP_CHAIN_DESC sd;
@ -65,28 +86,17 @@ HRESULT InitDeviceD3D(HWND hWnd)
pRState->Release(); pRState->Release();
} }
// Create the render target CreateRenderTarget();
{
ID3D11Texture2D* pBackBuffer;
D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
render_target_view_desc.Format = sd.BufferDesc.Format;
render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView);
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL);
pBackBuffer->Release();
}
return S_OK; return S_OK;
} }
void CleanupDeviceD3D() void CleanupDeviceD3D()
{ {
if (g_mainRenderTargetView) g_mainRenderTargetView->Release(); CleanupRenderTarget();
if (g_pSwapChain) g_pSwapChain->Release(); if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; }
if (g_pd3dDeviceContext) g_pd3dDeviceContext->Release(); if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = NULL; }
if (g_pd3dDevice) g_pd3dDevice->Release(); if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; }
} }
extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
@ -97,6 +107,16 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
switch (msg) switch (msg)
{ {
case WM_SIZE:
if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED)
{
ImGui_ImplDX11_InvalidateDeviceObjects();
CleanupRenderTarget();
g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, 0);
CreateRenderTarget();
ImGui_ImplDX11_CreateDeviceObjects();
}
return 0;
case WM_DESTROY: case WM_DESTROY:
PostQuitMessage(0); PostQuitMessage(0);
return 0; return 0;
@ -112,7 +132,7 @@ int main(int argc, char** argv)
HWND hwnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); HWND hwnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL);
// Initialize Direct3D // Initialize Direct3D
if (InitDeviceD3D(hwnd) < 0) if (CreateDeviceD3D(hwnd) < 0)
{ {
CleanupDeviceD3D(); CleanupDeviceD3D();
UnregisterClass(L"ImGui Example", wc.hInstance); UnregisterClass(L"ImGui Example", wc.hInstance);
@ -131,7 +151,6 @@ int main(int argc, char** argv)
//ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1; //ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1;
//ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1; //ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1;
//ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese()); //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese());
ImGui_ImplDX11_InitFontsTexture();
bool show_test_window = true; bool show_test_window = true;
bool show_another_window = false; bool show_another_window = false;