diff --git a/examples/directx11_example/directx11_example.vcxproj b/examples/directx11_example/directx11_example.vcxproj index ec95e4ab..beddb330 100644 --- a/examples/directx11_example/directx11_example.vcxproj +++ b/examples/directx11_example/directx11_example.vcxproj @@ -48,7 +48,7 @@ Level3 Disabled - $(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories) + ..\..;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories) true @@ -63,7 +63,7 @@ MaxSpeed true true - $(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories) + ..\..;$(DXSDK_DIR)/Include;%(AdditionalIncludeDirectories) true @@ -77,9 +77,11 @@ + + diff --git a/examples/directx11_example/directx11_example.vcxproj.filters b/examples/directx11_example/directx11_example.vcxproj.filters index ab9c654e..fca4dcfd 100644 --- a/examples/directx11_example/directx11_example.vcxproj.filters +++ b/examples/directx11_example/directx11_example.vcxproj.filters @@ -15,6 +15,9 @@ imgui + + sources + @@ -23,5 +26,8 @@ sources + + sources + \ No newline at end of file diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp new file mode 100644 index 00000000..bc693a47 --- /dev/null +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -0,0 +1,447 @@ +// ImGui Win32 + DirectX11 binding +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_dx11.h" + +// DirectX +#include +#include +#define DIRECTINPUT_VERSION 0x0800 +#include + +// Data +static INT64 g_Time = 0; +static INT64 g_TicksPerSecond = 0; +static bool g_FontTextureLoaded = false; + +static ID3D11Device* g_pd3dDevice = NULL; +static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; +static ID3D11Buffer* g_pVB = NULL; +static ID3D10Blob * g_pVertexShaderBlob = NULL; +static ID3D11VertexShader* g_pVertexShader = NULL; +static ID3D11InputLayout* g_pInputLayout = NULL; +static ID3D11Buffer* g_pVertexConstantBuffer = NULL; +static ID3D10Blob * g_pPixelShaderBlob = NULL; +static ID3D11PixelShader* g_pPixelShader = NULL; +static ID3D11SamplerState* g_pFontSampler = NULL; +static ID3D11BlendState* g_blendState = NULL; + +struct CUSTOMVERTEX +{ + float pos[2]; + float uv[2]; + unsigned int col; +}; + +struct VERTEX_CONSTANT_BUFFER +{ + float mvp[4][4]; +}; + +// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// If text or lines are blurry when integrating ImGui in your engine: +// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) +static void ImGui_ImplDX11_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) +{ + // Copy and convert all vertices into a single contiguous buffer + D3D11_MAPPED_SUBRESOURCE mappedResource; + if (g_pd3dDeviceContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) + return; + CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData; + for (int n = 0; n < cmd_lists_count; n++) + { + const ImDrawList* cmd_list = cmd_lists[n]; + const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0]; + for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) + { + vtx_dst->pos[0] = vtx_src->pos.x; + vtx_dst->pos[1] = vtx_src->pos.y; + vtx_dst->uv[0] = vtx_src->uv.x; + vtx_dst->uv[1] = vtx_src->uv.y; + vtx_dst->col = vtx_src->col; + vtx_dst++; + vtx_src++; + } + } + g_pd3dDeviceContext->Unmap(g_pVB, 0); + + // Setup orthographic projection matrix into our constant buffer + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + if (g_pd3dDeviceContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) + return; + + VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData; + const float L = 0.0f; + const float R = ImGui::GetIO().DisplaySize.x; + const float B = ImGui::GetIO().DisplaySize.y; + const float T = 0.0f; + const float mvp[4][4] = + { + { 2.0f/(R-L), 0.0f, 0.0f, 0.0f}, + { 0.0f, 2.0f/(T-B), 0.0f, 0.0f,}, + { 0.0f, 0.0f, 0.5f, 0.0f }, + { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, + }; + memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); + g_pd3dDeviceContext->Unmap(g_pVertexConstantBuffer, 0); + } + + // Setup viewport + { + D3D11_VIEWPORT vp; + memset(&vp, 0, sizeof(D3D11_VIEWPORT)); + vp.Width = ImGui::GetIO().DisplaySize.x; + vp.Height = ImGui::GetIO().DisplaySize.y; + vp.MinDepth = 0.0f; + vp.MaxDepth = 1.0f; + vp.TopLeftX = 0; + vp.TopLeftY = 0; + g_pd3dDeviceContext->RSSetViewports(1, &vp); + } + + // Bind shader and vertex buffers + unsigned int stride = sizeof(CUSTOMVERTEX); + unsigned int offset = 0; + g_pd3dDeviceContext->IASetInputLayout(g_pInputLayout); + g_pd3dDeviceContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); + g_pd3dDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + g_pd3dDeviceContext->VSSetShader(g_pVertexShader, NULL, 0); + g_pd3dDeviceContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); + g_pd3dDeviceContext->PSSetShader(g_pPixelShader, NULL, 0); + g_pd3dDeviceContext->PSSetSamplers(0, 1, &g_pFontSampler); + + // Setup render state + const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; + g_pd3dDeviceContext->OMSetBlendState(g_blendState, blendFactor, 0xffffffff); + + // Render command lists + int vtx_offset = 0; + for (int n = 0; n < cmd_lists_count; n++) + { + const ImDrawList* cmd_list = cmd_lists[n]; + for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; + const D3D11_RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w }; + g_pd3dDeviceContext->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->texture_id); + g_pd3dDeviceContext->RSSetScissorRects(1, &r); + g_pd3dDeviceContext->Draw(pcmd->vtx_count, vtx_offset); + vtx_offset += pcmd->vtx_count; + } + } + + // Restore modified state + g_pd3dDeviceContext->IASetInputLayout(NULL); + g_pd3dDeviceContext->PSSetShader(NULL, NULL, 0); + g_pd3dDeviceContext->VSSetShader(NULL, NULL, 0); +} + +LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + ImGuiIO& io = ImGui::GetIO(); + switch (msg) + { + case WM_LBUTTONDOWN: + io.MouseDown[0] = true; + return true; + case WM_LBUTTONUP: + io.MouseDown[0] = false; + return true; + case WM_RBUTTONDOWN: + io.MouseDown[1] = true; + return true; + case WM_RBUTTONUP: + io.MouseDown[1] = false; + return true; + case WM_MOUSEWHEEL: + io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return true; + case WM_MOUSEMOVE: + io.MousePos.x = (signed short)(lParam); + io.MousePos.y = (signed short)(lParam >> 16); + return true; + case WM_KEYDOWN: + if (wParam >= 0 && wParam < 256) + io.KeysDown[wParam] = 1; + return true; + case WM_KEYUP: + if (wParam >= 0 && wParam < 256) + io.KeysDown[wParam] = 0; + return true; + case WM_CHAR: + // You can also use ToAscii()+GetKeyboardState() to retrieve characters. + if (wParam > 0 && wParam < 0x10000) + io.AddInputCharacter((unsigned short)wParam); + return true; + } + return 0; +} + +void ImGui_ImplDX11_InitFontsTexture() +{ + ImGuiIO& io = ImGui::GetIO(); + + // Build + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Create DX11 texture + D3D11_TEXTURE2D_DESC texDesc; + ZeroMemory(&texDesc, sizeof(texDesc)); + texDesc.Width = width; + texDesc.Height = height; + texDesc.MipLevels = 1; + texDesc.ArraySize = 1; + texDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + texDesc.SampleDesc.Count = 1; + texDesc.Usage = D3D11_USAGE_DEFAULT; + texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + texDesc.CPUAccessFlags = 0; + + ID3D11Texture2D *pTexture = NULL; + D3D11_SUBRESOURCE_DATA subResource; + subResource.pSysMem = pixels; + subResource.SysMemPitch = texDesc.Width * 4; + subResource.SysMemSlicePitch = 0; + g_pd3dDevice->CreateTexture2D(&texDesc, &subResource, &pTexture); + + // Create texture view + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + ZeroMemory(&srvDesc, sizeof(srvDesc)); + srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = texDesc.MipLevels; + srvDesc.Texture2D.MostDetailedMip = 0; + ID3D11ShaderResourceView* font_texture_view = NULL; + g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &font_texture_view); + pTexture->Release(); + + // Store our identifier + io.Fonts->TexID = (void *)font_texture_view; + + // Create texture sampler + D3D11_SAMPLER_DESC samplerDesc; + ZeroMemory(&samplerDesc, sizeof(samplerDesc)); + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; + samplerDesc.MipLODBias = 0.f; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; + samplerDesc.MinLOD = 0.f; + samplerDesc.MaxLOD = 0.f; + g_pd3dDevice->CreateSamplerState(&samplerDesc, &g_pFontSampler); +} + +static bool InitDirect3DState() +{ + // Create the vertex shader + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(c0) \ + {\ + float4x4 ProjectionMatrix; \ + };\ + struct VS_INPUT\ + {\ + float2 pos : POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + \ + PS_INPUT main(VS_INPUT input)\ + {\ + PS_INPUT output;\ + output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ + output.col = input.col;\ + output.uv = input.uv;\ + return output;\ + }"; + + D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL); + if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) + return false; + + // Create the input layout + D3D11_INPUT_ELEMENT_DESC localLayout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((CUSTOMVERTEX*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) + return false; + + // Create the constant buffer + { + D3D11_BUFFER_DESC cbDesc; + cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); + cbDesc.Usage = D3D11_USAGE_DYNAMIC; + cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + cbDesc.MiscFlags = 0; + g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); + } + } + + // Create the pixel shader + { + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + sampler sampler0;\ + Texture2D texture0;\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL); + if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! + return false; + if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) + return false; + } + + // Create the blending setup + { + D3D11_BLEND_DESC desc; + ZeroMemory(&desc, sizeof(desc)); + desc.AlphaToCoverageEnable = false; + desc.RenderTarget[0].BlendEnable = true; + desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; + desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; + desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + g_pd3dDevice->CreateBlendState(&desc, &g_blendState); + } + + // Create the vertex buffer + { + D3D11_BUFFER_DESC bufferDesc; + memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.ByteWidth = 100000 * sizeof(CUSTOMVERTEX); // Maybe we should handle that more dynamically? + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0) + return false; + } + + return true; +} + +bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context) +{ + g_pd3dDevice = device; + g_pd3dDeviceContext = device_context; + + if (!InitDirect3DState()) + { + IM_ASSERT(0); + return false; + } + + if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) + return false; + if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) + return false; + + // FIXME: resizing + RECT rect; + GetClientRect((HWND)hwnd, &rect); + int display_w = (int)(rect.right - rect.left); + int display_h = (int)(rect.bottom - rect.top); + + ImGuiIO& io = ImGui::GetIO(); + io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. + io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. + io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; + io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; + io.KeyMap[ImGuiKey_UpArrow] = VK_UP; + io.KeyMap[ImGuiKey_DownArrow] = VK_UP; + io.KeyMap[ImGuiKey_Home] = VK_HOME; + io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Delete] = VK_DELETE; + io.KeyMap[ImGuiKey_Backspace] = VK_BACK; + io.KeyMap[ImGuiKey_Enter] = VK_RETURN; + io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; + io.KeyMap[ImGuiKey_A] = 'A'; + io.KeyMap[ImGuiKey_C] = 'C'; + io.KeyMap[ImGuiKey_V] = 'V'; + io.KeyMap[ImGuiKey_X] = 'X'; + io.KeyMap[ImGuiKey_Y] = 'Y'; + io.KeyMap[ImGuiKey_Z] = 'Z'; + + io.RenderDrawListsFn = ImGui_ImplDX11_RenderDrawLists; + io.ImeWindowHandle = hwnd; + + return true; +} + +void ImGui_ImplDX11_Shutdown() +{ + if (g_pd3dDeviceContext) g_pd3dDeviceContext->ClearState(); + + 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(); +} + +void ImGui_ImplDX11_NewFrame() +{ + if (!g_FontTextureLoaded) + ImGui_ImplDX11_InitFontsTexture(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup time step + INT64 current_time; + QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); + io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; + g_Time = current_time; + + // Read keyboard modifiers inputs + io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; + io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; + // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events + // io.MousePos : filled by WM_MOUSEMOVE events + // io.MouseDown : filled by WM_*BUTTON* events + // io.MouseWheel : filled by WM_MOUSEWHEEL events + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/directx11_example/imgui_impl_dx11.h b/examples/directx11_example/imgui_impl_dx11.h new file mode 100644 index 00000000..aa33edb2 --- /dev/null +++ b/examples/directx11_example/imgui_impl_dx11.h @@ -0,0 +1,17 @@ +// ImGui Win32 + DirectX11 binding +// https://github.com/ocornut/imgui + +struct ID3D11Device; +struct ID3D11DeviceContext; + +bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context); +void ImGui_ImplDX11_InitFontsTexture(); +void ImGui_ImplDX11_Shutdown(); +void ImGui_ImplDX11_NewFrame(); + +// 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. +// Commented out to avoid dragging dependencies on types. You can copy the extern declaration in your code. +/* +extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +*/ diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index a7f7a993..75c77064 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -1,147 +1,18 @@ // ImGui - standalone example application for DirectX 11 +// TODO: Allow resizing the application window. -#include -#include "../../imgui.h" - -// DirectX 11 +#include +#include "imgui_impl_dx11.h" #include #include #define DIRECTINPUT_VERSION 0x0800 #include -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strdup - -static HWND hWnd; +// Data static ID3D11Device* g_pd3dDevice = NULL; -static ID3D11DeviceContext* g_pd3dDeviceImmediateContext = NULL; +static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; static IDXGISwapChain* g_pSwapChain = NULL; -static ID3D11Buffer* g_pVB = NULL; -static ID3D11RenderTargetView* g_mainRenderTargetView; - -static ID3D10Blob * g_pVertexShaderBlob = NULL; -static ID3D11VertexShader* g_pVertexShader = NULL; -static ID3D11InputLayout* g_pInputLayout = NULL; -static ID3D11Buffer* g_pVertexConstantBuffer = NULL; - -static ID3D10Blob * g_pPixelShaderBlob = NULL; -static ID3D11PixelShader* g_pPixelShader = NULL; - -static ID3D11SamplerState* g_pFontSampler = NULL; -static ID3D11BlendState* g_blendState = NULL; - -struct CUSTOMVERTEX -{ - float pos[2]; - float uv[2]; - unsigned int col; -}; - -struct VERTEX_CONSTANT_BUFFER -{ - float mvp[4][4]; -}; - -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -// If text or lines are blurry when integrating ImGui in your engine: -// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) -static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) -{ - // Copy and convert all vertices into a single contiguous buffer - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (g_pd3dDeviceImmediateContext->Map(g_pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) - return; - CUSTOMVERTEX* vtx_dst = (CUSTOMVERTEX*)mappedResource.pData; - for (int n = 0; n < cmd_lists_count; n++) - { - const ImDrawList* cmd_list = cmd_lists[n]; - const ImDrawVert* vtx_src = &cmd_list->vtx_buffer[0]; - for (size_t i = 0; i < cmd_list->vtx_buffer.size(); i++) - { - vtx_dst->pos[0] = vtx_src->pos.x; - vtx_dst->pos[1] = vtx_src->pos.y; - vtx_dst->uv[0] = vtx_src->uv.x; - vtx_dst->uv[1] = vtx_src->uv.y; - vtx_dst->col = vtx_src->col; - vtx_dst++; - vtx_src++; - } - } - g_pd3dDeviceImmediateContext->Unmap(g_pVB, 0); - - // Setup orthographic projection matrix into our constant buffer - { - D3D11_MAPPED_SUBRESOURCE mappedResource; - if (g_pd3dDeviceImmediateContext->Map(g_pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource) != S_OK) - return; - - VERTEX_CONSTANT_BUFFER* pConstantBuffer = (VERTEX_CONSTANT_BUFFER*)mappedResource.pData; - const float L = 0.0f; - const float R = ImGui::GetIO().DisplaySize.x; - const float B = ImGui::GetIO().DisplaySize.y; - const float T = 0.0f; - const float mvp[4][4] = - { - { 2.0f/(R-L), 0.0f, 0.0f, 0.0f}, - { 0.0f, 2.0f/(T-B), 0.0f, 0.0f,}, - { 0.0f, 0.0f, 0.5f, 0.0f }, - { (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f }, - }; - memcpy(&pConstantBuffer->mvp, mvp, sizeof(mvp)); - g_pd3dDeviceImmediateContext->Unmap(g_pVertexConstantBuffer, 0); - } - - // Setup viewport - { - D3D11_VIEWPORT vp; - memset(&vp, 0, sizeof(D3D11_VIEWPORT)); - vp.Width = ImGui::GetIO().DisplaySize.x; - vp.Height = ImGui::GetIO().DisplaySize.y; - vp.MinDepth = 0.0f; - vp.MaxDepth = 1.0f; - vp.TopLeftX = 0; - vp.TopLeftY = 0; - g_pd3dDeviceImmediateContext->RSSetViewports(1, &vp); - } - - // Bind shader and vertex buffers - unsigned int stride = sizeof(CUSTOMVERTEX); - unsigned int offset = 0; - g_pd3dDeviceImmediateContext->IASetInputLayout(g_pInputLayout); - g_pd3dDeviceImmediateContext->IASetVertexBuffers(0, 1, &g_pVB, &stride, &offset); - g_pd3dDeviceImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - - g_pd3dDeviceImmediateContext->VSSetShader(g_pVertexShader, NULL, 0); - g_pd3dDeviceImmediateContext->VSSetConstantBuffers(0, 1, &g_pVertexConstantBuffer); - - g_pd3dDeviceImmediateContext->PSSetShader(g_pPixelShader, NULL, 0); - g_pd3dDeviceImmediateContext->PSSetSamplers(0, 1, &g_pFontSampler); - - // Setup render state - const float blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; - g_pd3dDeviceImmediateContext->OMSetBlendState(g_blendState, blendFactor, 0xffffffff); - - // Render command lists - int vtx_offset = 0; - for (int n = 0; n < cmd_lists_count; n++) - { - // Render command list - const ImDrawList* cmd_list = cmd_lists[n]; - for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) - { - const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; - const D3D11_RECT r = { (LONG)pcmd->clip_rect.x, (LONG)pcmd->clip_rect.y, (LONG)pcmd->clip_rect.z, (LONG)pcmd->clip_rect.w }; - g_pd3dDeviceImmediateContext->PSSetShaderResources(0, 1, (ID3D11ShaderResourceView**)&pcmd->texture_id); - g_pd3dDeviceImmediateContext->RSSetScissorRects(1, &r); - g_pd3dDeviceImmediateContext->Draw(pcmd->vtx_count, vtx_offset); - vtx_offset += pcmd->vtx_count; - } - } - - // Restore modified state - g_pd3dDeviceImmediateContext->IASetInputLayout(NULL); - g_pd3dDeviceImmediateContext->PSSetShader(NULL, NULL, 0); - g_pd3dDeviceImmediateContext->VSSetShader(NULL, NULL, 0); -} +static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; HRESULT InitDeviceD3D(HWND hWnd) { @@ -170,7 +41,7 @@ HRESULT InitDeviceD3D(HWND hWnd) #endif D3D_FEATURE_LEVEL featureLevel; const D3D_FEATURE_LEVEL featureLevelArray[1] = { D3D_FEATURE_LEVEL_11_0, }; - if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceImmediateContext) != S_OK) + if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 1, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) return E_FAIL; // Setup rasterizer @@ -190,7 +61,7 @@ HRESULT InitDeviceD3D(HWND hWnd) ID3D11RasterizerState* pRState = NULL; g_pd3dDevice->CreateRasterizerState(&RSDesc, &pRState); - g_pd3dDeviceImmediateContext->RSSetState(pRState); + g_pd3dDeviceContext->RSSetState(pRState); pRState->Release(); } @@ -203,356 +74,70 @@ HRESULT InitDeviceD3D(HWND hWnd) 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_pd3dDeviceImmediateContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); pBackBuffer->Release(); } - // Create the vertex shader - { - static const char* vertexShader = - "cbuffer vertexBuffer : register(c0) \ - {\ - float4x4 ProjectionMatrix; \ - };\ - struct VS_INPUT\ - {\ - float2 pos : POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - \ - struct PS_INPUT\ - {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - \ - PS_INPUT main(VS_INPUT input)\ - {\ - PS_INPUT output;\ - output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\ - output.col = input.col;\ - output.uv = input.uv;\ - return output;\ - }"; - - D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_5_0", 0, 0, &g_pVertexShaderBlob, NULL); - if (g_pVertexShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return E_FAIL; - if (g_pd3dDevice->CreateVertexShader((DWORD*)g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), NULL, &g_pVertexShader) != S_OK) - return E_FAIL; - - // Create the input layout - D3D11_INPUT_ELEMENT_DESC localLayout[] = { - { "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((CUSTOMVERTEX*)0)->col), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((CUSTOMVERTEX*)0)->uv), D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - if (g_pd3dDevice->CreateInputLayout(localLayout, 3, g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize(), &g_pInputLayout) != S_OK) - return E_FAIL; - - // Create the constant buffer - { - D3D11_BUFFER_DESC cbDesc; - cbDesc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER); - cbDesc.Usage = D3D11_USAGE_DYNAMIC; - cbDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - cbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - cbDesc.MiscFlags = 0; - g_pd3dDevice->CreateBuffer(&cbDesc, NULL, &g_pVertexConstantBuffer); - } - } - - // Create the pixel shader - { - static const char* pixelShader = - "struct PS_INPUT\ - {\ - float4 pos : SV_POSITION;\ - float4 col : COLOR0;\ - float2 uv : TEXCOORD0;\ - };\ - sampler sampler0;\ - Texture2D texture0;\ - \ - float4 main(PS_INPUT input) : SV_Target\ - {\ - float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ - return out_col; \ - }"; - - D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_5_0", 0, 0, &g_pPixelShaderBlob, NULL); - if (g_pPixelShaderBlob == NULL) // NB: Pass ID3D10Blob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob! - return E_FAIL; - if (g_pd3dDevice->CreatePixelShader((DWORD*)g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize(), NULL, &g_pPixelShader) != S_OK) - return E_FAIL; - } - - // Create the blending setup - { - D3D11_BLEND_DESC desc; - ZeroMemory(&desc, sizeof(desc)); - desc.AlphaToCoverageEnable = false; - desc.RenderTarget[0].BlendEnable = true; - desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; - desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; - desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; - desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; - g_pd3dDevice->CreateBlendState(&desc, &g_blendState); - } - return S_OK; } -void CleanupDevice() +void CleanupDeviceD3D() { - if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->ClearState(); - - // InitImGui - 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(); - - // InitDeviceD3D - 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(); if (g_mainRenderTargetView) g_mainRenderTargetView->Release(); if (g_pSwapChain) g_pSwapChain->Release(); - if (g_pd3dDeviceImmediateContext) g_pd3dDeviceImmediateContext->Release(); + if (g_pd3dDeviceContext) g_pd3dDeviceContext->Release(); if (g_pd3dDevice) g_pd3dDevice->Release(); } +extern LRESULT ImGui_ImplDX11_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - ImGuiIO& io = ImGui::GetIO(); + if (ImGui_ImplDX11_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + switch (msg) { - case WM_LBUTTONDOWN: - io.MouseDown[0] = true; - return true; - case WM_LBUTTONUP: - io.MouseDown[0] = false; - return true; - case WM_RBUTTONDOWN: - io.MouseDown[1] = true; - return true; - case WM_RBUTTONUP: - io.MouseDown[1] = false; - return true; - case WM_MOUSEWHEEL: - io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; - case WM_MOUSEMOVE: - // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) - io.MousePos.x = (signed short)(lParam); - io.MousePos.y = (signed short)(lParam >> 16); - return true; - case WM_KEYDOWN: - if (wParam >= 0 && wParam < 256) - io.KeysDown[wParam] = 1; - return true; - case WM_KEYUP: - if (wParam >= 0 && wParam < 256) - io.KeysDown[wParam] = 0; - return true; - case WM_CHAR: - // You can also use ToAscii()+GetKeyboardState() to retrieve characters. - if (wParam > 0 && wParam < 0x10000) - io.AddInputCharacter((unsigned short)wParam); - return true; case WM_DESTROY: - CleanupDevice(); PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, msg, wParam, lParam); } -void LoadFontsTexture() -{ - // Load one or more font - ImGuiIO& io = ImGui::GetIO(); - //ImFont* my_font1 = io.Fonts->AddFontDefault(); - //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); - //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_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese()); - - // Build - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - - // Create texture - D3D11_TEXTURE2D_DESC desc; - ZeroMemory(&desc, sizeof(desc)); - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - desc.SampleDesc.Count = 1; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.CPUAccessFlags = 0; - - ID3D11Texture2D *pTexture = NULL; - D3D11_SUBRESOURCE_DATA subResource; - subResource.pSysMem = pixels; - subResource.SysMemPitch = desc.Width * 4; - subResource.SysMemSlicePitch = 0; - g_pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture); - - // Create texture view - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - ZeroMemory(&srvDesc, sizeof(srvDesc)); - srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = desc.MipLevels; - srvDesc.Texture2D.MostDetailedMip = 0; - ID3D11ShaderResourceView* font_texture_view = NULL; - g_pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &font_texture_view); - pTexture->Release(); - - // Store our identifier - io.Fonts->TexID = (void *)font_texture_view; -} - -void InitImGui() -{ - RECT rect; - GetClientRect(hWnd, &rect); - int display_w = (int)(rect.right - rect.left); - int display_h = (int)(rect.bottom - rect.top); - - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. - io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable) - io.KeyMap[ImGuiKey_Tab] = VK_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime. - io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = VK_UP; - io.KeyMap[ImGuiKey_DownArrow] = VK_UP; - io.KeyMap[ImGuiKey_Home] = VK_HOME; - io.KeyMap[ImGuiKey_End] = VK_END; - io.KeyMap[ImGuiKey_Delete] = VK_DELETE; - io.KeyMap[ImGuiKey_Backspace] = VK_BACK; - io.KeyMap[ImGuiKey_Enter] = VK_RETURN; - io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; - io.KeyMap[ImGuiKey_A] = 'A'; - io.KeyMap[ImGuiKey_C] = 'C'; - io.KeyMap[ImGuiKey_V] = 'V'; - io.KeyMap[ImGuiKey_X] = 'X'; - io.KeyMap[ImGuiKey_Y] = 'Y'; - io.KeyMap[ImGuiKey_Z] = 'Z'; - - io.RenderDrawListsFn = ImImpl_RenderDrawLists; - io.ImeWindowHandle = hWnd; - - // Create the vertex buffer - { - D3D11_BUFFER_DESC bufferDesc; - memset(&bufferDesc, 0, sizeof(D3D11_BUFFER_DESC)); - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.ByteWidth = 100000 * sizeof(CUSTOMVERTEX); // Maybe we should handle that more dynamically? - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - if (g_pd3dDevice->CreateBuffer(&bufferDesc, NULL, &g_pVB) < 0) - { - IM_ASSERT(0); - return; - } - } - - // Load fonts - LoadFontsTexture(); - - // Create texture sampler - { - D3D11_SAMPLER_DESC desc; - ZeroMemory(&desc, sizeof(desc)); - desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP; - desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP; - desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; - desc.MipLODBias = 0.f; - desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS; - desc.MinLOD = 0.f; - desc.MaxLOD = 0.f; - g_pd3dDevice->CreateSamplerState(&desc, &g_pFontSampler); - } -} - -INT64 ticks_per_second = 0; -INT64 last_time = 0; - -void UpdateImGui() -{ - ImGuiIO& io = ImGui::GetIO(); - - // Setup time step - INT64 current_time; - QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); - io.DeltaTime = (float)(current_time - last_time) / ticks_per_second; - last_time = current_time; - - // Read keyboard modifiers inputs - io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0; - io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0; - // io.KeysDown : filled by WM_KEYDOWN/WM_KEYUP events - // io.MousePos : filled by WM_MOUSEMOVE events - // io.MouseDown : filled by WM_*BUTTON* events - // io.MouseWheel : filled by WM_MOUSEWHEEL events - - // Start the frame - ImGui::NewFrame(); -} - int main(int argc, char** argv) { - // Register the window class + // Create application window WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL }; RegisterClassEx(&wc); - - // Create the application's window - hWnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); - - if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) - return 1; - if (!QueryPerformanceCounter((LARGE_INTEGER *)&last_time)) - return 1; + HWND hwnd = CreateWindow(L"ImGui Example", L"ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); // Initialize Direct3D - if (InitDeviceD3D(hWnd) < 0) + if (InitDeviceD3D(hwnd) < 0) { - CleanupDevice(); + CleanupDeviceD3D(); UnregisterClass(L"ImGui Example", wc.hInstance); return 1; } // Show the window - ShowWindow(hWnd, SW_SHOWDEFAULT); - UpdateWindow(hWnd); + ShowWindow(hwnd, SW_SHOWDEFAULT); + UpdateWindow(hwnd); - InitImGui(); + // Setup ImGui binding + ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pd3dDeviceContext); + //ImGuiIO& io = ImGui::GetIO(); + //ImFont* my_font1 = io.Fonts->AddFontDefault(); + //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); + //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_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, io.Fonts->GetGlyphRangesJapanese()); + ImGui_ImplDX11_InitFontsTexture(); bool show_test_window = true; bool show_another_window = false; ImVec4 clear_col = ImColor(114, 144, 154); - // Enter the message loop + // Main loop MSG msg; ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) @@ -563,7 +148,7 @@ int main(int argc, char** argv) DispatchMessage(&msg); continue; } - UpdateImGui(); + ImGui_ImplDX11_NewFrame(); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" @@ -593,12 +178,13 @@ int main(int argc, char** argv) } // Rendering - g_pd3dDeviceImmediateContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_col); ImGui::Render(); g_pSwapChain->Present(0, 0); } - ImGui::Shutdown(); + ImGui_ImplDX11_Shutdown(); + CleanupDeviceD3D(); UnregisterClass(L"ImGui Example", wc.hInstance); return 0; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 370bcb12..ccddbe05 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -90,7 +90,6 @@ static void ImGui_ImplDX9_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_ int vtx_offset = 0; for (int n = 0; n < cmd_lists_count; n++) { - // Render command list const ImDrawList* cmd_list = cmd_lists[n]; for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) { @@ -184,7 +183,7 @@ bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) return false; - // FIXME + // FIXME: resizing RECT rect; GetClientRect((HWND)hwnd, &rect); int display_w = (int)(rect.right - rect.left); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 65069805..9224be50 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -1,7 +1,6 @@ // ImGui - standalone example application for DirectX 9 // TODO: Allow resizing the application window. -#include #include #include "imgui_impl_dx9.h" #include @@ -25,11 +24,9 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) int main(int argc, char** argv) { - // Register the window class + // Create application window WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, L"ImGui Example", NULL }; RegisterClassEx(&wc); - - // Create the application's window HWND hwnd = CreateWindow(L"ImGui Example", L"ImGui DirectX9 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); // Initialize Direct3D @@ -60,7 +57,7 @@ int main(int argc, char** argv) ShowWindow(hwnd, SW_SHOWDEFAULT); UpdateWindow(hwnd); - // ImGui + // Setup ImGui binding ImGui_ImplDX9_Init(hwnd, pd3dDevice); //ImGuiIO& io = ImGui::GetIO(); //ImFont* my_font1 = io.Fonts->AddFontDefault(); @@ -129,7 +126,6 @@ int main(int argc, char** argv) } ImGui_ImplDX9_Shutdown(); - if (pd3dDevice) pd3dDevice->Release(); if (pD3D) pD3D->Release(); UnregisterClass(L"ImGui Example", wc.hInstance);