From f6181b3428ffb414767ee4eb2bea202280261e6e Mon Sep 17 00:00:00 2001 From: Jefferson Montgomery Date: Mon, 22 Feb 2016 15:22:48 -0800 Subject: [PATCH 01/87] Examples: DirectX12: Add directx12_example --- examples/README.txt | 4 + examples/directx12_example/build_win32.bat | 4 + .../directx12_example.vcxproj | 164 +++++ .../directx12_example.vcxproj.filters | 45 ++ .../directx12_example/imgui_impl_dx12.cpp | 667 ++++++++++++++++++ examples/directx12_example/imgui_impl_dx12.h | 34 + examples/directx12_example/main.cpp | 418 +++++++++++ examples/imgui_examples_msvc2010.sln | 10 + 8 files changed, 1346 insertions(+) create mode 100644 examples/directx12_example/build_win32.bat create mode 100644 examples/directx12_example/directx12_example.vcxproj create mode 100644 examples/directx12_example/directx12_example.vcxproj.filters create mode 100644 examples/directx12_example/imgui_impl_dx12.cpp create mode 100644 examples/directx12_example/imgui_impl_dx12.h create mode 100644 examples/directx12_example/main.cpp diff --git a/examples/README.txt b/examples/README.txt index b80866c1..11d785d4 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -58,6 +58,10 @@ directx11_example/ DirectX11 example, Windows only. This is quite long and tedious, because: DirectX11. +directx12_example/ + DirectX12 example, Windows only. + This is quite long and tedious, because: DirectX12. + ios_example/ iOS example. Using Synergy to access keyboard/mouse data from server computer. diff --git a/examples/directx12_example/build_win32.bat b/examples/directx12_example/build_win32.bat new file mode 100644 index 00000000..dd919b23 --- /dev/null +++ b/examples/directx12_example/build_win32.bat @@ -0,0 +1,4 @@ +@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. +mkdir Debug +cl /nologo /Zi /MD /I ..\.. /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include" /D UNICODE /D _UNICODE *.cpp ..\..\*.cpp /FeDebug/directx12_example.exe /FoDebug/ /link /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d12.lib d3dcompiler.lib + diff --git a/examples/directx12_example/directx12_example.vcxproj b/examples/directx12_example/directx12_example.vcxproj new file mode 100644 index 00000000..94d7fa08 --- /dev/null +++ b/examples/directx12_example/directx12_example.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {b4cf9797-519d-4afe-a8f4-5141a6b521d3} + directx12_example + 10.0.10240.0 + + + + Application + true + Unicode + v140 + + + Application + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + Application + false + true + Unicode + v140 + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + + + + Level4 + Disabled + ..\..;%(AdditionalIncludeDirectories) + + + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + Disabled + ..\..;%(AdditionalIncludeDirectories) + + + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;%(AdditionalIncludeDirectories) + + + true + true + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + Level4 + MaxSpeed + true + true + ..\..;%(AdditionalIncludeDirectories) + + + true + true + true + d3d12.lib;d3dcompiler.lib;dxgi.lib;imm32.lib;%(AdditionalDependencies) + %(AdditionalLibraryDirectories) + Console + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/directx12_example/directx12_example.vcxproj.filters b/examples/directx12_example/directx12_example.vcxproj.filters new file mode 100644 index 00000000..d445f985 --- /dev/null +++ b/examples/directx12_example/directx12_example.vcxproj.filters @@ -0,0 +1,45 @@ + + + + + {fb3d294f-51ec-478e-a627-25831c80fefd} + + + {4f33ddea-9910-456d-b868-4267eb3c2b19} + + + + + imgui + + + imgui + + + sources + + + imgui + + + + + imgui + + + sources + + + sources + + + imgui + + + imgui + + + + + + diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp new file mode 100644 index 00000000..f1983927 --- /dev/null +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -0,0 +1,667 @@ +// ImGui Win32 + DirectX12 binding +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include +#include "imgui_impl_dx12.h" + +// DirectX +#include +#include + +struct FrameResources +{ + ID3D12Resource* IB; + ID3D12Resource* VB; + int VertexBufferSize; + int IndexBufferSize; +}; + +// Data +static INT64 g_Time = 0; +static INT64 g_TicksPerSecond = 0; + +static HWND g_hWnd = 0; +static ID3D12Device* g_pd3dDevice = NULL; +static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; +static ID3D10Blob* g_pVertexShaderBlob = NULL; +static ID3D10Blob* g_pPixelShaderBlob = NULL; +static ID3D12RootSignature* g_pRootSignature = NULL; +static ID3D12PipelineState* g_pPipelineState = NULL; +static ID3D12Resource* g_pFontTextureResource = NULL; +static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; +static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; + +static FrameResources* g_pFrameResources = NULL; +static UINT g_numFramesInFlight = 0; +static UINT g_frameIndex = UINT_MAX; + +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) +void ImGui_ImplDX12_RenderDrawLists(ImDrawData* draw_data) +{ + // Create and grow vertex/index buffers if needed + // + // NOTE: I'm assuming that this only get's called once per frame! If not, + // we can't just re-allocate the IB or VB, we'll have to do a proper + // allocator. + g_frameIndex = g_frameIndex + 1; + FrameResources* frameResources = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; + + D3D12_HEAP_PROPERTIES props = {}; + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + D3D12_RESOURCE_DESC desc = {}; + desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + desc.Height = 1; + desc.DepthOrArraySize = 1; + desc.MipLevels = 1; + desc.Format = DXGI_FORMAT_UNKNOWN; + desc.SampleDesc.Count = 1; + desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + if (!frameResources->VB || frameResources->VertexBufferSize < draw_data->TotalVtxCount) + { + if (frameResources->VB) { frameResources->VB->Release(); frameResources->VB = NULL; } + frameResources->VertexBufferSize = draw_data->TotalVtxCount + 5000; + desc.Width = frameResources->VertexBufferSize * sizeof(ImDrawVert); + HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&frameResources->VB)); + assert(SUCCEEDED(hr)); + } + if (!frameResources->IB || frameResources->IndexBufferSize < draw_data->TotalIdxCount) + { + if (frameResources->IB) { frameResources->IB->Release(); frameResources->IB = NULL; } + frameResources->IndexBufferSize = draw_data->TotalIdxCount + 10000; + desc.Width = frameResources->IndexBufferSize * sizeof(ImDrawIdx); + HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&frameResources->IB)); + assert(SUCCEEDED(hr)); + } + + // Copy and convert all vertices into a single contiguous buffer + D3D12_RANGE range = {}; + void* vtx_resource = NULL; + HRESULT hr = frameResources->VB->Map(0, &range, &vtx_resource); + assert(SUCCEEDED(hr)); + + void* idx_resource = NULL; + hr = frameResources->IB->Map(0, &range, &idx_resource); + assert(SUCCEEDED(hr)); + + ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource; + ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + memcpy(vtx_dst, &cmd_list->VtxBuffer[0], cmd_list->VtxBuffer.size() * sizeof(ImDrawVert)); + memcpy(idx_dst, &cmd_list->IdxBuffer[0], cmd_list->IdxBuffer.size() * sizeof(ImDrawIdx)); + vtx_dst += cmd_list->VtxBuffer.size(); + idx_dst += cmd_list->IdxBuffer.size(); + } + frameResources->VB->Unmap(0, &range); + frameResources->IB->Unmap(0, &range); + + // Setup orthographic projection matrix into our constant buffer + VERTEX_CONSTANT_BUFFER vertexConstantBuffer = {}; + { + 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(&vertexConstantBuffer.mvp, mvp, sizeof(mvp)); + } + + // Setup viewport + D3D12_VIEWPORT viewport = {}; + viewport.Width = ImGui::GetIO().DisplaySize.x; + viewport.Height = ImGui::GetIO().DisplaySize.y; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + + // Bind shader and vertex buffers + D3D12_VERTEX_BUFFER_VIEW vbv = {}; + vbv.BufferLocation = frameResources->VB->GetGPUVirtualAddress(); + vbv.SizeInBytes = frameResources->VertexBufferSize * sizeof(ImDrawVert); + vbv.StrideInBytes = sizeof(ImDrawVert); + + D3D12_INDEX_BUFFER_VIEW ibv = {}; + ibv.BufferLocation = frameResources->IB->GetGPUVirtualAddress(); + ibv.SizeInBytes = frameResources->IndexBufferSize * sizeof(ImDrawIdx); + ibv.Format = sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT; + + FLOAT blendFactor[4] = { 0.f, 0.f, 0.f, 0.f }; + + g_pd3dCommandList->SetPipelineState(g_pPipelineState); + g_pd3dCommandList->SetGraphicsRootSignature(g_pRootSignature); + g_pd3dCommandList->SetGraphicsRoot32BitConstants(0, 16, &vertexConstantBuffer, 0); + g_pd3dCommandList->IASetIndexBuffer(&ibv); + g_pd3dCommandList->IASetVertexBuffers(0, 1, &vbv); + g_pd3dCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + g_pd3dCommandList->RSSetViewports(1, &viewport); + g_pd3dCommandList->OMSetBlendFactor(blendFactor); + + // Render command lists + int vtx_offset = 0; + int idx_offset = 0; + for (int n = 0; n < draw_data->CmdListsCount; n++) + { + const ImDrawList* cmd_list = draw_data->CmdLists[n]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) + { + const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; + if (pcmd->UserCallback) + { + pcmd->UserCallback(cmd_list, pcmd); + } + else + { + D3D12_RECT scissorRect = { (LONG)pcmd->ClipRect.x, (LONG)pcmd->ClipRect.y, (LONG)pcmd->ClipRect.z, (LONG)pcmd->ClipRect.w }; + + D3D12_GPU_DESCRIPTOR_HANDLE srvHandle = {}; + srvHandle.ptr = (UINT64) pcmd->TextureId; + + g_pd3dCommandList->SetGraphicsRootDescriptorTable(1, srvHandle); + g_pd3dCommandList->RSSetScissorRects(1, &scissorRect); + g_pd3dCommandList->DrawIndexedInstanced(pcmd->ElemCount, 1, idx_offset, vtx_offset, 0); + } + idx_offset += pcmd->ElemCount; + } + vtx_offset += cmd_list->VtxBuffer.size(); + } +} + +IMGUI_API LRESULT ImGui_ImplDX12_WndProcHandler(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_MBUTTONDOWN: + io.MouseDown[2] = true; + return true; + case WM_MBUTTONUP: + io.MouseDown[2] = 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 < 256) + io.KeysDown[wParam] = 1; + return true; + case WM_KEYUP: + if (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; +} + +static void ImGui_ImplDX12_CreateFontsTexture() +{ + // Build texture atlas + ImGuiIO& io = ImGui::GetIO(); + unsigned char* pixels; + int width, height; + io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); + + // Upload texture to graphics system + { + D3D12_RESOURCE_DESC resourceDesc = {}; + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resourceDesc.Alignment = 0; + resourceDesc.Width = width; + resourceDesc.Height = height; + resourceDesc.DepthOrArraySize = 1; + resourceDesc.MipLevels = 1; + resourceDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + resourceDesc.SampleDesc.Count = 1; + resourceDesc.SampleDesc.Quality = 0; + resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + D3D12_HEAP_PROPERTIES props = {}; + props.Type = D3D12_HEAP_TYPE_DEFAULT; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &resourceDesc, + D3D12_RESOURCE_STATE_COPY_DEST, NULL, IID_PPV_ARGS(&g_pFontTextureResource)); + assert(SUCCEEDED(hr)); + + UINT uploadPitch = (width * 4 + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u); + UINT uploadSize = height * uploadPitch; + resourceDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + resourceDesc.Alignment = 0; + resourceDesc.Width = uploadSize; + resourceDesc.Height = 1; + resourceDesc.DepthOrArraySize = 1; + resourceDesc.MipLevels = 1; + resourceDesc.Format = DXGI_FORMAT_UNKNOWN; + resourceDesc.SampleDesc.Count = 1; + resourceDesc.SampleDesc.Quality = 0; + resourceDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + resourceDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + props.Type = D3D12_HEAP_TYPE_UPLOAD; + props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + + ID3D12Resource* uploadBuffer = NULL; + hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &resourceDesc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&uploadBuffer)); + assert(SUCCEEDED(hr)); + + void* mapped = NULL; + D3D12_RANGE range = { 0, uploadSize }; + hr = uploadBuffer->Map(0, &range, &mapped); + assert(SUCCEEDED(hr)); + for (int y = 0; y < height; ++y) + { + memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4); + } + uploadBuffer->Unmap(0, &range); + + D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; + srcLocation.pResource = uploadBuffer; + srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + srcLocation.PlacedFootprint.Footprint.Width = width; + srcLocation.PlacedFootprint.Footprint.Height = height; + srcLocation.PlacedFootprint.Footprint.Depth = 1; + srcLocation.PlacedFootprint.Footprint.RowPitch = uploadPitch; + + D3D12_TEXTURE_COPY_LOCATION dstLocation = {}; + dstLocation.pResource = g_pFontTextureResource; + dstLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + dstLocation.SubresourceIndex = 0; + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = g_pFontTextureResource; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE; + + ID3D12Fence* fence = NULL; + hr = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); + assert(SUCCEEDED(hr)); + + HANDLE event = CreateEvent(0, 0, 0, 0); + assert(event != NULL); + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.NodeMask = 1; + + ID3D12CommandQueue* cmdQueue = NULL; + hr = g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue)); + assert(SUCCEEDED(hr)); + + ID3D12CommandAllocator* cmdAlloc = NULL; + hr = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc)); + assert(SUCCEEDED(hr)); + + ID3D12GraphicsCommandList* cmdList = NULL; + hr = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList)); + assert(SUCCEEDED(hr)); + + cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL); + cmdList->ResourceBarrier(1, &barrier); + + hr = cmdList->Close(); + assert(SUCCEEDED(hr)); + + cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*) &cmdList); + hr = cmdQueue->Signal(fence, 1); + assert(SUCCEEDED(hr)); + + fence->SetEventOnCompletion(1, event); + WaitForSingleObject(event, INFINITE); + + cmdList->Release(); + cmdAlloc->Release(); + cmdQueue->Release(); + CloseHandle(event); + fence->Release(); + uploadBuffer->Release(); + } + + // Create texture view + g_pd3dDevice->CreateShaderResourceView(g_pFontTextureResource, NULL, g_hFontSrvCpuDescHandle); + + // Store our identifier + static_assert(sizeof(void*) >= sizeof(g_hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID"); + ImGui::GetIO().Fonts->TexID = (void*) g_hFontSrvGpuDescHandle.ptr; +} + +bool ImGui_ImplDX12_CreateDeviceObjects() +{ + if (!g_pd3dDevice) + return false; + if (g_pPipelineState) + ImGui_ImplDX12_InvalidateDeviceObjects(); + + // Create the root signature + { + D3D12_DESCRIPTOR_RANGE descRange = {}; + descRange.RangeType = D3D12_DESCRIPTOR_RANGE_TYPE_SRV; + descRange.NumDescriptors = 1; + descRange.BaseShaderRegister = 0; + descRange.RegisterSpace = 0; + descRange.OffsetInDescriptorsFromTableStart = 0; + + D3D12_ROOT_PARAMETER param[2] = {}; + + param[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + param[0].Constants.ShaderRegister = 0; + param[0].Constants.RegisterSpace = 0; + param[0].Constants.Num32BitValues = 16; + param[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_VERTEX; + + param[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + param[1].DescriptorTable.NumDescriptorRanges = 1; + param[1].DescriptorTable.pDescriptorRanges = &descRange; + param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_STATIC_SAMPLER_DESC staticSampler = {}; + staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR; + staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP; + staticSampler.MipLODBias = 0.f; + staticSampler.MaxAnisotropy = 0; + staticSampler.ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS; + staticSampler.BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK; + staticSampler.MinLOD = 0.f; + staticSampler.MaxLOD = 0.f; + staticSampler.ShaderRegister = 0; + staticSampler.RegisterSpace = 0; + staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL; + + D3D12_ROOT_SIGNATURE_DESC desc = {}; + desc.NumParameters = _countof(param); + desc.pParameters = param; + desc.NumStaticSamplers = 1; + desc.pStaticSamplers = &staticSampler; + desc.Flags = + D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT | + D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS | + D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS; + + ID3DBlob* blob = NULL; + if (D3D12SerializeRootSignature(&desc, D3D_ROOT_SIGNATURE_VERSION_1, &blob, NULL) != S_OK) + return false; + + g_pd3dDevice->CreateRootSignature(0, blob->GetBufferPointer(), blob->GetBufferSize(), IID_PPV_ARGS(&g_pRootSignature)); + blob->Release(); + } + // Create the pipeline state object + { + static const char* vertexShader = + "cbuffer vertexBuffer : register(b0) \ + {\ + 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;\ + }"; + + static const char* pixelShader = + "struct PS_INPUT\ + {\ + float4 pos : SV_POSITION;\ + float4 col : COLOR0;\ + float2 uv : TEXCOORD0;\ + };\ + SamplerState sampler0 : register(s0);\ + Texture2D texture0 : register(t0);\ + \ + float4 main(PS_INPUT input) : SV_Target\ + {\ + float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \ + return out_col; \ + }"; + + 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; + + 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; + + D3D12_INPUT_ELEMENT_DESC localLayout[] = { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->pos), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (size_t)(&((ImDrawVert*)0)->uv), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (size_t)(&((ImDrawVert*)0)->col), D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }, + }; + + D3D12_GRAPHICS_PIPELINE_STATE_DESC desc = {}; + desc.NodeMask = 1; + desc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + desc.InputLayout = { localLayout, _countof(localLayout) }; + desc.pRootSignature = g_pRootSignature; + desc.VS = { g_pVertexShaderBlob->GetBufferPointer(), g_pVertexShaderBlob->GetBufferSize() }; + desc.PS = { g_pPixelShaderBlob->GetBufferPointer(), g_pPixelShaderBlob->GetBufferSize() }; + desc.SampleMask = UINT_MAX; + desc.NumRenderTargets = 1; + desc.RTVFormats[0] = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.SampleDesc.Count = 1; + desc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + desc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID; + desc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + desc.RasterizerState.FrontCounterClockwise = FALSE; + desc.RasterizerState.DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + desc.RasterizerState.DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + desc.RasterizerState.SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + desc.RasterizerState.DepthClipEnable = TRUE; + desc.RasterizerState.MultisampleEnable = FALSE; + desc.RasterizerState.AntialiasedLineEnable = FALSE; + desc.RasterizerState.ForcedSampleCount = 0; + desc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + + desc.BlendState.AlphaToCoverageEnable = FALSE; + desc.BlendState.RenderTarget[0].BlendEnable = TRUE; + desc.BlendState.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA; + desc.BlendState.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA; + desc.BlendState.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD; + desc.BlendState.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_INV_SRC_ALPHA; + desc.BlendState.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO; + desc.BlendState.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD; + desc.BlendState.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL; + + desc.DepthStencilState.DepthEnable = FALSE; + desc.DepthStencilState.StencilEnable = FALSE; + + HRESULT hr = g_pd3dDevice->CreateGraphicsPipelineState(&desc, IID_PPV_ARGS(&g_pPipelineState)); + assert(SUCCEEDED(hr)); + } + + ImGui_ImplDX12_CreateFontsTexture(); + + return true; +} + +void ImGui_ImplDX12_InvalidateDeviceObjects() +{ + if (!g_pd3dDevice) + return; + + if (g_pVertexShaderBlob) { g_pVertexShaderBlob->Release(); g_pVertexShaderBlob = NULL; } + if (g_pPixelShaderBlob) { g_pPixelShaderBlob->Release(); g_pPixelShaderBlob = NULL; } + if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; } + if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; } + if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; } + for (UINT i = 0; i < g_numFramesInFlight; ++i) + { + if (g_pFrameResources[i].IB) { g_pFrameResources[i].IB->Release(); g_pFrameResources[i].IB = NULL; } + if (g_pFrameResources[i].VB) { g_pFrameResources[i].VB->Release(); g_pFrameResources[i].VB = NULL; } + } + ImGui::GetIO().Fonts->TexID = 0; +} + +bool ImGui_ImplDX12_Init(void* hwnd, int numFramesInFlight, + ID3D12Device* device, ID3D12GraphicsCommandList* cmdList, + D3D12_CPU_DESCRIPTOR_HANDLE fontSrvCpuDescHandle, + D3D12_GPU_DESCRIPTOR_HANDLE fontSrvGpuDescHandle) +{ + g_hWnd = (HWND)hwnd; + g_pd3dDevice = device; + g_pd3dCommandList = cmdList; + g_hFontSrvCpuDescHandle = fontSrvCpuDescHandle; + g_hFontSrvGpuDescHandle = fontSrvGpuDescHandle; + g_pFrameResources = new FrameResources [numFramesInFlight]; + g_numFramesInFlight = numFramesInFlight; + g_frameIndex = UINT_MAX; + + for (int i = 0; i < numFramesInFlight; ++i) + { + g_pFrameResources[i].IB = NULL; + g_pFrameResources[i].VB = NULL; + g_pFrameResources[i].VertexBufferSize = 5000; + g_pFrameResources[i].IndexBufferSize = 10000; + } + + if (!QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) + return false; + if (!QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) + return false; + + ImGuiIO& io = ImGui::GetIO(); + 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_DOWN; + io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR; + io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; + 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_ImplDX12_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. + io.ImeWindowHandle = g_hWnd; + + return true; +} + +void ImGui_ImplDX12_Shutdown() +{ + ImGui_ImplDX12_InvalidateDeviceObjects(); + ImGui::Shutdown(); + delete[] g_pFrameResources; + g_pd3dDevice = NULL; + g_hWnd = (HWND)0; + g_pd3dCommandList = NULL; + g_hFontSrvCpuDescHandle.ptr = 0; + g_hFontSrvGpuDescHandle.ptr = 0; + g_pFrameResources = NULL; + g_numFramesInFlight = 0; + g_frameIndex = UINT_MAX; +} + +void ImGui_ImplDX12_NewFrame() +{ + if (!g_pPipelineState) + ImGui_ImplDX12_CreateDeviceObjects(); + + ImGuiIO& io = ImGui::GetIO(); + + // Setup display size (every frame to accommodate for window resizing) + RECT rect; + GetClientRect(g_hWnd, &rect); + io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); + + // 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.KeyAlt = (GetKeyState(VK_MENU) & 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 + + // Hide OS mouse cursor if ImGui is drawing it + SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW)); + + // Start the frame + ImGui::NewFrame(); +} diff --git a/examples/directx12_example/imgui_impl_dx12.h b/examples/directx12_example/imgui_impl_dx12.h new file mode 100644 index 00000000..f5c58bb8 --- /dev/null +++ b/examples/directx12_example/imgui_impl_dx12.h @@ -0,0 +1,34 @@ +// ImGui Win32 + DirectX12 binding +// You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. +// If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// https://github.com/ocornut/imgui + +#include + +// cmdList is the command list that the implementation will use to render the +// GUI. +// +// Before calling ImGui::Render(), caller must prepare cmdList by resetting it +// and setting the appropriate render target and descriptor heap that contains +// fontSrv*puDescHandle. +// +// fontSrvCpuDescHandle and fontSrvGpuDescHandle are handles to a single SRV +// descriptor to use for the internal font texture. +IMGUI_API bool ImGui_ImplDX12_Init(void* hwnd, int numFramesInFlight, + ID3D12Device* device, ID3D12GraphicsCommandList* cmdList, + D3D12_CPU_DESCRIPTOR_HANDLE fontSrvCpuDescHandle, + D3D12_GPU_DESCRIPTOR_HANDLE fontSrvGpuDescHandle); +IMGUI_API void ImGui_ImplDX12_Shutdown(); +IMGUI_API void ImGui_ImplDX12_NewFrame(); + +// Use if you want to reset your rendering device without losing ImGui state. +IMGUI_API void ImGui_ImplDX12_InvalidateDeviceObjects(); +IMGUI_API bool ImGui_ImplDX12_CreateDeviceObjects(); + +// 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. +/* +IMGUI_API LRESULT ImGui_ImplDX12_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +*/ diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp new file mode 100644 index 00000000..dbd822ac --- /dev/null +++ b/examples/directx12_example/main.cpp @@ -0,0 +1,418 @@ +// ImGui - standalone example application for DirectX 11 +// If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. + +#include +#include +#include "imgui_impl_dx12.h" +#include +#include +#include + +struct FrameContext +{ + ID3D12CommandAllocator* CommandAllocator; + UINT64 FenceValue; + bool FenceSignalled; +}; + +// Data +static int const NUM_FRAMES_IN_FLIGHT = 3; +static FrameContext g_frameContext[NUM_FRAMES_IN_FLIGHT] = {}; +static UINT g_frameIndex = 0; + +static int const NUM_BACK_BUFFERS = 3; +static IDXGIFactory4* g_pdxgiFactory = NULL; +static ID3D12Device* g_pd3dDevice = NULL; +static ID3D12DescriptorHeap* g_pd3dRtvDescHeap = NULL; +static ID3D12DescriptorHeap* g_pd3dSrvDescHeap = NULL; +static ID3D12CommandQueue* g_pd3dCommandQueue = NULL; +static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; +static ID3D12Fence* g_fence = NULL; +static HANDLE g_fenceEvent = NULL; +static UINT64 g_fenceLastSignalledValue = 0; +static IDXGISwapChain3* g_pSwapChain = NULL; +static HANDLE g_hSwapChainWaitableObject = NULL; +static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; +static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFERS] = {}; + +static void WaitForLastSubmittedFrame() +{ + FrameContext* frameCtxt = &g_frameContext[g_frameIndex % NUM_FRAMES_IN_FLIGHT]; + + UINT64 fenceValue = frameCtxt->FenceValue; + if (fenceValue == 0) { // means no fence was signalled + return; + } + + frameCtxt->FenceValue = 0; + if (g_fence->GetCompletedValue() >= fenceValue) { + return; + } + + HRESULT hr = g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent); + assert(SUCCEEDED(hr)); + + WaitForSingleObject(g_fenceEvent, INFINITE); +} + +static FrameContext* WaitForNextFrameResources() +{ + UINT nextFrameIndex = g_frameIndex + 1; + g_frameIndex = nextFrameIndex; + + HANDLE waitableObjects[] = { + g_hSwapChainWaitableObject, + NULL, + }; + DWORD numWaitableObjects = 1; + + FrameContext* frameCtxt = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT]; + UINT64 fenceValue = frameCtxt->FenceValue; + if (fenceValue != 0) { // means no fence was signalled + frameCtxt->FenceValue = 0; + + HRESULT hr = g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent); + assert(SUCCEEDED(hr)); + + waitableObjects[1] = g_fenceEvent; + numWaitableObjects = 2; + } + + HRESULT hr = WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE); + assert(SUCCEEDED(hr)); + + return frameCtxt; +} + +void CreateRenderTarget(HWND hWnd, int width, int height) +{ + DXGI_SWAP_CHAIN_DESC1 desc = {}; + desc.Width = width; + desc.Height = height; + desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; + desc.Stereo = FALSE; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + desc.BufferCount = NUM_BACK_BUFFERS; + desc.Scaling = DXGI_SCALING_STRETCH; + desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD; + desc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED; + desc.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT; + + IDXGISwapChain1* swapChain1 = NULL; + HRESULT hr = g_pdxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &desc, NULL, NULL, &swapChain1); + assert(SUCCEEDED(hr)); + + hr = swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)); + assert(SUCCEEDED(hr)); + + swapChain1->Release(); + + hr = g_pSwapChain->SetMaximumFrameLatency(NUM_BACK_BUFFERS); + assert(SUCCEEDED(hr)); + + g_hSwapChainWaitableObject = g_pSwapChain->GetFrameLatencyWaitableObject(); + assert(g_hSwapChainWaitableObject != NULL); + + for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) + { + hr = g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&g_mainRenderTargetResource[i])); + assert(SUCCEEDED(hr)); + + g_pd3dDevice->CreateRenderTargetView(g_mainRenderTargetResource[i], NULL, g_mainRenderTargetDescriptor[i]); + } +} + +void CleanupRenderTarget() +{ + WaitForLastSubmittedFrame(); + + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } + for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) + { + if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = NULL; } + } + if (g_hSwapChainWaitableObject != NULL) { CloseHandle(g_hSwapChainWaitableObject); } +} + +HRESULT CreateDeviceD3D(HWND hWnd) +{ + (void) hWnd; + +#ifdef _DEBUG + { + ID3D12Debug* debugController = NULL; + if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController)))) + { + debugController->EnableDebugLayer(); + debugController->Release(); + } + } +#endif + + if (CreateDXGIFactory1(IID_PPV_ARGS(&g_pdxgiFactory)) != S_OK) + return E_FAIL; + + IDXGIAdapter1* adapter = NULL; + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != g_pdxgiFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc = {}; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + adapter->Release(); + continue; + } + + if (FAILED(D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, _uuidof(ID3D12Device), NULL))) + { + adapter->Release(); + continue; + } + + break; + } + + HRESULT hr = D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&g_pd3dDevice)); + + if (adapter != NULL) + { + adapter->Release(); + } + + if (FAILED(hr)) + return hr; + + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + desc.NumDescriptors = NUM_BACK_BUFFERS; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + desc.NodeMask = 1; + if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dRtvDescHeap)) != S_OK) + return E_FAIL; + + SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart(); + for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) { + g_mainRenderTargetDescriptor[i] = rtvHandle; + rtvHandle.ptr += rtvDescriptorSize; + } + } + + { + D3D12_DESCRIPTOR_HEAP_DESC desc = {}; + desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; + desc.NumDescriptors = 1; + desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE; + if (g_pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&g_pd3dSrvDescHeap)) != S_OK) + return E_FAIL; + } + + { + D3D12_COMMAND_QUEUE_DESC desc = {}; + desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + desc.NodeMask = 1; + if (g_pd3dDevice->CreateCommandQueue(&desc, IID_PPV_ARGS(&g_pd3dCommandQueue)) != S_OK) + return E_FAIL; + } + + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; ++i) + { + if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK) + return E_FAIL; + } + + if (g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_frameContext[0].CommandAllocator, NULL, IID_PPV_ARGS(&g_pd3dCommandList)) != S_OK || + g_pd3dCommandList->Close() != S_OK) + return E_FAIL; + + if (g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&g_fence)) != S_OK) + return E_FAIL; + + g_fenceEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (g_fenceEvent == NULL) + return E_FAIL; + + return S_OK; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; ++i) + { + if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = NULL; } + } + if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; } + if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = NULL; } + if (g_pd3dRtvDescHeap) { g_pd3dRtvDescHeap->Release(); g_pd3dRtvDescHeap = NULL; } + if (g_pd3dSrvDescHeap) { g_pd3dSrvDescHeap->Release(); g_pd3dSrvDescHeap = NULL; } + if (g_fence) { g_fence->Release(); g_fence = NULL; } + if (g_fenceEvent) { CloseHandle(g_fenceEvent); g_fenceEvent = NULL; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + if (g_pdxgiFactory) { g_pdxgiFactory->Release(); g_pdxgiFactory = NULL; } +} + +extern LRESULT ImGui_ImplDX12_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplDX12_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + ImGui_ImplDX12_InvalidateDeviceObjects(); + CleanupRenderTarget(); + CreateRenderTarget(hWnd, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam)); + ImGui_ImplDX12_CreateDeviceObjects(); + } + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +int main(int, char**) +{ + // Create application window + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, _T("ImGui Example"), NULL }; + RegisterClassEx(&wc); + HWND hwnd = CreateWindow(_T("ImGui Example"), _T("ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); + + // Initialize Direct3D + if (CreateDeviceD3D(hwnd) < 0) + { + CleanupDeviceD3D(); + UnregisterClass(_T("ImGui Example"), wc.hInstance); + return 1; + } + + // Show the window + ShowWindow(hwnd, SW_SHOWDEFAULT); + UpdateWindow(hwnd); + + // Setup ImGui binding + ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, g_pd3dCommandList, + g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), + g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); + + // Load Fonts + // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) + //ImGuiIO& io = ImGui::GetIO(); + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); + //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + + bool show_test_window = true; + bool show_another_window = false; + ImVec4 clear_col = ImColor(114, 144, 154); + + // Main loop + MSG msg; + ZeroMemory(&msg, sizeof(msg)); + while (msg.message != WM_QUIT) + { + if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + continue; + } + + // Wait for frame resources to be available + + ImGui_ImplDX12_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" + { + static float f = 0.0f; + ImGui::Text("Hello, world!"); + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); + ImGui::ColorEdit3("clear color", (float*)&clear_col); + if (ImGui::Button("Test Window")) show_test_window ^= 1; + if (ImGui::Button("Another Window")) show_another_window ^= 1; + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + } + + // 2. Show another simple window, this time using an explicit Begin/End pair + if (show_another_window) + { + ImGui::SetNextWindowSize(ImVec2(200,100), ImGuiSetCond_FirstUseEver); + ImGui::Begin("Another Window", &show_another_window); + ImGui::Text("Hello"); + ImGui::End(); + } + + // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() + if (show_test_window) + { + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::ShowTestWindow(&show_test_window); + } + + // Rendering + FrameContext* frameCtxt = WaitForNextFrameResources(); + UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex(); + + HRESULT hr = frameCtxt->CommandAllocator->Reset(); + assert(SUCCEEDED(hr)); + + hr = g_pd3dCommandList->Reset(frameCtxt->CommandAllocator, NULL); + assert(SUCCEEDED(hr)); + + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE; + barrier.Transition.pResource = g_mainRenderTargetResource[backBufferIdx]; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET; + g_pd3dCommandList->ResourceBarrier(1, &barrier); + + g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], (float*)&clear_col, 0, NULL); + g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); + g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); + ImGui::Render(); + + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; + g_pd3dCommandList->ResourceBarrier(1, &barrier); + + hr = g_pd3dCommandList->Close(); + assert(SUCCEEDED(hr)); + + g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*) &g_pd3dCommandList); + + hr = g_pSwapChain->Present(1, 0); + assert(SUCCEEDED(hr)); + + auto fenceValue = g_fenceLastSignalledValue + 1; + hr = g_pd3dCommandQueue->Signal(g_fence, fenceValue); + assert(SUCCEEDED(hr)); + g_fenceLastSignalledValue = fenceValue; + frameCtxt->FenceValue = fenceValue; + } + + ImGui_ImplDX12_Shutdown(); + CleanupDeviceD3D(); + UnregisterClass(_T("ImGui Example"), wc.hInstance); + + return 0; +} diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples_msvc2010.sln index b7e6a252..200a38f5 100644 --- a/examples/imgui_examples_msvc2010.sln +++ b/examples/imgui_examples_msvc2010.sln @@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx11_example", "directx11_example\directx11_example.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx12_example", "directx12_example\directx12_example.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl3_example", "opengl3_example\opengl3_example.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx10_example", "directx10_example\directx10_example.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}" @@ -43,6 +45,14 @@ Global {9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32 {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.ActiveCfg = Release|x64 {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.Build.0 = Release|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.ActiveCfg = Debug|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.Build.0 = Debug|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.ActiveCfg = Debug|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.Build.0 = Debug|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.ActiveCfg = Release|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.Build.0 = Release|Win32 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.ActiveCfg = Release|x64 + {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.Build.0 = Release|x64 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.ActiveCfg = Debug|Win32 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.Build.0 = Debug|Win32 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|x64.ActiveCfg = Debug|x64 From f6b6dace9e79c75f8f494f71eb50228062d3e59c Mon Sep 17 00:00:00 2001 From: Jefferson Montgomery Date: Sun, 24 Sep 2017 14:43:37 -0700 Subject: [PATCH 02/87] Pass command list in using ImGui_ImplDX12_NewFrame() instead of ImGui_ImplDX12_Init() --- examples/directx12_example/imgui_impl_dx12.cpp | 7 ++++--- examples/directx12_example/imgui_impl_dx12.h | 4 ++-- examples/directx12_example/main.cpp | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index b2d62840..8f81b007 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -629,13 +629,12 @@ void ImGui_ImplDX12_InvalidateDeviceObjects() } bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, - ID3D12Device* device, ID3D12GraphicsCommandList* command_list, + ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) { g_hWnd = (HWND)hwnd; g_pd3dDevice = device; - g_pd3dCommandList = command_list; g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; g_pFrameResources = new FrameResources [num_frames_in_flight]; @@ -697,11 +696,13 @@ void ImGui_ImplDX12_Shutdown() g_frameIndex = UINT_MAX; } -void ImGui_ImplDX12_NewFrame() +void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* command_list) { if (!g_pPipelineState) ImGui_ImplDX12_CreateDeviceObjects(); + g_pd3dCommandList = command_list; + ImGuiIO& io = ImGui::GetIO(); // Setup display size (every frame to accommodate for window resizing) diff --git a/examples/directx12_example/imgui_impl_dx12.h b/examples/directx12_example/imgui_impl_dx12.h index 78cef4ab..7bc828eb 100644 --- a/examples/directx12_example/imgui_impl_dx12.h +++ b/examples/directx12_example/imgui_impl_dx12.h @@ -21,11 +21,11 @@ struct D3D12_GPU_DESCRIPTOR_HANDLE; // fontSrvCpuDescHandle and fontSrvGpuDescHandle are handles to a single SRV // descriptor to use for the internal font texture. IMGUI_API bool ImGui_ImplDX12_Init(void* hwnd, int numFramesInFlight, - ID3D12Device* device, ID3D12GraphicsCommandList* cmdList, + ID3D12Device* device, D3D12_CPU_DESCRIPTOR_HANDLE fontSrvCpuDescHandle, D3D12_GPU_DESCRIPTOR_HANDLE fontSrvGpuDescHandle); IMGUI_API void ImGui_ImplDX12_Shutdown(); -IMGUI_API void ImGui_ImplDX12_NewFrame(); +IMGUI_API void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* cmdList); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplDX12_InvalidateDeviceObjects(); diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 1fc6f37b..4bca2a29 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -300,7 +300,7 @@ int main(int, char**) UpdateWindow(hwnd); // Setup ImGui binding - ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, g_pd3dCommandList, + ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); @@ -329,7 +329,7 @@ int main(int, char**) DispatchMessage(&msg); continue; } - ImGui_ImplDX12_NewFrame(); + ImGui_ImplDX12_NewFrame(g_pd3dCommandList); // 1. Show a simple window // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" From 3fd5790814aca2e0379cb4188d517640cf070feb Mon Sep 17 00:00:00 2001 From: Jefferson Montgomery Date: Sun, 24 Sep 2017 14:57:38 -0700 Subject: [PATCH 03/87] Pass render target format in ImGui_ImplDX12_Init() instead of hard-coded. --- examples/directx12_example/imgui_impl_dx12.cpp | 5 ++++- examples/directx12_example/imgui_impl_dx12.h | 2 ++ examples/directx12_example/main.cpp | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index 8f81b007..b0b65d7d 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -32,6 +32,7 @@ static ID3D10Blob* g_pVertexShaderBlob = NULL; static ID3D10Blob* g_pPixelShaderBlob = NULL; static ID3D12RootSignature* g_pRootSignature = NULL; static ID3D12PipelineState* g_pPipelineState = NULL; +static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; static ID3D12Resource* g_pFontTextureResource = NULL; static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; @@ -489,7 +490,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects() psoDesc.pRootSignature = g_pRootSignature; psoDesc.SampleMask = UINT_MAX; psoDesc.NumRenderTargets = 1; - psoDesc.RTVFormats[0] = DXGI_FORMAT_R8G8B8A8_UNORM; + psoDesc.RTVFormats[0] = g_RTVFormat; psoDesc.SampleDesc.Count = 1; psoDesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; @@ -630,11 +631,13 @@ void ImGui_ImplDX12_InvalidateDeviceObjects() bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, ID3D12Device* device, + DXGI_FORMAT rtv_format, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) { g_hWnd = (HWND)hwnd; g_pd3dDevice = device; + g_RTVFormat = rtv_format; g_hFontSrvCpuDescHandle = font_srv_cpu_desc_handle; g_hFontSrvGpuDescHandle = font_srv_gpu_desc_handle; g_pFrameResources = new FrameResources [num_frames_in_flight]; diff --git a/examples/directx12_example/imgui_impl_dx12.h b/examples/directx12_example/imgui_impl_dx12.h index 7bc828eb..059d73e1 100644 --- a/examples/directx12_example/imgui_impl_dx12.h +++ b/examples/directx12_example/imgui_impl_dx12.h @@ -6,6 +6,7 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +enum DXGI_FORMAT; struct ID3D12Device; struct ID3D12GraphicsCommandList; struct D3D12_CPU_DESCRIPTOR_HANDLE; @@ -22,6 +23,7 @@ struct D3D12_GPU_DESCRIPTOR_HANDLE; // descriptor to use for the internal font texture. IMGUI_API bool ImGui_ImplDX12_Init(void* hwnd, int numFramesInFlight, ID3D12Device* device, + DXGI_FORMAT rtv_format, D3D12_CPU_DESCRIPTOR_HANDLE fontSrvCpuDescHandle, D3D12_GPU_DESCRIPTOR_HANDLE fontSrvGpuDescHandle); IMGUI_API void ImGui_ImplDX12_Shutdown(); diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 4bca2a29..51b9da4e 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -301,6 +301,7 @@ int main(int, char**) // Setup ImGui binding ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, + DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); From 6d3cfba8342c32c8f4739eb818779a9d5b05e260 Mon Sep 17 00:00:00 2001 From: stfx Date: Thu, 23 Nov 2017 12:37:11 +0100 Subject: [PATCH 04/87] Add Slider hover color just like Drag I feel like there should be hover color options for each different control instead of the grouped frame color to make it usable for everyone. This also would not reduce performance as all controls already check for hover state as required by the ImGUI::IsHoveredItem() API. --- imgui.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index c1361f73..9149eabe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6856,7 +6856,8 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v const ImGuiStyle& style = g.Style; // Draw frame - RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f); const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; From 6668e80bed2f9541be65b60985e43c8f5be160f8 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 15 Feb 2018 10:33:22 +0100 Subject: [PATCH 05/87] Update README.md --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index fada3f86..a51632c0 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ dear imgui, [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) -(This library is free but needs your support to sustain its development. There are lots of desirable new features and maintenance to do. If you are an individual using dear imgui, please consider donating via Patreon or PayPal. If your company is using dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for private support, custom development etc. E-mail: omarcornut at gmail.) +_(This library is free but needs your support to sustain its development. There are many desirable features and maintenance ahead If you are an individual using dear imgui, please consider donating via Patreon or PayPal. If your company is using dear imgui, please consider financial support (e.g. sponsoring a few weeks/months of development). I can invoice for technical support, custom development etc. E-mail: omarcornut at gmail.)_ Monthly donations via Patreon:
[![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) @@ -11,11 +11,11 @@ Monthly donations via Patreon: One-off donations via PayPal:
[![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) -**Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).** +Dear ImGui is a bloat-free graphical user interface library for C++. It outputs optimized vertex buffers that you can render anytime in your 3D-pipeline enabled application. It is fast, portable, renderer agnostic and self-contained (no external dependencies).** -**Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries. Within the scope of what it has to offer, working with Dear ImGui tends to be more efficient and less error prone than working with Qt, WPF, etc. by a significant order of magnitude.** +Dear ImGui is designed to enable fast iterations and to empower programmers to create content creation tools and visualization / debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and lacks certain features normally found in more high-level libraries. -Dear ImGui is particularly suited to integration in games, realtime 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard. +Dear ImGui is particularly suited to integration in games engine (for tooling), realtime 3D applications, fullscreen applications, embedded applications, or any applications on consoles platforms where operating system features are non-standard. Dear ImGui is self-contained within a few files that you can easily copy and compile into your application/engine: - imgui.cpp @@ -32,7 +32,7 @@ No specific build process is required. You can add the .cpp files to your projec ### Usage -Your code passes mouse/keyboard inputs and settings to Dear ImGui (see example applications for more details). After Dear ImGui is setup, you can use it from anywhere in your program loop: +Your code passes mouse/keyboard/gamepad inputs and settings to Dear ImGui (see example applications for more details). After Dear ImGui is setup, you can use it from \_anywhere\_ in your program loop: Code: ```cpp @@ -84,7 +84,7 @@ Result: ### How it works -Check out the References section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize state synchronization and storage from the user's point of view. It is less error prone (less code and less bugs) than traditional retained-mode interfaces, and lends itself to create dynamic user interfaces. +Check out the References section if you want to understand the core principles behind the IMGUI paradigm. An IMGUI tries to minimize state duplication, state synchronization and state storage from the user's point of view. It is less error prone (less code and less bugs) than traditional retained-mode interfaces, and lends itself to create dynamic user interfaces. Dear ImGui outputs vertex buffers and command lists that you can easily render in your application. The number of draw calls and state changes is typically very small. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate dear imgui with your existing codebase. @@ -103,7 +103,7 @@ The demo applications are unfortunately not yet DPI aware so expect some blurryn Bindings -------- -Integrating Dear ImGui within your custom engine is a matter of wiring mouse/keyboard inputs and providing a render function that can bind a texture and render simple textured triangles. The examples/ folder is populated with applications doing just that. If you are an experienced programmer it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation! +Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading one texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that. If you are an experienced programmer and at ease with those concepts, it should take you less than an hour to integrate Dear ImGui in your custom engine, but make sure to spend time reading the FAQ, the comments and other documentation! _NB: those third-party bindings may be more or less maintained, more or less close to the original API (as people who create language bindings sometimes haven't used the C++ API themselves.. for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ @@ -155,7 +155,7 @@ Some of the goals for 2018 are: - Finish work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787)) - Finish work on viewports and multiple OS windows management. (see [#1542](https://github.com/ocornut/imgui/issues/1542)) - Finish work on docking, tabs. (see [#351](https://github.com/ocornut/imgui/issues/351#issuecomment-346865709)) -- Make Columns better (they are currently pretty terrible!). +- Make Columns better. (they are currently pretty terrible!) - Make the examples look better, improve styles, improve font support, make the examples hi-DPI aware. Gallery @@ -251,7 +251,7 @@ See the FAQ in imgui.cpp for answers. You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.NavFlags |= ImGuiNavFlags_EnableGamepad`). -You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org) ([sources](https://github.com/symless/synergy)). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). +You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimising for screen real-estate and precision. From 41ecebff5a63b1fa71ad0d1ef6f1e6d3d39ef07d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 15 Feb 2018 11:11:21 +0100 Subject: [PATCH 06/87] Examples: SDL: Added Changelog at the top of the imgui_impl files. (#1618) --- .../sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 14 ++++++++++++++ .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 17 +++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index fe73bcc3..11aa6a5a 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -17,6 +17,20 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// 2018-02-06: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: SDL: Added mapping for ImGuiKey_Space. +// 2018-02-05: SDL: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: SDL: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: SDL: Added Horizontal Mouse Wheel support. +// 2018-01-19: SDL: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: SDL: Added mapping for ImGuiKey_Insert. +// 2017-09-01: OpenGL: Save and restore current polygon mode. +// 2017-08-25: SDL: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Added a void* user_data parameter to Clipboard function handlers. +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. +// 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) + #include #include #include diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index ceb2e7eb..7e0d2688 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -10,6 +10,23 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// 2018-02-06: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: SDL: Added mapping for ImGuiKey_Space. +// 2018-02-05: SDL: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: SDL: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: SDL: Added Horizontal Mouse Wheel support. +// 2018-01-19: SDL: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: SDL: Added mapping for ImGuiKey_Insert. +// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. +// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode. +// 2017-08-25: SDL: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2017-05-01: OpenGL: Fixed save and restore of current blend func state. +// 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. +// 2016-10-15: Added a void* user_data parameter to Clipboard function handlers. +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. +// 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) + #include "imgui.h" #include "imgui_impl_sdl_gl3.h" From ff5f56dd21e2d088f2d4256c85e1ff24d4900652 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 11:59:23 +0100 Subject: [PATCH 07/87] Updated to stb_truetype 1.19 (include minor fix for #1622) --- stb_truetype.h | 955 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 895 insertions(+), 60 deletions(-) diff --git a/stb_truetype.h b/stb_truetype.h index 92b9a875..a08e929f 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1,4 +1,4 @@ -// stb_truetype.h - v1.14 - public domain +// stb_truetype.h - v1.19 - public domain // authored from 2009-2016 by Sean Barrett / RAD Game Tools // // This library processes TrueType files: @@ -6,6 +6,7 @@ // extract glyph metrics // extract glyph shapes // render glyphs to one-channel bitmaps with antialiasing (box filter) +// render glyphs to one-channel SDF bitmaps (signed-distance field/function) // // Todo: // non-MS cmaps @@ -21,39 +22,40 @@ // Mikko Mononen: compound shape support, more cmap formats // Tor Andersson: kerning, subpixel rendering // Dougall Johnson: OpenType / Type 2 font handling +// Daniel Ribeiro Maciel: basic GPOS-based kerning // // Misc other: // Ryan Gordon // Simon Glass // github:IntellectualKitty +// Imanol Celaya +// Daniel Ribeiro Maciel // // Bug/warning reports/fixes: -// "Zer" on mollyrocket (with fix) -// Cass Everitt -// stoiko (Haemimont Games) -// Brian Hook -// Walter van Niftrik -// David Gow -// David Given -// Ivan-Assen Ivanov -// Anthony Pesch -// Johan Duparc -// Hou Qiming -// Fabian "ryg" Giesen -// Martins Mozeiko -// Cap Petschulat -// Omar Cornut -// github:aloucks -// Peter LaValle -// Sergey Popov -// Giumo X. Clanjor -// Higor Euripedes -// Thomas Fields -// Derek Vinyard -// +// "Zer" on mollyrocket Fabian "ryg" Giesen +// Cass Everitt Martins Mozeiko +// stoiko (Haemimont Games) Cap Petschulat +// Brian Hook Omar Cornut +// Walter van Niftrik github:aloucks +// David Gow Peter LaValle +// David Given Sergey Popov +// Ivan-Assen Ivanov Giumo X. Clanjor +// Anthony Pesch Higor Euripedes +// Johan Duparc Thomas Fields +// Hou Qiming Derek Vinyard +// Rob Loach Cort Stratton +// Kenney Phillis Jr. github:oyvindjam +// Brian Costabile github:vassvik +// // VERSION HISTORY // -// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts, num-fonts-in-TTC function +// 1.19 (2018-02-11) GPOS kerning, STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts // 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef @@ -69,9 +71,7 @@ // // LICENSE // -// This software is dual-licensed to the public domain and under the following -// license: you are granted a perpetual, irrevocable license to copy, modify, -// publish, and distribute this file as you see fit. +// See end of file for license information. // // USAGE // @@ -91,7 +91,7 @@ // Improved 3D API (more shippable): // #include "stb_rect_pack.h" -- optional, but you really want it // stbtt_PackBegin() -// stbtt_PackSetOversample() -- for improved quality on small fonts +// stbtt_PackSetOversampling() -- for improved quality on small fonts // stbtt_PackFontRanges() -- pack and renders // stbtt_PackEnd() // stbtt_GetPackedQuad() @@ -109,6 +109,7 @@ // Character advance/positioning // stbtt_GetCodepointHMetrics() // stbtt_GetFontVMetrics() +// stbtt_GetFontVMetricsOS2() // stbtt_GetCodepointKernAdvance() // // Starting with version 1.06, the rasterizer was replaced with a new, @@ -164,7 +165,7 @@ // measurement for describing font size, defined as 72 points per inch. // stb_truetype provides a point API for compatibility. However, true // "per inch" conventions don't make much sense on computer displays -// since they different monitors have different number of pixels per +// since different monitors have different number of pixels per // inch. For example, Windows traditionally uses a convention that // there are 96 pixels per inch, thus making 'inch' measurements have // nothing to do with inches, and thus effectively defining a point to @@ -174,6 +175,39 @@ // for non-commercial fonts, thus making fonts scaled in points // according to the TrueType spec incoherently sized in practice. // +// DETAILED USAGE: +// +// Scale: +// Select how high you want the font to be, in points or pixels. +// Call ScaleForPixelHeight or ScaleForMappingEmToPixels to compute +// a scale factor SF that will be used by all other functions. +// +// Baseline: +// You need to select a y-coordinate that is the baseline of where +// your text will appear. Call GetFontBoundingBox to get the baseline-relative +// bounding box for all characters. SF*-y0 will be the distance in pixels +// that the worst-case character could extend above the baseline, so if +// you want the top edge of characters to appear at the top of the +// screen where y=0, then you would set the baseline to SF*-y0. +// +// Current point: +// Set the current point where the first character will appear. The +// first character could extend left of the current point; this is font +// dependent. You can either choose a current point that is the leftmost +// point and hope, or add some padding, or check the bounding box or +// left-side-bearing of the first character to be displayed and set +// the current point based on that. +// +// Displaying a character: +// Compute the bounding box of the character. It will contain signed values +// relative to . I.e. if it returns x0,y0,x1,y1, +// then the character should be displayed in the rectangle from +// to #define STBTT_ifloor(x) ((int) floor(x)) @@ -406,6 +441,18 @@ int main(int arg, char **argv) #ifndef STBTT_sqrt #include #define STBTT_sqrt(x) sqrt(x) + #define STBTT_pow(x,y) pow(x,y) + #endif + + #ifndef STBTT_fmod + #include + #define STBTT_fmod(x,y) fmod(x,y) + #endif + + #ifndef STBTT_cos + #include + #define STBTT_cos(x) cos(x) + #define STBTT_acos(x) acos(x) #endif #ifndef STBTT_fabs @@ -431,7 +478,7 @@ int main(int arg, char **argv) #endif #ifndef STBTT_memcpy - #include + #include #define STBTT_memcpy memcpy #define STBTT_memset memset #endif @@ -494,7 +541,7 @@ typedef struct float x1,y1,s1,t1; // bottom-right } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display float *xpos, float *ypos, // pointers to current position in screen pixel space stbtt_aligned_quad *q, // output: quad to draw @@ -547,7 +594,7 @@ STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); #define STBTT_POINT_SIZE(x) (-(x)) -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); // Creates character bitmaps from the font_index'th font found in fontdata (use // font_index=0 if you don't know what that is). It creates num_chars_in_range @@ -572,7 +619,7 @@ typedef struct unsigned char h_oversample, v_oversample; // don't set these, they're used internally } stbtt_pack_range; -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); // Creates character bitmaps from multiple ranges of characters stored in // ranges. This will usually create a better-packed bitmap than multiple // calls to stbtt_PackFontRange. Note that you can call this multiple @@ -594,7 +641,7 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h // To use with PackFontRangesGather etc., you must set it before calls // call to PackFontRangesGatherRects. -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above int char_index, // character to display float *xpos, float *ypos, // pointers to current position in screen pixel space stbtt_aligned_quad *q, // output: quad to draw @@ -657,7 +704,7 @@ struct stbtt_fontinfo int numGlyphs; // number of glyphs, needed for range checking - int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf + int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf int index_map; // a cmap mapping for our chosen character encoding int indexToLocFormat; // format needed to map from glyph index to glyph @@ -714,6 +761,12 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in // these are expressed in unscaled coordinates, so you must multiply by // the scale factor for a given size +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); +// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 +// table (specific to MS/Windows TTF files). +// +// Returns 1 on success (table present), 0 on failure. + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); // the bounding box around all possible characters @@ -808,6 +861,10 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel // shift for the character +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint); +// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering +// is performed (see stbtt_PackSetOversampling) + STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); // get the bbox of the bitmap centered around the glyph origin; so the // bitmap width is ix1-ix0, height is iy1-iy0, and location to place @@ -825,6 +882,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph); STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); @@ -847,6 +905,64 @@ STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap int invert, // if non-zero, vertically flip shape void *userdata); // context for to STBTT_MALLOC +////////////////////////////////////////////////////////////////////////////// +// +// Signed Distance Function (or Field) rendering + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata); +// frees the SDF bitmap allocated below + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); +// These functions compute a discretized SDF field for a single character, suitable for storing +// in a single-channel texture, sampling with bilinear filtering, and testing against +// larger than some threshhold to produce scalable fonts. +// info -- the font +// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap +// glyph/codepoint -- the character to generate the SDF for +// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), +// which allows effects like bit outlines +// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) +// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) +// if positive, > onedge_value is inside; if negative, < onedge_value is inside +// width,height -- output height & width of the SDF bitmap (including padding) +// xoff,yoff -- output origin of the character +// return value -- a 2D array of bytes 0..255, width*height in size +// +// pixel_dist_scale & onedge_value are a scale & bias that allows you to make +// optimal use of the limited 0..255 for your application, trading off precision +// and special effects. SDF values outside the range 0..255 are clamped to 0..255. +// +// Example: +// scale = stbtt_ScaleForPixelHeight(22) +// padding = 5 +// onedge_value = 180 +// pixel_dist_scale = 180/5.0 = 36.0 +// +// This will create an SDF bitmap in which the character is about 22 pixels +// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled +// shape, sample the SDF at each pixel and fill the pixel if the SDF value +// is greater than or equal to 180/255. (You'll actually want to antialias, +// which is beyond the scope of this example.) Additionally, you can compute +// offset outlines (e.g. to stroke the character border inside & outside, +// or only outside). For example, to fill outside the character up to 3 SDF +// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above +// choice of variables maps a range from 5 pixels outside the shape to +// 2 pixels inside the shape to 0..255; this is intended primarily for apply +// outside effects only (the interior range is needed to allow proper +// antialiasing of the font at *smaller* sizes) +// +// The function computes the SDF analytically at each SDF pixel, not by e.g. +// building a higher-res bitmap and approximating it. In theory the quality +// should be as high as possible for an SDF of this size & representation, but +// unclear if this is true in practice (perhaps building a higher-res bitmap +// and computing from that can allow drop-out prevention). +// +// The algorithm has not been optimized at all, so expect it to be slow +// if computing lots of characters or very large sizes. + + + ////////////////////////////////////////////////////////////////////////////// // // Finding the right font... @@ -1231,6 +1347,7 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required if (!cmap || !info->head || !info->hhea || !info->hmtx) return 0; @@ -2084,7 +2201,7 @@ static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, st // push immediate if (b0 == 255) { - f = (float)stbtt__buf_get32(&b) / 0x10000; + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; } else { stbtt__buf_skip(&b, -1); f = (float)(stbtt_int16)stbtt__cff_int(&b); @@ -2122,12 +2239,10 @@ static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, in { stbtt__csctx c = STBTT__CSCTX_INIT(1); int r = stbtt__run_charstring(info, glyph_index, &c); - if (x0) { - *x0 = r ? c.min_x : 0; - *y0 = r ? c.min_y : 0; - *x1 = r ? c.max_x : 0; - *y1 = r ? c.max_y : 0; - } + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; return r ? c.num_vertices : 0; } @@ -2151,7 +2266,7 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde } } -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { stbtt_uint8 *data = info->data + info->kern; stbtt_uint32 needle, straw; @@ -2181,9 +2296,260 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, return 0; } +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +{ + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch(coverageFormat) { + case 1: { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + + // Binary search. + stbtt_int32 l=0, r=glyphCount-1, m; + int straw, needle=glyph; + while (l <= r) { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + return m; + } + } + } break; + + case 2: { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; + + // Binary search. + stbtt_int32 l=0, r=rangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) +{ + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch(classDefFormat) + { + case 1: { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + + classDefTable = classDef1ValueArray + 2 * glyphCount; + } break; + + case 2: { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; + + // Binary search. + stbtt_int32 l=0, r=classRangeCount-1, m; + int strawStart, strawEnd, needle=glyph; + while (l <= r) { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } + + classDefTable = classRangeRecords + 6 * classRangeCount; + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + } break; + } + + return -1; +} + +// Define to STBTT_assert(x) if you want to break on unimplemented formats. +#define STBTT_GPOS_TODO_assert(x) + +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +{ + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i; + + if (!info->gpos) return 0; + + data = info->data + info->gpos; + + if (ttUSHORT(data+0) != 1) return 0; // Major version 1 + if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 + + lookupListOffset = ttUSHORT(data+8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); + + for (i=0; i> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } break; + + case 2: { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + STBTT_assert(glyph1class < class1Count); + STBTT_assert(glyph2class < class2Count); + + // TODO: Support more formats. + STBTT_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + STBTT_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; + + if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { + stbtt_uint8 *class1Records = table + 16; + stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); + stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } + } break; + + default: { + // There are no other cases. + STBTT_assert(0); + break; + }; + } + } + break; + }; + + default: + // TODO: Implement other stuff. + break; + } + } + + return 0; +} + +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) +{ + int xAdvance = 0; + + if (info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + + if (info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + + return xAdvance; +} + STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { - if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs return 0; return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); } @@ -2200,6 +2566,17 @@ STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, in if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); } +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) +{ + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if (!tab) + return 0; + if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68); + if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70); + if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72); + return 1; +} + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) { *x0 = ttSHORT(info->data + info->head + 36); @@ -2296,7 +2673,7 @@ static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) hh->num_remaining_in_head_chunk = count; } --hh->num_remaining_in_head_chunk; - return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk; + return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; } } @@ -2692,19 +3069,18 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, // from the other y segment, and it might ignored as an empty segment. to avoid // that, we need to explicitly produce segments based on x positions. - // rename variables to clear pairs + // rename variables to clearly-defined pairs float y0 = y_top; float x1 = (float) (x); float x2 = (float) (x+1); float x3 = xb; float y3 = y_bottom; - float y1,y2; // x = e->x + e->dx * (y-y_top) // (y-y_top) = (x - e->x) / e->dx // y = (x - e->x) / e->dx + y_top - y1 = (x - x0) / dx + y_top; - y2 = (x+1 - x0) / dx + y_top; + float y1 = (x - x0) / dx + y_top; + float y2 = (x+1 - x0) / dx + y_top; if (x0 < x1 && x3 > x2) { // three segments descending down-right stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); @@ -3131,8 +3507,9 @@ error: STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count, *winding_lengths; + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count = 0; + int *winding_lengths = NULL; stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); if (windings) { stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); @@ -3220,6 +3597,11 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); } +STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) +{ + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint)); +} + STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) { stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); @@ -3287,11 +3669,11 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo return bottom_y; } -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) +STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) { float d3d_bias = opengl_fillrule ? 0 : -0.5f; float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_bakedchar *b = chardata + char_index; + const stbtt_bakedchar *b = chardata + char_index; int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); @@ -3599,6 +3981,29 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb return k; } +STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph) +{ + stbtt_MakeGlyphBitmapSubpixel(info, + output, + out_w - (prefilter_x - 1), + out_h - (prefilter_y - 1), + out_stride, + scale_x, + scale_y, + shift_x, + shift_y, + glyph); + + if (prefilter_x > 1) + stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); + + if (prefilter_y > 1) + stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); + + *sub_x = stbtt__oversample_shift(prefilter_x); + *sub_y = stbtt__oversample_shift(prefilter_y); +} + // rects array must be big enough to accommodate all characters in the given ranges STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { @@ -3687,7 +4092,7 @@ STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); } -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) +STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { stbtt_fontinfo info; int i,j,n, return_value = 1; @@ -3723,7 +4128,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd return return_value; } -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, +STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) { stbtt_pack_range range; @@ -3735,10 +4140,10 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontda return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); } -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) +STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) { float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_packedchar *b = chardata + char_index; + const stbtt_packedchar *b = chardata + char_index; if (align_to_integer) { float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); @@ -3762,6 +4167,387 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, i *xpos += b->xadvance; } +////////////////////////////////////////////////////////////////////////////// +// +// sdf computation +// + +#define STBTT_min(a,b) ((a) < (b) ? (a) : (b)) +#define STBTT_max(a,b) ((a) < (b) ? (b) : (a)) + +static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) +{ + float q0perp = q0[1]*ray[0] - q0[0]*ray[1]; + float q1perp = q1[1]*ray[0] - q1[0]*ray[1]; + float q2perp = q2[1]*ray[0] - q2[0]*ray[1]; + float roperp = orig[1]*ray[0] - orig[0]*ray[1]; + + float a = q0perp - 2*q1perp + q2perp; + float b = q1perp - q0perp; + float c = q0perp - roperp; + + float s0 = 0., s1 = 0.; + int num_s = 0; + + if (a != 0.0) { + float discr = b*b - a*c; + if (discr > 0.0) { + float rcpna = -1 / a; + float d = (float) STBTT_sqrt(discr); + s0 = (b+d) * rcpna; + s1 = (b-d) * rcpna; + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { + if (num_s == 0) s0 = s1; + ++num_s; + } + } + } else { + // 2*b*s + c = 0 + // s = -c / (2*b) + s0 = c / (-2 * b); + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + } + + if (num_s == 0) + return 0; + else { + float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]); + float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; + + float q0d = q0[0]*rayn_x + q0[1]*rayn_y; + float q1d = q1[0]*rayn_x + q1[1]*rayn_y; + float q2d = q2[0]*rayn_x + q2[1]*rayn_y; + float rod = orig[0]*rayn_x + orig[1]*rayn_y; + + float q10d = q1d - q0d; + float q20d = q2d - q0d; + float q0rd = q0d - rod; + + hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d; + hits[0][1] = a*s0+b; + + if (num_s > 1) { + hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d; + hits[1][1] = a*s1+b; + return 2; + } else { + return 1; + } + } +} + +static int equal(float *a, float *b) +{ + return (a[0] == b[0] && a[1] == b[1]); +} + +static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) +{ + int i; + float orig[2], ray[2] = { 1, 0 }; + float y_frac; + int winding = 0; + + orig[0] = x; + orig[1] = y; + + // make sure y never passes through a vertex of the shape + y_frac = (float) STBTT_fmod(y, 1.0f); + if (y_frac < 0.01f) + y += 0.01f; + else if (y_frac > 0.99f) + y -= 0.01f; + orig[1] = y; + + // test a ray from (-infinity,y) to (x,y) + for (i=0; i < nverts; ++i) { + if (verts[i].type == STBTT_vline) { + int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y; + int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + if (verts[i].type == STBTT_vcurve) { + int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ; + int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy; + int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ; + int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2)); + int by = STBTT_max(y0,STBTT_max(y1,y2)); + if (y > ay && y < by && x > ax) { + float q0[2],q1[2],q2[2]; + float hits[2][2]; + q0[0] = (float)x0; + q0[1] = (float)y0; + q1[0] = (float)x1; + q1[1] = (float)y1; + q2[0] = (float)x2; + q2[1] = (float)y2; + if (equal(q0,q1) || equal(q1,q2)) { + x0 = (int)verts[i-1].x; + y0 = (int)verts[i-1].y; + x1 = (int)verts[i ].x; + y1 = (int)verts[i ].y; + if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { + float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } else { + int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); + if (num_hits >= 1) + if (hits[0][0] < 0) + winding += (hits[0][1] < 0 ? -1 : 1); + if (num_hits >= 2) + if (hits[1][0] < 0) + winding += (hits[1][1] < 0 ? -1 : 1); + } + } + } + } + return winding; +} + +static float stbtt__cuberoot( float x ) +{ + if (x<0) + return -(float) STBTT_pow(-x,1.0f/3.0f); + else + return (float) STBTT_pow( x,1.0f/3.0f); +} + +// x^3 + c*x^2 + b*x + a = 0 +static int stbtt__solve_cubic(float a, float b, float c, float* r) +{ + float s = -a / 3; + float p = b - a*a / 3; + float q = a * (2*a*a - 9*b) / 27 + c; + float p3 = p*p*p; + float d = q*q + 4*p3 / 27; + if (d >= 0) { + float z = (float) STBTT_sqrt(d); + float u = (-q + z) / 2; + float v = (-q - z) / 2; + u = stbtt__cuberoot(u); + v = stbtt__cuberoot(v); + r[0] = s + u + v; + return 1; + } else { + float u = (float) STBTT_sqrt(-p/3); + float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float) STBTT_cos(v); + float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f; + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); + + //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? + //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); + //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); + return 3; + } +} + +STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + float scale_x = scale, scale_y = scale; + int ix0,iy0,ix1,iy1; + int w,h; + unsigned char *data; + + // if one scale is 0, use same scale for both + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) { + if (scale_x == 0) return NULL; // if both scales are 0, return NULL + scale_y = scale_x; + } + + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); + + // if empty, return NULL + if (ix0 == ix1 || iy0 == iy1) + return NULL; + + ix0 -= padding; + iy0 -= padding; + ix1 += padding; + iy1 += padding; + + w = (ix1 - ix0); + h = (iy1 - iy0); + + if (width ) *width = w; + if (height) *height = h; + if (xoff ) *xoff = ix0; + if (yoff ) *yoff = iy0; + + // invert for y-downwards bitmaps + scale_y = -scale_y; + + { + int x,y,i,j; + float *precompute; + stbtt_vertex *verts; + int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); + data = (unsigned char *) STBTT_malloc(w * h, info->userdata); + precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata); + + for (i=0,j=num_verts-1; i < num_verts; j=i++) { + if (verts[i].type == STBTT_vline) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y; + float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)); + precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y; + float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y; + float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float len2 = bx*bx + by*by; + if (len2 != 0.0f) + precompute[i] = 1.0f / (bx*bx + by*by); + else + precompute[i] = 0.0f; + } else + precompute[i] = 0.0f; + } + + for (y=iy0; y < iy1; ++y) { + for (x=ix0; x < ix1; ++x) { + float val; + float min_dist = 999999.0f; + float sx = (float) x + 0.5f; + float sy = (float) y + 0.5f; + float x_gspace = (sx / scale_x); + float y_gspace = (sy / scale_y); + + int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path + + for (i=0; i < num_verts; ++i) { + float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + + // check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve + float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); + if (dist2 < min_dist*min_dist) + min_dist = (float) STBTT_sqrt(dist2); + + if (verts[i].type == STBTT_vline) { + float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y; + + // coarse culling against bbox + //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && + // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) + float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; + STBTT_assert(i != 0); + if (dist < min_dist) { + // check position along line + // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) + // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) + float dx = x1-x0, dy = y1-y0; + float px = x0-sx, py = y0-sy; + // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy + // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve + float t = -(px*dx + py*dy) / (dx*dx + dy*dy); + if (t >= 0.0f && t <= 1.0f) + min_dist = dist; + } + } else if (verts[i].type == STBTT_vcurve) { + float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y; + float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y; + float box_x0 = STBTT_min(STBTT_min(x0,x1),x2); + float box_y0 = STBTT_min(STBTT_min(y0,y1),y2); + float box_x1 = STBTT_max(STBTT_max(x0,x1),x2); + float box_y1 = STBTT_max(STBTT_max(y0,y1),y2); + // coarse culling against bbox to avoid computing cubic unnecessarily + if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) { + int num=0; + float ax = x1-x0, ay = y1-y0; + float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; + float mx = x0 - sx, my = y0 - sy; + float res[3],px,py,t,it; + float a_inv = precompute[i]; + if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula + float a = 3*(ax*bx + ay*by); + float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by); + float c = mx*ax+my*ay; + if (a == 0.0) { // if a is 0, it's linear + if (b != 0.0) { + res[num++] = -c/b; + } + } else { + float discriminant = b*b - 4*a*c; + if (discriminant < 0) + num = 0; + else { + float root = (float) STBTT_sqrt(discriminant); + res[0] = (-b - root)/(2*a); + res[1] = (-b + root)/(2*a); + num = 2; // don't bother distinguishing 1-solution case, as code below will still work + } + } + } else { + float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv; + float d = (mx*ax+my*ay) * a_inv; + num = stbtt__solve_cubic(b, c, d, res); + } + if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { + t = res[0], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { + t = res[1], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { + t = res[2], it = 1.0f - t; + px = it*it*x0 + 2*t*it*x1 + t*t*x2; + py = it*it*y0 + 2*t*it*y1 + t*t*y2; + dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); + if (dist2 < min_dist * min_dist) + min_dist = (float) STBTT_sqrt(dist2); + } + } + } + } + if (winding == 0) + min_dist = -min_dist; // if outside the shape, value is negative + val = onedge_value + pixel_dist_scale * min_dist; + if (val < 0) + val = 0; + else if (val > 255) + val = 255; + data[(y-iy0)*w+(x-ix0)] = (unsigned char) val; + } + } + STBTT_free(precompute, info->userdata); + STBTT_free(verts, info->userdata); + } + return data; +} + +STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +{ + return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); +} + +STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) +{ + STBTT_free(bitmap, userdata); +} ////////////////////////////////////////////////////////////////////////////// // @@ -3969,6 +4755,13 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const // FULL VERSION HISTORY // +// 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod +// 1.18 (2018-01-29) add missing function +// 1.17 (2017-07-23) make more arguments const; doc fix +// 1.16 (2017-07-12) SDF support +// 1.15 (2017-03-03) make more arguments const +// 1.14 (2017-01-16) num-fonts-in-TTC function +// 1.13 (2017-01-02) support OpenType fonts, certain Apple fonts // 1.12 (2016-10-25) suppress warnings about casting away const with -Wcast-qual // 1.11 (2016-04-02) fix unused-variable warning // 1.10 (2016-04-02) allow user-defined fabs() replacement @@ -4016,3 +4809,45 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const // 0.2 (2009-03-11) Fix unsigned/signed char warnings // 0.1 (2009-03-09) First public release // + +/* +------------------------------------------------------------------------------ +This software is available under 2 licenses -- choose whichever you prefer. +------------------------------------------------------------------------------ +ALTERNATIVE A - MIT License +Copyright (c) 2017 Sean Barrett +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +------------------------------------------------------------------------------ +ALTERNATIVE B - Public Domain (www.unlicense.org) +This is free and unencumbered software released into the public domain. +Anyone is free to copy, modify, publish, use, compile, sell, or distribute this +software, either in source code form or as a compiled binary, for any purpose, +commercial or non-commercial, and by any means. +In jurisdictions that recognize copyright laws, the author or authors of this +software dedicate any and all copyright interest in the software to the public +domain. We make this dedication for the benefit of the public at large and to +the detriment of our heirs and successors. We intend this dedication to be an +overt act of relinquishment in perpetuity of all present and future rights to +this software under copyright law. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +------------------------------------------------------------------------------ +*/ From 1cbfe0700c790285bc84a6150083666b8ecd9858 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 14:34:49 +0100 Subject: [PATCH 08/87] Plot: plot a flat line if scale_min==scale_max (#1621) --- imgui.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index b72cc38d..de69156d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9287,11 +9287,12 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge } const float t_step = 1.0f / (float)res_w; + const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); float v0 = values_getter(data, (0 + values_offset) % values_count); float t0 = 0.0f; - ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) / (scale_max - scale_min)) ); // Point in the normalized space of our target rectangle - float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min / (scale_max - scale_min)) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands + ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) ); // Point in the normalized space of our target rectangle + float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); @@ -9302,7 +9303,7 @@ void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_ge const int v1_idx = (int)(t0 * item_count + 0.5f); IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); - const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) / (scale_max - scale_min)) ); + const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale) ); // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); From 20c14f95891b145ebffa8d349ca033d67eac1c24 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 15:43:28 +0100 Subject: [PATCH 09/87] Fixed GCC zealous warnings (#1623) --- imgui.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index de69156d..29bafca6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -681,6 +681,7 @@ #pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers #pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false #endif // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall @@ -4876,6 +4877,7 @@ static ImGuiWindow* GetFrontMostModalRootWindow() static void ClosePopupToLevel(int remaining) { + IM_ASSERT(remaining >= 0); ImGuiContext& g = *GImGui; ImGuiWindow* focus_window = (remaining > 0) ? g.OpenPopupStack[remaining-1].Window : g.OpenPopupStack[0].ParentWindow; if (g.NavLayer == 0) @@ -11215,7 +11217,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' want_close = true; if (want_close && IsPopupOpen(id)) - ClosePopupToLevel(GImGui->CurrentPopupStack.Size); + ClosePopupToLevel(g.CurrentPopupStack.Size); if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) { From 0cefd40888c3d6c5e84754d2dadb6135d91b6f1f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 17:20:18 +0100 Subject: [PATCH 10/87] Examples: Added Changelog to make updates easier. --- .../directx10_example/imgui_impl_dx10.cpp | 13 +++++++++++++ .../directx11_example/imgui_impl_dx11.cpp | 13 +++++++++++++ .../opengl2_example/imgui_impl_glfw_gl2.cpp | 14 ++++++++++++++ .../opengl3_example/imgui_impl_glfw_gl3.cpp | 16 ++++++++++++++++ .../imgui_impl_sdl_gl2.cpp | 19 ++++++++++--------- .../imgui_impl_sdl_gl3.cpp | 19 ++++++++++--------- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 13 +++++++++++++ 7 files changed, 89 insertions(+), 18 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index a0bd98bf..0d3f9233 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -8,6 +8,19 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. +// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. +// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. +// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. +// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. +// 2016-05-07: DirectX10: Disabling depth-write. + #include "imgui.h" #include "imgui_impl_dx10.h" diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index fa77735c..29a4af4f 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -8,6 +8,19 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. +// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. +// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read. +// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. +// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set. +// 2016-05-07: DirectX11: Disabling depth-write. + #include "imgui.h" #include "imgui_impl_dx11.h" diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 2df70f2b..ce97f272 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -17,6 +17,20 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2018-01-09: Misc: Renamed imgui_impl_glfw.* to imgui_impl_glfw_gl2.*. +// 2017-09-01: OpenGL: Save and restore current polygon mode. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. +// 2016-09-10: OpenGL: Uploading font texture as RGBA32 to increase compatibility with users shaders (not ideal). +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. + #include "imgui.h" #include "imgui_impl_glfw_gl2.h" diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index cd652c0b..2e0863f3 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -11,6 +11,22 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-01-25: Inputs: Added gamepad support if ImGuiNavFlags_EnableGamepad is set. +// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. (Also changed GL context from 3.3 to 3.2 in example's main.cpp) +// 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2017-05-01: OpenGL: Fixed save and restore of current blend function state. +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. +// 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. +// 2016-04-30: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. + #include "imgui.h" #include "imgui_impl_glfw_gl3.h" diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 11aa6a5a..17c29edc 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -18,16 +18,17 @@ // https://github.com/ocornut/imgui // CHANGELOG -// 2018-02-06: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. -// 2018-02-06: SDL: Added mapping for ImGuiKey_Space. -// 2018-02-05: SDL: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). -// 2018-02-05: SDL: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. -// 2018-01-20: SDL: Added Horizontal Mouse Wheel support. -// 2018-01-19: SDL: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. -// 2018-01-18: SDL: Added mapping for ImGuiKey_Insert. +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. // 2017-09-01: OpenGL: Save and restore current polygon mode. -// 2017-08-25: SDL: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). -// 2016-10-15: Added a void* user_data parameter to Clipboard function handlers. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 7e0d2688..a5098831 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -11,19 +11,20 @@ // https://github.com/ocornut/imgui // CHANGELOG -// 2018-02-06: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. -// 2018-02-06: SDL: Added mapping for ImGuiKey_Space. -// 2018-02-05: SDL: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). -// 2018-02-05: SDL: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. -// 2018-01-20: SDL: Added Horizontal Mouse Wheel support. -// 2018-01-19: SDL: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. -// 2018-01-18: SDL: Added mapping for ImGuiKey_Insert. +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). +// 2018-02-05: Inputs: Keyboard mapping is using scancodes everywhere instead of a confusing mixture of keycodes and scancodes. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-19: Inputs: When available (SDL 2.0.4+) using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging. Otherwise (SDL 2.0.3 and before) testing for SDL_WINDOW_INPUT_FOCUS instead of SDL_WINDOW_MOUSE_FOCUS. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. // 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. // 2017-09-01: OpenGL: Save and restore current bound sampler. Save and restore current polygon mode. -// 2017-08-25: SDL: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). // 2017-05-01: OpenGL: Fixed save and restore of current blend func state. // 2017-05-01: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. -// 2016-10-15: Added a void* user_data parameter to Clipboard function handlers. +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index d86ad575..70fa6cc4 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -8,6 +8,19 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. +// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. +// 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. +// 2017-08-25: Inputs: MousePos set to -FLT_MAX,-FLT_MAX when mouse is unavailable/missing (instead of -1,-1). +// 2017-05-15: Vulkan: Fix scissor offset being negative. Fix new Vulkan validation warnings. Set required depth member for buffer image copy. +// 2016-11-13: Vulkan: Fix validation layer warnings and errors and redeclare gl_PerVertex. +// 2016-10-18: Vulkan: Add location decorators & change to use structs as in/out in glsl, update embedded spv (produced with glslangValidator -x). Null the released resources. +// 2016-10-15: Misc: Added a void* user_data parameter to Clipboard function handlers. +// 2016-08-27: Vulkan: Fix Vulkan example for use when a depth buffer is active. + #include "imgui.h" #include "imgui_impl_glfw_vulkan.h" From 63332d152a7ad238d80f990df4cb9e77cf790c2a Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 19:18:16 +0100 Subject: [PATCH 11/87] Obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display..(#1599) Examples: Updated examples. --- examples/allegro5_example/imgui_impl_a5.cpp | 11 +++++++++-- examples/allegro5_example/imgui_impl_a5.h | 1 + examples/allegro5_example/main.cpp | 1 + examples/directx10_example/imgui_impl_dx10.cpp | 9 ++++----- examples/directx10_example/imgui_impl_dx10.h | 1 + examples/directx10_example/main.cpp | 1 + examples/directx11_example/imgui_impl_dx11.cpp | 9 ++++----- examples/directx11_example/imgui_impl_dx11.h | 1 + examples/directx11_example/main.cpp | 1 + examples/directx9_example/imgui_impl_dx9.cpp | 14 +++++++++----- examples/directx9_example/imgui_impl_dx9.h | 1 + examples/directx9_example/main.cpp | 1 + .../marmalade_example/imgui_impl_marmalade.cpp | 12 +++++++++--- examples/marmalade_example/imgui_impl_marmalade.h | 1 + examples/marmalade_example/main.cpp | 1 + examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 8 ++++---- examples/opengl2_example/imgui_impl_glfw_gl2.h | 1 + examples/opengl2_example/main.cpp | 1 + examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 8 ++++---- examples/opengl3_example/imgui_impl_glfw_gl3.h | 1 + examples/opengl3_example/main.cpp | 1 + .../sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 8 ++++---- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h | 1 + examples/sdl_opengl2_example/main.cpp | 1 + .../sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 4 ++-- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h | 1 + examples/sdl_opengl3_example/main.cpp | 1 + .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 5 +++-- imgui.cpp | 14 ++++++++++---- imgui.h | 15 ++++++++------- 30 files changed, 88 insertions(+), 47 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index d837edfa..479702b9 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -10,6 +10,12 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui, Original code by @birthggd +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplA5_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. + #include // uint64_t #include // memcpy #include "imgui.h" @@ -35,7 +41,9 @@ struct ImDrawVertAllegro ALLEGRO_COLOR col; }; -void ImGui_ImplA5_RenderDrawLists(ImDrawData* draw_data) +// Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplA5_RenderDrawData(ImDrawData* draw_data) { int op, src, dst; al_get_blender(&op, &src, &dst); @@ -190,7 +198,6 @@ bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display) io.KeyMap[ImGuiKey_Y] = ALLEGRO_KEY_Y; io.KeyMap[ImGuiKey_Z] = ALLEGRO_KEY_Z; - io.RenderDrawListsFn = ImGui_ImplA5_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. #ifdef _WIN32 io.ImeWindowHandle = al_get_win_window_handle(g_Display); #endif diff --git a/examples/allegro5_example/imgui_impl_a5.h b/examples/allegro5_example/imgui_impl_a5.h index 7f164435..ccc3ac45 100644 --- a/examples/allegro5_example/imgui_impl_a5.h +++ b/examples/allegro5_example/imgui_impl_a5.h @@ -18,6 +18,7 @@ union ALLEGRO_EVENT; IMGUI_API bool ImGui_ImplA5_Init(ALLEGRO_DISPLAY* display); IMGUI_API void ImGui_ImplA5_Shutdown(); IMGUI_API void ImGui_ImplA5_NewFrame(); +IMGUI_API void ImGui_ImplA5_RenderDrawData(ImDrawData* draw_data); IMGUI_API bool ImGui_ImplA5_ProcessEvent(ALLEGRO_EVENT* event); // Use if you want to reset your rendering device without losing ImGui state. diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 92368950..1478573c 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -114,6 +114,7 @@ int main(int, char**) // Rendering al_clear_to_color(al_map_rgba_f(clear_color.x, clear_color.y, clear_color.z, clear_color.w)); ImGui::Render(); + ImGui_ImplA5_RenderDrawData(ImGui::GetDrawData()); al_flip_display(); } diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 0d3f9233..10da969e 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. @@ -57,10 +58,9 @@ 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) -void ImGui_ImplDX10_RenderDrawLists(ImDrawData* draw_data) +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) { ID3D10Device* ctx = g_pd3dDevice; @@ -570,7 +570,6 @@ bool ImGui_ImplDX10_Init(void* hwnd, ID3D10Device* device) io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; - io.RenderDrawListsFn = ImGui_ImplDX10_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.ImeWindowHandle = g_hWnd; return true; diff --git a/examples/directx10_example/imgui_impl_dx10.h b/examples/directx10_example/imgui_impl_dx10.h index 604b7b63..a4741847 100644 --- a/examples/directx10_example/imgui_impl_dx10.h +++ b/examples/directx10_example/imgui_impl_dx10.h @@ -13,6 +13,7 @@ struct ID3D10Device; IMGUI_API bool ImGui_ImplDX10_Init(void* hwnd, ID3D10Device* device); IMGUI_API void ImGui_ImplDX10_Shutdown(); IMGUI_API void ImGui_ImplDX10_NewFrame(); +IMGUI_API void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplDX10_InvalidateDeviceObjects(); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 0198b34f..f20f6881 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -206,6 +206,7 @@ int main(int, char**) g_pd3dDevice->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); g_pd3dDevice->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); + ImGui_ImplDX10_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 29a4af4f..a0e9d7f3 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. @@ -57,10 +58,9 @@ 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) -void ImGui_ImplDX11_RenderDrawLists(ImDrawData* draw_data) +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) { ID3D11DeviceContext* ctx = g_pd3dDeviceContext; @@ -572,7 +572,6 @@ bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContex io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; - io.RenderDrawListsFn = ImGui_ImplDX11_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.ImeWindowHandle = g_hWnd; return true; diff --git a/examples/directx11_example/imgui_impl_dx11.h b/examples/directx11_example/imgui_impl_dx11.h index 90bfe4fe..9364b0ca 100644 --- a/examples/directx11_example/imgui_impl_dx11.h +++ b/examples/directx11_example/imgui_impl_dx11.h @@ -14,6 +14,7 @@ struct ID3D11DeviceContext; IMGUI_API bool ImGui_ImplDX11_Init(void* hwnd, ID3D11Device* device, ID3D11DeviceContext* device_context); IMGUI_API void ImGui_ImplDX11_Shutdown(); IMGUI_API void ImGui_ImplDX11_NewFrame(); +IMGUI_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplDX11_InvalidateDeviceObjects(); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index b1127fc8..f6dc6f74 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -209,6 +209,7 @@ int main(int, char**) g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, (float*)&clear_color); ImGui::Render(); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index c89b2478..e960b7c5 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -8,6 +8,12 @@ // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. + #include "imgui.h" #include "imgui_impl_dx9.h" @@ -34,10 +40,9 @@ struct CUSTOMVERTEX }; #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1) -// 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) -void ImGui_ImplDX9_RenderDrawLists(ImDrawData* draw_data) +// Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized ImGuiIO& io = ImGui::GetIO(); @@ -276,7 +281,6 @@ bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device) io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; - io.RenderDrawListsFn = ImGui_ImplDX9_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.ImeWindowHandle = g_hWnd; return true; diff --git a/examples/directx9_example/imgui_impl_dx9.h b/examples/directx9_example/imgui_impl_dx9.h index 41fa743d..e0ea2dea 100644 --- a/examples/directx9_example/imgui_impl_dx9.h +++ b/examples/directx9_example/imgui_impl_dx9.h @@ -13,6 +13,7 @@ struct IDirect3DDevice9; IMGUI_API bool ImGui_ImplDX9_Init(void* hwnd, IDirect3DDevice9* device); IMGUI_API void ImGui_ImplDX9_Shutdown(); IMGUI_API void ImGui_ImplDX9_NewFrame(); +IMGUI_API void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplDX9_InvalidateDeviceObjects(); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index dd4227ec..16482b3a 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -169,6 +169,7 @@ int main(int, char**) if (g_pd3dDevice->BeginScene() >= 0) { ImGui::Render(); + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); g_pd3dDevice->EndScene(); } HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); diff --git a/examples/marmalade_example/imgui_impl_marmalade.cpp b/examples/marmalade_example/imgui_impl_marmalade.cpp index 8342a701..947bcbd6 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.cpp +++ b/examples/marmalade_example/imgui_impl_marmalade.cpp @@ -11,6 +11,12 @@ // Copyright (C) 2015 by Giovanni Zito // This file is part of ImGui +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_Marmalade_RenderDrawData() in the .h file so you can call it yourself. +// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. +// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. + #include "imgui.h" #include "imgui_impl_marmalade.h" @@ -30,8 +36,9 @@ static bool g_osdKeyboardEnabled = false; // use this setting to scale the interface - e.g. on device you could use 2 or 3 scale factor static ImVec2 g_RenderScale = ImVec2(1.0f,1.0f); -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -void ImGui_Marmalade_RenderDrawLists(ImDrawData* draw_data) +// Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data) { // Handle cases of screen coordinates != from framebuffer coordinates (e.g. retina displays) ImGuiIO& io = ImGui::GetIO(); @@ -232,7 +239,6 @@ bool ImGui_Marmalade_Init(bool install_callbacks) io.KeyMap[ImGuiKey_Y] = s3eKeyY; io.KeyMap[ImGuiKey_Z] = s3eKeyZ; - io.RenderDrawListsFn = ImGui_Marmalade_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_Marmalade_SetClipboardText; io.GetClipboardTextFn = ImGui_Marmalade_GetClipboardText; diff --git a/examples/marmalade_example/imgui_impl_marmalade.h b/examples/marmalade_example/imgui_impl_marmalade.h index 79b5e50a..c41a5e8f 100644 --- a/examples/marmalade_example/imgui_impl_marmalade.h +++ b/examples/marmalade_example/imgui_impl_marmalade.h @@ -14,6 +14,7 @@ IMGUI_API bool ImGui_Marmalade_Init(bool install_callbacks); IMGUI_API void ImGui_Marmalade_Shutdown(); IMGUI_API void ImGui_Marmalade_NewFrame(); +IMGUI_API void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_Marmalade_InvalidateDeviceObjects(); diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index 0b862399..f2ddae40 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -100,6 +100,7 @@ int main(int, char**) IwGxSetColClear(clear_color.x * 255, clear_color.y * 255, clear_color.z * 255, clear_color.w * 255); IwGxClear(); ImGui::Render(); + ImGui_Marmalade_RenderDrawData(ImGui::GetDrawData()); IwGxSwapBuffers(); s3eDeviceYield(0); diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index ce97f272..2630f164 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. @@ -49,10 +50,10 @@ static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -void ImGui_ImplGlfwGL2_RenderDrawLists(ImDrawData* draw_data) +// OpenGL2 Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. -// 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) +void ImGui_ImplGlfwGL2_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -241,7 +242,6 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - io.RenderDrawListsFn = ImGui_ImplGlfwGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplGlfwGL2_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplGlfwGL2_GetClipboardText; io.ClipboardUserData = g_Window; diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.h b/examples/opengl2_example/imgui_impl_glfw_gl2.h index 91d1e087..268b0e49 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.h +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.h @@ -18,6 +18,7 @@ struct GLFWwindow; IMGUI_API bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks); IMGUI_API void ImGui_ImplGlfwGL2_Shutdown(); IMGUI_API void ImGui_ImplGlfwGL2_NewFrame(); +IMGUI_API void ImGui_ImplGlfwGL2_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index d0b500c8..caae8c2b 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -110,6 +110,7 @@ int main(int, char**) glClear(GL_COLOR_BUFFER_BIT); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound, but prefer using the GL3+ code. ImGui::Render(); + ImGui_ImplGlfwGL2_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 2e0863f3..9c82abc5 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-01-25: Inputs: Added gamepad support if ImGuiNavFlags_EnableGamepad is set. @@ -50,10 +51,10 @@ static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// OpenGL3 Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. -// 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) -void ImGui_ImplGlfwGL3_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -356,7 +357,6 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - io.RenderDrawListsFn = ImGui_ImplGlfwGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplGlfwGL3_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplGlfwGL3_GetClipboardText; io.ClipboardUserData = g_Window; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 6b4101f2..0e039d8d 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -16,6 +16,7 @@ struct GLFWwindow; IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks); IMGUI_API void ImGui_ImplGlfwGL3_Shutdown(); IMGUI_API void ImGui_ImplGlfwGL3_NewFrame(); +IMGUI_API void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index a13cbe5c..a5f59e8a 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -115,6 +115,7 @@ int main(int, char**) glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); + ImGui_ImplGlfwGL3_RenderDrawData(ImGui::GetDrawData()); glfwSwapBuffers(window); } diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 17c29edc..26cf8c65 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). @@ -43,10 +44,10 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; -// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) +// OpenGL2 Render function. +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. -// 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) -void ImGui_ImplSdlGL2_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplSdlGL2_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -245,7 +246,6 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; - io.RenderDrawListsFn = ImGui_ImplSdlGL2_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplSdlGL2_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h index 915ae52d..4df1c169 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.h @@ -19,6 +19,7 @@ typedef union SDL_Event SDL_Event; IMGUI_API bool ImGui_ImplSdlGL2_Init(SDL_Window* window); IMGUI_API void ImGui_ImplSdlGL2_Shutdown(); IMGUI_API void ImGui_ImplSdlGL2_NewFrame(SDL_Window* window); +IMGUI_API void ImGui_ImplSdlGL2_RenderDrawData(ImDrawData* draw_data); IMGUI_API bool ImGui_ImplSdlGL2_ProcessEvent(SDL_Event* event); // Use if you want to reset your rendering device without losing ImGui state. diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index f7926d00..8f4ca93d 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -122,6 +122,7 @@ int main(int, char**) glClear(GL_COLOR_BUFFER_BIT); //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context where shaders may be bound ImGui::Render(); + ImGui_ImplSdlGL2_RenderDrawData(ImGui::GetDrawData()); SDL_GL_SwapWindow(window); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index a5098831..b73fdbde 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-02-05: Misc: Using SDL_GetPerformanceCounter() instead of SDL_GetTicks() to be able to handle very high framerate (1000+ FPS). @@ -48,7 +49,7 @@ static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. // 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) -void ImGui_ImplSdlGL3_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) ImGuiIO& io = ImGui::GetIO(); @@ -359,7 +360,6 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.KeyMap[ImGuiKey_Y] = SDL_SCANCODE_Y; io.KeyMap[ImGuiKey_Z] = SDL_SCANCODE_Z; - io.RenderDrawListsFn = ImGui_ImplSdlGL3_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplSdlGL3_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; io.ClipboardUserData = NULL; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index 3f76e294..fa111a17 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -16,6 +16,7 @@ typedef union SDL_Event SDL_Event; IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window); IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window); +IMGUI_API void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data); IMGUI_API bool ImGui_ImplSdlGL3_ProcessEvent(SDL_Event* event); // Use if you want to reset your rendering device without losing ImGui state. diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index af25fdf0..a3fc625c 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -121,6 +121,7 @@ int main(int, char**) glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); glClear(GL_COLOR_BUFFER_BIT); ImGui::Render(); + ImGui_ImplSdlGL3_RenderDrawData(ImGui::GetDrawData()); SDL_GL_SwapWindow(window); } diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 70fa6cc4..8e93e7e9 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplGlfwVulkan_Render() calls ImGui_ImplGlfwVulkan_RenderDrawData() itself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. @@ -165,7 +166,7 @@ static void ImGui_ImplGlfwVulkan_VkResult(VkResult err) } // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) -void ImGui_ImplGlfwVulkan_RenderDrawLists(ImDrawData* draw_data) +void ImGui_ImplGlfwVulkan_RenderDrawData(ImDrawData* draw_data) { VkResult err; ImGuiIO& io = ImGui::GetIO(); @@ -778,7 +779,6 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; - io.RenderDrawListsFn = ImGui_ImplGlfwVulkan_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.SetClipboardTextFn = ImGui_ImplGlfwVulkan_SetClipboardText; io.GetClipboardTextFn = ImGui_ImplGlfwVulkan_GetClipboardText; io.ClipboardUserData = g_Window; @@ -851,6 +851,7 @@ void ImGui_ImplGlfwVulkan_Render(VkCommandBuffer command_buffer) { g_CommandBuffer = command_buffer; ImGui::Render(); + ImGui_ImplGlfwVulkan_RenderDrawData(ImGui::GetDrawData()); g_CommandBuffer = VK_NULL_HANDLE; g_FrameIndex = (g_FrameIndex + 1) % IMGUI_VK_QUEUED_FRAMES; } diff --git a/imgui.cpp b/imgui.cpp index 29bafca6..3eb51958 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -131,7 +131,6 @@ ImGuiIO& io = ImGui::GetIO(); io.DisplaySize.x = 1920.0f; io.DisplaySize.y = 1280.0f; - io.RenderDrawListsFn = MyRenderFunction; // Setup a render function, or set to NULL and call GetDrawData() after Render() to access render data. // TODO: Fill others settings of the io structure later. // Load texture atlas (there is a default font so you don't need to care about choosing a font yet) @@ -162,6 +161,7 @@ // Render & swap video buffers ImGui::Render(); + MyImGuiRenderFunction(ImGui::GetDrawData()); SwapBuffers(); } @@ -250,6 +250,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. - 2018/02/07 (1.60) - reorganized context handling to be more explicit, - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. - removed Shutdown() function, as DestroyContext() serve this purpose. @@ -882,15 +883,18 @@ ImGuiIO::ImGuiIO() OptMacOSXBehaviors = false; #endif OptCursorBlink = true; - + // Settings (User Functions) - RenderDrawListsFn = NULL; GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; ClipboardUserData = NULL; ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; ImeWindowHandle = NULL; +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + RenderDrawListsFn = NULL; +#endif + // Input (NB: we already have memset zero the entire structure) MousePos = ImVec2(-FLT_MAX, -FLT_MAX); MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); @@ -2657,7 +2661,7 @@ ImGuiStyle& ImGui::GetStyle() return GImGui->Style; } -// Same value as passed to your RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() +// Same value as passed to the old io.RenderDrawListsFn function. Valid after Render() and until the next call to NewFrame() ImDrawData* ImGui::GetDrawData() { return GImGui->DrawData.Valid ? &GImGui->DrawData : NULL; @@ -4079,8 +4083,10 @@ void ImGui::Render() g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) g.IO.RenderDrawListsFn(&g.DrawData); +#endif } } diff --git a/imgui.h b/imgui.h index 60d027e0..d421e224 100644 --- a/imgui.h +++ b/imgui.h @@ -147,9 +147,9 @@ namespace ImGui // Main IMGUI_API ImGuiIO& GetIO(); IMGUI_API ImGuiStyle& GetStyle(); - IMGUI_API ImDrawData* GetDrawData(); // same value as passed to your io.RenderDrawListsFn() function. valid after Render() and until the next call to NewFrame() IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until Render()/EndFrame(). - IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data, then call your io.RenderDrawListsFn() function if set. + IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data. (Obsolete: optionally call io.RenderDrawListsFn if set. Nowadays, prefer calling your render function yourself.) + IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render. (Obsolete: this used to be passed to your io.RenderDrawListsFn() function.) IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! // Demo, Debug, Informations @@ -981,11 +981,6 @@ struct ImGuiIO // Settings (User Functions) //------------------------------------------------------------------ - // Rendering function, will be called in Render(). - // Alternatively you can keep this to NULL and call GetDrawData() after Render() to get the same pointer. - // See example applications if you are unsure of how to implement this. - void (*RenderDrawListsFn)(ImDrawData* data); - // Optional: access OS clipboard // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) const char* (*GetClipboardTextFn)(void* user_data); @@ -997,6 +992,12 @@ struct ImGuiIO void (*ImeSetInputScreenPosFn)(int x, int y); void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). + // See example applications if you are unsure of how to implement this. + void (*RenderDrawListsFn)(ImDrawData* data); +#endif + //------------------------------------------------------------------ // Input - Fill before calling NewFrame() //------------------------------------------------------------------ From ffb6e89f30160c7b0f30acfa901531ff1aa07e06 Mon Sep 17 00:00:00 2001 From: Oliver Faircliff Date: Fri, 16 Feb 2018 17:45:31 +0000 Subject: [PATCH 12/87] Use SDL system cursors in SDL examples. (#1626) (Squashed 4 commits) --- .../imgui_impl_sdl_gl2.cpp | 21 ++++++++++++++++++- .../imgui_impl_sdl_gl3.cpp | 21 ++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 26cf8c65..fc5473ba 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -43,6 +43,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; +static SDL_Cursor *g_SdlCursorMap[ImGuiMouseCursor_Count_]; // OpenGL2 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -250,6 +251,14 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; + g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_SdlCursorMap[ImGuiMouseCursor_Move] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + #ifdef _WIN32 SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); @@ -265,6 +274,9 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) void ImGui_ImplSdlGL2_Shutdown() { ImGui_ImplSdlGL2_InvalidateDeviceObjects(); + + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + SDL_FreeCursor(g_SdlCursorMap[cursor_n]); } void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) @@ -314,7 +326,14 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) #endif // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + if (io.MouseDrawCursor) + SDL_ShowCursor(0); + else + { + SDL_Cursor *cursor = g_SdlCursorMap[ImGui::GetMouseCursor()]; + SDL_SetCursor(cursor); + SDL_ShowCursor(1); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index b73fdbde..10726300 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -45,6 +45,7 @@ static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; +static SDL_Cursor *g_SdlCursorMap[ImGuiMouseCursor_Count_]; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -364,6 +365,14 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; io.ClipboardUserData = NULL; + g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_SdlCursorMap[ImGuiMouseCursor_Move] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_SdlCursorMap[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + #ifdef _WIN32 SDL_SysWMinfo wmInfo; SDL_VERSION(&wmInfo.version); @@ -379,6 +388,9 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) void ImGui_ImplSdlGL3_Shutdown() { ImGui_ImplSdlGL3_InvalidateDeviceObjects(); + + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + SDL_FreeCursor(g_SdlCursorMap[cursor_n]); } void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) @@ -428,7 +440,14 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) #endif // Hide OS mouse cursor if ImGui is drawing it - SDL_ShowCursor(io.MouseDrawCursor ? 0 : 1); + if (io.MouseDrawCursor) + SDL_ShowCursor(0); + else + { + SDL_Cursor *cursor = g_SdlCursorMap[ImGui::GetMouseCursor()]; + SDL_SetCursor(cursor); + SDL_ShowCursor(1); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); From 7c7583520043078b18cef0c4e7847d623b37a29f Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 19:49:33 +0100 Subject: [PATCH 13/87] Renamed misleading ImGuiMouseCursor_Move to ImGuiMouseCursor_ResizeAll. SDL: Fixed cursor. (#1626) --- examples/allegro5_example/imgui_impl_a5.cpp | 2 +- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- imgui.h | 2 +- imgui_draw.cpp | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/allegro5_example/imgui_impl_a5.cpp b/examples/allegro5_example/imgui_impl_a5.cpp index 479702b9..127bf196 100644 --- a/examples/allegro5_example/imgui_impl_a5.cpp +++ b/examples/allegro5_example/imgui_impl_a5.cpp @@ -291,7 +291,7 @@ void ImGui_ImplA5_NewFrame() switch (ImGui::GetMouseCursor()) { case ImGuiMouseCursor_TextInput: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_EDIT; break; - case ImGuiMouseCursor_Move: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE; break; + case ImGuiMouseCursor_ResizeAll: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_MOVE; break; case ImGuiMouseCursor_ResizeNS: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_N; break; case ImGuiMouseCursor_ResizeEW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_E; break; case ImGuiMouseCursor_ResizeNESW: cursor_id = ALLEGRO_SYSTEM_MOUSE_CURSOR_RESIZE_NE; break; diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index fc5473ba..0a7b8d7e 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -253,7 +253,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursorMap[ImGuiMouseCursor_Move] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + g_SdlCursorMap[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 10726300..186e6d2c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -367,7 +367,7 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursorMap[ImGuiMouseCursor_Move] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_HAND); + g_SdlCursorMap[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); diff --git a/imgui.h b/imgui.h index d421e224..5ab6f332 100644 --- a/imgui.h +++ b/imgui.h @@ -881,7 +881,7 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_None = -1, ImGuiMouseCursor_Arrow = 0, ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. - ImGuiMouseCursor_Move, // Unused + ImGuiMouseCursor_ResizeAll, // Unused ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window diff --git a/imgui_draw.cpp b/imgui_draw.cpp index cafe6e08..118acabc 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1351,7 +1351,7 @@ static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][ // Pos ........ Size ......... Offset ...... { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput - { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_Move + { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_ResizeAll { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW From 03a44acf6f53887fc62758de5a48cafc9197bf44 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 19:55:16 +0100 Subject: [PATCH 14/87] Examples: SDL: Minor stylistic tweaks. Fixed handling of ImGuiMouseCursor_None so it doesn't underflow array. Fixed harmless uninitialized pointer. (#1626) --- .../imgui_impl_sdl_gl2.cpp | 27 ++++++++++--------- .../imgui_impl_sdl_gl3.cpp | 27 ++++++++++--------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 0a7b8d7e..769ebb9f 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -43,7 +44,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; -static SDL_Cursor *g_SdlCursorMap[ImGuiMouseCursor_Count_]; +static SDL_Cursor* g_SdlCursors[ImGuiMouseCursor_Count_] = { 0 }; // OpenGL2 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -251,13 +252,13 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; - g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursorMap[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + g_SdlCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_SdlCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_SdlCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + g_SdlCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_SdlCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_SdlCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_SdlCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); #ifdef _WIN32 SDL_SysWMinfo wmInfo; @@ -276,7 +277,7 @@ void ImGui_ImplSdlGL2_Shutdown() ImGui_ImplSdlGL2_InvalidateDeviceObjects(); for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) - SDL_FreeCursor(g_SdlCursorMap[cursor_n]); + SDL_FreeCursor(g_SdlCursors[cursor_n]); } void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) @@ -326,12 +327,14 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) #endif // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) + ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) + { SDL_ShowCursor(0); + } else { - SDL_Cursor *cursor = g_SdlCursorMap[ImGui::GetMouseCursor()]; - SDL_SetCursor(cursor); + SDL_SetCursor(g_SdlCursors[cursor]); SDL_ShowCursor(1); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 186e6d2c..5a1ec15d 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -45,7 +46,7 @@ static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; -static SDL_Cursor *g_SdlCursorMap[ImGuiMouseCursor_Count_]; +static SDL_Cursor* g_SdlCursors[ImGuiMouseCursor_Count_] = { 0 }; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -365,13 +366,13 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; io.ClipboardUserData = NULL; - g_SdlCursorMap[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - g_SdlCursorMap[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursorMap[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - g_SdlCursorMap[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - g_SdlCursorMap[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + g_SdlCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_SdlCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_SdlCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + g_SdlCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_SdlCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_SdlCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_SdlCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); #ifdef _WIN32 SDL_SysWMinfo wmInfo; @@ -390,7 +391,7 @@ void ImGui_ImplSdlGL3_Shutdown() ImGui_ImplSdlGL3_InvalidateDeviceObjects(); for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) - SDL_FreeCursor(g_SdlCursorMap[cursor_n]); + SDL_FreeCursor(g_SdlCursors[cursor_n]); } void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) @@ -440,12 +441,14 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) #endif // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) + ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) + { SDL_ShowCursor(0); + } else { - SDL_Cursor *cursor = g_SdlCursorMap[ImGui::GetMouseCursor()]; - SDL_SetCursor(cursor); + SDL_SetCursor(g_SdlCursors[cursor]); SDL_ShowCursor(1); } From 00b24f27c26694b7c33ebb337e744fac8573a1cc Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 22:09:23 +0100 Subject: [PATCH 15/87] Examples: SDL: Added .vcproj files. --- .../sdl_opengl2_example.vcxproj | 172 +++++++++++++++++ .../sdl_opengl2_example.vcxproj.filters | 49 +++++ .../sdl_opengl3_example.vcxproj | 175 ++++++++++++++++++ .../sdl_opengl3_example.vcxproj.filters | 61 ++++++ 4 files changed, 457 insertions(+) create mode 100644 examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj create mode 100644 examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj.filters create mode 100644 examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj create mode 100644 examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj.filters diff --git a/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj new file mode 100644 index 00000000..ad83c481 --- /dev/null +++ b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {2AE17FDE-F7F3-4CAC-ADAB-0710EDA4F741} + opengl3_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + + + true + %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + + + true + %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj.filters b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj.filters new file mode 100644 index 00000000..1c505f4e --- /dev/null +++ b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj.filters @@ -0,0 +1,49 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + + + + sources + + + \ No newline at end of file diff --git a/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj new file mode 100644 index 00000000..1ac4d0ac --- /dev/null +++ b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj @@ -0,0 +1,175 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {BBAEB705-1669-40F3-8567-04CF6A991F4C} + opengl3_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + + + true + %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + + + true + %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj.filters b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj.filters new file mode 100644 index 00000000..f8f43415 --- /dev/null +++ b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj.filters @@ -0,0 +1,61 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {f9997b32-5479-4756-9ffc-77793ad3764f} + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + gl3w + + + + + imgui + + + imgui + + + imgui + + + sources + + + gl3w + + + gl3w + + + + + + sources + + + \ No newline at end of file From 31158e575f637ccd5919bd611e7cca54f8dac1b5 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 22:09:32 +0100 Subject: [PATCH 16/87] Examples: SDL: Fixed minor warning. --- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 5a1ec15d..585439ab 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -39,7 +39,7 @@ #include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. // Data -static Uint64 g_Time = 0.0f; +static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; From 10752423ec04443f0cd4f7675eb0a624137bba62 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 22:34:41 +0100 Subject: [PATCH 17/87] Examples: Vulkan: Added .vcproj files. --- examples/.gitignore | 4 + .../vulkan_example/vulkan_example.vcxproj | 172 ++++++++++++++++++ .../vulkan_example.vcxproj.filters | 49 +++++ 3 files changed, 225 insertions(+) create mode 100644 examples/vulkan_example/vulkan_example.vcxproj create mode 100644 examples/vulkan_example/vulkan_example.vcxproj.filters diff --git a/examples/.gitignore b/examples/.gitignore index 12785499..7a6e9f4f 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -33,6 +33,10 @@ sdl_opengl3_example/Debug/* sdl_opengl3_example/Release/* sdl_opengl3_example/ipch/* sdl_opengl3_example/x64/* +vulkan_example/Debug/* +vulkan_example/Release/* +vulkan_example/ipch/* +vulkan_example/x64/* *.opensdf *.sdf *.suo diff --git a/examples/vulkan_example/vulkan_example.vcxproj b/examples/vulkan_example/vulkan_example.vcxproj new file mode 100644 index 00000000..a315d69e --- /dev/null +++ b/examples/vulkan_example/vulkan_example.vcxproj @@ -0,0 +1,172 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {57E2DF5A-6FC8-45BB-99DD-91A18C646E80} + opengl3_example + + + + Application + true + MultiByte + + + Application + true + MultiByte + + + Application + false + true + MultiByte + + + Application + false + true + MultiByte + + + + + + + + + + + + + + + + + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + $(ProjectDir)$(Configuration)\ + $(ProjectDir)$(Configuration)\ + $(IncludePath) + + + + Level4 + Disabled + %VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + %VULKAN_SDK%\lib32;$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + Disabled + %VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + + + true + %VULKAN_SDK%\lib;$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + msvcrt.lib + + + + + Level4 + MaxSpeed + true + true + %VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %VULKAN_SDK%\lib32;$(SolutionDir)\libs\glfw\lib-vc2010-32;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + Level4 + MaxSpeed + true + true + %VULKAN_SDK%\include;$(SolutionDir)\libs\glfw\include;..\..;%(AdditionalIncludeDirectories) + false + + + true + true + true + %VULKAN_SDK%\lib;$(SolutionDir)\libs\glfw\lib-vc2010-64;%(AdditionalLibraryDirectories) + vulkan-1.lib;glfw3.lib;%(AdditionalDependencies) + Console + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/vulkan_example/vulkan_example.vcxproj.filters b/examples/vulkan_example/vulkan_example.vcxproj.filters new file mode 100644 index 00000000..f3ed8ede --- /dev/null +++ b/examples/vulkan_example/vulkan_example.vcxproj.filters @@ -0,0 +1,49 @@ + + + + + {20b90ce4-7fcb-4731-b9a0-075f875de82d} + + + {f18ab499-84e1-499f-8eff-9754361e0e52} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + + + imgui + + + imgui + + + imgui + + + sources + + + sources + + + + + imgui + + + imgui + + + imgui + + + sources + + + + + + sources + + + \ No newline at end of file From 243fd67b1cd4bd10c4c0f088e17072663baae316 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 22:28:52 +0100 Subject: [PATCH 18/87] Examples: Vulkan: Fix for empty draw data (init time) + fixed warning. --- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 2 ++ examples/vulkan_example/main.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 8e93e7e9..31f22e86 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -170,6 +170,8 @@ void ImGui_ImplGlfwVulkan_RenderDrawData(ImDrawData* draw_data) { VkResult err; ImGuiIO& io = ImGui::GetIO(); + if (draw_data->TotalVtxCount == 0) + return; // Create the Vertex Buffer: size_t vertex_size = draw_data->TotalVtxCount * sizeof(ImDrawVert); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index 597374b5..be5fe528 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -507,7 +507,7 @@ static void cleanup_vulkan() static void frame_begin() { VkResult err; - while (true) + for (;;) { err = vkWaitForFences(g_Device, 1, &g_Fence[g_FrameIndex], VK_TRUE, 100); if (err == VK_SUCCESS) break; From 9e713b115f6dcc89ba088dda9af1a736f4bf1236 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 21:46:14 +0100 Subject: [PATCH 19/87] Examples: Renamed .sln file. --- examples/{imgui_examples_msvc2010.sln => imgui_examples.sln} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/{imgui_examples_msvc2010.sln => imgui_examples.sln} (100%) diff --git a/examples/imgui_examples_msvc2010.sln b/examples/imgui_examples.sln similarity index 100% rename from examples/imgui_examples_msvc2010.sln rename to examples/imgui_examples.sln From f5f3730b16e29fa3df7ad6348681263cc2450744 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 16 Feb 2018 23:19:38 +0100 Subject: [PATCH 20/87] Examples: GLFW+GL2/GL3: Added glPixelStorei() calls borrowed from SDL examples. --- examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 1 + examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 2630f164..d4a43570 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -194,6 +194,7 @@ bool ImGui_ImplGlfwGL2_CreateDeviceObjects() glBindTexture(GL_TEXTURE_2D, g_FontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 9c82abc5..24097686 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -218,6 +218,7 @@ bool ImGui_ImplGlfwGL3_CreateFontsTexture() glBindTexture(GL_TEXTURE_2D, g_FontTexture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); // Store our identifier From bdb27366e750ca83b6a72b2ccc6cd8ed1023f922 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 17 Feb 2018 00:19:04 +0100 Subject: [PATCH 21/87] Nav: Tweak windowing highlighting for full viewport windows. --- imgui.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 3eb51958..168162d1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5999,11 +5999,15 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Draw navigation selection/windowing rectangle border if (g.NavWindowingTarget == window) { + float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding); ImRect bb = window->Rect(); bb.Expand(g.FontSize); - if (bb.Contains(viewport_rect)) - bb.Expand(-g.FontSize - 2.0f); - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), g.Style.WindowRounding, ~0, 3.0f); + if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward + { + bb.Expand(-g.FontSize - 1.0f); + rounding = window->WindowRounding; + } + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f); } // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. From 1399c9c8a9cf1866bdddb8462bb50a3d4ccbfc0d Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 17 Feb 2018 00:49:57 +0100 Subject: [PATCH 22/87] Merged a bunch of small inconsequential things from my work branch, to reduce the diff noise. --- imgui.cpp | 25 +++++++++++++------------ imgui.h | 10 +++++----- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 168162d1..a2a7826d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -705,13 +705,13 @@ static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); -static ImGuiWindow* FindHoveredWindow(ImVec2 pos); +static ImGuiWindow* FindHoveredWindow(); static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); static void CheckStacksSize(ImGuiWindow* window, bool write); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); -static void AddDrawListToDrawData(ImVector* out_render_list, ImDrawList* draw_list); -static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWindow* window); +static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list); +static void AddWindowToDrawData(ImVector* out_list, ImGuiWindow* window); static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); static ImGuiWindowSettings* AddWindowSettings(const char* name); @@ -857,10 +857,10 @@ ImGuiIO::ImGuiIO() // Settings DisplaySize = ImVec2(-1.0f, -1.0f); DeltaTime = 1.0f/60.0f; + NavFlags = 0x00; IniSavingRate = 5.0f; IniFilename = "imgui.ini"; LogFilename = "imgui_log.txt"; - NavFlags = 0x00; MouseDoubleClickTime = 0.30f; MouseDoubleClickMaxDist = 6.0f; for (int i = 0; i < ImGuiKey_COUNT; i++) @@ -2664,7 +2664,8 @@ ImGuiStyle& ImGui::GetStyle() // Same value as passed to the old io.RenderDrawListsFn function. Valid after Render() and until the next call to NewFrame() ImDrawData* ImGui::GetDrawData() { - return GImGui->DrawData.Valid ? &GImGui->DrawData : NULL; + ImGuiContext& g = *GImGui; + return g.DrawData.Valid ? &g.DrawData : NULL; } float ImGui::GetTime() @@ -3415,7 +3416,7 @@ void ImGui::NewFrame() // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point. // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. - g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(g.IO.MousePos); + g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(); g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); @@ -3633,6 +3634,7 @@ void ImGui::Shutdown(ImGuiContext* context) SaveIniSettingsToDisk(g.IO.IniFilename); + // Clear everything else for (int i = 0; i < g.Windows.Size; i++) IM_DELETE(g.Windows[i]); g.Windows.clear(); @@ -4445,7 +4447,7 @@ void ImGui::CalcListClipping(int items_count, float items_height, int* out_items // Find window given position, search front-to-back // FIXME: Note that we have a lag here because WindowRectClipped is updated in Begin() so windows moved by user via SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is called, aka before the next Begin(). Moving window thankfully isn't affected. -static ImGuiWindow* FindHoveredWindow(ImVec2 pos) +static ImGuiWindow* FindHoveredWindow() { ImGuiContext& g = *GImGui; for (int i = g.Windows.Size - 1; i >= 0; i--) @@ -4458,7 +4460,7 @@ static ImGuiWindow* FindHoveredWindow(ImVec2 pos) // Using the clipped AABB, a child window will typically be clipped by its parent (not always) ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); - if (bb.Contains(pos)) + if (bb.Contains(g.IO.MousePos)) return window; } return NULL; @@ -6209,14 +6211,13 @@ void ImGui::End() if (window->DC.ColumnsSet != NULL) EndColumns(); - PopClipRect(); // inner window clip rectangle + PopClipRect(); // Inner window clip rectangle // Stop logging if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging LogFinish(); - // Pop - // NB: we don't clear 'window->RootWindow'. The pointer is allowed to live until the next call to Begin(). + // Pop from window stack g.CurrentWindowStack.pop_back(); if (window->Flags & ImGuiWindowFlags_Popup) g.CurrentPopupStack.pop_back(); @@ -13125,7 +13126,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) return; } - ImDrawList* overlay_draw_list = &GImGui->OverlayDrawList; // Render additional visuals into the top-most draw list + ImDrawList* overlay_draw_list = ImGui::GetOverlayDrawList(); // Render additional visuals into the top-most draw list if (window && ImGui::IsItemHovered()) overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); if (!node_open) diff --git a/imgui.h b/imgui.h index 5ab6f332..7629e06c 100644 --- a/imgui.h +++ b/imgui.h @@ -116,7 +116,7 @@ struct ImVec2 float x, y; ImVec2() { x = y = 0.0f; } ImVec2(float _x, float _y) { x = _x; y = _y; } - float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return *(&x + idx); } // We very rarely use this [] operator, thus an assert is fine. + float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, thus an assert is fine. #ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. IM_VEC2_CLASS_EXTRA #endif @@ -744,7 +744,7 @@ enum ImGuiNavInput_ ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ }; -// [BETA] Gamepad/Keyboard directional navigation options +// [BETA] Gamepad/Keyboard directional navigation flags, stored in io.NavFlags enum ImGuiNavFlags_ { ImGuiNavFlags_EnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. @@ -953,10 +953,10 @@ struct ImGuiIO ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + ImGuiNavFlags NavFlags; // = 0x00 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). - ImGuiNavFlags NavFlags; // = 0 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. @@ -1005,7 +1005,7 @@ struct ImGuiIO ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back ends. + float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control bool KeyShift; // Keyboard modifier pressed: Shift @@ -1151,7 +1151,7 @@ public: inline void pop_back() { IM_ASSERT(Size > 0); Size--; } inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); } - inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } + inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } }; From b33f0e215f82d3d4717b0cee797500c8e6ed1365 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 18 Feb 2018 23:25:48 +0100 Subject: [PATCH 23/87] Initialization happens during CreateContext(), which makes it easier for platform layers to interact with the context during their initialization. --- imgui.cpp | 17 +++++++++++------ imgui_internal.h | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index a2a7826d..f50f79f5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2636,6 +2636,7 @@ ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); if (GImGui == NULL) SetCurrentContext(ctx); + Initialize(ctx); return ctx; } @@ -3280,6 +3281,7 @@ void ImGui::NewFrame() // Check user data // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) + IM_ASSERT(g.Initialized); IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); @@ -3294,9 +3296,13 @@ void ImGui::NewFrame() if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); - // Initialize on first frame - if (!g.Initialized) - Initialize(&g); + // Load settings on first frame + if (!g.SettingsLoaded) + { + IM_ASSERT(g.SettingsWindows.empty()); + LoadIniSettingsFromDisk(g.IO.IniFilename); + g.SettingsLoaded = true; + } g.Time += g.IO.DeltaTime; g.FrameCount += 1; @@ -3602,6 +3608,7 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting void ImGui::Initialize(ImGuiContext* context) { ImGuiContext& g = *context; + IM_ASSERT(!g.Initialized && !g.SettingsLoaded); g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); // Add .ini handle for ImGuiWindow type @@ -3613,9 +3620,6 @@ void ImGui::Initialize(ImGuiContext* context) ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; g.SettingsHandlers.push_front(ini_handler); - // Load .ini file - IM_ASSERT(g.SettingsWindows.empty()); - LoadIniSettingsFromDisk(g.IO.IniFilename); g.Initialized = true; } @@ -3765,6 +3769,7 @@ static void LoadIniSettingsFromMemory(const char* buf_readonly) } } ImGui::MemFree(buf); + g.SettingsLoaded = true; } static void SaveIniSettingsToDisk(const char* ini_filename) diff --git a/imgui_internal.h b/imgui_internal.h index 168d337b..77d621bb 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -687,6 +687,7 @@ struct ImGuiContext ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor // Settings + bool SettingsLoaded; float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero ImVector SettingsWindows; // .ini settings for ImGuiWindow ImVector SettingsHandlers; // List of .ini settings handlers @@ -789,6 +790,7 @@ struct ImGuiContext TooltipOverrideCount = 0; OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); + SettingsLoaded = false; SettingsDirtyTimer = 0.0f; LogEnabled = false; From 7ee2bc8f5eae50db1016d376e2d630a60c8ea1c9 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 10:24:31 +0100 Subject: [PATCH 24/87] FAQ about backslashes in string literal since the one in main.cpp isn't being noticed enough. (#1397) --- imgui.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index f50f79f5..4dd404a4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -547,11 +547,15 @@ Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF/OTF file you want: - ImGuiIO& io = ImGui::GetIO(); io.Fonts->AddFontFromFileTTF("myfontfile.ttf", size_in_pixels); io.Fonts->GetTexDataAsRGBA32() or GetTexDataAsAlpha8() + New programmers: remember that in C/C++ and most programming languages if you want to use a backslash \ in a string literal you need to write a double backslash "\\": + io.Fonts->AddFontFromFileTTF("MyDataFolder\MyFontFile.ttf", size_in_pixels); // WRONG + io.Fonts->AddFontFromFileTTF("MyDataFolder\\MyFontFile.ttf", size_in_pixels); // CORRECT + io.Fonts->AddFontFromFileTTF("MyDataFolder/MyFontFile.ttf", size_in_pixels); // ALSO CORRECT + Q: How can I easily use icons in my application? A: The most convenient and practical way is to merge an icon font such as FontAwesome inside you main font. Then you can refer to icons within your strings. Read 'How can I load multiple fonts?' and the file 'misc/fonts/README.txt' for instructions and useful header files. From 7cbcccd96b18f3c5d4d4fe6e9570e40fb2dc3c3a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 12:08:37 +0100 Subject: [PATCH 25/87] Update Breaking Change section with moved misc/fonts/ (#1631) --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 4dd404a4..d6d9f40f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -257,6 +257,7 @@ - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance. - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. + - 2018/01/31 (1.60) - moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. - 2018/01/11 (1.60) - obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/11 (1.60) - obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - 2018/01/03 (1.60) - renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. From 7e2e0535dd4261f7a9102f9a776f0dd7a5357b45 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 13:55:09 +0100 Subject: [PATCH 26/87] Examples: DirectX 9,10,11: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). (#1495) --- .../directx10_example/imgui_impl_dx10.cpp | 51 +++++++++++++++++-- examples/directx10_example/main.cpp | 2 +- .../directx11_example/imgui_impl_dx11.cpp | 51 +++++++++++++++++-- examples/directx11_example/main.cpp | 2 +- examples/directx9_example/imgui_impl_dx9.cpp | 50 ++++++++++++++++-- examples/directx9_example/main.cpp | 2 +- 6 files changed, 141 insertions(+), 17 deletions(-) diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index 10da969e..ed1efeef 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -32,11 +33,13 @@ #define DIRECTINPUT_VERSION 0x0800 #include -// Data +// Win32 Data +static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; -static HWND g_hWnd = 0; +// DirectX data static ID3D10Device* g_pd3dDevice = NULL; static ID3D10Buffer* g_pVB = NULL; static ID3D10Buffer* g_pIB = NULL; @@ -240,6 +243,33 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data) ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } +static void ImGui_ImplWin32_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiMouseCursor imgui_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + ::SetCursor(NULL); + } + else + { + // Hardware cursor type + LPTSTR win32_cursor = IDC_ARROW; + switch (imgui_cursor) + { + case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; + } + ::SetCursor(::LoadCursor(NULL, win32_cursor)); + } +} + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. @@ -306,6 +336,13 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); return 0; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + ImGui_ImplWin32_UpdateMouseCursor(); + return 1; + } + return 0; } return 0; } @@ -618,9 +655,13 @@ void ImGui_ImplDX10_NewFrame() SetCursorPos(pos.x, pos.y); } - // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) - SetCursor(NULL); + // Update OS mouse cursor with the cursor requested by imgui + ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (g_LastMouseCursor != mouse_cursor) + { + g_LastMouseCursor = mouse_cursor; + ImGui_ImplWin32_UpdateMouseCursor(); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index f20f6881..4edf8be6 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -103,7 +103,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) int main(int, char**) { // Create application window - WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, _T("ImGui Example"), NULL }; + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; RegisterClassEx(&wc); HWND hwnd = CreateWindow(_T("ImGui Example"), _T("ImGui DirectX10 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index a0e9d7f3..84dcdbee 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -31,11 +32,13 @@ #define DIRECTINPUT_VERSION 0x0800 #include -// Data +// Win32 data +static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; -static HWND g_hWnd = 0; +// DirectX data static ID3D11Device* g_pd3dDevice = NULL; static ID3D11DeviceContext* g_pd3dDeviceContext = NULL; static ID3D11Buffer* g_pVB = NULL; @@ -247,6 +250,33 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data) ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release(); } +static void ImGui_ImplWin32_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiMouseCursor imgui_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + ::SetCursor(NULL); + } + else + { + // Hardware cursor type + LPTSTR win32_cursor = IDC_ARROW; + switch (imgui_cursor) + { + case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; + } + ::SetCursor(::LoadCursor(NULL, win32_cursor)); + } +} + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. @@ -313,6 +343,13 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); return 0; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + ImGui_ImplWin32_UpdateMouseCursor(); + return 1; + } + return 0; } return 0; } @@ -621,9 +658,13 @@ void ImGui_ImplDX11_NewFrame() SetCursorPos(pos.x, pos.y); } - // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) - SetCursor(NULL); + // Update OS mouse cursor with the cursor requested by imgui + ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (g_LastMouseCursor != mouse_cursor) + { + g_LastMouseCursor = mouse_cursor; + ImGui_ImplWin32_UpdateMouseCursor(); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index f6dc6f74..2ded0a90 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -106,7 +106,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) int main(int, char**) { // Create application window - WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, _T("ImGui Example"), NULL }; + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; RegisterClassEx(&wc); HWND hwnd = CreateWindow(_T("ImGui Example"), _T("ImGui DirectX11 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index e960b7c5..194752fb 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX9_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -22,10 +23,13 @@ #define DIRECTINPUT_VERSION 0x0800 #include -// Data +// Win32 data static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; + +// DirectX data static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; static LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; static LPDIRECT3DINDEXBUFFER9 g_pIB = NULL; @@ -178,6 +182,33 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) d3d9_state_block->Release(); } +static void ImGui_ImplWin32_UpdateMouseCursor() +{ + ImGuiIO& io = ImGui::GetIO(); + ImGuiMouseCursor imgui_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + ::SetCursor(NULL); + } + else + { + // Hardware cursor type + LPTSTR win32_cursor = IDC_ARROW; + switch (imgui_cursor) + { + case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; + } + ::SetCursor(::LoadCursor(NULL, win32_cursor)); + } +} + // Process Win32 mouse/keyboard inputs. // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. @@ -244,6 +275,13 @@ IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wPa if (wParam > 0 && wParam < 0x10000) io.AddInputCharacter((unsigned short)wParam); return 0; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + ImGui_ImplWin32_UpdateMouseCursor(); + return 1; + } + return 0; } return 0; } @@ -387,9 +425,13 @@ void ImGui_ImplDX9_NewFrame() SetCursorPos(pos.x, pos.y); } - // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) - SetCursor(NULL); + // Update OS mouse cursor with the cursor requested by imgui + ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (g_LastMouseCursor != mouse_cursor) + { + g_LastMouseCursor = mouse_cursor; + ImGui_ImplWin32_UpdateMouseCursor(); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index 16482b3a..f4c7a9f0 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -46,7 +46,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) int main(int, char**) { // Create application window - WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, _T("ImGui Example"), NULL }; + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; RegisterClassEx(&wc); HWND hwnd = CreateWindow(_T("ImGui Example"), _T("ImGui DirectX9 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); From 11b12488e87b5a57ae4541cd6aba35bc3fe38b45 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 14:09:46 +0100 Subject: [PATCH 27/87] Examples: GLFW*: Renamed GLFW callbacks exposed in .h to not include GL2/GL3/Vulkan in their name. --- .../opengl2_example/imgui_impl_glfw_gl2.cpp | 24 +++++++++++-------- .../opengl2_example/imgui_impl_glfw_gl2.h | 8 +++---- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 24 +++++++++++-------- .../opengl3_example/imgui_impl_glfw_gl3.h | 8 +++---- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 24 +++++++++++-------- .../vulkan_example/imgui_impl_glfw_vulkan.h | 8 +++---- 6 files changed, 54 insertions(+), 42 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index d4a43570..42075e4f 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL2 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -144,20 +145,20 @@ static void ImGui_ImplGlfwGL2_SetClipboardText(void* user_data, const char* text glfwSetClipboardString((GLFWwindow*)user_data, text); } -void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { ImGuiIO& io = ImGui::GetIO(); io.MouseWheelH += (float)xoffset; io.MouseWheel += (float)yoffset; } -void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +void ImGui_ImplGlfw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) { ImGuiIO& io = ImGui::GetIO(); if (action == GLFW_PRESS) @@ -172,7 +173,7 @@ void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow*, int key, int, int action, int mo io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; } -void ImGui_ImplGlfwGL2_CharCallback(GLFWwindow*, unsigned int c) +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) { ImGuiIO& io = ImGui::GetIO(); if (c > 0 && c < 0x10000) @@ -216,6 +217,14 @@ void ImGui_ImplGlfwGL2_InvalidateDeviceObjects() } } +static void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) +{ + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); +} + bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) { g_Window = window; @@ -251,12 +260,7 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) #endif if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL2_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfwGL2_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfwGL2_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfwGL2_CharCallback); - } + ImGui_ImplGlfw_InstallCallbacks(window); return true; } diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.h b/examples/opengl2_example/imgui_impl_glfw_gl2.h index 268b0e49..4e0f393c 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.h +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.h @@ -26,7 +26,7 @@ IMGUI_API bool ImGui_ImplGlfwGL2_CreateDeviceObjects(); // GLFW callbacks (registered by default to GLFW if you enable 'install_callbacks' during initialization) // Provided here if you want to chain callbacks yourself. You may also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfwGL2_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfwGL2_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlfwGL2_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfwGL2_CharCallback(GLFWwindow* window, unsigned int c); +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 24097686..16f89643 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -168,20 +169,20 @@ static void ImGui_ImplGlfwGL3_SetClipboardText(void* user_data, const char* text glfwSetClipboardString((GLFWwindow*)user_data, text); } -void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { ImGuiIO& io = ImGui::GetIO(); io.MouseWheelH += (float)xoffset; io.MouseWheel += (float)yoffset; } -void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +void ImGui_ImplGlfw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) { ImGuiIO& io = ImGui::GetIO(); if (action == GLFW_PRESS) @@ -196,7 +197,7 @@ void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow*, int key, int, int action, int mo io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; } -void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow*, unsigned int c) +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) { ImGuiIO& io = ImGui::GetIO(); if (c > 0 && c < 0x10000) @@ -331,6 +332,14 @@ void ImGui_ImplGlfwGL3_InvalidateDeviceObjects() } } +static void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) +{ + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); +} + bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) { g_Window = window; @@ -366,12 +375,7 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) #endif if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfwGL3_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfwGL3_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfwGL3_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfwGL3_CharCallback); - } + ImGui_ImplGlfw_InstallCallbacks(window); return true; } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 0e039d8d..71ea4122 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -25,7 +25,7 @@ IMGUI_API bool ImGui_ImplGlfwGL3_CreateDeviceObjects(); // GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) // Provided here if you want to chain callbacks. // You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfwGL3_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfwGL3_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlfwGL3_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfwGL3_CharCallback(GLFWwindow* window, unsigned int c); +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 31f22e86..3b3a1f02 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include Vulkan in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplGlfwVulkan_Render() calls ImGui_ImplGlfwVulkan_RenderDrawData() itself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. @@ -340,20 +341,20 @@ static void ImGui_ImplGlfwVulkan_SetClipboardText(void* user_data, const char* t glfwSetClipboardString((GLFWwindow*)user_data, text); } -void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) +void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow*, int button, int action, int /*mods*/) { if (action == GLFW_PRESS && button >= 0 && button < 3) g_MouseJustPressed[button] = true; } -void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) +void ImGui_ImplGlfw_ScrollCallback(GLFWwindow*, double xoffset, double yoffset) { ImGuiIO& io = ImGui::GetIO(); io.MouseWheelH += (float)xoffset; io.MouseWheel += (float)yoffset; } -void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int mods) +void ImGui_ImplGlfw_KeyCallback(GLFWwindow*, int key, int, int action, int mods) { ImGuiIO& io = ImGui::GetIO(); if (action == GLFW_PRESS) @@ -368,7 +369,7 @@ void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow*, int key, int, int action, int io.KeySuper = io.KeysDown[GLFW_KEY_LEFT_SUPER] || io.KeysDown[GLFW_KEY_RIGHT_SUPER]; } -void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow*, unsigned int c) +void ImGui_ImplGlfw_CharCallback(GLFWwindow*, unsigned int c) { ImGuiIO& io = ImGui::GetIO(); if (c > 0 && c < 0x10000) @@ -746,6 +747,14 @@ void ImGui_ImplGlfwVulkan_InvalidateDeviceObjects() if (g_Pipeline) { vkDestroyPipeline(g_Device, g_Pipeline, g_Allocator); g_Pipeline = VK_NULL_HANDLE; } } +static void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) +{ + glfwSetMouseButtonCallback(window, ImGui_ImplGlfw_MouseButtonCallback); + glfwSetScrollCallback(window, ImGui_ImplGlfw_ScrollCallback); + glfwSetKeyCallback(window, ImGui_ImplGlfw_KeyCallback); + glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); +} + bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, ImGui_ImplGlfwVulkan_Init_Data *init_data) { g_Allocator = init_data->allocator; @@ -789,12 +798,7 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im #endif if (install_callbacks) - { - glfwSetMouseButtonCallback(window, ImGui_ImplGlfwVulkan_MouseButtonCallback); - glfwSetScrollCallback(window, ImGui_ImplGlfwVulkan_ScrollCallback); - glfwSetKeyCallback(window, ImGui_ImplGlfwVulkan_KeyCallback); - glfwSetCharCallback(window, ImGui_ImplGlfwVulkan_CharCallback); - } + ImGui_ImplGlfw_InstallCallbacks(window); ImGui_ImplGlfwVulkan_CreateDeviceObjects(); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.h b/examples/vulkan_example/imgui_impl_glfw_vulkan.h index 54918d34..5d2b63cc 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.h +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.h @@ -39,8 +39,8 @@ IMGUI_API bool ImGui_ImplGlfwVulkan_CreateDeviceObjects(); // GLFW callbacks (installed by default if you enable 'install_callbacks' during initialization) // Provided here if you want to chain callbacks. // You can also handle inputs yourself and use those as a reference. -IMGUI_API void ImGui_ImplGlfwVulkan_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); -IMGUI_API void ImGui_ImplGlfwVulkan_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); -IMGUI_API void ImGui_ImplGlfwVulkan_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); -IMGUI_API void ImGui_ImplGlfwVulkan_CharCallback(GLFWwindow* window, unsigned int c); +IMGUI_API void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_ScrollCallback(GLFWwindow* window, double xoffset, double yoffset); +IMGUI_API void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int key, int scancode, int action, int mods); +IMGUI_API void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c); From d5342076220f2f4f270c1fdcb41b82d39fad25e4 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 14:18:02 +0100 Subject: [PATCH 28/87] Examples: GLFW: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). (#1495) --- .../opengl2_example/imgui_impl_glfw_gl2.cpp | 35 +++++++++++++++++-- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 35 +++++++++++++++++-- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 35 ++++++++++++++++--- 3 files changed, 95 insertions(+), 10 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 42075e4f..19b2cdc3 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL2 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. @@ -45,10 +46,13 @@ #include #endif -// Data +// GLFW data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; + +// OpenGL data static GLuint g_FontTexture = 0; // OpenGL2 Render function. @@ -259,6 +263,16 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) io.ImeWindowHandle = glfwGetWin32Window(g_Window); #endif + // Load cursors + // FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those. + g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + if (install_callbacks) ImGui_ImplGlfw_InstallCallbacks(window); @@ -267,6 +281,12 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL2_Shutdown() { + // Destroy GLFW mouse cursors + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + glfwDestroyCursor(g_MouseCursors[cursor_n]); + memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); + + // Destroy OpenGL objects ImGui_ImplGlfwGL2_InvalidateDeviceObjects(); } @@ -317,8 +337,17 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + // Update mouse cursor + ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + } + else + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 16f89643..65356846 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. @@ -42,10 +43,13 @@ #include #endif -// Data +// GLFW data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; + +// OpenGL3 data static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -374,6 +378,16 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) io.ImeWindowHandle = glfwGetWin32Window(g_Window); #endif + // Load cursors + // FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those. + g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + if (install_callbacks) ImGui_ImplGlfw_InstallCallbacks(window); @@ -382,6 +396,12 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL3_Shutdown() { + // Destroy GLFW mouse cursors + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + glfwDestroyCursor(g_MouseCursors[cursor_n]); + memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); + + // Destroy OpenGL objects ImGui_ImplGlfwGL3_InvalidateDeviceObjects(); } @@ -432,8 +452,17 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + // Update mouse cursor + ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + } + else + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + } // Gamepad navigation mapping [BETA] memset(io.NavInputs, 0, sizeof(io.NavInputs)); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 3b3a1f02..a2f02b2b 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -10,6 +10,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include Vulkan in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback, ImGui_ImplGlfwVulkan_Render() calls ImGui_ImplGlfwVulkan_RenderDrawData() itself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. @@ -37,12 +38,13 @@ #include #endif -// GLFW Data +// GLFW data static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; -// Vulkan Data +// Vulkan data static VkAllocationCallbacks* g_Allocator = NULL; static VkPhysicalDevice g_Gpu = VK_NULL_HANDLE; static VkDevice g_Device = VK_NULL_HANDLE; @@ -797,6 +799,16 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im io.ImeWindowHandle = glfwGetWin32Window(g_Window); #endif + // Load cursors + // FIXME: GLFW doesn't expose suitable cursors for ResizeAll, ResizeNESW, ResizeNWSE. We revert to arrow cursor for those. + g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); + if (install_callbacks) ImGui_ImplGlfw_InstallCallbacks(window); @@ -807,6 +819,12 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im void ImGui_ImplGlfwVulkan_Shutdown() { + // Destroy GLFW mouse cursors + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + glfwDestroyCursor(g_MouseCursors[cursor_n]); + memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); + + // Destroy Vulkan objects ImGui_ImplGlfwVulkan_InvalidateDeviceObjects(); } @@ -846,8 +864,17 @@ void ImGui_ImplGlfwVulkan_NewFrame() g_MouseJustPressed[i] = false; } - // Hide OS mouse cursor if ImGui is drawing it - glfwSetInputMode(g_Window, GLFW_CURSOR, io.MouseDrawCursor ? GLFW_CURSOR_HIDDEN : GLFW_CURSOR_NORMAL); + // Update mouse cursor + ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); + if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN); + } + else + { + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); From daddd09cd588d828c2362172e8404e8ef16c468b Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 14:23:22 +0100 Subject: [PATCH 29/87] Examples: Mouse cursor handling comments/tweaks to homogenize. (#1495) --- .../opengl2_example/imgui_impl_glfw_gl2.cpp | 4 +-- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 4 +-- .../imgui_impl_sdl_gl2.cpp | 29 ++++++++++--------- .../imgui_impl_sdl_gl3.cpp | 29 ++++++++++--------- .../vulkan_example/imgui_impl_glfw_vulkan.cpp | 4 +-- 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 19b2cdc3..259e5a2a 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -337,7 +337,7 @@ void ImGui_ImplGlfwGL2_NewFrame() g_MouseJustPressed[i] = false; } - // Update mouse cursor + // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) { @@ -345,8 +345,8 @@ void ImGui_ImplGlfwGL2_NewFrame() } else { - glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 65356846..84c1118b 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -452,7 +452,7 @@ void ImGui_ImplGlfwGL3_NewFrame() g_MouseJustPressed[i] = false; } - // Update mouse cursor + // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) { @@ -460,8 +460,8 @@ void ImGui_ImplGlfwGL3_NewFrame() } else { - glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } // Gamepad navigation mapping [BETA] diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index 769ebb9f..c99aaa08 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -44,7 +44,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; -static SDL_Cursor* g_SdlCursors[ImGuiMouseCursor_Count_] = { 0 }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; // OpenGL2 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -252,13 +252,13 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL2_GetClipboardText; io.ClipboardUserData = NULL; - g_SdlCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - g_SdlCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - g_SdlCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - g_SdlCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - g_SdlCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - g_SdlCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); #ifdef _WIN32 SDL_SysWMinfo wmInfo; @@ -274,10 +274,13 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) void ImGui_ImplSdlGL2_Shutdown() { - ImGui_ImplSdlGL2_InvalidateDeviceObjects(); - + // Destroy SDL mouse cursors for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) - SDL_FreeCursor(g_SdlCursors[cursor_n]); + SDL_FreeCursor(g_MouseCursors[cursor_n]); + memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); + + // Destroy OpenGL objects + ImGui_ImplSdlGL2_InvalidateDeviceObjects(); } void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) @@ -326,7 +329,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) io.MousePos = ImVec2((float)mx, (float)my); #endif - // Hide OS mouse cursor if ImGui is drawing it + // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) { @@ -334,7 +337,7 @@ void ImGui_ImplSdlGL2_NewFrame(SDL_Window *window) } else { - SDL_SetCursor(g_SdlCursors[cursor]); + SDL_SetCursor(g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); SDL_ShowCursor(1); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 585439ab..f9c4be03 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -46,7 +46,7 @@ static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; -static SDL_Cursor* g_SdlCursors[ImGuiMouseCursor_Count_] = { 0 }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -366,13 +366,13 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) io.GetClipboardTextFn = ImGui_ImplSdlGL3_GetClipboardText; io.ClipboardUserData = NULL; - g_SdlCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); - g_SdlCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); - g_SdlCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); - g_SdlCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - g_SdlCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); - g_SdlCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); - g_SdlCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); + g_MouseCursors[ImGuiMouseCursor_Arrow] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW); + g_MouseCursors[ImGuiMouseCursor_TextInput] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_IBEAM); + g_MouseCursors[ImGuiMouseCursor_ResizeAll] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEALL); + g_MouseCursors[ImGuiMouseCursor_ResizeNS] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); + g_MouseCursors[ImGuiMouseCursor_ResizeEW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); + g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENESW); + g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENWSE); #ifdef _WIN32 SDL_SysWMinfo wmInfo; @@ -388,10 +388,13 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) void ImGui_ImplSdlGL3_Shutdown() { - ImGui_ImplSdlGL3_InvalidateDeviceObjects(); - + // Destroy SDL mouse cursors for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) - SDL_FreeCursor(g_SdlCursors[cursor_n]); + SDL_FreeCursor(g_MouseCursors[cursor_n]); + memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); + + // Destroy OpenGL objects + ImGui_ImplSdlGL3_InvalidateDeviceObjects(); } void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) @@ -440,7 +443,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) io.MousePos = ImVec2((float)mx, (float)my); #endif - // Hide OS mouse cursor if ImGui is drawing it + // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) { @@ -448,7 +451,7 @@ void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window) } else { - SDL_SetCursor(g_SdlCursors[cursor]); + SDL_SetCursor(g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); SDL_ShowCursor(1); } diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index a2f02b2b..8f9fa654 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -864,7 +864,7 @@ void ImGui_ImplGlfwVulkan_NewFrame() g_MouseJustPressed[i] = false; } - // Update mouse cursor + // Update OS/hardware mouse cursor if imgui isn't drawing a software cursor ImGuiMouseCursor cursor = ImGui::GetMouseCursor(); if (io.MouseDrawCursor || cursor == ImGuiMouseCursor_None) { @@ -872,8 +872,8 @@ void ImGui_ImplGlfwVulkan_NewFrame() } else { - glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); glfwSetCursor(g_Window, g_MouseCursors[cursor] ? g_MouseCursors[cursor] : g_MouseCursors[ImGuiMouseCursor_Arrow]); + glfwSetInputMode(g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); } // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. From 98c2ca557c78392942ab2674186ccb5062458430 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 14:40:12 +0100 Subject: [PATCH 30/87] Update .travis.yml PPA source for glfw in the end of getting a newer version of GLFW --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 62e27968..005b6f83 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ compiler: - clang before_install: - - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:keithw/glfw3 && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi + - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3 && brew install sdl2; fi script: From 3186acdf8c104867d3e8b07ca4d8942aad695ea0 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 14:56:43 +0100 Subject: [PATCH 31/87] Trying to download and build GLFW since APT repository are unreliable --- .travis.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 005b6f83..517bc56e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,19 @@ compiler: - clang before_install: - - if [ $TRAVIS_OS_NAME == linux ]; then sudo add-apt-repository -y ppa:pyglfw/pyglfw && sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libglfw3-dev libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; fi - - if [ $TRAVIS_OS_NAME == osx ]; then brew update && brew install glfw3 && brew install sdl2; fi + - if [ $TRAVIS_OS_NAME == linux ]; then + sudo apt-get update -qq + sudo apt-get install -y --no-install-recommends libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev + wget https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip + unzip glfw-3.2.1.zip && cd glfw-3.2.1; + cmake -DCMAKE_INSTALL_PREFIX=$HOME -DBUILD_SHARED_LIBS=true -DGLFW_BUILD_EXAMPLES=false -DGLFW_BUILD_TESTS=false -DGLFW_BUILD_DOCS=false .; + sudo make -j $CPU_NUM install && cd .. + fi + - if [ $TRAVIS_OS_NAME == osx ]; then + brew update + brew install glfw3 + brew install sdl2 + fi script: - make -C examples/opengl2_example From 32bbd8be96c0f9114469ab1d10103cf90bb6f49f Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 15:07:34 +0100 Subject: [PATCH 32/87] Update .travis.yml --- .travis.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index 517bc56e..3f62b7fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: cpp +sudo: required +dist: trusty os: - linux @@ -10,17 +12,17 @@ compiler: before_install: - if [ $TRAVIS_OS_NAME == linux ]; then - sudo apt-get update -qq - sudo apt-get install -y --no-install-recommends libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev - wget https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip - unzip glfw-3.2.1.zip && cd glfw-3.2.1; + sudo apt-get update -qq; + sudo apt-get install -y --no-install-recommends libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; + wget https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip; + unzip glfw-3.2.1.zip && cd glfw-3.2.1; cmake -DCMAKE_INSTALL_PREFIX=$HOME -DBUILD_SHARED_LIBS=true -DGLFW_BUILD_EXAMPLES=false -DGLFW_BUILD_TESTS=false -DGLFW_BUILD_DOCS=false .; - sudo make -j $CPU_NUM install && cd .. + sudo make -j $CPU_NUM install && cd ..; fi - if [ $TRAVIS_OS_NAME == osx ]; then - brew update - brew install glfw3 - brew install sdl2 + brew update; + brew install glfw3; + brew install sdl2; fi script: From 201408a119e951350a6e09df52a029fdca3ff535 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 15:12:17 +0100 Subject: [PATCH 33/87] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3f62b7fa..f4de9eca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_install: sudo apt-get install -y --no-install-recommends libxrandr-dev libxi-dev libxxf86vm-dev libsdl2-dev; wget https://github.com/glfw/glfw/releases/download/3.2.1/glfw-3.2.1.zip; unzip glfw-3.2.1.zip && cd glfw-3.2.1; - cmake -DCMAKE_INSTALL_PREFIX=$HOME -DBUILD_SHARED_LIBS=true -DGLFW_BUILD_EXAMPLES=false -DGLFW_BUILD_TESTS=false -DGLFW_BUILD_DOCS=false .; + cmake -DBUILD_SHARED_LIBS=true -DGLFW_BUILD_EXAMPLES=false -DGLFW_BUILD_TESTS=false -DGLFW_BUILD_DOCS=false .; sudo make -j $CPU_NUM install && cd ..; fi - if [ $TRAVIS_OS_NAME == osx ]; then From 9c20a40b36dfdde2d26b119bd6f342d8a4372d92 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 20 Feb 2018 15:49:17 +0100 Subject: [PATCH 34/87] Examples: OpenGL: Cast call to glPolygonMode(). (#1628). --- examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 2 +- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 2 +- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 2 +- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 259e5a2a..f78b77be 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -134,7 +134,7 @@ void ImGui_ImplGlfwGL2_RenderDrawData(ImDrawData* draw_data) glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); - glPolygonMode(GL_FRONT, last_polygon_mode[0]); glPolygonMode(GL_BACK, last_polygon_mode[1]); + glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 84c1118b..72cc4bf6 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -158,7 +158,7 @@ void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data) if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); - glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0]); + glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index c99aaa08..c7eeaa91 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -125,7 +125,7 @@ void ImGui_ImplSdlGL2_RenderDrawData(ImDrawData* draw_data) glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); - glPolygonMode(GL_FRONT, last_polygon_mode[0]); glPolygonMode(GL_BACK, last_polygon_mode[1]); + glPolygonMode(GL_FRONT, (GLenum)last_polygon_mode[0]); glPolygonMode(GL_BACK, (GLenum)last_polygon_mode[1]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index f9c4be03..4b870ade 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -150,7 +150,7 @@ void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data) if (last_enable_cull_face) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); if (last_enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); if (last_enable_scissor_test) glEnable(GL_SCISSOR_TEST); else glDisable(GL_SCISSOR_TEST); - glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0]); + glPolygonMode(GL_FRONT_AND_BACK, (GLenum)last_polygon_mode[0]); glViewport(last_viewport[0], last_viewport[1], (GLsizei)last_viewport[2], (GLsizei)last_viewport[3]); glScissor(last_scissor_box[0], last_scissor_box[1], (GLsizei)last_scissor_box[2], (GLsizei)last_scissor_box[3]); } From 16ff9faf51b99f3e9bd862afb69cce46c0658bb9 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Feb 2018 13:12:13 +0100 Subject: [PATCH 35/87] Update issue_template.md --- .github/issue_template.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/issue_template.md b/.github/issue_template.md index a8745fad..e47ef9e8 100644 --- a/.github/issue_template.md +++ b/.github/issue_template.md @@ -1,2 +1,7 @@ -(Please read guidelines in https://github.com/ocornut/imgui/blob/master/.github/CONTRIBUTING.md then delete this line) +(Please carefully read guidelines in [CONTRIBUTING.md](https://github.com/ocornut/imgui/blob/master/.github/CONTRIBUTING.md) then delete this line) +You can include code this way: +```cpp +ImGui::Begin("Hello"); +ImGui::ThisIsMoreCode(); +``` From 2c3c5125b3e166dfd3d5b2ad0d4a4414e5a86df3 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Feb 2018 21:33:58 +0100 Subject: [PATCH 36/87] Drag and Drop: BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is really usable in typical conditions at the moment. (#143, #1637) --- imgui.cpp | 4 +++- imgui.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d6d9f40f..c0b8b0c2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -250,6 +250,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is really usable in typical conditions at the moment. - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. - 2018/02/07 (1.60) - reorganized context handling to be more explicit, - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. @@ -12744,7 +12745,7 @@ void ImGui::ClearDragDrop() // Call when current ID is active. // When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() -bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) +bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -12752,6 +12753,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags, int mouse_button) bool source_drag_active = false; ImGuiID source_id = 0; ImGuiID source_parent_id = 0; + int mouse_button = 0; if (!(flags & ImGuiDragDropFlags_SourceExtern)) { source_id = window->DC.LastItemId; diff --git a/imgui.h b/imgui.h index 7629e06c..9b051356 100644 --- a/imgui.h +++ b/imgui.h @@ -452,7 +452,7 @@ namespace ImGui // Drag and Drop // [BETA API] Missing Demo code. API may evolve. - IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0, int mouse_button = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() + IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() From 9b9d9321cf08253eae5b13d8f14d7ceb162efdf7 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Feb 2018 22:46:49 +0100 Subject: [PATCH 37/87] Examples: SDL: Using %SDL2_DIR% in the .vcproj instead of %SDL_DIR%, the earlier is more standard. --- examples/sdl_opengl2_example/build_win32.bat | 2 +- .../sdl_opengl2_example.vcxproj | 16 ++++++++-------- examples/sdl_opengl3_example/build_win32.bat | 2 +- .../sdl_opengl3_example.vcxproj | 16 ++++++++-------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/sdl_opengl2_example/build_win32.bat b/examples/sdl_opengl2_example/build_win32.bat index 799561de..6fe8cb9a 100644 --- a/examples/sdl_opengl2_example/build_win32.bat +++ b/examples/sdl_opengl2_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl_gl2.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2_DIR%\include main.cpp imgui_impl_sdl_gl2.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl2_example.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj index ad83c481..1f9f8177 100644 --- a/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj +++ b/examples/sdl_opengl2_example/sdl_opengl2_example.vcxproj @@ -85,11 +85,11 @@ Level4 Disabled - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) true - %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console msvcrt.lib @@ -99,11 +99,11 @@ Level4 Disabled - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) true - %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console msvcrt.lib @@ -115,14 +115,14 @@ MaxSpeed true true - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) false true true true - %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console @@ -135,14 +135,14 @@ MaxSpeed true true - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) false true true true - %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console diff --git a/examples/sdl_opengl3_example/build_win32.bat b/examples/sdl_opengl3_example/build_win32.bat index 43567542..aec9584e 100644 --- a/examples/sdl_opengl3_example/build_win32.bat +++ b/examples/sdl_opengl3_example/build_win32.bat @@ -1,3 +1,3 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. mkdir Debug -cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL_DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl3_example.exe /FoDebug/ /link /libpath:%SDL_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console +cl /nologo /Zi /MD /I ..\.. /I ..\libs\gl3w /I %SDL2_DIR%\include main.cpp imgui_impl_sdl_gl3.cpp ..\..\imgui*.cpp ..\libs\gl3w\GL\gl3w.c /FeDebug/sdl_opengl3_example.exe /FoDebug/ /link /libpath:%SDL2_DIR%\lib\x86 SDL2.lib SDL2main.lib opengl32.lib /subsystem:console diff --git a/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj index 1ac4d0ac..7bae65a8 100644 --- a/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj +++ b/examples/sdl_opengl3_example/sdl_opengl3_example.vcxproj @@ -85,11 +85,11 @@ Level4 Disabled - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) true - %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console msvcrt.lib @@ -99,11 +99,11 @@ Level4 Disabled - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) true - %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console msvcrt.lib @@ -115,14 +115,14 @@ MaxSpeed true true - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) false true true true - %SDL_DIR%\lib\x86;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x86;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console @@ -135,14 +135,14 @@ MaxSpeed true true - %SDL_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) + %SDL2_DIR%\include;$(SolutionDir)\libs\gl3w;..\..;%(AdditionalIncludeDirectories) false true true true - %SDL_DIR%\lib\x64;%(AdditionalLibraryDirectories) + %SDL2_DIR%\lib\x64;%(AdditionalLibraryDirectories) opengl32.lib;SDL2.lib;SDL2main.lib;%(AdditionalDependencies) Console From 493ec0bc9886fbe7ea2e5453408355f0cbe2a4e0 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 21 Feb 2018 23:13:53 +0100 Subject: [PATCH 38/87] Simplified .gitignore list --- examples/.gitignore | 50 ++++++++++----------------------------------- 1 file changed, 11 insertions(+), 39 deletions(-) diff --git a/examples/.gitignore b/examples/.gitignore index 7a6e9f4f..ff44bccb 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,42 +1,8 @@ build/* -Debug/* -Release/* -ipch/* -x64/* -directx9_example/Debug/* -directx9_example/Release/* -directx9_example/ipch/* -directx9_example/x64/* -directx10_example/Debug/* -directx10_example/Release/* -directx10_example/ipch/* -directx10_example/x64/* -directx11_example/Debug/* -directx11_example/Release/* -directx11_example/ipch/* -directx11_example/x64/* -opengl2_example/Debug/* -opengl2_example/Release/* -opengl2_example/ipch/* -opengl2_example/x64/* -opengl2_example/opengl_example -opengl3_example/Debug/* -opengl3_example/Release/* -opengl3_example/ipch/* -opengl3_example/x64/* -opengl3_example/opengl3_example -sdl_opengl2_example/Debug/* -sdl_opengl2_example/Release/* -sdl_opengl2_example/ipch/* -sdl_opengl2_example/x64/* -sdl_opengl3_example/Debug/* -sdl_opengl3_example/Release/* -sdl_opengl3_example/ipch/* -sdl_opengl3_example/x64/* -vulkan_example/Debug/* -vulkan_example/Release/* -vulkan_example/ipch/* -vulkan_example/x64/* +*/Debug/* +*/Release/* +*/ipch/* +*/x64/* *.opensdf *.sdf *.suo @@ -49,5 +15,11 @@ vulkan_example/x64/* *.VC.db *.VC.VC.opendb -## Ini files +## Unix executables +opengl2_example/opengl2_example +opengl3_example/opengl3_example +sdl_opengl2_example/sdl_opengl2_example +sdl_opengl3_example/sdl_opengl3_example + +## Dear ImGui Ini files imgui.ini From f43068c5438eee187a36992cb93b96e7edd5408d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 13:15:16 +0100 Subject: [PATCH 39/87] Examples: DirectX10, DirectX11: Simplified main example code. --- examples/directx10_example/main.cpp | 10 +--------- examples/directx11_example/main.cpp | 10 +--------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 4edf8be6..346fd35e 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -16,17 +16,9 @@ static ID3D10RenderTargetView* g_mainRenderTargetView = NULL; void CreateRenderTarget() { - DXGI_SWAP_CHAIN_DESC sd; - g_pSwapChain->GetDesc(&sd); - - // Create the render target ID3D10Texture2D* pBackBuffer; - D3D10_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 = D3D10_RTV_DIMENSION_TEXTURE2D; g_pSwapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&pBackBuffer); - g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &g_mainRenderTargetView); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); pBackBuffer->Release(); } diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 2ded0a90..518aa7c2 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -16,17 +16,9 @@ static ID3D11RenderTargetView* g_mainRenderTargetView = NULL; 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_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); pBackBuffer->Release(); } From b28995b66702e10c0ec369e0a3ff0426d0e9cba3 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 15:39:49 +0100 Subject: [PATCH 40/87] Nav: Internals: Exposed NavMoveRequestCancel in imgui_internal.h (#1640) --- imgui.cpp | 4 ++-- imgui_internal.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c0b8b0c2..7f5049a0 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2349,7 +2349,7 @@ static bool NavMoveRequestButNoResultYet() return g.NavMoveRequest && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; } -static void NavMoveRequestCancel() +void ImGui::NavMoveRequestCancel() { ImGuiContext& g = *GImGui; g.NavMoveRequest = false; @@ -5006,7 +5006,7 @@ static void NavProcessMoveRequestWrapAround(ImGuiWindow* window) if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0) { g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; - NavMoveRequestCancel(); + ImGui::NavMoveRequestCancel(); g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = ((g.NavMoveDir == ImGuiDir_Up) ? ImMax(window->SizeFull.y, window->SizeContents.y) : 0.0f) - window->Scroll.y; } } diff --git a/imgui_internal.h b/imgui_internal.h index 77d621bb..c2c05550 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1066,6 +1066,7 @@ namespace ImGui IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); + IMGUI_API void NavMoveRequestCancel(); IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); From 94466745bb6491449d4d71ca88b4bfdf823088e4 Mon Sep 17 00:00:00 2001 From: Podgorskiy Date: Wed, 21 Feb 2018 23:18:25 -0500 Subject: [PATCH 41/87] A tiny optimization to ImLineClosestPoint. Removed unnecessary sqrtf call. ab_lenSqr -> ab_len_sqr Moved line where ab_len_sqr is computed after the first return --- imgui.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d6d9f40f..3451eb9f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -950,14 +950,13 @@ ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) { ImVec2 ap = p - a; ImVec2 ab_dir = b - a; - float ab_len = sqrtf(ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y); - ab_dir *= 1.0f / ab_len; float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; if (dot < 0.0f) return a; - if (dot > ab_len) + float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; + if (dot > ab_len_sqr) return b; - return a + ab_dir * dot; + return a + ab_dir * dot / ab_len_sqr; } bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) From 913f3692a25e578db81d20dc6e576efe342c69ca Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 22:25:30 +0100 Subject: [PATCH 42/87] Examples: DirectX12: Removed from current solution which is meant to be VS2010 compatible for now (will change soon). --- examples/imgui_examples.sln | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/examples/imgui_examples.sln b/examples/imgui_examples.sln index 04851d7c..6ae2e4f1 100644 --- a/examples/imgui_examples.sln +++ b/examples/imgui_examples.sln @@ -1,14 +1,14 @@  -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl2_example", "opengl2_example\opengl2_example.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx9_example", "directx9_example\directx9_example.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx11_example", "directx11_example\directx11_example.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx12_example", "directx12_example\directx12_example.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl3_example", "opengl3_example\opengl3_example.vcxproj", "{4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "directx10_example", "directx10_example\directx10_example.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}" @@ -45,14 +45,6 @@ Global {9F316E83-5AE5-4939-A723-305A94F48005}.Release|Win32.Build.0 = Release|Win32 {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.ActiveCfg = Release|x64 {9F316E83-5AE5-4939-A723-305A94F48005}.Release|x64.Build.0 = Release|x64 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.ActiveCfg = Debug|Win32 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|Win32.Build.0 = Debug|Win32 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.ActiveCfg = Debug|x64 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Debug|x64.Build.0 = Debug|x64 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.ActiveCfg = Release|Win32 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|Win32.Build.0 = Release|Win32 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.ActiveCfg = Release|x64 - {B4CF9797-519D-4AFE-A8F4-5141A6B521D3}.Release|x64.Build.0 = Release|x64 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.ActiveCfg = Debug|Win32 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|Win32.Build.0 = Debug|Win32 {4A1FB5EA-22F5-42A8-AB92-1D2DF5D47FB9}.Debug|x64.ActiveCfg = Debug|x64 From 9be7d048c83c77a2c9694a899143d0f44778d799 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 22:18:59 +0100 Subject: [PATCH 43/87] Examples: DirectX12: Merge, various styling tweaks, update for 1.60 wip, synchronized Win32 features with other examples. (#301) --- README.md | 3 +- examples/README.txt | 4 +- .../directx12_example.vcxproj | 2 +- .../directx12_example/imgui_impl_dx12.cpp | 205 ++++++++++++------ examples/directx12_example/imgui_impl_dx12.h | 29 ++- examples/directx12_example/main.cpp | 137 ++++++------ 6 files changed, 229 insertions(+), 151 deletions(-) diff --git a/README.md b/README.md index a51632c0..51e9193a 100644 --- a/README.md +++ b/README.md @@ -123,11 +123,10 @@ Languages: (third-party bindinds) - Rust: [imgui-rs](https://github.com/Gekkio/imgui-rs) Frameworks: -- DirectX 9, DirectX 10, DirectX 11: [examples/](https://github.com/ocornut/imgui/tree/master/examples) +- DirectX 9, DirectX 10, DirectX 11, DirectX 12: [examples/](https://github.com/ocornut/imgui/tree/master/examples) - OpenGL 2/3 (with GLFW or SDL): [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Vulkan (with GLFW): [examples/](https://github.com/ocornut/imgui/tree/master/examples) - Allegro 5, iOS, Marmalade: [examples/](https://github.com/ocornut/imgui/tree/master/examples) -- Unmerged PR: DirectX12: [#301](https://github.com/ocornut/imgui/pull/301) - Unmerged PR: SDL2 + OpenGLES + Emscripten: [#336](https://github.com/ocornut/imgui/pull/336) - Unmerged PR: FreeGlut + OpenGL2: [#801](https://github.com/ocornut/imgui/pull/801) - Unmerged PR: Native Win32 and OSX: [#281](https://github.com/ocornut/imgui/pull/281) diff --git a/examples/README.txt b/examples/README.txt index 7c2506c2..13660c31 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -4,8 +4,8 @@ Binaries of some of those demos: http://www.miracleworld.net/imgui/binaries Third party languages and frameworks bindings: https://github.com/ocornut/imgui/wiki/Links (languages: C, C#, ChaiScript, D, Go, Haxe, Odin, Python, Rust, Lua, Pascal) -(frameworks: DX12, OpenGLES, FreeGlut, Cinder, Cocos2d-x, SFML, GML/GameMaker Studio, Irrlicht, Ogre, - OpenSceneGraph, openFrameworks, LOVE, NanoRT, Qt3d, SFML, Unreal Engine 4, etc.) +(other frameworks: OpenGLES, FreeGlut, Cinder, Cocos2d-x, SFML, GML/GameMaker Studio, Irrlicht, + Ogre, OpenSceneGraph, openFrameworks, LOVE, NanoRT, Qt3d, SFML, Unreal Engine 4, etc.) (extras: RemoteImGui, ImWindow, imgui_wm, etc.) diff --git a/examples/directx12_example/directx12_example.vcxproj b/examples/directx12_example/directx12_example.vcxproj index 37b7327e..d3962a31 100644 --- a/examples/directx12_example/directx12_example.vcxproj +++ b/examples/directx12_example/directx12_example.vcxproj @@ -21,7 +21,7 @@ {b4cf9797-519d-4afe-a8f4-5141a6b521d3} directx12_example - 10.0.10240.0 + 10.0.16299.0 diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index b0b65d7d..2da3624d 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -1,18 +1,43 @@ // ImGui Win32 + DirectX12 binding -// In this binding, ImTextureID is used to store a 'D3D12_GPU_DESCRIPTOR_HANDLE' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// FIXME: 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)) + +// Implemented features: +// [X] User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. // https://github.com/ocornut/imgui -#include +// CHANGELOG +// (minor and older changes stripped away, please see git history for details) +// 2018-02-22: Merged into master with all Win32 code synchronized to other examples. + +#include "imgui.h" #include "imgui_impl_dx12.h" // DirectX #include #include +// Win32 data +static HWND g_hWnd = 0; +static INT64 g_Time = 0; +static INT64 g_TicksPerSecond = 0; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; + +// DirectX data +static ID3D12Device* g_pd3dDevice = NULL; +static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; +static ID3D10Blob* g_pVertexShaderBlob = NULL; +static ID3D10Blob* g_pPixelShaderBlob = NULL; +static ID3D12RootSignature* g_pRootSignature = NULL; +static ID3D12PipelineState* g_pPipelineState = NULL; +static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; +static ID3D12Resource* g_pFontTextureResource = NULL; +static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; +static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; + struct FrameResources { ID3D12Resource* IB; @@ -20,40 +45,21 @@ struct FrameResources int VertexBufferSize; int IndexBufferSize; }; - -// Data -static INT64 g_Time = 0; -static INT64 g_TicksPerSecond = 0; - -static HWND g_hWnd = 0; -static ID3D12Device* g_pd3dDevice = NULL; -static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; -static ID3D10Blob* g_pVertexShaderBlob = NULL; -static ID3D10Blob* g_pPixelShaderBlob = NULL; -static ID3D12RootSignature* g_pRootSignature = NULL; -static ID3D12PipelineState* g_pPipelineState = NULL; -static DXGI_FORMAT g_RTVFormat = DXGI_FORMAT_UNKNOWN; -static ID3D12Resource* g_pFontTextureResource = NULL; -static D3D12_CPU_DESCRIPTOR_HANDLE g_hFontSrvCpuDescHandle = {}; -static D3D12_GPU_DESCRIPTOR_HANDLE g_hFontSrvGpuDescHandle = {}; - -static FrameResources* g_pFrameResources = NULL; -static UINT g_numFramesInFlight = 0; -static UINT g_frameIndex = UINT_MAX; +static FrameResources* g_pFrameResources = NULL; +static UINT g_numFramesInFlight = 0; +static UINT g_frameIndex = UINT_MAX; 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) -void ImGui_ImplDX12_RenderDrawLists(ImDrawData* draw_data) +// Render function +// (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) +void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data) { - // NOTE: I'm assuming that this only get's called once per frame! If not, - // we can't just re-allocate the IB or VB, we'll have to do a proper - // allocator. + // NOTE: I'm assuming that this only get's called once per frame! + // If not, we can't just re-allocate the IB or VB, we'll have to do a proper allocator. g_frameIndex = g_frameIndex + 1; FrameResources* frameResources = &g_pFrameResources[g_frameIndex % g_numFramesInFlight]; ID3D12Resource* g_pVB = frameResources->VB; @@ -215,49 +221,106 @@ void ImGui_ImplDX12_RenderDrawLists(ImDrawData* draw_data) } } -IMGUI_API LRESULT ImGui_ImplDX12_WndProcHandler(HWND, UINT msg, WPARAM wParam, LPARAM lParam) +static void ImGui_ImplWin32_UpdateMouseCursor() { + ImGuiIO& io = ImGui::GetIO(); + ImGuiMouseCursor imgui_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (imgui_cursor == ImGuiMouseCursor_None) + { + // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor + ::SetCursor(NULL); + } + else + { + // Hardware cursor type + LPTSTR win32_cursor = IDC_ARROW; + switch (imgui_cursor) + { + case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; + case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; + case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; + case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; + case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; + case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; + case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; + } + ::SetCursor(::LoadCursor(NULL, win32_cursor)); + } +} + +// Process Win32 mouse/keyboard inputs. +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinations when dragging mouse outside of our window bounds. +// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui::GetCurrentContext() == NULL) + return 0; + ImGuiIO& io = ImGui::GetIO(); switch (msg) { - case WM_LBUTTONDOWN: - io.MouseDown[0] = true; - return true; + case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: + case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: + case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: + { + int button = 0; + if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) button = 0; + if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) button = 1; + if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) button = 2; + if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL) + ::SetCapture(hwnd); + io.MouseDown[button] = true; + return 0; + } 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_MBUTTONDOWN: - io.MouseDown[2] = true; - return true; case WM_MBUTTONUP: - io.MouseDown[2] = false; - return true; + { + int button = 0; + if (msg == WM_LBUTTONUP) button = 0; + if (msg == WM_RBUTTONUP) button = 1; + if (msg == WM_MBUTTONUP) button = 2; + io.MouseDown[button] = false; + if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd) + ::ReleaseCapture(); + return 0; + } case WM_MOUSEWHEEL: io.MouseWheel += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; - return true; + return 0; + case WM_MOUSEHWHEEL: + io.MouseWheelH += GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? +1.0f : -1.0f; + return 0; case WM_MOUSEMOVE: io.MousePos.x = (signed short)(lParam); io.MousePos.y = (signed short)(lParam >> 16); - return true; + return 0; case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (wParam < 256) io.KeysDown[wParam] = 1; - return true; + return 0; case WM_KEYUP: + case WM_SYSKEYUP: if (wParam < 256) io.KeysDown[wParam] = 0; - return true; + return 0; 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; + case WM_SETCURSOR: + if (LOWORD(lParam) == HTCLIENT) + { + ImGui_ImplWin32_UpdateMouseCursor(); + return 1; + } + return 0; } return 0; } @@ -317,16 +380,14 @@ static void ImGui_ImplDX12_CreateFontsTexture() ID3D12Resource* uploadBuffer = NULL; HRESULT hr = g_pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc, D3D12_RESOURCE_STATE_GENERIC_READ, NULL, IID_PPV_ARGS(&uploadBuffer)); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); void* mapped = NULL; D3D12_RANGE range = { 0, uploadSize }; hr = uploadBuffer->Map(0, &range, &mapped); - assert(SUCCEEDED(hr)); - for (int y = 0; y < height; ++y) - { + IM_ASSERT(SUCCEEDED(hr)); + for (int y = 0; y < height; y++) memcpy((void*) ((uintptr_t) mapped + y * uploadPitch), pixels + y * width * 4, width * 4); - } uploadBuffer->Unmap(0, &range); D3D12_TEXTURE_COPY_LOCATION srcLocation = {}; @@ -353,10 +414,10 @@ static void ImGui_ImplDX12_CreateFontsTexture() ID3D12Fence* fence = NULL; hr = g_pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence)); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); HANDLE event = CreateEvent(0, 0, 0, 0); - assert(event != NULL); + IM_ASSERT(event != NULL); D3D12_COMMAND_QUEUE_DESC queueDesc = {}; queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; @@ -365,25 +426,25 @@ static void ImGui_ImplDX12_CreateFontsTexture() ID3D12CommandQueue* cmdQueue = NULL; hr = g_pd3dDevice->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&cmdQueue)); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); ID3D12CommandAllocator* cmdAlloc = NULL; hr = g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc)); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); ID3D12GraphicsCommandList* cmdList = NULL; hr = g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, NULL, IID_PPV_ARGS(&cmdList)); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); cmdList->CopyTextureRegion(&dstLocation, 0, 0, 0, &srcLocation, NULL); cmdList->ResourceBarrier(1, &barrier); hr = cmdList->Close(); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*) &cmdList); hr = cmdQueue->Signal(fence, 1); - assert(SUCCEEDED(hr)); + IM_ASSERT(SUCCEEDED(hr)); fence->SetEventOnCompletion(1, event); WaitForSingleObject(event, INFINITE); @@ -622,7 +683,7 @@ void ImGui_ImplDX12_InvalidateDeviceObjects() if (g_pRootSignature) { g_pRootSignature->Release(); g_pRootSignature = NULL; } if (g_pPipelineState) { g_pPipelineState->Release(); g_pPipelineState = NULL; } if (g_pFontTextureResource) { g_pFontTextureResource->Release(); g_pFontTextureResource = NULL; ImGui::GetIO().Fonts->TexID = NULL; } // We copied g_pFontTextureView to io.Fonts->TexID so let's clear that as well. - for (UINT i = 0; i < g_numFramesInFlight; ++i) + for (UINT i = 0; i < g_numFramesInFlight; i++) { if (g_pFrameResources[i].IB) { g_pFrameResources[i].IB->Release(); g_pFrameResources[i].IB = NULL; } if (g_pFrameResources[i].VB) { g_pFrameResources[i].VB->Release(); g_pFrameResources[i].VB = NULL; } @@ -644,7 +705,7 @@ bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, g_numFramesInFlight = num_frames_in_flight; g_frameIndex = UINT_MAX; - for (int i = 0; i < num_frames_in_flight; ++i) + for (int i = 0; i < num_frames_in_flight; i++) { g_pFrameResources[i].IB = NULL; g_pFrameResources[i].VB = NULL; @@ -667,8 +728,10 @@ bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, io.KeyMap[ImGuiKey_PageDown] = VK_NEXT; io.KeyMap[ImGuiKey_Home] = VK_HOME; io.KeyMap[ImGuiKey_End] = VK_END; + io.KeyMap[ImGuiKey_Insert] = VK_INSERT; io.KeyMap[ImGuiKey_Delete] = VK_DELETE; io.KeyMap[ImGuiKey_Backspace] = VK_BACK; + io.KeyMap[ImGuiKey_Space] = VK_SPACE; io.KeyMap[ImGuiKey_Enter] = VK_RETURN; io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE; io.KeyMap[ImGuiKey_A] = 'A'; @@ -678,7 +741,6 @@ bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, io.KeyMap[ImGuiKey_Y] = 'Y'; io.KeyMap[ImGuiKey_Z] = 'Z'; - io.RenderDrawListsFn = ImGui_ImplDX12_RenderDrawLists; // Alternatively you can set this to NULL and call ImGui::GetDrawData() after ImGui::Render() to get the same ImDrawData pointer. io.ImeWindowHandle = g_hWnd; return true; @@ -687,7 +749,6 @@ bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, void ImGui_ImplDX12_Shutdown() { ImGui_ImplDX12_InvalidateDeviceObjects(); - ImGui::Shutdown(); delete[] g_pFrameResources; g_pd3dDevice = NULL; g_hWnd = (HWND)0; @@ -737,10 +798,14 @@ void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* command_list) SetCursorPos(pos.x, pos.y); } - // Hide OS mouse cursor if ImGui is drawing it - if (io.MouseDrawCursor) - SetCursor(NULL); + // Update OS mouse cursor with the cursor requested by imgui + ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); + if (g_LastMouseCursor != mouse_cursor) + { + g_LastMouseCursor = mouse_cursor; + ImGui_ImplWin32_UpdateMouseCursor(); + } - // Start the frame + // Start the frame. This call will update the io.WantCaptureMouse, io.WantCaptureKeyboard flag that you can use to dispatch inputs (or not) to your application. ImGui::NewFrame(); } diff --git a/examples/directx12_example/imgui_impl_dx12.h b/examples/directx12_example/imgui_impl_dx12.h index 059d73e1..628bbd49 100644 --- a/examples/directx12_example/imgui_impl_dx12.h +++ b/examples/directx12_example/imgui_impl_dx12.h @@ -1,5 +1,8 @@ // ImGui Win32 + DirectX12 binding -// In this binding, ImTextureID is used to store a 'D3D12_GPU_DESCRIPTOR_HANDLE' texture identifier. Read the FAQ about ImTextureID in imgui.cpp. +// FIXME: 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)) + +// Implemented features: +// [X] User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). @@ -12,22 +15,18 @@ struct ID3D12GraphicsCommandList; struct D3D12_CPU_DESCRIPTOR_HANDLE; struct D3D12_GPU_DESCRIPTOR_HANDLE; -// cmdList is the command list that the implementation will use to render the -// GUI. -// -// Before calling ImGui::Render(), caller must prepare cmdList by resetting it -// and setting the appropriate render target and descriptor heap that contains -// fontSrvCpuDescHandle/fontSrvGpuDescHandle. -// -// fontSrvCpuDescHandle and fontSrvGpuDescHandle are handles to a single SRV -// descriptor to use for the internal font texture. -IMGUI_API bool ImGui_ImplDX12_Init(void* hwnd, int numFramesInFlight, +// cmd_list is the command list that the implementation will use to render imgui draw lists. +// Before calling the render function, caller must prepare cmd_list by resetting it and setting the appropriate +// render target and descriptor heap that contains font_srv_cpu_desc_handle/font_srv_gpu_desc_handle. +// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture. +IMGUI_API bool ImGui_ImplDX12_Init(void* hwnd, int num_frames_in_flight, ID3D12Device* device, DXGI_FORMAT rtv_format, - D3D12_CPU_DESCRIPTOR_HANDLE fontSrvCpuDescHandle, - D3D12_GPU_DESCRIPTOR_HANDLE fontSrvGpuDescHandle); + D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, + D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle); IMGUI_API void ImGui_ImplDX12_Shutdown(); -IMGUI_API void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* cmdList); +IMGUI_API void ImGui_ImplDX12_NewFrame(ID3D12GraphicsCommandList* cmd_list); +IMGUI_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data); // Use if you want to reset your rendering device without losing ImGui state. IMGUI_API void ImGui_ImplDX12_InvalidateDeviceObjects(); @@ -37,5 +36,5 @@ IMGUI_API bool ImGui_ImplDX12_CreateDeviceObjects(); // 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. /* -IMGUI_API LRESULT ImGui_ImplDX12_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +IMGUI_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); */ diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 51b9da4e..7e6d6719 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -1,19 +1,19 @@ -// ImGui - standalone example application for DirectX 11 +// ImGui - standalone example application for DirectX 12 // If you are new to ImGui, see examples/README.txt and documentation at the top of imgui.cpp. +// FIXME: 64-bit only for now! (Because sizeof(ImTextureId) == sizeof(void*)) -#include +#include "imgui.h" #include "imgui_impl_dx12.h" #include #include #include -#define D3D11_CREATE_DEVICE_DEBUG 2 +#define DX12_ENABLE_DEBUG_LAYER 0 struct FrameContext { ID3D12CommandAllocator* CommandAllocator; UINT64 FenceValue; - bool FenceSignalled; }; // Data @@ -29,7 +29,7 @@ static ID3D12CommandQueue* g_pd3dCommandQueue = NULL; static ID3D12GraphicsCommandList* g_pd3dCommandList = NULL; static ID3D12Fence* g_fence = NULL; static HANDLE g_fenceEvent = NULL; -static UINT64 g_fenceLastSignalledValue = 0; +static UINT64 g_fenceLastSignaledValue = 0; static IDXGISwapChain3* g_pSwapChain = NULL; static HANDLE g_hSwapChainWaitableObject = NULL; static ID3D12Resource* g_mainRenderTargetResource[NUM_BACK_BUFFERS] = {}; @@ -37,19 +37,11 @@ static D3D12_CPU_DESCRIPTOR_HANDLE g_mainRenderTargetDescriptor[NUM_BACK_BUFFER void CreateRenderTarget() { - DXGI_SWAP_CHAIN_DESC sd; - g_pSwapChain->GetDesc(&sd); - - // Create the render target ID3D12Resource* pBackBuffer; - D3D12_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 = D3D12_RTV_DIMENSION_TEXTURE2D; - for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) { g_pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer)); - g_pd3dDevice->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, g_mainRenderTargetDescriptor[i]); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, NULL, g_mainRenderTargetDescriptor[i]); g_mainRenderTargetResource[i] = pBackBuffer; } } @@ -60,7 +52,7 @@ void WaitForLastSubmittedFrame() UINT64 fenceValue = frameCtxt->FenceValue; if (fenceValue == 0) - return; // no fence was signalled + return; // No fence was signaled frameCtxt->FenceValue = 0; if (g_fence->GetCompletedValue() >= fenceValue) @@ -75,15 +67,12 @@ FrameContext* WaitForNextFrameResources() UINT nextFrameIndex = g_frameIndex + 1; g_frameIndex = nextFrameIndex; - HANDLE waitableObjects[] = { - g_hSwapChainWaitableObject, - NULL, - }; + HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, NULL }; DWORD numWaitableObjects = 1; FrameContext* frameCtxt = &g_frameContext[nextFrameIndex % NUM_FRAMES_IN_FLIGHT]; UINT64 fenceValue = frameCtxt->FenceValue; - if (fenceValue != 0) // means no fence was signalled + if (fenceValue != 0) // means no fence was signaled { frameCtxt->FenceValue = 0; g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent); @@ -125,7 +114,7 @@ void CleanupRenderTarget() { WaitForLastSubmittedFrame(); - for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = NULL; } } @@ -149,11 +138,7 @@ HRESULT CreateDeviceD3D(HWND hWnd) sd.Stereo = FALSE; } - UINT createDeviceFlags = 0; - //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - D3D_FEATURE_LEVEL featureLevel; - featureLevel = D3D_FEATURE_LEVEL_11_0; - if (createDeviceFlags & D3D11_CREATE_DEVICE_DEBUG) + if (DX12_ENABLE_DEBUG_LAYER) { ID3D12Debug* dx12Debug = NULL; if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&dx12Debug)))) @@ -162,6 +147,8 @@ HRESULT CreateDeviceD3D(HWND hWnd) dx12Debug->Release(); } } + + D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; if (D3D12CreateDevice(NULL, featureLevel, IID_PPV_ARGS(&g_pd3dDevice)) != S_OK) return E_FAIL; @@ -176,7 +163,8 @@ HRESULT CreateDeviceD3D(HWND hWnd) SIZE_T rtvDescriptorSize = g_pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = g_pd3dRtvDescHeap->GetCPUDescriptorHandleForHeapStart(); - for (UINT i = 0; i < NUM_BACK_BUFFERS; ++i) { + for (UINT i = 0; i < NUM_BACK_BUFFERS; i++) + { g_mainRenderTargetDescriptor[i] = rtvHandle; rtvHandle.ptr += rtvDescriptorSize; } @@ -200,11 +188,9 @@ HRESULT CreateDeviceD3D(HWND hWnd) return E_FAIL; } - for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; ++i) - { + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) if (g_pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&g_frameContext[i].CommandAllocator)) != S_OK) return E_FAIL; - } if (g_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, g_frameContext[0].CommandAllocator, NULL, IID_PPV_ARGS(&g_pd3dCommandList)) != S_OK || g_pd3dCommandList->Close() != S_OK) @@ -240,7 +226,7 @@ void CleanupDeviceD3D() CleanupRenderTarget(); if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = NULL; } if (g_hSwapChainWaitableObject != NULL) { CloseHandle(g_hSwapChainWaitableObject); } - for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; ++i) + for (UINT i = 0; i < NUM_FRAMES_IN_FLIGHT; i++) if (g_frameContext[i].CommandAllocator) { g_frameContext[i].CommandAllocator->Release(); g_frameContext[i].CommandAllocator = NULL; } if (g_pd3dCommandQueue) { g_pd3dCommandQueue->Release(); g_pd3dCommandQueue = NULL; } if (g_pd3dCommandList) { g_pd3dCommandList->Release(); g_pd3dCommandList = NULL; } @@ -251,10 +237,10 @@ void CleanupDeviceD3D() if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } } -extern LRESULT ImGui_ImplDX12_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - if (ImGui_ImplDX12_WndProcHandler(hWnd, msg, wParam, lParam)) + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; switch (msg) @@ -283,7 +269,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) int main(int, char**) { // Create application window - WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL, _T("ImGui Example"), NULL }; + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, _T("ImGui Example"), NULL }; RegisterClassEx(&wc); HWND hwnd = CreateWindow(_T("ImGui Example"), _T("ImGui DirectX12 Example"), WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, NULL, NULL, wc.hInstance, NULL); @@ -300,30 +286,46 @@ int main(int, char**) UpdateWindow(hwnd); // Setup ImGui binding + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), g_pd3dSrvDescHeap->GetGPUDescriptorHandleForHeapStart()); - // Load Fonts - // (there is a default font, this is only if you want to change it. see extra_fonts/README.txt for more details) - //ImGuiIO& io = ImGui::GetIO(); - //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/Cousine-Regular.ttf", 15.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/DroidSans.ttf", 16.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyClean.ttf", 13.0f); - //io.Fonts->AddFontFromFileTTF("../../extra_fonts/ProggyTiny.ttf", 10.0f); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + // Setup style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsClassic(); - bool show_test_window = true; + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Read 'misc/fonts/README.txt' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != NULL); + + bool show_demo_window = true; bool show_another_window = false; - ImVec4 clear_col = ImColor(114, 144, 154); + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); // Main loop MSG msg; ZeroMemory(&msg, sizeof(msg)); while (msg.message != WM_QUIT) { + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { TranslateMessage(&msg); @@ -332,31 +334,41 @@ int main(int, char**) } ImGui_ImplDX12_NewFrame(g_pd3dCommandList); - // 1. Show a simple window - // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" + // 1. Show a simple window. + // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets automatically appears in a window called "Debug". { static float f = 0.0f; - ImGui::Text("Hello, world!"); - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); - ImGui::ColorEdit3("clear color", (float*)&clear_col); - if (ImGui::Button("Test Window")) show_test_window ^= 1; - if (ImGui::Button("Another Window")) show_another_window ^= 1; + static int counter = 0; + ImGui::Text("Hello, world!"); // Display some text (you can use a format string too) + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our windows open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + if (ImGui::Button("Button")) // Buttons return true when clicked (NB: most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); } - // 2. Show another simple window, this time using an explicit Begin/End pair + // 2. Show another simple window. In most cases you will use an explicit Begin/End pair to name your windows. if (show_another_window) { ImGui::Begin("Another Window", &show_another_window); ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; ImGui::End(); } - // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() - if (show_test_window) + // 3. Show the ImGui demo window. Most of the sample code is in ImGui::ShowDemoWindow(). Read its code to learn more about Dear ImGui! + if (show_demo_window) { - ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call it because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! - ImGui::ShowTestWindow(&show_test_window); + ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiCond_FirstUseEver); // Normally user code doesn't need/want to call this because positions are saved in .ini file anyway. Here we just want to make the demo initial state a bit more friendly! + ImGui::ShowDemoWindow(&show_demo_window); } // Rendering @@ -374,10 +386,11 @@ int main(int, char**) g_pd3dCommandList->Reset(frameCtxt->CommandAllocator, NULL); g_pd3dCommandList->ResourceBarrier(1, &barrier); - g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], (float*)&clear_col, 0, NULL); + g_pd3dCommandList->ClearRenderTargetView(g_mainRenderTargetDescriptor[backBufferIdx], (float*)&clear_color, 0, NULL); g_pd3dCommandList->OMSetRenderTargets(1, &g_mainRenderTargetDescriptor[backBufferIdx], FALSE, NULL); g_pd3dCommandList->SetDescriptorHeaps(1, &g_pd3dSrvDescHeap); ImGui::Render(); + ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData()); barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET; barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT; g_pd3dCommandList->ResourceBarrier(1, &barrier); @@ -388,13 +401,15 @@ int main(int, char**) g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync - auto fenceValue = g_fenceLastSignalledValue + 1; + UINT64 fenceValue = g_fenceLastSignaledValue + 1; g_pd3dCommandQueue->Signal(g_fence, fenceValue); - g_fenceLastSignalledValue = fenceValue; + g_fenceLastSignaledValue = fenceValue; frameCtxt->FenceValue = fenceValue; } ImGui_ImplDX12_Shutdown(); + ImGui::DestroyContext(); + CleanupDeviceD3D(); UnregisterClass(_T("ImGui Example"), wc.hInstance); From 7e24ce0956a2d65df8a0a30661e493ca45276b2d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 23:04:28 +0100 Subject: [PATCH 44/87] Examples: DirectX12: Fixed shutdown issue. (#301) --- examples/directx12_example/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 7e6d6719..6a4b78d8 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -396,7 +396,7 @@ int main(int, char**) g_pd3dCommandList->ResourceBarrier(1, &barrier); g_pd3dCommandList->Close(); - g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*) &g_pd3dCommandList); + g_pd3dCommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&g_pd3dCommandList); g_pSwapChain->Present(1, 0); // Present with vsync //g_pSwapChain->Present(0, 0); // Present without vsync @@ -407,9 +407,9 @@ int main(int, char**) frameCtxt->FenceValue = fenceValue; } + WaitForLastSubmittedFrame(); ImGui_ImplDX12_Shutdown(); ImGui::DestroyContext(); - CleanupDeviceD3D(); UnregisterClass(_T("ImGui Example"), wc.hInstance); From 63be3e7c82630d5ed3a33d1b665d33f08beff8ba Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Feb 2018 23:20:37 +0100 Subject: [PATCH 45/87] Update README.txt --- examples/README.txt | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/README.txt b/examples/README.txt index 13660c31..171c3381 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -13,7 +13,7 @@ TL;DR; - Newcomers, read 'PROGRAMMER GUIDE' in imgui.cpp for notes on how to setup ImGui in your codebase. - If you are using of the backend provided here, so you can copy the imgui_impl_xxx.cpp/h files to your project and use them unmodified. - - To LEARN how the library is setup, you may refer to 'opengl2_example' because is the simplest one to read. + - To LEARN how to setup imgui, you may refer to 'opengl2_example' because is the simplest one to read. However, do NOT USE the 'opengl2_example' if your code is using any modern GL3+ calls. Mixing old fixed-pipeline OpenGL2 and modern OpenGL3+ is going to make everything more complicated. Read comments below for details. If you are not sure, in doubt, use 'opengl3_example'. @@ -53,15 +53,15 @@ opengl2_example/ **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** **Prefer using the code in the opengl3_example/ folder** GLFW + OpenGL example (legacy, fixed pipeline). - This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. - If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more - complicated, will require your code to reset every single OpenGL attributes to their initial state, and might - confuse your GPU driver. + This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter. + If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to + make things more complicated, will require your code to several OpenGL attributes to their initial state, + and might confuse your GPU driver. opengl3_example/ GLFW + OpenGL example (programmable pipeline, binding modern functions with GL3W). This uses more modern OpenGL calls and custom shaders. - Prefer using that if you are using modern OpenGL in your application (anything with shaders, vbo, vao, etc.). + Prefer using that if you are using modern OpenGL in your application (anything with shaders). directx9_example/ DirectX9 example, Windows only. @@ -76,7 +76,7 @@ directx11_example/ directx12_example/ DirectX12 example, Windows only. - This is quite long and tedious, because: DirectX12. + This is quite longer and tedious, because: DirectX12. apple_example/ OSX & iOS example. @@ -87,15 +87,15 @@ sdl_opengl2_example/ **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** **Prefer using the code in the sdl_opengl3_example/ folder** SDL2 + OpenGL example (legacy, fixed pipeline). - This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter to read. - If your code is using GL3+ context or any semi modern OpenGL calls, using this is likely to make everything more - complicated, will require your code to reset every single OpenGL attributes to their initial state, and might - confuse your GPU driver. + This code is mostly provided as a reference to learn how ImGui integration works, because it is shorter. + If your code is using GL3+ context or any semi modern OpenGL calls, using this renderer is likely to + make things more complicated, will require your code to several OpenGL attributes to their initial state, + and might confuse your GPU driver. sdl_opengl3_example/ SDL2 + OpenGL3 example. This uses more modern OpenGL calls and custom shaders. - Prefer using that if you are using modern OpenGL in your application (anything with shaders, vbo, vao, etc.). + Prefer using that if you are using modern OpenGL in your application (anything with shaders). allegro5_example/ Allegro 5 example. @@ -104,7 +104,5 @@ marmalade_example/ Marmalade example using IwGx vulkan_example/ - Vulkan example. - This is quite long and tedious, because: Vulkan. - -TODO: Apple, SDL GL2/GL3, Allegro, Marmalade, Vulkan examples do not honor the io.WantMoveMouse flag. + Vulkan example. + This is quite longer and tedious, because: Vulkan. From 288351a8019cea3dcbbc8d42d55768b5e80d39bf Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 00:00:43 +0100 Subject: [PATCH 46/87] Examples: DirectX12: Tweaked assertion to more accurately represent what it wants to say. (#301) --- examples/directx12_example/imgui_impl_dx12.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index 2da3624d..beb48b9c 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -471,7 +471,7 @@ static void ImGui_ImplDX12_CreateFontsTexture() } // Store our identifier - static_assert(sizeof(void*) >= sizeof(g_hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID"); + static_assert(sizeof(ImTextureID) >= sizeof(g_hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID"); io.Fonts->TexID = (void *)g_hFontSrvGpuDescHandle.ptr; } From 79969931e6a016f0d733732edaf2bce5c8d83197 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 00:01:34 +0100 Subject: [PATCH 47/87] ImDrawList: PushTextureID(): Removed unnecessary param by reference. --- imgui.h | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 9b051356..2f874c6f 100644 --- a/imgui.h +++ b/imgui.h @@ -1505,7 +1505,7 @@ struct ImDrawList IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) IMGUI_API void PushClipRectFullScreen(); IMGUI_API void PopClipRect(); - IMGUI_API void PushTextureID(const ImTextureID& texture_id); + IMGUI_API void PushTextureID(ImTextureID texture_id); IMGUI_API void PopTextureID(); inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); } inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); } diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 118acabc..7a38af8b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -450,7 +450,7 @@ void ImDrawList::PopClipRect() UpdateClipRect(); } -void ImDrawList::PushTextureID(const ImTextureID& texture_id) +void ImDrawList::PushTextureID(ImTextureID texture_id) { _TextureIdStack.push_back(texture_id); UpdateTextureID(); From 6662fe7b185aab29aa4b2c5e08784e9da75bc700 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 11:07:51 +0100 Subject: [PATCH 48/87] stb_truetype: Fixed unused variable warnings for configuration where asserts are disabled. (#1642) --- stb_truetype.h | 1 + 1 file changed, 1 insertion(+) diff --git a/stb_truetype.h b/stb_truetype.h index a08e929f..f65deb50 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -2463,6 +2463,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i if (valueFormat2 != 0) return 0; STBTT_assert(coverageIndex < pairSetCount); + STBTT__NOTUSED(pairSetCount); needle=glyph2; r=pairValueCount-1; From d749d49903fb0eb56b08961d989ed90a9d97c28b Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 12:37:49 +0100 Subject: [PATCH 49/87] Examples: OpenGL3: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. (#1217) --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 32 ++++++++-------- .../imgui_impl_sdl_gl3.cpp | 38 ++++++++++--------- 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 72cc4bf6..85c76684 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. @@ -54,7 +55,7 @@ static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; +static unsigned int g_VboHandle = 0, g_ElementsHandle = 0; // OpenGL3 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -113,9 +114,22 @@ void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data) glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); glBindSampler(0, 0); // Rely on combined texture/sampler state. + // Recreate the VAO every time + // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) + GLuint vao_handle = 0; + glGenVertexArrays(1, &vao_handle); + glBindVertexArray(vao_handle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + + // Draw for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -289,17 +303,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_ElementsHandle); - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); - ImGui_ImplGlfwGL3_CreateFontsTexture(); // Restore modified GL state @@ -312,10 +315,9 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() void ImGui_ImplGlfwGL3_InvalidateDeviceObjects() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + g_VboHandle = g_ElementsHandle = 0; if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); if (g_VertHandle) glDeleteShader(g_VertHandle); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 4b870ade..2434ceac 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. @@ -38,15 +39,17 @@ #include #include // This example is using gl3w to access OpenGL functions (because it is small). You may use glew/glad/glLoadGen/etc. whatever already works for you. -// Data +// SDL data static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; + +// OpenGL data static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; static int g_AttribLocationPosition = 0, g_AttribLocationUV = 0, g_AttribLocationColor = 0; -static unsigned int g_VboHandle = 0, g_VaoHandle = 0, g_ElementsHandle = 0; -static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static unsigned int g_VboHandle = 0,g_ElementsHandle = 0; // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) // Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly, in order to be able to run within any OpenGL engine that doesn't do so. @@ -105,9 +108,22 @@ void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data) glUseProgram(g_ShaderHandle); glUniform1i(g_AttribLocationTex, 0); glUniformMatrix4fv(g_AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - glBindVertexArray(g_VaoHandle); glBindSampler(0, 0); // Rely on combined texture/sampler state. + // Recreate the VAO every time + // (This is to easily allow multiple GL contexts. VAO are not shared among GL contexts, and we don't track creation/deletion of windows so we don't have an obvious key to use to cache them.) + GLuint vao_handle = 0; + glGenVertexArrays(1, &vao_handle); + glBindVertexArray(vao_handle); + glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); + glEnableVertexAttribArray(g_AttribLocationPosition); + glEnableVertexAttribArray(g_AttribLocationUV); + glEnableVertexAttribArray(g_AttribLocationColor); + glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); + glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); + glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); + + // Draw for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* cmd_list = draw_data->CmdLists[n]; @@ -289,17 +305,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glGenBuffers(1, &g_VboHandle); glGenBuffers(1, &g_ElementsHandle); - glGenVertexArrays(1, &g_VaoHandle); - glBindVertexArray(g_VaoHandle); - glBindBuffer(GL_ARRAY_BUFFER, g_VboHandle); - glEnableVertexAttribArray(g_AttribLocationPosition); - glEnableVertexAttribArray(g_AttribLocationUV); - glEnableVertexAttribArray(g_AttribLocationColor); - - glVertexAttribPointer(g_AttribLocationPosition, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, pos)); - glVertexAttribPointer(g_AttribLocationUV, 2, GL_FLOAT, GL_FALSE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, uv)); - glVertexAttribPointer(g_AttribLocationColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)IM_OFFSETOF(ImDrawVert, col)); - ImGui_ImplSdlGL3_CreateFontsTexture(); // Restore modified GL state @@ -312,10 +317,9 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() void ImGui_ImplSdlGL3_InvalidateDeviceObjects() { - if (g_VaoHandle) glDeleteVertexArrays(1, &g_VaoHandle); if (g_VboHandle) glDeleteBuffers(1, &g_VboHandle); if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle); - g_VaoHandle = g_VboHandle = g_ElementsHandle = 0; + g_VboHandle = g_ElementsHandle = 0; if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle); if (g_VertHandle) glDeleteShader(g_VertHandle); From d7f97922b883aec0c873e0e405c46b154d382120 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Feb 2018 22:46:14 +0100 Subject: [PATCH 50/87] Examples: Fix d749d49903fb0eb56b08961d989ed90a9d97c28b missing the deletion code. (#1217) --- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 1 + examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 85c76684..ce8030b1 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -157,6 +157,7 @@ void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data) idx_buffer_offset += pcmd->ElemCount; } } + glDeleteVertexArrays(1, &vao_handle); // Restore modified GL state glUseProgram(last_program); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index 2434ceac..d5bd364c 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -151,6 +151,7 @@ void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data) idx_buffer_offset += pcmd->ElemCount; } } + glDeleteVertexArrays(1, &vao_handle); // Restore modified GL state glUseProgram(last_program); From 403b2d7d59f84ec0e6abfd247b762007dd5dbc54 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 25 Feb 2018 13:02:25 +0100 Subject: [PATCH 51/87] ImDrawList: Better looking non-AA rectangle (lower-right corner and rounding). (#1646) --- imgui_draw.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7a38af8b..9ba63056 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -982,7 +982,10 @@ void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float roun { if ((col & IM_COL32_A_MASK) == 0) return; - PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners_flags); + if (Flags & ImDrawListFlags_AntiAliasedLines) + PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.50f,0.50f), rounding, rounding_corners_flags); + else + PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.49f,0.49f), rounding, rounding_corners_flags); // Better looking lower-right corner and rounded non-AA shapes. PathStroke(col, true, thickness); } From 27667fc0351025f0de6936767ed9a421f94a9d50 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 25 Feb 2018 13:45:47 +0100 Subject: [PATCH 52/87] TreeNode: Renamed Beta ImGuiTreeNodeFlags_NavCloseFromChild to ImGuiTreeNodeFlags_NavLeftJumpsBackHere. (#1079) --- imgui.cpp | 10 +++++----- imgui.h | 2 +- imgui_internal.h | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5d4c87c1..7475120b 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6060,7 +6060,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->DC.TextWrapPosStack.resize(0); window->DC.ColumnsSet = NULL; window->DC.TreeDepth = 0; - window->DC.TreeDepthMayCloseOnPop = 0x00; + window->DC.TreeDepthMayJumpToParentOnPop = 0x00; window->DC.StateStorage = &window->StateStorage; window->DC.GroupStack.resize(0); window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user); @@ -8020,8 +8020,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child. // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). // This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero. - if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavCloseFromChild) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) - window->DC.TreeDepthMayCloseOnPop |= (1 << window->DC.TreeDepth); + if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavLeftJumpsBackHere) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + window->DC.TreeDepthMayJumpToParentOnPop |= (1 << window->DC.TreeDepth); bool item_add = ItemAdd(interact_bb, id); window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; @@ -12689,12 +12689,12 @@ void ImGui::TreePop() window->DC.TreeDepth--; if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) - if (g.NavIdIsAlive && (window->DC.TreeDepthMayCloseOnPop & (1 << window->DC.TreeDepth))) + if (g.NavIdIsAlive && (window->DC.TreeDepthMayJumpToParentOnPop & (1 << window->DC.TreeDepth))) { SetNavID(window->IDStack.back(), g.NavLayer); NavMoveRequestCancel(); } - window->DC.TreeDepthMayCloseOnPop &= (1 << window->DC.TreeDepth) - 1; + window->DC.TreeDepthMayJumpToParentOnPop &= (1 << window->DC.TreeDepth) - 1; PopID(); } diff --git a/imgui.h b/imgui.h index 2f874c6f..bd63a2b0 100644 --- a/imgui.h +++ b/imgui.h @@ -611,7 +611,7 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible - ImGuiTreeNodeFlags_NavCloseFromChild = 1 << 13, // (WIP) Nav: left direction may close this TreeNode() when focusing on any child (items submitted between TreeNode and TreePop) + ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 13, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog // Obsolete names (will be removed) diff --git a/imgui_internal.h b/imgui_internal.h index c2c05550..221e5d46 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -834,7 +834,7 @@ struct IMGUI_API ImGuiDrawContext float PrevLineTextBaseOffset; float LogLinePosY; int TreeDepth; - ImU32 TreeDepthMayCloseOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 + ImU32 TreeDepthMayJumpToParentOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 ImGuiID LastItemId; ImGuiItemStatusFlags LastItemStatusFlags; ImRect LastItemRect; // Interaction rect @@ -874,7 +874,7 @@ struct IMGUI_API ImGuiDrawContext CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; LogLinePosY = -1.0f; TreeDepth = 0; - TreeDepthMayCloseOnPop = 0x00; + TreeDepthMayJumpToParentOnPop = 0x00; LastItemId = 0; LastItemStatusFlags = 0; LastItemRect = LastItemDisplayRect = ImRect(); From 133f06d658763e4e65361881e01a9fb0756b262a Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 24 Feb 2018 16:56:15 +0100 Subject: [PATCH 53/87] Changelog: Added Changelog with info from 1.48 to 1.53. Haven't added 1.53..current yet. --- CHANGELOG.txt | 582 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 582 insertions(+) create mode 100644 CHANGELOG.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 00000000..fd2f5759 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,582 @@ +dear imgui +CHANGELOG + +----------------------------------------------------------------------- + +This document holds the programmer changelog that we also use in release notes. +We generally fold multiple commits pertaining to the same topic as a single entry and simplify a few things. + +Release notes: (with links and screenshots) + https://github.com/ocornut/imgui/releases + +Changes to the examples/bindings are included within the individual .cpp files in examples. + +Individual commits: + https://github.com/ocornut/imgui/commits/master + +Report issues, ask questions: + https://github.com/ocornut/imgui/issues + +----------------------------------------------------------------------- + +WHEN TO UPDATE? + +It is generally safe to sync to the latest commit in master. The library is fairly stable and regressions tends to be fixed fast when reported. +Keeping your copy of dear imgui updated once in a while is recommended. + +HOW TO UPDATE? + +- Overwrite every file except imconfig.h (if you have modified it). +- You may also locally branch to modify imconfig.h and merge latest into your branch. +- Read the `Breaking Changes` section (in imgui.cpp or here in the Changelog). +- If you have a problem with a missing function/symbols, search for its name in the code, there will likely be a comment about it. +- If you are dropping this repository in your codebase, please leave the demo and text files in there, they will be useful. +- You may diff your previous Changelog with the one you just copied and read that diff. +- You may enable `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in imconfig.h to forcefully disable legacy names and symbols. Doing it every once in a while is a good way to make sure you are not using obsolete symbols. Dear ImGui is in active development API updates have a little more frequent lately. They are carefully documented and should not affect all users. +- Please report any issue! + +----------------------------------------------------------------------- + +VERSION 1.60 WIP (Latest, currently in development) + + + +----------------------------------------------------------------------- + +VERSION 1.53 (Released 2017-12-25) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.53 + +Breaking Changes: + +- Renamed the emblematic `ShowTestWindow()` function to `ShowDemoWindow()`. Kept redirection function (will obsolete). +- Renamed `GetItemsLineHeightWithSpacing()` to `GetFrameHeightWithSpacing()` for consistency. Kept redirection function (will obsolete). +- Renamed `ImGuiTreeNodeFlags_AllowOverlapMode` flag to `ImGuiTreeNodeFlags_AllowItemOverlap`. Kept redirection enum (will obsolete). +- Obsoleted `IsRootWindowFocused()` in favor of using `IsWindowFocused(ImGuiFocusedFlags_RootWindow)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `IsRootWindowOrAnyChildFocused()` in favor of using `IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `IsRootWindowOrAnyChildHovered()` in favor of using `IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows)`. Kept redirection function (will obsolete). (#1382) +- Obsoleted `SetNextWindowContentWidth() in favor of using `SetNextWindowContentSize()`. Kept redirection function (will obsolete). +- Renamed `ImGuiTextBuffer::append()` helper to `appendf()`, and `appendv()` to `appendfv()` for consistency. If you copied the 'Log' demo in your code, it uses appendv() so that needs to be renamed. +- ImDrawList: Removed 'bool anti_aliased = true' final parameter of `ImDrawList::AddPolyline()` and `ImDrawList::AddConvexPolyFilled()`. Prefer manipulating ImDrawList::Flags if you need to toggle them during the frame. +- Style, ImDrawList: Renamed `style.AntiAliasedShapes` to `style.AntiAliasedFill` for consistency and as a way to explicitly break code that manipulate those flag at runtime. You can now manipulate ImDrawList::Flags. +- Style, Begin: Removed `ImGuiWindowFlags_ShowBorders` window flag. Borders are now fully set up in the ImGuiStyle structure (see e.g. `style.FrameBorderSize`, `style.WindowBorderSize`). Use `ImGui::ShowStyleEditor()` to look them up. + Please note that the style system will keep evolving (hopefully stabilizing in Q1 2018), and so custom styles will probably subtly break over time. + It is recommended that you use the `StyleColorsClassic()`, `StyleColorsDark()`, `StyleColorsLight()` functions. Also see `ShowStyleSelector()`. +- Style: Removed `ImGuiCol_ComboBg` in favor of combo boxes using `ImGuiCol_PopupBg` for consistency. Combo are normal popups. +- Style: Renamed `ImGuiCol_ChildWindowBg` to `ImGuiCol_ChildBg`. +- Style: Renamed `style.ChildWindowRounding` to `style.ChildRounding`, `ImGuiStyleVar_ChildWindowRounding` to `ImGuiStyleVar_ChildRounding`. +- Removed obsolete redirection functions: SetScrollPosHere() - marked obsolete in v1.42, July 2015. +- Removed obsolete redirection functions: GetWindowFont(), GetWindowFontSize() - marked obsolete in v1.48, March 2016. + +Other Changes: + +- Added `io.OptCursorBlink` option to allow disabling cursor blinking. (#1427) +- Added `GetOverlayDrawList()` helper to quickly get access to a ImDrawList that will be rendered in front of every windows. +- Added `GetFrameHeight()` helper which returns `(FontSize + style.FramePadding.y * 2)`. +- DragDrop: Added Beta API to easily use drag and drop patterns between imgui widgets. + - Setup a source on a widget with `BeginDragDropSource()`, `SetDragDropPayload()`, `EndDragDropSource()` functions. + - Receive data with `BeginDragDropTarget()`, `AcceptDragDropPayload()`, `EndDragDropTarget()`. + - See ImGuiDragDropFlags for various options. + - The ColorEdit4() and ColorButton() widgets now support Drag and Drop. + - The API is tagged as Beta as it still may be subject to small changes. +- DragDrop: When drag and drop is active, tree nodes and collapsing header can be opened by hovering on them for 0.7 seconds. +- Renamed io.OSXBehaviors to io.OptMacOSXBehaviors. Should not affect users as the compile-time default is usually enough. (#473, #650) +- Style: Added StyleColorsDark() style. (#707) [@dougbinks] +- Style: Added StyleColorsLight() style. Best used with frame borders + thicker font than the default font. (#707) +- Style: Added style.PopupRounding setting. (#1112) +- Style: Added style.FrameBorderSize, style.WindowBorderSize. Removed ImGuiWindowFlags_ShowBorders window flag! Borders are now fully set up in the ImGuiStyle structure. Use ImGui::ShowStyleEditor() to look them up. (#707, fix #819, #1031) +- Style: Various small changes to the classic style (most noticeably, buttons are now using blue shades). (#707) +- Style: Renamed ImGuiCol_ChildWindowBg to ImGuiCol_ChildBg. +- Style: Renamed style.ChildWindowRounding to style.ChildRounding, ImGuiStyleVar_ChildWindowRounding to ImGuiStyleVar_ChildRounding. +- Style: Removed ImGuiCol_ComboBg in favor of combo boxes using ImGuiCol_PopupBg for consistency. (#707) +- Style: Made the ScaleAllSizes() helper rounds down every values so they are aligned on integers. +- Focus: Added SetItemDefaultFocus(), which in the current (master) branch behave the same as doing `if (IsWindowAppearing()) SetScrollHere()`. + In the navigation branch this will also set the default focus. Prefer using this when creating combo boxes with `BeginCombo()` so your code will be forward-compatible with gamepad/keyboard navigation features. (#787) +- Combo: Popup grows horizontally to accomodate for contents that is larger then the parent combo button. +- Combo: Added BeginCombo()/EndCombo() API which allows use to submit content of any form and manage your selection state without relying on indices. +- Combo: Added ImGuiComboFlags_PopupAlignLeft flag to BeginCombo() to prioritize keeping the popup on the left side (for small-button-looking combos). +- Combo: Added ImGuiComboFlags_HeightSmall, ImGuiComboFlags_HeightLarge, ImGuiComboFlags_HeightLargest to easily provide desired popup height. +- Combo: You can use SetNextWindowSizeConstraints() before BeginCombo() to specify specific popup width/height constraints. +- Combo: Offset popup position by border size so that a double border isn't so visible. (#707) +- Combo: Recycling windows by using a stack number instead of a unique id, wasting less memory (like menus do). +- InputText: Added ImGuiInputTextFlags_NoUndoRedo flag. (#1506, #1508) [@ibachar] +- Window: Fixed auto-resize allocating too much space for scrollbar when SizeContents is bigger than maximum window size (fixes c0547d3). (#1417) +- Window: Child windows with MenuBar use regular WindowPadding.y so layout look consistent as child or as a regular window. +- Window: Begin(): Fixed appending into a child window with a second Begin() from a different window stack querying the wrong window for the window->Collapsed test. +- Window: Calling IsItemActive(), IsItemHovered() etc. after a call to Begin() provides item data for the title bar, so you can easily test if the title bar is being hovered, etc. (#823) +- Window: Made it possible to use SetNextWindowPos() on a child window. +- Window: Fixed a one frame glitch. When an appearing window claimed the focus themselves, the title bar wouldn't use the focused color for one frame. +- Window: Added ImGuiWindowFlags_ResizeFromAnySide flag to resize from any borders or from the lower-left corner of a window. This requires your backend to honor GetMouseCursor() requests for full usability. (#822) +- Window: Sizing fixes when useing SetNextWindowSize() on individual axises. +- Window: Made mouse wheel scrolling accomodate better to windows that are smaller than the scroll step. +- Window: SetNextWindowContentSize() adjust for the size of decorations (title bar/menu bar), but _not_ for borders are we consistently make borders not affect layout. + If you need a non-child window of an exact size with border enabled but zero window padding, you'll need to accodomate for the border size yourself. +- Window: Using the ImGuiWindowFlags_NoScrollWithMouse flag on a child window forwards the mouse wheel event to the parent window, unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set. (#1380, #1502) +- Window: Active Modal window always set the WantCaptureKeyboard flag. (#744) +- Window: Moving window doesn't use accumulating MouseDelta so straying out of imgui boundaries keeps moved imgui window at the same cursor-relative position. +- IsWindowFocused(): Added ImGuiFocusedFlags_ChildWindows flag to include child windows in the focused test. (#1382). +- IsWindowFocused(): Added ImGuiFocusedFlags_RootWindow flag to start focused test from the root (top-most) window. Obsolete IsRootWindowFocused(). (#1382) +- IsWindowHovered(): Added ImGuiHoveredFlags_ChildWindows flag to include child windows in the hovered test. (#1382). +- IsWindowHovered(): Added ImGuiHoveredFlags_RootWindow flag to start hovered test from the root (top-most) window. The combination of both flags obsoletes IsRootWindowOrAnyChildHovered(). (#1382) +- IsWindowHovered(): Fixed return value when an item is active to use the same logic as IsItemHovered(). (#1382, #1404) +- IsWindowHovered(): Always return true when current window is being moved. (#1382) +- Scrollbar: Fixed issues with vertical scrollbar flickering/appearing, typically when manually resizing and using a pattern of filling available height (e.g. full sized BeginChild). +- Scrollbar: Minor graphical fix for when scrollbar don't have enough visible space to display the full grab. +- Scrolling: Fixed padding and scrolling asymetry where lower/right sides of a window wouldn't use WindowPadding properly + causing minor scrolling glitches. +- Tree: TreePush with zero arguments was ambiguous. Resolved by making it call TreePush(const void*). [@JasonWilkins] +- Tree: Renamed ImGuiTreeNodeFlags_AllowOverlapMode to ImGuiTreeNodeFlags_AllowItemOverlap. (#600, #1330) +- MenuBar: Fixed minor rendering issues on the right size when resizing a window very small and using rounded window corners. +- MenuBar: better software clipping to handle small windows, in particular child window don't have minimum constraints so we need to render clipped menus better. +- BeginMenu(): Tweaked the Arrow/Triangle displayed on child menu items. +- Columns: Clipping columns borders on Y axis on CPU because some Linux GPU drivers appears to be unhappy with triangle spanning large regions. (#125) +- Columns: Added ImGuiColumnsFlags_GrowParentContentsSize to internal API to restore old content sizes behavior (may be obsolete). (#1444, #125) +- Columns: Columns width is no longer lost when dragging a column to the right side of the window, until releasing the mouse button you have a chance to save them. (#1499, #125). [@ggtucker] +- Columns: Fixed dragging when using a same of columns multiple times in the frame. (#125) +- Indent(), Unindent(): Allow passing negative values. +- ColorEdit4(): Made IsItemActive() return true when picker popup is active. (#1489) +- ColorEdit4(): Tweaked tooltip so that the color button aligns more correctly with text. +- ColorEdit4(): Support drag and drop. Color buttons can be used as drag sources, and ColorEdit widgets as drag targets. (#143) +- ColorPicker4(): Fixed continously returning true when holding mouse button on the sat/value/alpha locations. We only return true on value change. (#1489) +- NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger). +- NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423) +- ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch. +- ImFont: Added GetDebugName() helper. +- ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect] +- ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. +- ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd] +- ImDrawList: Refactored to make ImDrawList independant of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some. +- ImDrawList: Exposed ImDrawCornerFlags, replaced occurences of ~0 with an explicit ImDrawCornerFlags_All. NB: Inversed BotLeft (prev 1<<3, now 1<<2) and BotRight (prev 1<<2, now 1<<3). +- ImVector: Added ImVector::push_front() helper. +- ImVector: Added ImVector::contains() helper. +- ImVector: insert() uses grow_capacity() instead of using grow policy inconsistent with push_back(). +- Internals: Remove requirement to define IMGUI_DEFINE_PLACEMENT_NEW to use the IM_PLACEMENT_NEW macro. (#1103) +- Internals: ButtonBehavior: Fixed ImGuiButtonFlags_NoHoldingActiveID flag from incorrectly setting the ActiveIdClickOffset field. + This had no known effect within imgui code but could have affected custom drag and drop patterns. And it is more correct this way! (#1418) +- Internals: ButtonBehavior: Fixed ImGuiButtonFlags_AllowOverlapMode to avoid temporarily activating widgets on click before they have been correctly double-hovered. (#319, #600) +- Internals: Added SplitterBehavior() helper. (#319) +- Internals: Added IM_NEW(), IM_DELETE() helpers. (#484, #504, #1517) +- Internals: Basic refactor of the settings API which now allows external elements to be loaded/saved. +- Demo: Added ShowFontSelector() showing loaded fonts. +- Demo: Added ShowStyleSelector() to select among default styles. (#707) +- Demo: Renamed the emblematic ShowTestWindow() function to ShowDemoWindow(). +- Demo: Style Editor: Added a "Simplified settings" sections with checkboxes for border size and frame rounding. (#707, #1019) +- Demo: Style Editor: Added combo box to select stock styles and select current font when multiple are loaded. (#707) +- Demo: Style Editor: Using local storage so Save/Revert button makes more sense without code passing its storage. Aadded horizontal scroll bar. Fixed Save/Revert button to be always accessible. (#1211) +- Demo: Console: Fixed context menu issue. (#1404) +- Demo: Console: Fixed incorrect positioning which was hidden by a minor scroll issue (this would affect people who copied the Console code as is). +- Demo: Constrained Resize: Added more test cases. (#1417) +- Demo: Custom Rendering: Fixed clipping rectangle extruding out of parent window. +- Demo: Layout: Removed unnecessary and misleading BeginChild/EndChild calls. +- Demo: The "Color Picker with Palette" demo supports drag and drop. (#143) +- Demo: Display better mouse cursor info for debugging backends. +- Demo: Stopped using rand() function in demo code. +- Examples: Added a handful of extra comments (about fonts, third-party libraries used in the examples, etc.). +- Examples: DirectX9: Handle loss of D3D9 device (D3DERR_DEVICELOST). (#1464) +- Examples: Added null_example/ which is helpful for quick testing on multiple compilers/settings without relying on graphics library. +- Fix for using alloca() in "Clang with Microsoft Codechain" mode. +- Various fixes, optimizations, comments. + +----------------------------------------------------------------------- + +VERSION 1.52 (2017-10-27) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.52 + +Breaking Changes: + +- IO: `io.MousePos` needs to be set to ImVec2(-FLT_MAX,-FLT_MAX) when mouse is unavailable/missing, instead of ImVec2(-1,-1) as previously) This is needed so we can clear `io.MouseDelta` field when the mouse is made available again. +- Renamed `AlignFirstTextHeightToWidgets()` to `AlignTextToFramePadding()`. Kept inline redirection function (will obsolete). +- Obsoleted the legacy 5 parameters version of Begin(). Please avoid using it. If you need a transparent window background, uses `PushStyleColor()`. The old size parameter there was also misleading and equivalent to calling `SetNextWindowSize(size, ImGuiCond_FirstTimeEver)`. Kept inline redirection function (will obsolete). +- Obsoleted `IsItemHoveredRect()`, `IsMouseHoveringWindow()` in favor of using the newly introduced flags of `IsItemHovered()` and `IsWindowHovered()`. Kept inline redirection function (will obsolete). (#1382) +- Removed `IsItemRectHovered()`, `IsWindowRectHovered()` recently introduced in 1.51 which were merely the more consistent/correct names for the above functions which are now obsolete anyway. (#1382) +- Changed `IsWindowHovered()` default parameters behavior to return false if an item is active in another window (e.g. click-dragging item from another window to this window). You can use the newly introduced IsWindowHovered() flags to requests this specific behavior if you need it. (#1382) +- Renamed imconfig.h's `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCS` to `IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS`/`IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS` for consistency. + +Other Changes: + +- ProgressBar: fixed rendering when straddling rounded area. (#1296) +- SliderFloat, DragFloat: Using scientific notation e.g. "%.1e" in the displayed format string doesn't mistakenly trigger rounding of the value. [@MomentsInGraphics] +- Combo, InputFloat, InputInt: Made the small button on the right side align properly with the equivalent colored button of ColorEdit4(). +- IO: Tweaked logic for `io.WantCaptureMouse` so it now outputs false when e.g. hovering over void while an InputText() is active. (#621) [@pdoane] +- IO: Fixed `io.WantTextInput` from mistakenly outputting true when an activated Drag or Slider was previously turned into an InputText(). (#1317) +- Misc: Added flags to `IsItemHovered()`, `IsWindowHovered()` to access advanced hovering-test behavior. Generally useful for popups and drag'n drop behaviors: (relates to ~#439, #1013, #143, #925) + - `ImGuiHoveredFlags_AllowWhenBlockedByPopup` + - `ImGuiHoveredFlags_AllowWhenBlockedByActiveItem` + - `ImGuiHoveredFlags_AllowWhenOverlapped` + - `ImGuiHoveredFlags_RectOnly` +- Input: Added `IsMousePosValid()` helper. +- Input: Added `GetKeyPressedAmount()` to easily measure press count when the repeat rate is faster than the frame rate. +- Input/Focus: Disabled TAB and Shift+TAB when CTRL key is held. +- Checkbox: Now rendering a tick mark instead of a full square. +- ColorEdit4: Added "Copy as..." option in context menu. (#346) +- ColorPicker: Improved ColorPicker hue wheel color interpolation. (#1313) [@thevaber] +- ColorButton: Reduced bordering artefact that would be particularly visible with an opaque Col_FrameBg and FrameRounding enabled. +- ColorButton: Fixed rendering color button with a checkerboard if the transparency comes from the global style.Alpha and not from the actual source color. +- TreeNode: Added `ImGuiTreeNodeFlags_FramePadding` flag to conveniently create a tree node with full padding at the beginning of a line, without having to call `AlignTextToFramePadding()`. +- Trees: Fixed calling `SetNextTreeNodeOpen()` on a collapsed window leaking to the first tree node item of the next frame. +- Layout: Horizontal layout is automatically enforced in a menu bar, so you can use non-MenuItem elements without calling SameLine(). +- Separator: Output a vertical separator when used inside a menu bar (or in general when horizontal layout is active, but that isn't exposed yet!). +- Windows: Added `IsWindowAppearing()` helper (helpful e.g. as a condition before initializing some of your own things.). +- Windows: Fixed title bar color of top-most window under a modal window. +- Windows: Fixed not being able to move a window by clicking on one of its child window. (#1337, #635) +- Windows: Fixed `Begin()` auto-fit calculation code that predict the presence of a scrollbar so it works better when window size constraints are used. +- Windows: Fixed calling `Begin()` more than once per frame setting `window_just_activated_by_user` which in turn would set enable the Appearing condition for that frame. +- Windows: The implicit "Debug" window now uses a "Debug##Default" identifier instead of "Debug" to allow user creating a window called "Debug" without losing their custom flags. +- Windows: Made the `ImGuiWindowFlags_NoMove` flag properly inherited from parent to child. In a setup with ParentWindow (no flag) -> Child (NoMove) -> SubChild (no flag), the user won't be able to move the parent window by clicking on SubChild. (#1381) +- Popups: Popups can be closed with a right-click anywhere, without altering focus under the popup. (~#439) +- Popups: `BeginPopupContextItem()`, `BeginPopupContextWindow()` are now setup to allow reopening a context menu by right-clicking again. (~#439) +- Popups: `BeginPopupContextItem()` now supports a NULL string identifier and uses the last item ID if available. +- Popups: Added `OpenPopupOnItemClick()` helper which mimic `BeginPopupContextItem()` but doesn't do the BeginPopup(). +- MenuItem: Only activating on mouse release. [@Urmeli0815] (was already fixed in nav branch). +- MenuItem: Made tick mark thicker (thick mark?). +- MenuItem: Tweaks to be usable inside a menu bar (nb: it looks like a regular menu and thus is misleading, prefer using Button() and regular widgets in menu bar if you need to). (#1387) +- ImDrawList: Fixed a rare draw call merging bug which could lead to undisplayed triangles. (#1172, #1368) +- ImDrawList: Fixed a rare bug in `ChannelsMerge()` when all contents has been clipped, leading to an extraneous draw call being created. (#1172, #1368) +- ImFont: Added `AddGlyph()` building helper for use by custom atlas builders. +- ImFontAtlas: Added support for CustomRect API to submit custom rectangles to be packed into the atlas. You can map them as font glyphs, or use them for custom purposes. + After the atlas is built you can query the position of your rectangles in the texture and then copy your data there. You can use this features to create e.g. full color font-mapped icons. +- ImFontAtlas: Fixed fall-back handling when merging fonts, if a glyph was missing from the second font input it could have used a glyph from the first one. (#1349) [@inolen] +- ImFontAtlas: Fixed memory leak on build failure case when stbtt_InitFont failed (generally due to incorrect or supported font type). (#1391) (@Moka42) +- ImFontConfig: Added `RasterizerMultiply` option to alter the brightness of individual fonts at rasterization time, which may help increasing readability for some. +- ImFontConfig: Added `RasterizerFlags` to pass options to custom rasterizer (e.g. the [imgui_freetype](https://github.com/ocornut/imgui_club/tree/master/imgui_freetype) rasterizer in imgui_club has such options). +- ImVector: added resize() variant with initialization value. +- Misc: Changed the internal name formatting of child windows identifier to use slashes (instead of dots) as separator, more readable. +- Misc: Fixed compilation with `IMGUI_DISABLE_OBSOLETE_FUNCTIONS` defined. +- Misc: Marked all format+va_list functions with format attribute so GCC/Clang can warn about misuses. +- Misc: Fixed compilation on NetBSD due to missing alloca.h (#1319) [@RyuKojiro] +- Misc: Improved warnings compilation for newer versions of Clang. (#1324) (@waywardmonkeys) +- Misc: Added `io.WantMoveMouse flags` (from Nav branch) and honored in Examples applications. Currently unused but trying to spread Examples applications code that supports it. +- Misc: Added `IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS` support in imconfig.h to allow user reimplementing the `ImFormatString()` functions e.g. to use stb_printf(). (#1038) +- Misc: [Windows] Fixed default Win32 `SetClipboardText()` handler leaving the Win32 clipboard handler unclosed on failure. [@pdoane] +- Style: Added `ImGuiStyle::ScaleAllSizes(float)` helper to make it easier to have application transition e.g. from low to high DPI with a matching style. +- Metrics: Draw window bounding boxes when hovering Pos/Size; List all draw layers; Trimming empty commands like Render() does. +- Examples: OpenGL3: Save and restore sampler state. (#1145) [@nlguillemot] +- Examples: OpenGL2, OpenGL3: Save and restore polygon mode. (#1307) [@JJscott] +- Examples: DirectX11: Allow creating device with feature level 10 since we don't really need much for that example. (#1333) +- Examples: DirectX9/10/12: Using the Win32 SetCapture/ReleaseCapture API to read mouse coordinates when they are out of bounds. (#1375) [@Gargaj, @ocornut] +- Tools: Fixed binary_to_compressed_c tool to return 0 when successful. (#1350) [@benvanik] +- Internals: Exposed more helpers and unfinished features in imgui_internal.h. (use at your own risk!). +- Internals: A bunch of internal refactoring, hopefully haven't broken anything! Merged a bunch of internal changes from the upcoming Navigation branch. +- Various tweaks, fixes and documentation changes. + +Beta Navigation Branch: +(Lots of work has been done toward merging the Beta Gamepad/Keyboard Navigation branch (#787) in master.) +(Please note that this branch is always kept up to date with master. If you are using the navigation branch, some of the changes include:) +- Nav: Added `#define IMGUI_HAS_NAV` in imgui.h to ease sharing code between both branches. (#787) +- Nav: MainMenuBar now releases focus when user gets out of the menu layer. (#787) +- Nav: When applying focus to a window with only menus, the menu layer is automatically activated. (#787) +- Nav: Added `ImGuiNavInput_KeyMenu` (~Alt key) aside from ImGuiNavInput_PadMenu input as it is one differentiator of pad vs keyboard that was detrimental to the keyboard experience. Although isn't officially supported, it makes the current experience better. (#787) +- Nav: Move requests now wrap vertically inside Menus and Popups. (#787) +- Nav: Allow to collapse tree nodes with NavLeft and open them with NavRight. (#787, #1079). +- Nav: It's now possible to navigate sibling of a menu-bar while navigating inside one of their child. If a Left<>Right navigation request fails to find a match we forward the request to the root menu. (#787, #126) +- Nav: Fixed `SetItemDefaultFocus` from stealing default focus when we are initializing default focus for a menu bar layer. (#787) +- Nav: Support for fall-back horizontal scrolling with PadLeft/PadRight (nb: fall-back scrolling is only used to navigate windows that have no interactive items). (#787) +- Nav: Fixed tool-tip from being selectable in the window selection list. (#787) +- Nav: `CollapsingHeader(bool*)` variant: fixed for `IsItemHovered()` not working properly in the nav branch. (#600, #787) +- Nav: InputText: Fixed using Up/Down history callback feature when Nav is enabled. (#787) +- Nav: InputTextMultiline: Fixed navigation/selection. Disabled selecting all when activating a multi-line text editor. (#787) +- Nav: More consistently drawing a (thin) navigation rectangle hover filled frames such as tree nodes, collapsing header, menus. (#787) +- Nav: Various internal refactoring. + +----------------------------------------------------------------------- + +VERSION 1.51 (2017-08-24) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.51 + +Breaking Changes: + +Work on dear imgui has been gradually resuming. It means that fixes and new features should be tackled at a faster rate than last year. However, in order to move forward with the library and get rid of some cruft, I have taken the liberty to be a little bit more aggressive than usual with API breaking changes. Read the details below and search for those names in your code! In the grand scheme of things, those changes are small and should not affect everyone, but this is technically our most aggressive release so far in term of API breakage. If you want to be extra forward-facing, you can enable `#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS` in your imconfig.h to disable the obsolete names/redirection. + +- Renamed `IsItemHoveredRect()` to `IsItemRectHovered()`. Kept inline redirection function (will obsolete). +- Renamed `IsMouseHoveringWindow()` to `IsWindowRectHovered()` for consistency. Kept inline redirection function (will obsolete). +- Renamed `IsMouseHoveringAnyWindow()` to `IsAnyWindowHovered()` for consistency. Kept inline redirection function (will obsolete). +- Renamed `ImGuiCol_Columns***` enums to `ImGuiCol_Separator***`. Kept redirection enums (will obsolete). +- Renamed `ImGuiSetCond***` types and enums to `ImGuiCond***`. Kept redirection enums (will obsolete). +- Renamed `GetStyleColName()` to `GetStyleColorName()` for consistency. Unlikely to be used by end-user! +- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload, which _might_ cause an "ambiguous call" compilation error if you are using ImColor() with implicit cast. Cast to ImU32 or ImVec4 explicily to fix. +- Marked the weird `IMGUI_ONCE_UPON_A_FRAME` helper macro as obsolete. Prefer using the more explicit `ImGuiOnceUponAFrame`. +- Changed `ColorEdit4(const char* label, float col[4], bool show_alpha = true)` signature to `ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0)`, where flags 0x01 is a safe no-op (hello dodgy backward compatibility!). The new `ColorEdit4`/`ColorPicker4` functions have lots of available flags! Check and run the demo window, under "Color/Picker Widgets", to understand the various new options. +- Changed signature of `ColorButton(ImVec4 col, bool small_height = false, bool outline_border = true)` to `ColorButton(const char* desc_id, ImVec4 col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0))`. This function was rarely used and was very dodgy (no explicit ID!). +- Changed `BeginPopupContextWindow(bool also_over_items=true, const char* str_id=NULL, int mouse_button=1)` signature to `(const char* str_id=NULL, int mouse_button=1, bool also_over_items=true)`. This is perhaps the most aggressive change in this update, but note that the majority of users relied on default parameters completely, so this will affect only a fraction of users of this already rarely used function. +- Removed `IsPosHoveringAnyWindow()`, which was partly broken and misleading. In the vast majority of cases, people using that function wanted to use `io.WantCaptureMouse` flag. Replaced with IM_ASSERT + comment redirecting user to `io.WantCaptureMouse`. (#1237) +- Removed the old `ValueColor()` helpers, they are equivalent to calling `Text(label)` + `SameLine()` + `ColorButton()`. +- Removed `ColorEditMode()` and `ImGuiColorEditMode` type in favor of `ImGuiColorEditFlags` and parameters to the various Color*() functions. The `SetColorEditOptions()` function allows to initialize default but the user can still change them with right-click context menu. Commenting out your old call to `ColorEditMode()` may just be fine! + +Other Changes: + +- Added flags to `ColorEdit3()`, `ColorEdit4()`. The color edit widget now has a context-menu and access to the color picker. (#346) +- Added flags to `ColorButton()`. (#346) +- Added `ColorPicker3()`, `ColorPicker4()`. The API along with those of the updated `ColorEdit4()` was designed so you may use them in various situation and hopefully compose your own picker if required. There are a bunch of available flags, check the Demo window and comment for `ImGuiColorEditFlags_`. Some of the options it supports are: two color picker types (hue bar + sat/val rectangle, hue wheel + rotating sat/val triangle), display as u8 or float, lifting 0.0..1.0 constraints (currently rgba only), context menus, alpha bar, background checkerboard options, preview tooltip, basic revert. For simple use, calling the existing `ColorEdit4()` function as you did before will be enough, as you can now open the color picker from there. (#346) [@r-lyeh, @nem0, @thennequin, @dariomanesku and @ocornut] +- Added `SetColorEditOptions()` to set default color options (e.g. if you want HSV over RGBA, float over u8, select a default picker mode etc. at startup time without a user intervention. Note that the user can still change options with the context menu unless disabled with `ImGuiColorFlags_NoOptions` or explicitly enforcing a display type/picker mode etc.). +- Added user-facing `IsPopupOpen()` function. (#891) [@mkeeter] +- Added `GetColorU32(u32)` variant that perform the style alpha multiply without a floating-point round trip, and helps makes code more consistent when using ImDrawList APIs. +- Added `PushStyleColor(ImGuiCol idx, ImU32 col)` overload. +- Added `GetStyleColorVec4(ImGuiCol idx)` which is equivalent to accessing `ImGui::GetStyle().Colors[idx]` (aka return the raw style color without alpha alteration). +- ImFontAtlas: Added `GlyphRangesBuilder` helper class, which makes it easier to build custom glyph ranges from your app/game localization data, or add into existing glyph ranges. +- ImFontAtlas: Added `TexGlyphPadding` option. (#1282) [@jadwallis] +- ImFontAtlas: Made it possible to override size of AddFontDefault() (even if it isn't really recommended!). +- ImDrawList: Added `GetClipRectMin()`, `GetClipRectMax()` helpers. +- Fixed Ini saving crash if the ImGuiWindowFlags_NoSavedSettings gets removed from a window after its creation (unlikely!). (#1000) +- Fixed `PushID()`/`PopID()` from marking parent window as Accessed (which needlessly woke up the root "Debug" window when used outside of a regular window). (#747) +- Fixed an assert when calling `CloseCurrentPopup()` twice in a row. [@nem0] +- Window size can be loaded from .ini data even if ImGuiWindowFlags_NoResize flag is set. (#1048, #1056) +- Columns: Added `SetColumnWidth()`. (#913) [@ggtucker] +- Columns: Dragging a column preserve its width by default. (#913) [@ggtucker] +- Columns: Fixed first column appearing wider than others. (#1266) +- Columns: Fixed allocating space on the right-most side with the assumption of a vertical scrollbar. The space is only allocated when needed. (#125, #913, #893, #1138) +- Columns: Fixed the right-most column from registering its content width to the parent window, which led to various issues when using auto-resizing window or e.g. horizonal scrolling. (#519, #125, #913) +- Columns: Refactored some of the columns code internally toward a better API (not yet exposed) + minor optimizations. (#913) [@ggtucker, @ocornut] +- Popups: Most popups windows can be moved by the user after appearing (if they don't have explicit positions provided by caller, or e.g. sub-menu popup). The previous restriction was totally arbitrary. (#1252) +- Tooltip: `SetTooltip()` is expanded immediately into a window, honoring current font / styling setting. Add internal mechanism to override tooltips. (#862) +- PlotHistogram: bars are drawn based on zero-line, so negative values are going under. (#828) +- Scrolling: Fixed return values of `GetScrollMaxX()`, `GetScrollMaxY()` when both scrollbars were enabled. Tweak demo to display more data. (#1271) [@degracode] +- Scrolling: Fixes for Vertical Scrollbar not automatically getting enabled if enabled Horizontal Scrollbar straddle the vertical limit. (#1271, #246) +- Scrolling: `SetScrollHere()`, `SetScrollFromPosY()`: Fixed Y scroll aiming when Horizontal Scrollbar is enabled. (#665). +- [Windows] Clipboard: Fixed not closing win32 clipboard on early open failure path. (#1264) +- Removed an unnecessary dependency on int64_t which failed on some older compilers. +- Demo: Rearranged everything under Widgets in a more consistent way. +- Demo: Columns: Added Horizontal Scrolling demo. Tweaked another Columns demo. (#519, #125, #913) +- Examples: OpenGL: Various makefiles for MINGW, Linux. (#1209, #1229, #1209) [@fr500, @acda] +- Examples: Enabled vsync by default in example applications, so it doesn't confuse people that the sample run at 2000+ fps and waste an entire CPU. (#1213, #1151). +- Various other small fixes, tweaks, comments, optimizations. + +----------------------------------------------------------------------- + +VERSION 1.50 (2017-06-02) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.50 + +Breaking Changes: + + - Added a void* user_data parameter to Clipboard function handlers. (#875) + - SameLine(x) with x>0.0f is now relative to left of column/group if any, and not always to left of window. This was sort of always the intent and hopefully breakage should be minimal. + - Renamed ImDrawList::PathFill() - rarely used directly - to ImDrawList::PathFillConvex() for clarity and consistency. + - Removed ImFontConfig::MergeGlyphCenterV in favor of a more multipurpose ImFontConfig::GlyphOffset. + - Style: style.WindowTitleAlign is now a ImVec2 (ImGuiAlign enum was removed). set to (0.5f,0.5f) for horizontal+vertical centering, (0.0f,0.0f) for upper-left, etc. + - BeginChild(const char*) now applies the stack id to the provided label, consistently with other functions as it should always have been. It shouldn't affect you unless (extremely unlikely) you were appending multiple times to a same child from different locations of the stack id. If that's the case, generate an id with GetId() and use it instead of passing string to BeginChild(). + +Other Changes: + +- InputText(): Added support for CTRL+Backspace (delete word). +- InputText(): OSX uses Super+Arrows for home/end. Add Shortcut+Backspace support. (#650) [@michaelbartnett] +- InputText(): Got rid of individual OSX-specific options in ImGuiIO, added a single io.OSXBehaviors flag. (#473, #650) +- InputText(): Fixed pressing home key on last character when it isn't a trailing \n (#588, #815) +- InputText(): Fixed state corruption/crash bug in stb_textedit.h redo logic when exhausting undo/redo char buffer. (#715. #681) +- InputTextMultiline(): Fixed Ctrl+DownArrow moving scrolling out of bounds. +- InputTextMultiline(): Scrollbar fix for when input and latched internal buffers differs in a way that affects vertical scrollbar existence. (#725) +- ImFormatString(): Fixed an overflow handling bug with implementation of vsnprintf() that do not return -1. (#793) +- BeginChild(const char*) now applies stack id to provided label, consistent with other widgets. (#894, #713) +- SameLine() with explicit X position is relative to left of group/columns. (ref #746, #125, #630) +- SliderInt(), SliderFloat() supports reverse direction (where v_min > v_max). (#854) +- SliderInt(), SliderFloat() better support for when v_min==v_max. (#919) +- SliderInt(), SliderFloat() enforces writing back value when interacting, to be consistent with other widgets. (#919) +- SliderInt, SliderFloat(): Fixed edge case where style.GrabMinSize being bigger than slider width can lead to a division by zero. (#919) +- Added IsRectVisible() variation with explicit start-end positions. (#768) [@thedmd] +- Fixed TextUnformatted() clipping bug in the large-text path when horizontal scroll has been applied. (#692, #246) +- Fixed minor text clipping issue in window title when using font straying above usual line. (#699) +- Fixed SetCursorScreenPos() fixed not adjusting CursorMaxPos as well. +- Fixed scrolling offset when using SetScrollY(), SetScrollFromPosY(), SetScrollHere() with menu bar. +- Fixed using IsItemActive() after EndGroup() or any widget using groups. (#840, #479) +- Fixed IsItemActive() lagging by one frame on initial widget activation. (#840) +- Fixed Separator() zero-height bounding box resulting in clipping when laying exactly on top line of clipping rectangle (#860) +- Fixed PlotLines() PlotHistogram() calling with values_count == 0. +- Fixed clicking on a window's void while staying still overzealously marking .ini settings as dirty. (#923) +- Fixed assert triggering when a window has zero rendering but has a callback. (#810) +- Scrollbar: Fixed rendering when sizes are negative to reduce glitches (which can happen with certain style settings and zero WindowMinSize). +- EndGroup(): Made IsItemHovered() work when an item was activated within the group. (#849) +- BulletText(): Fixed stopping to display formatted string after the '##' mark. +- Closing the focused window restore focus to the first active root window in descending z-order .(part of #727) +- Word-wrapping: Fixed a bug where we never wrapped after a 1 character word. [@sronsse] +- Word-wrapping: Fixed TextWrapped() overriding wrap position if one is already set. (#690) +- Word-wrapping: Fixed incorrect testing for negative wrap coordinates, they are perfectly legal. (#706) +- ImGuiListClipper: fixed automatic-height calc path dumbly having user display element 0 twice. (#661, #716) +- ImGuiListClipper: Fix to behave within column. (#661, #662, #716) +- ImDrawList: Renamed ImDrawList::PathFill() to ImDrawList::PathFillConvex() for clarity. (BREAKING API) +- Columns: End() avoid calling Columns(1) if no columns set is open, not sure why it wasn't the case already (pros: faster, cons: exercise less code). +- ColorButton(): Fix ColorButton showing wrong hex value for alpha. (#1068) [@codecat] +- ColorEdit4(): better preserve inputting value out of 0..255 range, display then clamped in Hexadecimal form. +- Shutdown() clear out some remaining pointers for sanity. (#836) +- Added IMGUI_USE_BGRA_PACKED_COLOR option in imconfig.h (#767, #844) [@thedmd] +- Style: Removed the inconsistent shadow under RenderCollapseTriangle() (~#707) +- Style: Added ButtonTextAlign, ImGuiStyleVar_ButtonTextAlign. (#842) +- ImFont: Allowing to use up to 0xFFFE glyphs in same font (increased from previous 0x8000). +- ImFont: Added GetGlyphRangesThai() helper. [@nProtect] +- ImFont: CalcWordWrapPositionA() fixed font scaling with fallback character. +- ImFont: Calculate and store the approximate texture surface to get an idea of how costly each source font is. +- ImFontConfig: Added GlyphOffset to explicitely offset glyphs at font build time, useful for merged fonts. Removed MergeGlyphCenterV. (BREAKING API) +- Clarified asserts in CheckStacksSize() when there is a stack mismatch. +- Context: Support for #define-ing GImGui and IMGUI_SET_CURRENT_CONTEXT_FUNC to enable custom thread-based hackery (#586) +- Updated stb_truetype.h to 1.14 (added OTF support, removed warnings). (#883, #976) +- Updated stb_rect_pack.h to 0.10 (removed warnings). (#883) +- Added ImGuiMouseCursor_None enum value for convenient usage by app/binding. +- Clipboard: Added a void* user_data parameter to Clipboard function handlers. (#875) (BREAKING API) +- Internals: Refactor internal text alignment options to use ImVec2, removed ImGuiAlign. (#842, #222) +- Internals: Renamed ImLoadFileToMemory to ImFileLoadToMemory to be consistent with ImFileOpen + fix mismatching .h name. (#917) +- Windows: Fixed Windows default clipboard handler leaving its buffer unfreed on application's exit. (#714) +- Windows: No default IME handler when compiling for Windows using GCC. (#738) +- Windows: Now using _wfopen() instead of fopen() to allow passing in paths/filenames with UTF-8 characters. (#917) +- Tools: binary_to_compressed_c: Avoid ?? trigraphs sequences in string outputs which break some older compilers. (#839) +- Demo: Added an extra 3-way columns demo. +- Demo: ShowStyleEditor: show font character map / grid in more details. +- Demo: Console: Fixed a completion bug when multiple candidates are equals and match until the end. +- Demo: Fixed 1-byte off overflow in the ShowStyleEditor() combo usage. (#783) [@bear24rw] +- Examples: Accessing ImVector fields directly, feel less stl-ey. (#810) +- Examples: OpenGL*: Saving/restoring existing scissor rectangle for completeness. (#807) +- Examples: OpenGL*: Saving/restoring active texture number (the value modified by glActiveTexture). (#1087, #1088, #1116) +- Examples: OpenGL*: Saving/restoring separate color/alpha blend functions correctly. (#1120) [@greggman] +- Examples: OpenGL2: Uploading font texture as RGBA32 to increase compatibility with users shaders for beginners. (#824) +- Examples: Vulkan: Countless fixes and improvements. (#785, #804, #910, #1017, #1039, #1041, #1042, #1043, #1080) [@martty, @Loftilus, @ParticlePeter, @SaschaWillems] +- Examples: DirectX9/10/10: Only call SetCursor(NULL) is io.MouseDrawCursor is set. (#585, #909) +- Examples: DirectX9: Explicitely setting viewport to match that other examples are doing. (#937) +- Examples: GLFW+OpenGL3: Fixed Shutdown() calling GL functions with NULL parameters if NewFrame was never called. (#800) +- Examples: GLFW+OpenGL2: Renaming opengl_example/ to opengl2_example/ for clarity. +- Examples: SDL+OpenGL: explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) +- Examples: SDL2: Added build .bat files for Win32. +- Added various links to language/engine bindings. +- Various other minor fixes, tweaks, comments, optimizations. + +----------------------------------------------------------------------- + +VERSION 1.49 (2016-05-09) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.49 + +Breaking Changes: + +- Renamed `SetNextTreeNodeOpened()` to `SetNextTreeNodeOpen()` for consistency, no redirection. +- Removed confusing set of `GetInternalState()`, `GetInternalStateSize()`, `SetInternalState()` functions. Now using `CreateContext()`, `DestroyContext()`, `GetCurrentContext()`, `SetCurrentContext()`. If you were using multiple contexts the change should be obvious and trivial. +- Obsoleted old signature of `CollapsingHeader(const char* label, const char* str_id = NULL, bool display_frame = true, bool default_open = false)`, as extra parameters were badly designed and rarely used. Most uses were using 1 parameter and shouldn't affect you. You can replace the "default_open = true" flag in new API with `CollapsingHeader(label, ImGuiTreeNodeFlags_DefaultOpen)`. +- Changed `ImDrawList::PushClipRect(ImVec4 rect)` to `ImDraw::PushClipRect(Imvec2 min,ImVec2 max,bool intersect_with_current_clip_rect=false)`. Note that higher-level `ImGui::PushClipRect()` is preferable because it will clip at logic/widget level, whereas `ImDrawList::PushClipRect()` only affect your renderer. +- Title bar (using ImGuiCol_TitleBg/ImGuiCol_TitleBgActive colors) isn't rendered over a window background (ImGuiCol_WindowBg color) anymore (see #655). If your TitleBg/TitleBgActive alpha was 1.0f or you are using the default theme it will not affect you. However if your TitleBg/TitleBgActive alpha was <1.0f you need to tweak your custom theme to readjust for the fact that we don't draw a WindowBg background behind the title bar. + This helper function will convert an old TitleBg/TitleBgActive color into a new one with the same visual output, given the OLD color and the OLD WindowBg color. (Or If this is confusing, just pick the RGB value from title bar from an old screenshot and apply this as TitleBg/TitleBgActive. Or you may just create TitleBgActive from a tweaked TitleBg color.) + + ImVec4 ConvertTitleBgCol(const ImVec4& win_bg_col, const ImVec4& title_bg_col) + { + float new_a = 1.0f - ((1.0f - win_bg_col.w) * (1.0f - title_bg_col.w)); + float k = title_bg_col.w / new_a; + return ImVec4((win_bg_col.x * win_bg_col.w + title_bg_col.x) * k, (win_bg_col.y * win_bg_col.w + title_bg_col.y) * k, (win_bg_col.z * win_bg_col.w + title_bg_col.z) * k, new_a); + } + +Other changes: + +- New version of ImGuiListClipper helper calculates item height automatically. See comments and demo code. (#662, #661, #660) +- Added SetNextWindowSizeConstraints() to enable basic min/max and programmatic size constraints on window. Added demo. (#668) +- Added PushClipRect()/PopClipRect() (previously part of imgui_internal.h). Changed ImDrawList::PushClipRect() prototype. (#610) +- Added IsRootWindowOrAnyChildHovered() helper. (#615) +- Added TreeNodeEx() functions. (#581, #600, #190) +- Added ImGuiTreeNodeFlags_Selected flag to display treenode as "selected". (#581, #190) +- Added ImGuiTreeNodeFlags_AllowOverlapMode flag. (#600) +- Added ImGuiTreeNodeFlags_NoTreePushOnOpen flag (#590). +- Added ImGuiTreeNodeFlags_NoAutoOpenOnLog flag (previously private). +- Added ImGuiTreeNodeFlags_DefaultOpen flag (previously private). +- Added ImGuiTreeNodeFlags_OpenOnDoubleClick flag. +- Added ImGuiTreeNodeFlags_OpenOnArrow flag. +- Added ImGuiTreeNodeFlags_Leaf flag, always opened, no arrow, for convenience. For simple use case prefer using TreeAdvanceToLabelPos()+Text(). +- Added ImGuiTreeNodeFlags_Bullet flag, to add a bullet to Leaf node or replace Arrow with a bullet. +- Added TreeAdvanceToLabelPos(), GetTreeNodeToLabelSpacing() helpers. (#581, #324) +- Added CreateContext()/DestroyContext()/GetCurrentContext()/SetCurrentContext(). Obsoleted nearly identical GetInternalState()/SetInternalState() functions. (#586, #269) +- Added NewLine() to undo a SameLine() and as a shy reminder that horizontal layout support hasn't been implemented yet. +- Added IsItemClicked() helper. (#581) +- Added CollapsingHeader() variant with close button. (#600) +- Fixed MenuBar missing lower border when borders are enabled. +- InputText(): Fixed clipping of cursor rendering in case it gets out of the box (which can be forced w/ ImGuiInputTextFlags_NoHorizontalScroll. (#601) +- Style: Changed default IndentSpacing from 22 to 21. (#581, #324) +- Style: Fixed TitleBg/TitleBgActive color being rendered above WindowBg color, which was inconsistent and causing visual artefact. (#655) + This broke the meaning of TitleBg and TitleBgActive. Only affect values where Alpha<1.0f. Fixed default theme. Read comments in "API BREAKING CHANGES" section to convert. +- Relative rendering of order of Child windows creation is preserved, to allow more control with overlapping childs. (#595) +- Fixed GetWindowContentRegionMax() being off by ScrollbarSize amount when explicit SizeContents is set. +- Indent(), Unindent(): optional non-default indenting width. (#324, #581) +- Bullet(), BulletText(): Slightly bigger. Less polygons. +- ButtonBehavior(): fixed subtle old bug when a repeating button would also return true on mouse release (barely noticeable unless RepeatRate is set to be very slow). (#656) +- BeginMenu(): a menu that becomes disabled while open gets closed down, facilitate user's code. (#126) +- BeginGroup(): fixed using within Columns set. (#630) +- Fixed a lag in reading the currently hovered window when dragging a window. (#635) +- Obsoleted 4 parameters version of CollapsingHeader(). Refactored code into TreeNodeBehavior. (#600, #579) +- Scrollbar: minor fix for top-right rounding of scrollbar background when window has menubar but no title bar. +- MenuItem(): checkmark render in disabled color when menu item is disabled. +- Fixed clipping rectangle floating point representation to ensure renderer-side float point operations yield correct results in typical DirectX/GL settings. (#582, 597) +- Fixed GetFrontMostModalRootWindow(), fixing missing fade-out when a combo pop was used stacked over a modal window. (#604) +- ImDrawList: Added AddQuad(), AddQuadFilled() helpers. +- ImDrawList: AddText() refactor, moving some code to ImFont, reserving less unused vertices when large vertical clipping occurs. +- ImFont: Added RenderChar() helper. +- ImFont: Added AddRemapChar() helper. (#609) +- ImFontConfig: Clarified persistence requirement of GlyphRanges array. (#651) +- ImGuiStorage: Added bool helper functions for completeness. +- AddFontFromMemoryCompressedTTF(): Fix font config propagation. (#587) +- Renamed majority of use of the word "opened" to "open" for clarity. Renamed SetNextTreeNodeOpened() to SetNextTreeNodeOpen(). (#625, #579) +- Examples: OpenGL3: Saving/restoring glActiveTexture() state. (#602) +- Examples: DirectX9: save/restore all device state. +- Examples: DirectX9: Removed dependency on d3dx9.h, d3dx9.lib, dxguid.lib so it can be used in a DirectXMath.h only environment. (#611) +- Examples: DirectX10/X11: Apply depth-stencil state (no use of depth buffer). (#640, #636) +- Examples: DirectX11/X11: Added comments on removing dependency on D3DCompiler. (#638) +- Examples: SDL: Initialize video+timer subsystem only. +- Examples: Apple/iOS: lowered xcode project deployment target from 10.7 to 10.11. (#598, #575) + +----------------------------------------------------------------------- + +VERSION 1.48 (2016-04-09) +Decorated log: https://github.com/ocornut/imgui/releases/tag/v1.48 + +Breaking Changes: + +- Consistently honoring exact width passed to PushItemWidth() (when positive), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346) +- Style: removed `style.WindowFillAlphaDefault` which was confusing and redundant, baked alpha into `ImGuiCol_WindowBg` color. If you had a custom WindowBg color but didn't change WindowFillAlphaDefault, multiply WindowBg alpha component by 0.7. Renamed `ImGuiCol_TooltipBg` to `ImGuiCol_PopupBG`, applies to other types of popups. `bg_alpha` parameter of 5-parameters version of Begin() is an override. (#337) +- InputText(): Added BufTextLen field in ImGuiTextEditCallbackData. Requesting user to update it if the buffer is modified in the callback. Added a temporary length-check assert to minimize panic for the 3 people using the callback. (#541) +- Renamed GetWindowFont() to GetFont(), GetWindowFontSize() to GetFontSize(). Kept inline redirection function (will obsolete). (#340) + +Other Changes: + +- Consistently honoring exact width passed to PushItemWidth(), previously it would add extra FramePadding.x*2 over that width. Some hand-tuned layout may be affected slightly. (#346) +- Fixed clipping of child windows within parent not taking account of child outer clipping boundaries (including scrollbar, etc.). (#506) +- TextUnformatted(): Fixed rare crash bug with large blurb of text (2k+) not finished with a '\n' and fully above the clipping Y line. (#535) +- IO: Added 'KeySuper' field to hold Cmd keyboard modifiers for OS X. Updated all examples accordingly. (#473) +- Added ImGuiWindowFlags_ForceVerticalScrollbar, ImGuiWindowFlags_ForceHorizontalScrollbar flags. (#476) +- Added IM_COL32 macros to generate a U32 packed color, convenient for direct use of ImDrawList api. (#346) +- Added GetFontTexUvWhitePixel() helper, convenient for direct use of ImDrawList api. +- Selectable(): Added ImGuiSelectableFlags_AllowDoubleClick flag to allow user reacting on double-click. (@zapolnov) (#516) +- Begin(): made the close button explicitly set the boolean to false instead of toggling it. (#499) +- BeginChild()/EndChild(): fixed incorrect layout to allow widgets submitted after an auto-fitted child window. (#540) +- BeginChild(): Added ImGuiWindowFlags_AlwaysUseWindowPadding flag to ensure non-bordered child window uses window padding. (#462) +- Fixed InputTextMultiLine(), ListBox(), BeginChildFrame(), ProgressBar(): outer frame not honoring bordering. (#462, #503) +- Fixed Image(), ImageButtion() rendering a rectangle 1 px too large on each axis. (#457) +- SetItemAllowOverlap(): Promoted from imgui_internal.h to public imgui.h api. (#517) +- Combo(): Right-most button stays highlighted when popup is open. +- Combo(): Display popup above if there's isn't enough space below / or select largest side. (#505) +- DragFloat(), SliderFloat(), InputFloat(): fixed cases of erroneously returning true repeatedly after a text input modification (e.g. "0.0" --> "0.000" would keep returning true). (#564) +- DragFloat(): Always apply value when mouse is held/widget active, so that an always-reseting variable (e.g. non saved local) can be passed. +- InputText(): OS X friendly behaviors: Word movement uses Alt key; Shortcuts uses Cmd key; Double-clicking text select a single word; Jumping to next word sets cursor to end of current word instead of beginning of current word. (@zhiayang), (#473) +- InputText(): Added BufTextLen in ImGuiTextEditCallbackData. Requesting user to maintain it if buffer is modified. Zero-ing structure properly before use. (#541) +- CheckboxFlags(): Added support for testing/setting multiple flags at the same time. (@DMartinek) (#555) +- TreeNode(), CollapsingHeader() fixed not being able to use "##" sequence in a formatted label. +- ColorEdit4(): Empty label doesn't add InnerSpacing.x, matching behavior of other widgets. (#346) +- ColorEdit4(): Removed unnecessary calls to scanf() when idle in hexadecimal edit mode. +- BeginPopupContextItem(), BeginPopupContextWindow(): added early out optimization. +- CaptureKeyboardFromApp() / CaptureMouseFromApp(): added argument to allow clearing the capture flag. (#533) +- ImDrawList: Fixed index-overflow check broken by AddText() casting current index back to ImDrawIdx. (#514) +- ImDrawList: Fixed incorrect removal of trailing draw command if it is a callback command. +- ImDrawList: Allow windows with only a callback only to be functional. (#524) +- ImDrawList: Fixed ImDrawList::AddRect() which used to render a rectangle 1 px too large on each axis. (#457) +- ImDrawList: Fixed ImDrawList::AddCircle() to fit precisely within bounding box like AddCircleFilled() and AddRectFilled(). (#457) +- ImDrawList: AddCircle(), AddRect() takes optional thickness parameter. +- ImDrawList: Added AddTriangle(). +- ImDrawList: Added PrimQuadUV() helper to ease custom rendering of textured quads (require primitive reserve). +- ImDrawList: Allow AddText(ImFont\* font, float font_size, ...) variant to take NULL/0.0f as default. +- ImFontAtlas: heuristic increase default texture width up for large number of glyphs. (#491) +- ImTextBuffer: Fixed empty() helper which was utterly broken. +- Metrics: allow to inspect individual triangles in drawcalls. +- Demo: added more draw primitives in the Custom Rendering example. (#457) +- Demo: extra comments and example for PushItemWidth(-1) patterns. +- Demo: InputText password demo filters out blanks. (#515) +- Demo: Fixed malloc/free mismatch and leak when destructing demo console, if it has been used. (@fungos) (#536) +- Demo: plot code doesn't use ImVector to avoid heap allocation and be more friendly to custom allocator users. (#538) +- Fixed compilation on DragonFly BSD (@mneumann) (#563) +- Examples: Vulkan: Added a Vulkan example (@Loftilus) (#549) +- Examples: DX10, DX11: Saving/restoring most device state so dropping render function in your codebase shouldn't have DX device side-effects. (#570) +- Examples: DX10, DX11: Fixed ImGui_ImplDX??_NewFrame() from recreating device objects if render isn't called (g_pVB not set). +- Examples: OpenGL3: Fix BindVertexArray/BindBuffer order. (@nlguillemot) (#527) +- Examples: OpenGL: skip rendering and calling glViewport() if we have zero-fixed buffer. (#486) +- Examples: SDL2+OpenGL3: Fix context creation options. Made ImGui_ImplSdlGL3_NewFrame() signature match GL2 one. (#468, #463) +- Examples: SDL2+OpenGL2/3: Fix for high-dpi displays. (@nickgravelyn) +- Various extra comments and clarification in the code. +- Various other fixes and optimisations. + +----------------------------------------------------------------------- + +For older version, see https://github.com/ocornut/imgui/releases + From bd267ad7396d8141531dc800a2d27e712710dd3c Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 25 Feb 2018 14:14:17 +0100 Subject: [PATCH 54/87] Changelog: Added all change infos since 1.53 up to the current version. --- CHANGELOG.txt | 125 ++++++++++++++++++++++++++++++++++++++++++++++++-- imgui.cpp | 2 +- 2 files changed, 122 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index fd2f5759..a0f0e2a7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,7 +4,7 @@ CHANGELOG ----------------------------------------------------------------------- This document holds the programmer changelog that we also use in release notes. -We generally fold multiple commits pertaining to the same topic as a single entry and simplify a few things. +We generally fold multiple commits pertaining to the same topic as a single entry, and simplify various things. Release notes: (with links and screenshots) https://github.com/ocornut/imgui/releases @@ -39,7 +39,124 @@ HOW TO UPDATE? VERSION 1.60 WIP (Latest, currently in development) - +The gamepad/keyboard navigation branch (which has been in the work since July 2016) has been merged. +Gamepad/keyboard navigation is still marked as Beta and has to be enabled explicitely. +Various internal refactors have also been done, as part of the navigation work and as part of the upcoing viewport/docking work. + +Breaking Changes: +(IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.60) + + - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. + - Obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. + - Reorganized context handling to be more explicit, + - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. + - removed Shutdown() function, as DestroyContext() serve this purpose. + - you may pass a ImFontAtlas* pointer to CreateContext() to share a font atlas between contexts. Otherwhise CreateContext() will create its own font atlas instance. + - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. + - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. + - Moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. + - Obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). + - Obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). + - Renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. + - Removed CalcItemRectClosestPoint() which was weird and not really used by anyone except demo code. If you need it it's easy to replicate on your side. + +Other Changes: +(IN PROGRESS, WILL ADD TO THIS LIST AS WE WORK ON 1.60) + +- Navigation: merged in the gamepad/keyboard navigation (about one million changes!). (#787, #323) + The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. + - To use Keyboard Navigation: + - Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + NavFlags_EnableKeyboard), the io.WantCaptureKeyboard flag will be set. + For more advanced uses, you may want to read from io.NavActive or io.NavVisible. Read imgui.cpp for more details. + - To use Gamepad Navigation: + - Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - See https://github.com/ocornut/imgui/issues/1599 for recommended gamepad mapping. + - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. Read imgui.cpp for more details. +- Navigation: SetItemDefaultFocus() sets the navigation position in addition to scrolling. (#787) +- Navigation: Added IsItemFocused(), added IsAnyItemFocused(). (#787) +- Navigation: Added window flags: ImGuiWindowFlags_NoNav (ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus). +- Navigation: Style: Added ImGuiCol_NavHighlight, ImGuiCol_NavWindowingHighlight colors. (#787) +- Navigation: TreeNode: Added ImGuiTreeNodeFlags_NavLeftJumpsBackHere flag to allow Nav Left direction to jump back to parent tree node from any of its child. (#1079) +- Navigation: IO: Added io.NavFlags (input), io.NavActive (output), io.NavVisible (output). (#787) +- Context: Removed the default global context and font atlas instances, which caused various problems to users of multiple contexts and DLL users. (#1565) + YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. Existing apps will assert/crash without it. +- Context: Removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions() and shared by all contexts. (#1565, #586, #992, #1007, #1558) +- Context: You may pass a ImFontAtlas to CreateContext() to specify a font atlas to share. Shared font atlas are not owned by the context and not destroyed along with it. +- Context: Added IMGUI_DISABLE_DEFAULT_ALLOCATORS to disable linking with malloc/free. (#1565, #586, #992, #1007, #1558) +- IO: Added ImGuiKey_Insert, ImGuiKey_Space keys. Setup in all example bindings. (#1541) +- IO: Added Horizontal Mouse Wheel support for horizontal scrolling. (#1463) [@tseeker] +- IO: Added IsAnyMouseDown() helper which is helpful for bindings to handle mouse capturing. +- Window: Clicking on a window with the ImGuiWIndowFlags_NoMove flags takes an ActiveId so we can't hover something else when dragging afterwards. (ref #1381, #1337) +- Window: IsWindowHovered(): Added ImGuiHoveredFlags_AnyWindow, ImGuiFocusedFlags_AnyWindow flags (See Breaking Changes). Added to demo. (#1382) +- Window: Added SetNextWindowBgAlpha() helper. Particularly helpul since the legacy 5-parameters version of Begin() has been marked as obsolete in 1.53. (#1567) +- Window: Fixed SetNextWindowContentSize() with 0.0f on Y axis (or SetNextWindowContentWidth()) overwriting the contents size. Got broken on Dec 10 (1.53). (#1363) +- Window: CloseButton: Fixed cross positioning being a little off. +- InputText: Added alternative clipboard shortcuts: Shift+Delete (cut), Ctrl+Insert (copy), Shift+Insert (paste). (#1541) +- InputText: Fixed losing Cursor X position when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) +- Style: Enable window border by default. (#707) +- Style: Exposed ImGuiStyleVar_WindowTitleAlign, ImGuiStyleVar_ScrollbarSize, ImGuiStyleVar_ScrollbarRounding, ImGuiStyleVar_GrabRounding + added an assert to reduce accidental breakage. (#1181) +- Style: Added style.MouseCursorScale help when using the software mouse cursor facility. (#939). +- Popup: OpenPopup() Always reopen existing popup. (Removed imgui_internal.h's OpenPopupEx() which was used for this.) (#1497, #1533). +- Popup: BeginPopupContextItem(), BeginPopupContextWindow(), BeginPopupContextVoid(), OpenPopupOnItemClick() all react on mouse release instead of mouse press. (~#439) +- Popup: Better handling of user mistakenly calling OpenPopup() every frame (with reopen_existing option). The error will now be more visible and easier to understand. (#1497) +- Popup: BeginPopup(): Exposed extra_flags parameter that are passed through to Begin(). (#1533) +- Popup: BeginPopupModal: fixed the conditional test for SetNextWindowPos() which was polling the wrong window, which in practice made the test succeed all the time. +- Tooltip: BeginTooltip() sets NoInputs flag. +- Scrollbar: Fixed ScrollbarY enable test after ScrollbarX has been enabled being a little off (small regression from Nov 2017). (#1574) +- Scrollbar: Fixed ScrollbarX enable test subtracting WindowPadding.x (this has been there since the addition of horizontal scroll bar!). +- Columns: Clear offsets data when columns count changed. (#1525) +- Columns: Fixed a memory leak of ImGuiColumnsSet's Columns vector. (#1529) [@unprompted] +- MenuBar: Fixed menu bar pushing a clipping rect outside of its allocated bound (usually unnoticeable). +- TreeNode: nodes with the ImGuiTreeNodeFlags_Leaf flag correctly disable highlight when DragDrop is active. (#143, #581) +- Drag and Drop: Increased payload type string to 12 characters instead of 8. (#143) +- Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143) +- DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) +- PlotLines: plot a flat line if scale_min==scale_max. (#1621) +- ImFontAtlas: Handle stb_truetype stbtt_InitFont() and stbtt_PackBegin() possible failures more gracefully, GetTexDataAsRGBA32() won't crash during conversion. (#1527) +- ImFontAtlas: Moved mouse cursor data out of ImGuiContext, fix drawing them with multiple contexts. Also remove the last remaining undesirable dependency on ImGui in imgui_draw.cpp. (#939) +- ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight flag to disable padding font height to nearest power of two. (#1613) +- ImFontAtlas: Added ImFontAtlasFlags_NoMouseCursors flag to disable baking software mouse cursors, mostly to save texture memory on very low end hardware. (#1613) +- ImDrawList: Fixed AddRect() with antialiasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646) +- Misc: Functions passed to libc qsort are explicitely marked cdecl to support compiling with vectorcall as the default calling convention. (#1230, #1611) [@RandyGaul] +- Misc: ImVec2: added [] operator. This is becoming desirable for some types of code, better added sooner than later. +- Misc: Exposed IM_OFFSETOF() helper in imgui.h. +- Misc: NewFrame(): Added an assert to detect incorrect filling of the io.KeyMap[] array earlier. (#1555) +- Misc: Added obsolete redirection function GetItemsLineHeightWithSpacing() (which redirects to GetFrameHeightWithSpacing()), as intended and stated in docs of 1.53. +- Misc: Added misc/natvis/imgui.natvis for visual studio debugger users to easily visualizer imgui internal types. Added to examples projects. +- Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41) +- Misc: Updated stb_rect_pack from 0.10 to 0.11 (minor changes). +- Fonts: Updated stb_truetype from 1.14 to stb_truetype 1.19. (w/ include fix from some platforms #1622) +- Fonts: Added optional FreeType rasterizer in misc/freetype. Moved from imgui_club repo. (#618) [@Vuhdo, @mikesart, @ocornut] +- Fonts: Moved extra_fonts/ to misc/fonts/. +- Demo: Improved Selectable() examples. (#1528) +- Demo: Tweaked the Child demos, added a menu bar to the second child to test some navigation functions. +- Demo: Console: Using ImGuiCol_Text to be more friendly to color changes. +- Demo: Using IM_COL32() instead of ImColor() in ImDrawList centric contexts. Trying to phase out use of the ImColor helper whenever possible. +- Examples: Files in examples/ now include their own changelog so it is easier to occasionally update your bindings if needed. +- Examples: Using Dark theme by default. (#707). Tweaked demo code. +- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) +- Examples: DirectX12: Added DirectX 12 example. (#301) [@jdm3] +- Examples: OpenGL3+GLFW,SDL: Changed GLSL shader version to 150 (#1466, #1504). +- Examples: OpenGL3+GLFW,SDL: Creating VAO in the render function so it can be more easily used by multiple shared OpenGL contexts. (#1217) +- Examples: OpenGL3+GLFW: Using 3.2 context instead of 3.3. (#1466) +- Examples: OpenGL: Setting up glPixelStorei() explicitly before uploading texture. +- Examples: OpenGL: Calls to glPolygonMode() are casting parameters as GLEnum to not fail with more strict bindings. (#1628) [@ilia-glushchenko] +- Examples: Win32 (DirectX9,10,11,12): Added support for mouse cursor shapes. (#1495) +- Examples: Win32 (DirectX9,10,11,12: Support for windows using the CS_DBLCLKS class flag by handling the double-click messages (WM_LBUTTONDBLCLK etc.). (#1538, #754) [@ndandoulakis] +- Examples: Win32 (DirectX9,10,11,12): Made the Win32 proc handlers not assert if there is no active context yet, to be more flexible with creation order. (#1565) +- Examples: GLFW: Added support for mouse cursor shapes (the diagonal resize cursors are unfortunately not supported by GLFW at the moment. (#1495) +- Examples: SDL: Added support for mouse cursor shapes. (#1626) [@olls] +- Examples: SDL: Using SDL_CaptureMouse() to retrieve coordinates outside of client area when dragging (SDL 2.0.4+ only, otherwise using SDL_WINDOW_INPUT_FOCUS instead of previously SDL_WINDOW_MOUSE_FOCUS). (#1559) +- Examples: SDL: Enabled vsync by default so people don't come at us with demoes running at 2000 FPS burning a cpu core. +- Examples: SDL: Using SDL_GetPerformanceCounter() / SDL_GetPerformanceFrequency() to handle framerate over 1000 FPS properly. (#996) +- Examples: SDL: Using scancode exclusively instead of a confusing mixture of scancodes and keycodes. +- Examples: SDL: Visual Studio: Added .vcxproj file. Using %SDL2_DIR% in the default .vcxproj and build files instead of %SDL_DIR%, the earlier being more standard. +- Examples: Vulkan: Visual Studio: Added .vcxproj file. +- Examples: Apple: Fixed filenames in OSX xcode project. Various other Mac friendly fixes. [@gerryhernandez etc.] +- Examples: Visual Studio: Disabled extraneous function-level check in Release build. +- Internals: Lots of refactoring! +- Various minor fixes, tweaks, optimizations, comments. ----------------------------------------------------------------------- @@ -72,13 +189,13 @@ Other Changes: - Added `io.OptCursorBlink` option to allow disabling cursor blinking. (#1427) - Added `GetOverlayDrawList()` helper to quickly get access to a ImDrawList that will be rendered in front of every windows. - Added `GetFrameHeight()` helper which returns `(FontSize + style.FramePadding.y * 2)`. -- DragDrop: Added Beta API to easily use drag and drop patterns between imgui widgets. +- Drag and Drop: Added Beta API to easily use drag and drop patterns between imgui widgets. - Setup a source on a widget with `BeginDragDropSource()`, `SetDragDropPayload()`, `EndDragDropSource()` functions. - Receive data with `BeginDragDropTarget()`, `AcceptDragDropPayload()`, `EndDragDropTarget()`. - See ImGuiDragDropFlags for various options. - The ColorEdit4() and ColorButton() widgets now support Drag and Drop. - The API is tagged as Beta as it still may be subject to small changes. -- DragDrop: When drag and drop is active, tree nodes and collapsing header can be opened by hovering on them for 0.7 seconds. +- Drag and Drop: When drag and drop is active, tree nodes and collapsing header can be opened by hovering on them for 0.7 seconds. - Renamed io.OSXBehaviors to io.OptMacOSXBehaviors. Should not affect users as the compile-time default is usually enough. (#473, #650) - Style: Added StyleColorsDark() style. (#707) [@dougbinks] - Style: Added StyleColorsLight() style. Best used with frame borders + thicker font than the default font. (#707) diff --git a/imgui.cpp b/imgui.cpp index 7475120b..c53edb84 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -250,7 +250,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. - - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is really usable in typical conditions at the moment. + - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. - 2018/02/07 (1.60) - reorganized context handling to be more explicit, - YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. From 5427eca960fc95249cf290eff124e6d27e16bf04 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 25 Feb 2018 19:05:31 +0100 Subject: [PATCH 55/87] Compacted some old Breaking Changes notes (Pre July 2015 stuff) --- imgui.cpp | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index c53edb84..4b387f45 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -340,18 +340,11 @@ this necessary change will break your rendering function! the fix should be very easy. sorry for that :( - if you are using a vanilla copy of one of the imgui_impl_XXXX.cpp provided in the example, you just need to update your copy and you can ignore the rest. - the signature of the io.RenderDrawListsFn handler has changed! - ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) - became: - ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data). - argument 'cmd_lists' -> 'draw_data->CmdLists' - argument 'cmd_lists_count' -> 'draw_data->CmdListsCount' - ImDrawList 'commands' -> 'CmdBuffer' - ImDrawList 'vtx_buffer' -> 'VtxBuffer' - ImDrawList n/a -> 'IdxBuffer' (new) - ImDrawCmd 'vtx_count' -> 'ElemCount' - ImDrawCmd 'clip_rect' -> 'ClipRect' - ImDrawCmd 'user_callback' -> 'UserCallback' - ImDrawCmd 'texture_id' -> 'TextureId' + old: ImGui_XXXX_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) + new: ImGui_XXXX_RenderDrawLists(ImDrawData* draw_data). + argument: 'cmd_lists' becomes 'draw_data->CmdLists', 'cmd_lists_count' becomes 'draw_data->CmdListsCount' + ImDrawList: 'commands' becomes 'CmdBuffer', 'vtx_buffer' becomes 'VtxBuffer', 'IdxBuffer' is new. + ImDrawCmd: 'vtx_count' becomes 'ElemCount', 'clip_rect' becomes 'ClipRect', 'user_callback' becomes 'UserCallback', 'texture_id' becomes 'TextureId'. - each ImDrawList now contains both a vertex buffer and an index buffer. For each command, render ElemCount/3 triangles using indices from the index buffer. - if you REALLY cannot render indexed primitives, you can call the draw_data->DeIndexAllBuffers() method to de-index the buffers. This is slow and a waste of CPU/GPU. Prefer using indexed rendering! - refer to code in the examples/ folder or ask on the GitHub if you are unsure of how to upgrade. please upgrade! @@ -382,18 +375,9 @@ - 2015/01/19 (1.30) - renamed ImGuiStorage::GetIntPtr()/GetFloatPtr() to GetIntRef()/GetIntRef() because Ptr was conflicting with actual pointer storage functions. - 2015/01/11 (1.30) - big font/image API change! now loads TTF file. allow for multiple fonts. no need for a PNG loader. (1.30) - removed GetDefaultFontData(). uses io.Fonts->GetTextureData*() API to retrieve uncompressed pixels. - this sequence: - const void* png_data; - unsigned int png_size; - ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); - // - became: - unsigned char* pixels; - int width, height; - io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); - // - io.Fonts->TexID = (your_texture_identifier); - you now have much more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. + font init: const void* png_data; unsigned int png_size; ImGui::GetDefaultFontData(NULL, NULL, &png_data, &png_size); <..Upload texture to GPU..> + became: unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); <..Upload texture to GPU>; io.Fonts->TexId = YourTextureIdentifier; + you now more flexibility to load multiple TTF fonts and manage the texture buffer for internal needs. it is now recommended that you sample the font texture with bilinear interpolation. (1.30) - added texture identifier in ImDrawCmd passed to your render function (we can now render images). make sure to set io.Fonts->TexID. (1.30) - removed IO.PixelCenterOffset (unnecessary, can be handled in user projection matrix) From c7835dd1892ab11750cd6917b37b74e426fe13b9 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 26 Feb 2018 13:10:34 +0100 Subject: [PATCH 56/87] ImRect: Removed misleading IsFinite() function used by some Nav code. --- imgui.cpp | 4 ++-- imgui_internal.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4b387f45..3a6d681e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3211,7 +3211,7 @@ static void ImGui::NavUpdate() } // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) - ImRect nav_rect_rel = (g.NavWindow && g.NavWindow->NavRectRel[g.NavLayer].IsFinite()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0,0,0,0); + ImRect nav_rect_rel = (g.NavWindow && !g.NavWindow->NavRectRel[g.NavLayer].IsInverted()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0,0,0,0); g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : GetViewportRect(); g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; @@ -13202,7 +13202,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); - if (window->NavRectRel[0].IsFinite()) + if (window->NavRectRel[0].IsInverted()) ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y); else ImGui::BulletText("NavRectRel[0]: "); diff --git a/imgui_internal.h b/imgui_internal.h index 221e5d46..ddbbf0d7 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -341,7 +341,6 @@ struct IMGUI_API ImRect void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } - bool IsFinite() const { return Min.x != FLT_MAX; } }; // Stacked color modifier, backup of modified data so we can restore it From a869e944b0671f406f3359ebb18a3947edbe1ab2 Mon Sep 17 00:00:00 2001 From: Hossam Ayman Date: Mon, 26 Feb 2018 17:31:02 +0200 Subject: [PATCH 57/87] README.md typo fix --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 51e9193a..1190405a 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/ _NB: those third-party bindings may be more or less maintained, more or less close to the original API (as people who create language bindings sometimes haven't used the C++ API themselves.. for the good reason that they aren't C++ users). Dear ImGui was designed with C++ in mind and some of the subtleties may be lost in translation with other languages. If your language supports it, I would suggest replicating the function overloading and default parameters used in the original, else the API may be harder to use. In doubt, please check the original C++ version first!_ -Languages: (third-party bindinds) +Languages: (third-party bindings) - C: [cimgui](https://github.com/Extrawurst/cimgui) - C#/.Net: [ImGui.NET](https://github.com/mellinoe/ImGui.NET) - ChaiScript: [imgui-chaiscript](https://github.com/JuJuBoSc/imgui-chaiscript) From 2c9f45bbe7260139b4fdb3c0285ecf170cdd4522 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Feb 2018 18:51:40 +0100 Subject: [PATCH 58/87] Renamed ImGuiNavFlags io.NavFlags to ImGuiConfigFlags io.ConfigFlags. (#787) --- CHANGELOG.txt | 8 +++--- README.md | 2 +- examples/allegro5_example/main.cpp | 2 +- .../directx10_example/imgui_impl_dx10.cpp | 2 +- examples/directx10_example/main.cpp | 2 +- .../directx11_example/imgui_impl_dx11.cpp | 2 +- examples/directx11_example/main.cpp | 2 +- examples/directx12_example/main.cpp | 2 +- examples/directx9_example/main.cpp | 2 +- examples/marmalade_example/main.cpp | 2 +- .../opengl2_example/imgui_impl_glfw_gl2.cpp | 2 +- examples/opengl2_example/main.cpp | 2 +- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 8 +++--- .../opengl3_example/imgui_impl_glfw_gl3.h | 2 +- examples/opengl3_example/main.cpp | 4 +-- examples/sdl_opengl2_example/main.cpp | 2 +- examples/sdl_opengl3_example/main.cpp | 2 +- examples/vulkan_example/main.cpp | 3 +- imgui.cpp | 28 +++++++++---------- imgui.h | 22 +++++++-------- imgui_demo.cpp | 6 ++-- imgui_internal.h | 4 +-- 22 files changed, 56 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a0f0e2a7..06ee3c3b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -66,11 +66,11 @@ Other Changes: - Navigation: merged in the gamepad/keyboard navigation (about one million changes!). (#787, #323) The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - To use Keyboard Navigation: - - Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + NavFlags_EnableKeyboard), the io.WantCaptureKeyboard flag will be set. + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from io.NavActive or io.NavVisible. Read imgui.cpp for more details. - To use Gamepad Navigation: - - Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). - See https://github.com/ocornut/imgui/issues/1599 for recommended gamepad mapping. - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. Read imgui.cpp for more details. - Navigation: SetItemDefaultFocus() sets the navigation position in addition to scrolling. (#787) @@ -78,7 +78,7 @@ Other Changes: - Navigation: Added window flags: ImGuiWindowFlags_NoNav (ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus). - Navigation: Style: Added ImGuiCol_NavHighlight, ImGuiCol_NavWindowingHighlight colors. (#787) - Navigation: TreeNode: Added ImGuiTreeNodeFlags_NavLeftJumpsBackHere flag to allow Nav Left direction to jump back to parent tree node from any of its child. (#1079) -- Navigation: IO: Added io.NavFlags (input), io.NavActive (output), io.NavVisible (output). (#787) +- Navigation: IO: Added io.ConfigFlags (input), io.NavActive (output), io.NavVisible (output). (#787) - Context: Removed the default global context and font atlas instances, which caused various problems to users of multiple contexts and DLL users. (#1565) YOU NOW NEED TO CALL ImGui::CreateContext() AT THE BEGINNING OF YOUR APP, AND CALL ImGui::DestroyContext() AT THE END. Existing apps will assert/crash without it. - Context: Removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions() and shared by all contexts. (#1565, #586, #992, #1007, #1558) diff --git a/README.md b/README.md index 1190405a..da797963 100644 --- a/README.md +++ b/README.md @@ -248,7 +248,7 @@ See the FAQ in imgui.cpp for answers. How do you use Dear ImGui on a platform that may not have a mouse or keyboard? -You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.NavFlags |= ImGuiNavFlags_EnableGamepad`). +You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`). You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). diff --git a/examples/allegro5_example/main.cpp b/examples/allegro5_example/main.cpp index 1478573c..6169ebca 100644 --- a/examples/allegro5_example/main.cpp +++ b/examples/allegro5_example/main.cpp @@ -25,8 +25,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplA5_Init(display); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index ed1efeef..caef5e1b 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -14,7 +14,7 @@ // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX10_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. diff --git a/examples/directx10_example/main.cpp b/examples/directx10_example/main.cpp index 346fd35e..f1afdf66 100644 --- a/examples/directx10_example/main.cpp +++ b/examples/directx10_example/main.cpp @@ -114,8 +114,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplDX10_Init(hwnd, g_pd3dDevice); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index 84dcdbee..c7f312c6 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -14,7 +14,7 @@ // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert. // 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag. diff --git a/examples/directx11_example/main.cpp b/examples/directx11_example/main.cpp index 518aa7c2..d9ef40d1 100644 --- a/examples/directx11_example/main.cpp +++ b/examples/directx11_example/main.cpp @@ -117,8 +117,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplDX11_Init(hwnd, g_pd3dDevice, g_pd3dDeviceContext); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/directx12_example/main.cpp b/examples/directx12_example/main.cpp index 6a4b78d8..65fe70b5 100644 --- a/examples/directx12_example/main.cpp +++ b/examples/directx12_example/main.cpp @@ -288,7 +288,7 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplDX12_Init(hwnd, NUM_FRAMES_IN_FLIGHT, g_pd3dDevice, DXGI_FORMAT_R8G8B8A8_UNORM, g_pd3dSrvDescHeap->GetCPUDescriptorHandleForHeapStart(), diff --git a/examples/directx9_example/main.cpp b/examples/directx9_example/main.cpp index f4c7a9f0..fce9482e 100644 --- a/examples/directx9_example/main.cpp +++ b/examples/directx9_example/main.cpp @@ -77,8 +77,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplDX9_Init(hwnd, g_pd3dDevice); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/marmalade_example/main.cpp b/examples/marmalade_example/main.cpp index f2ddae40..cb9113ed 100644 --- a/examples/marmalade_example/main.cpp +++ b/examples/marmalade_example/main.cpp @@ -19,8 +19,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_Marmalade_Init(true); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index f78b77be..03d7659e 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -24,7 +24,7 @@ // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL2_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-02-06: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. // 2018-01-09: Misc: Renamed imgui_impl_glfw.* to imgui_impl_glfw_gl2.*. diff --git a/examples/opengl2_example/main.cpp b/examples/opengl2_example/main.cpp index caae8c2b..37060688 100644 --- a/examples/opengl2_example/main.cpp +++ b/examples/opengl2_example/main.cpp @@ -29,8 +29,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplGlfwGL2_Init(window, true); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index ce8030b1..40b0c4d4 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -4,7 +4,7 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. -// [X] Gamepad navigation mapping. Enable with 'io.NavFlags |= ImGuiNavFlags_EnableGamepad'. +// [X] Gamepad navigation mapping. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). @@ -19,8 +19,8 @@ // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplGlfwGL3_RenderDrawData() in the .h file so you can call it yourself. // 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves. // 2018-02-06: Inputs: Added mapping for ImGuiKey_Space. -// 2018-01-25: Inputs: Added gamepad support if ImGuiNavFlags_EnableGamepad is set. -// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse by using navigation and ImGuiNavFlags_MoveMouse is set. +// 2018-01-25: Inputs: Added gamepad support if ImGuiConfigFlags_NavEnableGamepad is set. +// 2018-01-25: Inputs: Honoring the io.WantMoveMouse by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set). // 2018-01-20: Inputs: Added Horizontal Mouse Wheel support. // 2018-01-18: Inputs: Added mapping for ImGuiKey_Insert. // 2018-01-07: OpenGL: Changed GLSL shader version from 330 to 150. (Also changed GL context from 3.3 to 3.2 in example's main.cpp) @@ -469,7 +469,7 @@ void ImGui_ImplGlfwGL3_NewFrame() // Gamepad navigation mapping [BETA] memset(io.NavInputs, 0, sizeof(io.NavInputs)); - if (io.NavFlags & ImGuiNavFlags_EnableGamepad) + if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) { // Update gamepad inputs #define MAP_BUTTON(NAV_NO, BUTTON_NO) { if (buttons_count > BUTTON_NO && buttons[BUTTON_NO] == GLFW_PRESS) io.NavInputs[NAV_NO] = 1.0f; } diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 71ea4122..6cbbe4a5 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -4,7 +4,7 @@ // Implemented features: // [X] User texture binding. Cast 'GLuint' OpenGL texture identifier as void*/ImTextureID. Read the FAQ about ImTextureID in imgui.cpp. -// [X] Gamepad navigation mapping. Enable with 'io.NavFlags |= ImGuiNavFlags_EnableGamepad'. +// [X] Gamepad navigation mapping. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you use this binding you'll need to call 4 functions: ImGui_ImplXXXX_Init(), ImGui_ImplXXXX_NewFrame(), ImGui::Render() and ImGui_ImplXXXX_Shutdown(). diff --git a/examples/opengl3_example/main.cpp b/examples/opengl3_example/main.cpp index a5f59e8a..143dcc59 100644 --- a/examples/opengl3_example/main.cpp +++ b/examples/opengl3_example/main.cpp @@ -34,9 +34,9 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls ImGui_ImplGlfwGL3_Init(window, true); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls - //io.NavFlags |= ImGuiNavFlags_EnableGamepad; // Enable Gamepad Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/sdl_opengl2_example/main.cpp b/examples/sdl_opengl2_example/main.cpp index 8f4ca93d..2dfdd72b 100644 --- a/examples/sdl_opengl2_example/main.cpp +++ b/examples/sdl_opengl2_example/main.cpp @@ -36,8 +36,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplSdlGL2_Init(window); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/examples/sdl_opengl3_example/main.cpp b/examples/sdl_opengl3_example/main.cpp index a3fc625c..4426fcde 100644 --- a/examples/sdl_opengl3_example/main.cpp +++ b/examples/sdl_opengl3_example/main.cpp @@ -36,8 +36,8 @@ int main(int, char**) // Setup ImGui binding ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplSdlGL3_Init(window); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Setup style ImGui::StyleColorsDark(); diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index be5fe528..ca647926 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -624,8 +624,9 @@ int main(int, char**) init_data.pipeline_cache = g_PipelineCache; init_data.descriptor_pool = g_DescriptorPool; init_data.check_vk_result = check_vk_result; + + //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplGlfwVulkan_Init(window, true, &init_data); - //io.NavFlags |= ImGuiNavFlags_EnableKeyboard; // Enable Keyboard Controls // Setup style ImGui::StyleColorsDark(); diff --git a/imgui.cpp b/imgui.cpp index 3a6d681e..be0f532d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -216,15 +216,15 @@ - Ask questions and report issues at https://github.com/ocornut/imgui/issues/787 - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - Keyboard: - - Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. - - When keyboard navigation is active (io.NavActive + NavFlags_EnableKeyboard), the io.WantCaptureKeyboard flag will be set. + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. + - When keyboard navigation is active (io.NavActive + ImGuiConfigFlags_NavEnableKeyboard), the io.WantCaptureKeyboard flag will be set. For more advanced uses, you may want to read from: - io.NavActive: true when a window is focused and it doesn't have the ImGuiWindowFlags_NoNavInputs flag set. - io.NavVisible: true when the navigation cursor is visible (and usually goes false when mouse is used). - or query focus information with e.g. IsWindowFocused(), IsItemFocused() etc. functions. Please reach out if you think the game vs navigation input sharing could be improved. - Gamepad: - - Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). + - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values: 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. @@ -234,11 +234,11 @@ - Mouse: - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - Consoles/Tablet/Phone users: Consider using Synergy host (on your computer) + uSynergy.c (in your console/tablet/phone app) to use your PC mouse/keyboard. - - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiNavFlags_MoveMouse flag in io.NavFlags. - Enabling ImGuiNavFlags_MoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. + - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavMoveMouse flag. + Enabling ImGuiConfigFlags_NavMoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantMoveMouse' to notify you that it wants the mouse cursor to be moved. When that happens your back-end NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the binding in examples/ do that. - (If you set the ImGuiNavFlags_MoveMouse flag but don't honor 'io.WantMoveMouse' properly, imgui will misbehave as it will see your mouse as moving back and forth.) + (If you set the NavMoveMouse flag but don't honor 'io.WantMoveMouse' properly, imgui will misbehave as it will see your mouse as moving back and forth!) (In a setup when you may not have easy control over the mouse cursor, e.g. uSynergy.c doesn't expose moving remote mouse cursor, you may want to set a boolean to ignore your other external mouse positions until the external source is moved again.) @@ -847,7 +847,7 @@ ImGuiIO::ImGuiIO() // Settings DisplaySize = ImVec2(-1.0f, -1.0f); DeltaTime = 1.0f/60.0f; - NavFlags = 0x00; + ConfigFlags = 0x00; IniSavingRate = 5.0f; IniFilename = "imgui.ini"; LogFilename = "imgui_log.txt"; @@ -2810,7 +2810,7 @@ static void ImGui::NavUpdateWindowing() bool apply_toggle_layer = false; bool start_windowing_with_gamepad = !g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); - bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard); + bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard); if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavigable(g.Windows.Size - 1, -INT_MAX, -1)) { @@ -2965,7 +2965,7 @@ static void ImGui::NavUpdate() // Update Keyboard->Nav inputs mapping memset(g.IO.NavInputs + ImGuiNavInput_InternalStart_, 0, (ImGuiNavInput_COUNT - ImGuiNavInput_InternalStart_) * sizeof(g.IO.NavInputs[0])); - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) { #define NAV_MAP_KEY(_KEY, _NAV_INPUT) if (g.IO.KeyMap[_KEY] != -1 && IsKeyDown(g.IO.KeyMap[_KEY])) g.IO.NavInputs[_NAV_INPUT] = 1.0f; NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate ); @@ -3037,7 +3037,7 @@ static void ImGui::NavUpdate() if (g.NavMousePosDirty && g.NavIdIsAlive) { // Set mouse position given our knowledge of the nav widget position from last frame - if (g.IO.NavFlags & ImGuiNavFlags_MoveMouse) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavMoveMouse) { g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredMousePos(); g.IO.WantMoveMouse = true; @@ -3057,7 +3057,7 @@ static void ImGui::NavUpdate() NavUpdateWindowing(); // Set output flags for user application - g.IO.NavActive = (g.IO.NavFlags & (ImGuiNavFlags_EnableGamepad | ImGuiNavFlags_EnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); + g.IO.NavActive = (g.IO.ConfigFlags & (ImGuiConfigFlags_NavEnableGamepad | ImGuiConfigFlags_NavEnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); g.IO.NavVisible = (g.IO.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest; // Process NavCancel input (to close a popup, get back to parent, clear focus) @@ -3282,7 +3282,7 @@ void ImGui::NewFrame() IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); // Do a simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was super recently added in 1.60 WIP) - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); // Load settings on first frame @@ -3449,7 +3449,7 @@ void ImGui::NewFrame() g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); else g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); - if (g.IO.NavActive && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) && !(g.IO.NavFlags & ImGuiNavFlags_NoCaptureKeyboard)) + if (g.IO.NavActive && (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) g.IO.WantCaptureKeyboard = true; g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; @@ -5844,7 +5844,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) float sc = g.Style.MouseCursorScale; ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; ImRect rect_to_avoid; - if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.NavFlags & ImGuiNavFlags_MoveMouse)) + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavMoveMouse)) rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); else rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. diff --git a/imgui.h b/imgui.h index bd63a2b0..598c92fa 100644 --- a/imgui.h +++ b/imgui.h @@ -95,7 +95,7 @@ typedef int ImGuiComboFlags; // flags: for BeginCombo() typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ -typedef int ImGuiNavFlags; // flags: for io.NavFlags // enum ImGuiNavFlags_ +typedef int ImGuiConfigFlags; // flags: for io.ConfigFlags // enum ImGuiConfigFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ @@ -710,8 +710,8 @@ enum ImGuiKey_ }; // [BETA] Gamepad/Keyboard directional navigation -// Keyboard: Set io.NavFlags |= ImGuiNavFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. -// Gamepad: Set io.NavFlags |= ImGuiNavFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). +// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. +// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). // Read instructions in imgui.cpp for more details. enum ImGuiNavInput_ { @@ -744,13 +744,13 @@ enum ImGuiNavInput_ ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ }; -// [BETA] Gamepad/Keyboard directional navigation flags, stored in io.NavFlags -enum ImGuiNavFlags_ +// Configuration flags stored in io.ConfigFlags +enum ImGuiConfigFlags_ { - ImGuiNavFlags_EnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. - ImGuiNavFlags_EnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. - ImGuiNavFlags_MoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. - ImGuiNavFlags_NoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. + ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. + ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. + ImGuiConfigFlags_NavMoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. }; // Enumeration for PushStyleColor() / PopStyleColor() @@ -953,7 +953,7 @@ struct ImGuiIO ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - ImGuiNavFlags NavFlags; // = 0x00 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. + ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Gamepad/keyboard navigation options, etc. float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). @@ -1027,7 +1027,7 @@ struct ImGuiIO bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active). bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs. bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). - bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiNavFlags_MoveMouse flag is enabled in io.NavFlags. + bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiConfigFlags_NavMoveMouse flag is enabled. bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2a197278..142d9499 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1806,9 +1806,9 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); - ImGui::CheckboxFlags("io.NavFlags: EnableGamepad", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableGamepad); - ImGui::CheckboxFlags("io.NavFlags: EnableKeyboard", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableKeyboard); - ImGui::CheckboxFlags("io.NavFlags: MoveMouse", (unsigned int *)&io.NavFlags, ImGuiNavFlags_MoveMouse); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); + ImGui::CheckboxFlags("io.ConfigFlags: NavEnableKeyboard", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard); + ImGui::CheckboxFlags("io.ConfigFlags: NavMoveMouse", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NavMoveMouse); ImGui::SameLine(); ShowHelpMarker("Request ImGui to move your move cursor when using gamepad/keyboard navigation. NewFrame() will change io.MousePos and set the io.WantMoveMouse flag, your backend will need to apply the new mouse position."); if (ImGui::TreeNode("Keyboard, Mouse & Navigation State")) diff --git a/imgui_internal.h b/imgui_internal.h index ddbbf0d7..9b820436 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -633,8 +633,8 @@ struct ImGuiContext int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid - bool NavMousePosDirty; // When set we will update mouse position if (NavFlags & ImGuiNavFlags_MoveMouse) if set (NB: this not enabled by default) - bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (nb: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) + bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavMoveMouse) if set (NB: this not enabled by default) + bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest bool NavInitRequest; // Init request for appearing window to select first item From b3594a6407853767571b4e71daae5ce90a3609ed Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Feb 2018 21:16:47 +0100 Subject: [PATCH 59/87] Added ImGuiConfigFlags_IsSRGB, ImGuiConfigFlags_IsTouchScreen (strictly for user storage) --- CHANGELOG.txt | 2 ++ imgui.h | 12 ++++++++---- imgui_demo.cpp | 6 ++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 06ee3c3b..5758770d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -126,6 +126,8 @@ Other Changes: - Misc: Added misc/natvis/imgui.natvis for visual studio debugger users to easily visualizer imgui internal types. Added to examples projects. - Misc: Added IMGUI_USER_CONFIG to define a custom configuration filename. (#255, #1573, #1144, #41) - Misc: Updated stb_rect_pack from 0.10 to 0.11 (minor changes). +- Misc: Added ImGuiConfigFlags_IsSRGB and ImGuiConfigFlags_IsTouchScreen user flags (for io.ConfigFlags). + (Those flags are not used by ImGui itself, they only exists to make it easy for the engine/back-end to pass information to the application in a standard manner.) - Fonts: Updated stb_truetype from 1.14 to stb_truetype 1.19. (w/ include fix from some platforms #1622) - Fonts: Added optional FreeType rasterizer in misc/freetype. Moved from imgui_club repo. (#618) [@Vuhdo, @mikesart, @ocornut] - Fonts: Moved extra_fonts/ to misc/fonts/. diff --git a/imgui.h b/imgui.h index 598c92fa..0c39e69d 100644 --- a/imgui.h +++ b/imgui.h @@ -90,12 +90,12 @@ typedef int ImDrawListFlags; // flags: for ImDrawList typedef int ImFontAtlasFlags; // flags: for ImFontAtlas // enum ImFontAtlasFlags_ typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiConfigFlags; // flags: for io.ConfigFlags // enum ImGuiConfigFlags_ typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ -typedef int ImGuiConfigFlags; // flags: for io.ConfigFlags // enum ImGuiConfigFlags_ typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ @@ -710,8 +710,8 @@ enum ImGuiKey_ }; // [BETA] Gamepad/Keyboard directional navigation -// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_EnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. -// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_EnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). +// Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. +// Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). // Read instructions in imgui.cpp for more details. enum ImGuiNavInput_ { @@ -750,7 +750,11 @@ enum ImGuiConfigFlags_ ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. ImGuiConfigFlags_NavMoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. - ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. + + // User storage (to allow your back-end/engine to communicate to code that may be shared between multiple projects. Those flags are not used by core ImGui) + ImGuiConfigFlags_IsSRGB = 1 << 20, // Back-end is SRGB-aware. + ImGuiConfigFlags_IsTouchScreen = 1 << 21 // Back-end is using a touch screen instead of a mouse. }; // Enumeration for PushStyleColor() / PopStyleColor() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 142d9499..4addee55 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2211,10 +2211,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((float)font->MetricsTotalSurface), (int)sqrtf((float)font->MetricsTotalSurface)); for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) - { - ImFontConfig* cfg = &font->ConfigData[config_i]; - ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); - } + if (ImFontConfig* cfg = &font->ConfigData[config_i]) + ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) { // Display all glyphs of the fonts in separate pages of 256 characters From c994796e2648109a06dea6ca7bd583de70fd822e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 28 Feb 2018 21:45:02 +0100 Subject: [PATCH 60/87] Internal: Moved IM_NEWLINE helper to imgui_internal.h --- imgui.cpp | 7 ------- imgui_internal.h | 5 +++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index be0f532d..08a2fe90 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -924,13 +924,6 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) #define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose #define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 -// Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. -#ifdef _WIN32 -#define IM_NEWLINE "\r\n" -#else -#define IM_NEWLINE "\n" -#endif - ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) { ImVec2 ap = p - a; diff --git a/imgui_internal.h b/imgui_internal.h index 9b820436..22504c49 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -81,6 +81,11 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe //----------------------------------------------------------------------------- #define IM_PI 3.14159265358979323846f +#ifdef _WIN32 +#define IM_NEWLINE "\r\n" // Play it nice with Windows users (2018: Notepad _still_ doesn't display files properly when they use Unix-style carriage returns) +#else +#define IM_NEWLINE "\n" +#endif // Helpers: UTF-8 <> wchar IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count From 6797ee4b6839bfa83aa597415f5d5062359ef3e1 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 13:03:12 +0100 Subject: [PATCH 61/87] Nav: Added links to PNG/PSD files for PS4 and Switch. Fixed suggested Joy-con mapping as per typical Nintendo-style mapping. (#787) --- imgui.cpp | 3 ++- imgui.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 08a2fe90..2a67d283 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -77,7 +77,7 @@ - ESCAPE to revert text to its original value. - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - Controls are automatically adjusted for OSX to match standard OSX text editing operations. - - Gamepad navigation: see suggested mappings in imgui.h ImGuiNavInput_ + - Gamepad navigation: see suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at goo.gl/9LgVZW. PROGRAMMER GUIDE @@ -229,6 +229,7 @@ 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, maybe a power curve, etc.). + - You can download PNG/PSD files depicting the gamepad controls for common controllers at: goo.gl/9LgVZW. - If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. - Mouse: diff --git a/imgui.h b/imgui.h index 0c39e69d..ba74a7b7 100644 --- a/imgui.h +++ b/imgui.h @@ -712,12 +712,12 @@ enum ImGuiKey_ // [BETA] Gamepad/Keyboard directional navigation // Keyboard: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. // Gamepad: Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad to enable. Fill the io.NavInputs[] fields before calling NewFrame(). Note that io.NavInputs[] is cleared by EndFrame(). -// Read instructions in imgui.cpp for more details. +// Read instructions in imgui.cpp for more details. Download PNG/PSD at goo.gl/9LgVZW. enum ImGuiNavInput_ { // Gamepad Mapping - ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), B (Switch), Space (Keyboard) - ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), A (Switch), Escape (Keyboard) + ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), A (Switch), Space (Keyboard) + ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), B (Switch), Escape (Keyboard) ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) From 551932697db596a7a476ca536d798f99a408a99d Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Oct 2016 13:02:58 +0200 Subject: [PATCH 62/87] Ensure `make clean` is idempotent. Prior to this, `make clean` would fail if the project was not already fully built, and a second invokation would always fail. --- examples/opengl2_example/Makefile | 2 +- examples/opengl3_example/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index b0ee3152..acff2506 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -61,5 +61,5 @@ $(EXE): $(OBJS) $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) clean: - rm $(EXE) $(OBJS) + rm -f $(EXE) $(OBJS) diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index 133c0a64..cfe58021 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -62,4 +62,4 @@ $(EXE): $(OBJS) $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) clean: - rm $(EXE) $(OBJS) + rm -f $(EXE) $(OBJS) From d4f63c38448dcc7681f485006f5858cd12dca435 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Oct 2016 13:07:43 +0200 Subject: [PATCH 63/87] Use make variables $@ and $^ where appropriate. --- examples/opengl2_example/Makefile | 2 +- examples/opengl3_example/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index acff2506..5ea488ff 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -58,7 +58,7 @@ all: $(EXE) @echo Build complete for $(ECHO_MESSAGE) $(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) clean: rm -f $(EXE) $(OBJS) diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index cfe58021..56f1f8e2 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -59,7 +59,7 @@ all: $(EXE) @echo Build complete for $(ECHO_MESSAGE) $(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) clean: rm -f $(EXE) $(OBJS) From b6f251103bc709c062a3d0f2926df390c34c38fc Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Oct 2016 13:26:39 +0200 Subject: [PATCH 64/87] Define SOURCES instead of OBJS in Makefiles. OBJS is still deduced from SOURCES, but this change gives better control over where the object files get actually written. --- examples/opengl2_example/Makefile | 5 +++-- examples/opengl3_example/Makefile | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index 5ea488ff..621227b1 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -15,8 +15,9 @@ #CXX = clang++ EXE = opengl2_example -OBJS = main.o imgui_impl_glfw_gl2.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o +SOURCES = main.cpp imgui_impl_glfw_gl2.cpp +SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp +OBJS = $(addsuffix .o, $(basename $(SOURCES))) UNAME_S := $(shell uname -s) diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index 56f1f8e2..e2dd9761 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -15,9 +15,10 @@ #CXX = clang++ EXE = opengl3_example -OBJS = main.o imgui_impl_glfw_gl3.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o -OBJS += ../libs/gl3w/GL/gl3w.o +SOURCES = main.cpp imgui_impl_glfw_gl3.cpp +SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp +SOURCES += ../libs/gl3w/GL/gl3w.c +OBJS = $(addsuffix .o, $(basename $(SOURCES))) UNAME_S := $(shell uname -s) From 124d8522b1693f4e5e6aeb86581588f2aa94bc22 Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sat, 22 Oct 2016 13:36:49 +0200 Subject: [PATCH 65/87] Do not store compiled objects outside the project tree. --- examples/opengl2_example/Makefile | 7 +++++-- examples/opengl3_example/Makefile | 10 ++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/examples/opengl2_example/Makefile b/examples/opengl2_example/Makefile index 621227b1..aa7dbf47 100644 --- a/examples/opengl2_example/Makefile +++ b/examples/opengl2_example/Makefile @@ -17,7 +17,7 @@ EXE = opengl2_example SOURCES = main.cpp imgui_impl_glfw_gl2.cpp SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp -OBJS = $(addsuffix .o, $(basename $(SOURCES))) +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) @@ -52,7 +52,10 @@ ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) endif -.cpp.o: +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../../%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< all: $(EXE) diff --git a/examples/opengl3_example/Makefile b/examples/opengl3_example/Makefile index e2dd9761..008f2ca7 100644 --- a/examples/opengl3_example/Makefile +++ b/examples/opengl3_example/Makefile @@ -18,7 +18,7 @@ EXE = opengl3_example SOURCES = main.cpp imgui_impl_glfw_gl3.cpp SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp SOURCES += ../libs/gl3w/GL/gl3w.c -OBJS = $(addsuffix .o, $(basename $(SOURCES))) +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) @@ -53,9 +53,15 @@ ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) endif -.cpp.o: +%.o:%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< +%.o:../../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../libs/gl3w/GL/%.c + $(CC) $(CFLAGS) -c -o $@ $< + all: $(EXE) @echo Build complete for $(ECHO_MESSAGE) From b37ef20c5c1491f90e75d5699281b2722b2b00fb Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 15:54:12 +0100 Subject: [PATCH 66/87] Makefile: updated sdl_opengl3_example with all changes from #885. --- examples/sdl_opengl3_example/Makefile | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/examples/sdl_opengl3_example/Makefile b/examples/sdl_opengl3_example/Makefile index 45f6a663..67f0f03b 100644 --- a/examples/sdl_opengl3_example/Makefile +++ b/examples/sdl_opengl3_example/Makefile @@ -15,9 +15,10 @@ #CXX = clang++ EXE = sdl_opengl3_example -OBJS = main.o imgui_impl_sdl_gl3.o -OBJS += ../../imgui.o ../../imgui_demo.o ../../imgui_draw.o -OBJS += ../libs/gl3w/GL/gl3w.o +SOURCES = main.cpp imgui_impl_sdl_gl3.cpp +SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp +SOURCES += ../libs/gl3w/GL/gl3w.c +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) UNAME_S := $(shell uname -s) @@ -50,14 +51,20 @@ ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) endif -.cpp.o: +%.o:%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< +%.o:../../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../libs/gl3w/GL/%.c + $(CC) $(CFLAGS) -c -o $@ $< + all: $(EXE) @echo Build complete for $(ECHO_MESSAGE) $(EXE): $(OBJS) - $(CXX) -o $(EXE) $(OBJS) $(CXXFLAGS) $(LIBS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) clean: - rm $(EXE) $(OBJS) + rm -f $(EXE) $(OBJS) From df8a9c49eb6d9f134411eeffa0441f561aec3967 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 1 Mar 2018 16:29:32 +0100 Subject: [PATCH 67/87] Allow user to override ImTextureId. (#1641) --- imgui.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index ba74a7b7..2e66090f 100644 --- a/imgui.h +++ b/imgui.h @@ -74,11 +74,14 @@ struct ImGuiListClipper; // Helper to manually clip large list of ite struct ImGuiPayload; // User data payload for drag and drop operations struct ImGuiContext; // ImGui context (opaque) +#ifndef ImTextureID +typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) +#endif + // Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // character for keyboard input/display -typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ From 11f13ab24fda03a431937976985cde96de1acda0 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 3 Mar 2018 19:08:22 +0100 Subject: [PATCH 68/87] Internal: renamed RenderTriangle() to RenderArrow(). --- imgui.cpp | 14 +++++++------- imgui_internal.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 2a67d283..126a3ca7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4277,7 +4277,7 @@ void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) } // Render a triangle to denote expanded/collapsed state -void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) +void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; @@ -6079,7 +6079,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (ButtonBehavior(bb, id, NULL, NULL)) window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function RenderNavHighlight(bb, id); - RenderTriangle(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); + RenderArrow(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); } // Close button @@ -7736,7 +7736,7 @@ bool ImGui::ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFla const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); RenderNavHighlight(bb, id); RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderTriangle(bb.Min + padding, dir, 1.0f); + RenderArrow(bb.Min + padding, dir, 1.0f); return pressed; } @@ -8066,7 +8066,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l // Framed type RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding); RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin); - RenderTriangle(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); + RenderArrow(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); if (g.LogEnabled) { // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. @@ -8093,7 +8093,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (flags & ImGuiTreeNodeFlags_Bullet) RenderBullet(frame_bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y)); else if (!(flags & ImGuiTreeNodeFlags_Leaf)) - RenderTriangle(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); + RenderArrow(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); if (g.LogEnabled) LogRenderedText(&text_pos, ">"); RenderText(text_pos, label, label_end, false); @@ -10598,7 +10598,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF RenderNavHighlight(frame_bb, id); RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING - RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); + RenderArrow(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); if (preview_value != NULL) RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); if (label_size.x > 0) @@ -11150,7 +11150,7 @@ bool ImGui::BeginMenu(const char* label, bool enabled) float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right); + RenderArrow(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right); if (!enabled) PopStyleColor(); } diff --git a/imgui_internal.h b/imgui_internal.h index 22504c49..3b8461c4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1098,7 +1098,7 @@ namespace ImGui IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); - IMGUI_API void RenderTriangle(ImVec2 pos, ImGuiDir dir, float scale = 1.0f); + IMGUI_API void RenderArrow(ImVec2 pos, ImGuiDir dir, float scale = 1.0f); IMGUI_API void RenderBullet(ImVec2 pos); IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz); IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight From 839cdd37a31011992ec449d458b83de2b473e840 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 3 Mar 2018 19:23:48 +0100 Subject: [PATCH 69/87] Combo: Arrow button isn't displayed over frame color, so color is consistent with other button + the button doesn't have inner rounding. --- imgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 126a3ca7..077be83f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10596,8 +10596,9 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF const float arrow_size = GetFrameHeight(); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING + window->DrawList->AddRectFilled(frame_bb.Min, ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Max.y), GetColorU32(ImGuiCol_FrameBg), style.FrameRounding, ImDrawCornerFlags_Left); + window->DrawList->AddRectFilled(ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); + RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding); RenderArrow(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); if (preview_value != NULL) RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); From 1549c5cf5e64686ee8247510e9a36abbec1d0427 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 3 Mar 2018 19:43:31 +0100 Subject: [PATCH 70/87] BeginCombo(): Added ImGuiComboFlags_NoArrowButton and ImGuiComboFlags_NoPreview flags + hover color matches drag and sliders. --- CHANGELOG.txt | 4 ++++ imgui.cpp | 23 +++++++++++++++-------- imgui.h | 2 ++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5758770d..db2b8555 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -112,6 +112,10 @@ Other Changes: - Drag and Drop: Increased payload type string to 12 characters instead of 8. (#143) - Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143) - DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) +- Slider, Combo: Use ImGuiCol_FrameBgHovered color when hovered. (#1456) [@stfx] +- Combo: BeginCombo(): Added ImGuiComboFlags_NoArrowButton to disable the arrow button and only display the wide value preview box. +- Combo: BeginCombo(): Added ImGuiComboFlags_NoPreview to disable the preview and only display a square arrow button. +- Combo: Arrow button isn't displayed over frame background so its blended color matches other buttons. Left side of the button isn't rounded. - PlotLines: plot a flat line if scale_min==scale_max. (#1621) - ImFontAtlas: Handle stb_truetype stbtt_InitFont() and stbtt_PackBegin() possible failures more gracefully, GetTexDataAsRGBA32() won't crash during conversion. (#1527) - ImFontAtlas: Moved mouse cursor data out of ImGuiContext, fix drawing them with multiple contexts. Also remove the last remaining undesirable dependency on ImGui in imgui_draw.cpp. (#939) diff --git a/imgui.cpp b/imgui.cpp index b1a41449..bf8c81d6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -8562,7 +8562,7 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v const ImGuiStyle& style = g.Style; // Draw frame - const ImU32 frame_col = GetColorU32((g.ActiveId == id ) ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); RenderNavHighlight(frame_bb, id); RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); @@ -10573,16 +10573,19 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF ImGuiContext& g = *GImGui; ImGuiCond backup_next_window_size_constraint = g.NextWindowData.SizeConstraintCond; g.NextWindowData.SizeConstraintCond = 0; - + ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; + IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together + const ImGuiStyle& style = g.Style; const ImGuiID id = window->GetID(label); - const float w = CalcItemWidth(); + const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight(); const ImVec2 label_size = CalcTextSize(label, NULL, true); + const float w = (flags & ImGuiComboFlags_NoPreview) ? arrow_size : CalcItemWidth(); const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); ItemSize(total_bb, style.FramePadding.y); @@ -10593,14 +10596,18 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); bool popup_open = IsPopupOpen(id); - const float arrow_size = GetFrameHeight(); const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); + const ImU32 frame_col = GetColorU32(hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); RenderNavHighlight(frame_bb, id); - window->DrawList->AddRectFilled(frame_bb.Min, ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Max.y), GetColorU32(ImGuiCol_FrameBg), style.FrameRounding, ImDrawCornerFlags_Left); - window->DrawList->AddRectFilled(ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); + if (!(flags & ImGuiComboFlags_NoPreview)) + window->DrawList->AddRectFilled(frame_bb.Min, ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Max.y), frame_col, style.FrameRounding, ImDrawCornerFlags_Left); + if (!(flags & ImGuiComboFlags_NoArrowButton)) + { + window->DrawList->AddRectFilled(ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32((popup_open || hovered) ? ImGuiCol_ButtonHovered : ImGuiCol_Button), style.FrameRounding, (w <= arrow_size) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Right); + RenderArrow(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); + } RenderFrameBorder(frame_bb.Min, frame_bb.Max, style.FrameRounding); - RenderArrow(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); - if (preview_value != NULL) + if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview)) RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); if (label_size.x > 0) RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); diff --git a/imgui.h b/imgui.h index 2e66090f..07f6ec78 100644 --- a/imgui.h +++ b/imgui.h @@ -639,6 +639,8 @@ enum ImGuiComboFlags_ ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_NoArrowButton = 1 << 5, // Display on the preview box without the square arrow button + ImGuiComboFlags_NoPreview = 1 << 6, // Display only a square arrow button ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest }; From 8a4093f38b0b964c66e6e3111db9388e135c4e38 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 3 Mar 2018 20:08:03 +0100 Subject: [PATCH 71/87] Added ArrowButton(). Exposed ImGuiDir. --- CHANGELOG.txt | 1 + imgui.cpp | 38 ++++++++++++++++++++++++++++++++------ imgui.h | 15 ++++++++++++++- imgui_demo.cpp | 6 ++++++ imgui_internal.h | 10 ---------- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index db2b8555..59e1aa61 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -92,6 +92,7 @@ Other Changes: - Window: Added SetNextWindowBgAlpha() helper. Particularly helpul since the legacy 5-parameters version of Begin() has been marked as obsolete in 1.53. (#1567) - Window: Fixed SetNextWindowContentSize() with 0.0f on Y axis (or SetNextWindowContentWidth()) overwriting the contents size. Got broken on Dec 10 (1.53). (#1363) - Window: CloseButton: Fixed cross positioning being a little off. +- ArrowButton: Added ArrowButton() given a cardinal direction (e.g. ImGuiDir_Left). - InputText: Added alternative clipboard shortcuts: Shift+Delete (cut), Ctrl+Insert (copy), Shift+Insert (paste). (#1541) - InputText: Fixed losing Cursor X position when clicking outside on an item that's submitted after the InputText(). It was only noticeable when restoring focus programmatically. (#1418, #1554) - Style: Enable window border by default. (#707) diff --git a/imgui.cpp b/imgui.cpp index bf8c81d6..1bf25b70 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4306,7 +4306,7 @@ void ImGui::RenderArrow(ImVec2 p_min, ImGuiDir dir, float scale) c = ImVec2(-0.500f,-0.866f) * r; break; case ImGuiDir_None: - case ImGuiDir_Count_: + case ImGuiDir_COUNT: IM_ASSERT(0); break; } @@ -5200,8 +5200,8 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& siz // Combo Box policy (we want a connecting edge) if (policy == ImGuiPopupPositionPolicy_ComboBox) { - const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; - for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) + const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++) { const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; if (n != -1 && dir == *last_dir) // Already tried this direction? @@ -5219,8 +5219,8 @@ static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& siz } // Default popup policy - const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; - for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) + const ImGuiDir dir_prefered_order[ImGuiDir_COUNT] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_COUNT; n++) { const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; if (n != -1 && dir == *last_dir) // Already tried this direction? @@ -7663,6 +7663,32 @@ bool ImGui::SmallButton(const char* label) return pressed; } +bool ImGui::ArrowButton(const char* str_id, ImGuiDir dir) +{ + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + + ImGuiContext& g = *GImGui; + const ImGuiID id = window->GetID(str_id); + float sz = ImGui::GetFrameHeight(); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(sz, sz)); + ItemSize(bb); + if (!ItemAdd(bb, id)) + return false; + + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + + // Render + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, g.Style.FrameRounding); + RenderArrow(bb.Min + g.Style.FramePadding, dir); + + return pressed; +} + // Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg) @@ -11734,7 +11760,7 @@ static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGui case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; - case ImGuiDir_None: case ImGuiDir_Count_: break; // Fix warnings + case ImGuiDir_None: case ImGuiDir_COUNT: break; // Fix warnings } } diff --git a/imgui.h b/imgui.h index 07f6ec78..d2bf0682 100644 --- a/imgui.h +++ b/imgui.h @@ -78,11 +78,12 @@ struct ImGuiContext; // ImGui context (opaque) typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) #endif -// Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) +// Typedefs and Enumerations (declared as int for compatibility with old C++ and to not pollute the top of this file) typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) typedef unsigned short ImWchar; // character for keyboard input/display typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ +typedef int ImGuiDir; // enum: a cardinal direction // enum ImGuiDir_ typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ typedef int ImGuiNavInput; // enum: an input identifier for navigation // enum ImGuiNavInput_ @@ -312,6 +313,7 @@ namespace ImGui // Widgets: Main IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text + IMGUI_API bool ArrowButton(const char* str_id, ImGuiDir dir); IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding @@ -687,6 +689,17 @@ enum ImGuiDragDropFlags_ #define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. #define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. +// A direction +enum ImGuiDir_ +{ + ImGuiDir_None = -1, + ImGuiDir_Left = 0, + ImGuiDir_Right = 1, + ImGuiDir_Up = 2, + ImGuiDir_Down = 3, + ImGuiDir_COUNT +}; + // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4addee55..34dae8a7 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -300,6 +300,12 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::PopID(); } + // Arrow buttons + float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + if (ImGui::ArrowButton("##left", ImGuiDir_Left)) {} + ImGui::SameLine(0.0f, spacing); + if (ImGui::ArrowButton("##left", ImGuiDir_Right)) {} + ImGui::Text("Hover over me"); if (ImGui::IsItemHovered()) ImGui::SetTooltip("I am a tooltip"); diff --git a/imgui_internal.h b/imgui_internal.h index 3b8461c4..10ba8532 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -260,16 +260,6 @@ enum ImGuiDataType ImGuiDataType_Float2 }; -enum ImGuiDir -{ - ImGuiDir_None = -1, - ImGuiDir_Left = 0, - ImGuiDir_Right = 1, - ImGuiDir_Up = 2, - ImGuiDir_Down = 3, - ImGuiDir_Count_ -}; - enum ImGuiInputSource { ImGuiInputSource_None = 0, From 69e700f8694f89707b7aec91551f4a9546684040 Mon Sep 17 00:00:00 2001 From: omar Date: Sat, 3 Mar 2018 20:15:10 +0100 Subject: [PATCH 72/87] Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT for consistency with other enums. Added --- CHANGELOG.txt | 1 + examples/directx10_example/imgui_impl_dx10.cpp | 2 +- examples/directx11_example/imgui_impl_dx11.cpp | 2 +- examples/directx12_example/imgui_impl_dx12.cpp | 2 +- examples/directx9_example/imgui_impl_dx9.cpp | 2 +- examples/opengl2_example/imgui_impl_glfw_gl2.cpp | 4 ++-- examples/opengl3_example/imgui_impl_glfw_gl3.cpp | 4 ++-- examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp | 4 ++-- examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp | 4 ++-- examples/vulkan_example/imgui_impl_glfw_vulkan.cpp | 4 ++-- imgui.cpp | 7 ++++--- imgui.h | 11 ++++++++--- imgui_demo.cpp | 4 ++-- imgui_draw.cpp | 4 ++-- imgui_internal.h | 2 +- 15 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 59e1aa61..6ce0cd55 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -55,6 +55,7 @@ Breaking Changes: - removed allocator parameters from CreateContext(), they are now setup with SetAllocatorFunctions(), and shared by all contexts. - removed the default global context and font atlas instance, which were confusing for users of DLL reloading and users of multiple contexts. - Moved sample TTF files from extra_fonts/ to misc/fonts/. If you loaded files directly from the imgui repo you may need to update your paths. + - Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. - Obsoleted IsAnyWindowHovered() in favor of IsWindowHovered(ImGuiHoveredFlags_AnyWindow). Kept redirection function (will obsolete). - Obsoleted IsAnyWindowFocused() in favor of IsWindowFocused(ImGuiFocusedFlags_AnyWindow). Kept redirection function (will obsolete). - Renamed ImGuiSizeConstraintCallback to ImGuiSizeCallback, ImGuiSizeConstraintCallbackData to ImGuiSizeCallbackData. diff --git a/examples/directx10_example/imgui_impl_dx10.cpp b/examples/directx10_example/imgui_impl_dx10.cpp index caef5e1b..cbf791be 100644 --- a/examples/directx10_example/imgui_impl_dx10.cpp +++ b/examples/directx10_example/imgui_impl_dx10.cpp @@ -37,7 +37,7 @@ static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; -static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; // DirectX data static ID3D10Device* g_pd3dDevice = NULL; diff --git a/examples/directx11_example/imgui_impl_dx11.cpp b/examples/directx11_example/imgui_impl_dx11.cpp index c7f312c6..b100cf96 100644 --- a/examples/directx11_example/imgui_impl_dx11.cpp +++ b/examples/directx11_example/imgui_impl_dx11.cpp @@ -36,7 +36,7 @@ static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; -static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; // DirectX data static ID3D11Device* g_pd3dDevice = NULL; diff --git a/examples/directx12_example/imgui_impl_dx12.cpp b/examples/directx12_example/imgui_impl_dx12.cpp index beb48b9c..6c74dadf 100644 --- a/examples/directx12_example/imgui_impl_dx12.cpp +++ b/examples/directx12_example/imgui_impl_dx12.cpp @@ -24,7 +24,7 @@ static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; -static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; // DirectX data static ID3D12Device* g_pd3dDevice = NULL; diff --git a/examples/directx9_example/imgui_impl_dx9.cpp b/examples/directx9_example/imgui_impl_dx9.cpp index 194752fb..157c27d5 100644 --- a/examples/directx9_example/imgui_impl_dx9.cpp +++ b/examples/directx9_example/imgui_impl_dx9.cpp @@ -27,7 +27,7 @@ static HWND g_hWnd = 0; static INT64 g_Time = 0; static INT64 g_TicksPerSecond = 0; -static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_Count_; +static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; // DirectX data static LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; diff --git a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp index 03d7659e..89d2509f 100644 --- a/examples/opengl2_example/imgui_impl_glfw_gl2.cpp +++ b/examples/opengl2_example/imgui_impl_glfw_gl2.cpp @@ -50,7 +50,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL data static GLuint g_FontTexture = 0; @@ -282,7 +282,7 @@ bool ImGui_ImplGlfwGL2_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL2_Shutdown() { // Destroy GLFW mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(g_MouseCursors[cursor_n]); memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index 40b0c4d4..e7571942 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -48,7 +48,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL3 data static GLuint g_FontTexture = 0; @@ -400,7 +400,7 @@ bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) void ImGui_ImplGlfwGL3_Shutdown() { // Destroy GLFW mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(g_MouseCursors[cursor_n]); memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); diff --git a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp index c7eeaa91..ca224744 100644 --- a/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp +++ b/examples/sdl_opengl2_example/imgui_impl_sdl_gl2.cpp @@ -44,7 +44,7 @@ static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; static GLuint g_FontTexture = 0; -static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL2 Render function. // (this used to be set in io.RenderDrawListsFn and called by ImGui::Render(), but you can now call this directly from your main loop) @@ -275,7 +275,7 @@ bool ImGui_ImplSdlGL2_Init(SDL_Window* window) void ImGui_ImplSdlGL2_Shutdown() { // Destroy SDL mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) SDL_FreeCursor(g_MouseCursors[cursor_n]); memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index d5bd364c..a0ca7e62 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -42,7 +42,7 @@ // SDL data static Uint64 g_Time = 0; static bool g_MousePressed[3] = { false, false, false }; -static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL data static GLuint g_FontTexture = 0; @@ -394,7 +394,7 @@ bool ImGui_ImplSdlGL3_Init(SDL_Window* window) void ImGui_ImplSdlGL3_Shutdown() { // Destroy SDL mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) SDL_FreeCursor(g_MouseCursors[cursor_n]); memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); diff --git a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp index 8f9fa654..f982d643 100644 --- a/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp +++ b/examples/vulkan_example/imgui_impl_glfw_vulkan.cpp @@ -42,7 +42,7 @@ static GLFWwindow* g_Window = NULL; static double g_Time = 0.0f; static bool g_MouseJustPressed[3] = { false, false, false }; -static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // Vulkan data static VkAllocationCallbacks* g_Allocator = NULL; @@ -820,7 +820,7 @@ bool ImGui_ImplGlfwVulkan_Init(GLFWwindow* window, bool install_callbacks, Im void ImGui_ImplGlfwVulkan_Shutdown() { // Destroy GLFW mouse cursors - for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_Count_; cursor_n++) + for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(g_MouseCursors[cursor_n]); memset(g_MouseCursors, 0, sizeof(g_MouseCursors)); diff --git a/imgui.cpp b/imgui.cpp index 1bf25b70..4195a8c5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -251,6 +251,7 @@ Here is a change-log of API breaking changes, if you are using one of the functions listed, expect to have to fix some code. Also read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2018/03/03 (1.60) - Renamed ImGuiStyleVar_Count_ to ImGuiStyleVar_COUNT and ImGuiMouseCursor_Count_ to ImGuiMouseCursor_COUNT for consistency with other public enums. - 2018/02/18 (1.60) - BeginDragDropSource(): temporarily removed the optional mouse_button=0 parameter because it is not really usable in many situations at the moment. - 2018/02/16 (1.60) - obsoleted the io.RenderDrawListsFn callback, you can call your graphics engine render function after ImGui::Render(). Use ImGui::GetDrawData() to retrieve the ImDrawData* to display. - 2018/02/07 (1.60) - reorganized context handling to be more explicit, @@ -6597,8 +6598,8 @@ static const ImGuiStyleVarInfo GStyleVarInfo[] = static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) { - IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_); - IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_Count_); + IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_COUNT); + IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_COUNT); return &GStyleVarInfo[idx]; } @@ -13261,7 +13262,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) } if (ImGui::TreeNode("Internal state")) { - const char* input_source_names[] = { "None", "Mouse", "Nav", "NavGamepad", "NavKeyboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_Count_); + const char* input_source_names[] = { "None", "Mouse", "Nav", "NavGamepad", "NavKeyboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not diff --git a/imgui.h b/imgui.h index d2bf0682..e6b3fe39 100644 --- a/imgui.h +++ b/imgui.h @@ -859,11 +859,11 @@ enum ImGuiStyleVar_ ImGuiStyleVar_GrabMinSize, // float GrabMinSize ImGuiStyleVar_GrabRounding, // float GrabRounding ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign - ImGuiStyleVar_Count_ + ImGuiStyleVar_COUNT // Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding + , ImGuiStyleVar_Count_ = ImGuiStyleVar_COUNT, ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding #endif }; @@ -908,7 +908,12 @@ enum ImGuiMouseCursor_ ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window - ImGuiMouseCursor_Count_ + ImGuiMouseCursor_COUNT + + // Obsolete names (will be removed) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + , ImGuiMouseCursor_Count_ = ImGuiMouseCursor_COUNT +#endif }; // Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 34dae8a7..fe6d208c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1993,12 +1993,12 @@ void ImGui::ShowDemoWindow(bool* p_open) if (ImGui::TreeNode("Mouse cursors")) { const char* mouse_cursors_names[] = { "Arrow", "TextInput", "Move", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE" }; - IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_Count_); + IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_COUNT); ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); ImGui::Text("Hover to see mouse cursors:"); ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); - for (int i = 0; i < ImGuiMouseCursor_Count_; i++) + for (int i = 0; i < ImGuiMouseCursor_COUNT; i++) { char label[32]; sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 9ba63056..c939733d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1349,7 +1349,7 @@ static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA " - XX XX - " }; -static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][3] = +static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_COUNT][3] = { // Pos ........ Size ......... Offset ...... { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow @@ -1622,7 +1622,7 @@ void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, I bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) { - if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_Count_) + if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_COUNT) return false; if (Flags & ImFontAtlasFlags_NoMouseCursors) return false; diff --git a/imgui_internal.h b/imgui_internal.h index 10ba8532..dd0e08ad 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -267,7 +267,7 @@ enum ImGuiInputSource ImGuiInputSource_Nav, ImGuiInputSource_NavKeyboard, // Only used occasionally for storage, not tested/handled by most code ImGuiInputSource_NavGamepad, // " - ImGuiInputSource_Count_, + ImGuiInputSource_COUNT, }; // FIXME-NAV: Clarify/expose various repeat delay/rate From ee770af72c93172ff6f0feafd22c6f7f6db28be9 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 16:06:43 +0100 Subject: [PATCH 73/87] Columns: Adding per-window display in Metrics. Tidying up, removing old code/comments. (#125, #1499, #1656) --- imgui.cpp | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4195a8c5..8d9611bf 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12384,7 +12384,7 @@ static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. + IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + GetColumnsRectHalfWidth() - window->Pos.x; @@ -12405,16 +12405,6 @@ float ImGui::GetColumnOffset(int column_index) column_index = columns->Current; IM_ASSERT(column_index < columns->Columns.Size); - /* - if (g.ActiveId) - { - ImGuiContext& g = *GImGui; - const ImGuiID column_id = columns->ColumnsSetId + ImGuiID(column_index); - if (g.ActiveId == column_id) - return GetDraggedColumnOffset(columns, column_index); - } - */ - const float t = columns->Columns[column_index].OffsetNorm; const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); return x_offset; @@ -12524,7 +12514,6 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - //column->MaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; columns->MaxX = content_region_width - window->Scroll.x; columns->StartPosY = window->DC.CursorPos.y; columns->StartMaxPosX = window->DC.CursorMaxPos.x; @@ -12640,7 +12629,7 @@ void ImGui::EndColumns() window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } -// [2017/12: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] +// [2018-03: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] void ImGui::Columns(int columns_count, const char* id, bool border) { ImGuiWindow* window = GetCurrentWindow(); @@ -13237,6 +13226,21 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::BulletText("NavRectRel[0]: "); if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + if (window->ColumnsStorage.Size > 0 && ImGui::TreeNode("Columns", "Columns sets (%d)", window->ColumnsStorage.Size)) + { + for (int n = 0; n < window->ColumnsStorage.Size; n++) + { + const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; + if (ImGui::TreeNode((void*)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) + { + ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); + for (int column_n = 0; column_n < columns->Columns.Size; column_n++) + ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, OffsetNormToPixels(columns, columns->Columns[column_n].OffsetNorm)); + ImGui::TreePop(); + } + } + ImGui::TreePop(); + } ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); ImGui::TreePop(); } From 968a8d2a3fecc3bf870a20f3e6a2f10dbe2cddab Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 16:57:44 +0100 Subject: [PATCH 74/87] Columns: Clamping MaxX above MinX. This shouldn't have much of a benefit / affect, but the internal values are more sane this way. (#125) --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 8d9611bf..27a82075 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12514,7 +12514,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag // Set state for first column const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - columns->MaxX = content_region_width - window->Scroll.x; + columns->MaxX = ImMax(content_region_width - window->Scroll.x, columns->MinX + 1.0f); columns->StartPosY = window->DC.CursorPos.y; columns->StartMaxPosX = window->DC.CursorMaxPos.x; columns->CellMinY = columns->CellMaxY = window->DC.CursorPos.y; From bf7481eba01252f3e53590c7c592b86b318bcd52 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 17:44:17 +0100 Subject: [PATCH 75/87] Columns: Extent stop at the right-most clipped pixel. The right-most column might appear a little wider but it's usable space matches the others. (#125). +9 Internal: Store InnerClipRect. --- imgui.cpp | 19 +++++++++---------- imgui_internal.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 27a82075..d9991336 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -6131,21 +6131,20 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + // Inner clipping rectangle + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + window->InnerClipRect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); + window->InnerClipRect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - window->WindowBorderSize))); + window->InnerClipRect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); + // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). window->DC.LastItemId = window->MoveId; window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; window->DC.LastItemRect = title_bar_rect; } - // Inner clipping rectangle - // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. - const float border_size = window->WindowBorderSize; - ImRect clip_rect; - clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); - clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); - PushClipRect(clip_rect.Min, clip_rect.Max, true); + PushClipRect(window->InnerClipRect.Min, window->InnerClipRect.Max, true); // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) if (first_begin_of_the_frame) @@ -12512,7 +12511,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag window->DC.ColumnsSet = columns; // Set state for first column - const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); + const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->InnerClipRect.Max.x - window->Pos.x); columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range columns->MaxX = ImMax(content_region_width - window->Scroll.x, columns->MinX + 1.0f); columns->StartPosY = window->DC.CursorPos.y; diff --git a/imgui_internal.h b/imgui_internal.h index dd0e08ad..79fc4d95 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -944,7 +944,7 @@ struct IMGUI_API ImGuiWindow ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. - ImRect InnerRect; + ImRect InnerRect, InnerClipRect; int LastFrameActive; float ItemWidthDefault; ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items From 5ed45d0aec76ffae27e8089024c8b4531c7214e0 Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 4 Mar 2018 17:55:59 +0100 Subject: [PATCH 76/87] Columns: Fixed destructive small resize. (#1656). The OffsetNorm clamp introduced by #913 was ok as it didn't write back into the storage, which #1499 started doing making it destructive. Right now I don't think the clamp is needed at all. It had uses (eg: hide the issue fixed by bf7481eba01252f3e53590c7c592b86b318bcd52). --- imgui.cpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d9991336..bfbac41f 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12537,19 +12537,10 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag } } - for (int n = 0; n < columns_count + 1; n++) + for (int n = 0; n < columns_count; n++) { - // Clamp position - ImGuiColumnData* column = &columns->Columns[n]; - float t = column->OffsetNorm; - if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, (columns->MaxX - columns->MinX) - g.Style.ColumnsMinSpacing * (columns->Count - n))); - column->OffsetNorm = t; - - if (n == columns_count) - continue; - // Compute clipping rectangle + ImGuiColumnData* column = &columns->Columns[n]; float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); From 0ec356eb6e5471178ea543d02c28b59bb97d659a Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 11:30:23 +0100 Subject: [PATCH 77/87] Comments, FAQ update. --- README.md | 7 +++---- imgui.cpp | 53 +++++++++++++++++++++++--------------------------- imgui.h | 11 ++++++----- imgui_draw.cpp | 2 +- 4 files changed, 34 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index da797963..b5f43563 100644 --- a/README.md +++ b/README.md @@ -231,18 +231,17 @@ See the [Software using dear imgui page](https://github.com/ocornut/imgui/wiki/S The library started its life and is best known as "ImGui" only due to the fact that I didn't give it a proper name when I released it. However, the term IMGUI (immediate-mode graphical user interface) was coined before and is being used in variety of other situations. It seemed confusing and unfair to hog the name. To reduce the ambiguity without affecting existing codebases, I have decided on an alternate, longer name "dear imgui" that people can use to refer to this specific library in ambiguous situations. -How can I help? +How can I tell whether to dispatch mouse/keyboard to imgui or to my application?
How can I display an image? What is ImTextureID, how does it works?
How can I have multiple widgets with the same label, or without any label? (Yes). A primer on labels and ID stack. -
How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application?
How can I load a different font than the default?
How can I easily use icons in my application?
How can I load multiple fonts?
How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? -
How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables)
How can I use the drawing facilities without an Dear ImGui window? (using ImDrawList API)
I integrated Dear ImGui in my engine and the text or lines are blurry..
I integrated Dear ImGui in my engine and some elements are disappearing when I move windows around.. +
How can I help? See the FAQ in imgui.cpp for answers. @@ -250,7 +249,7 @@ See the FAQ in imgui.cpp for answers. You can control Dear ImGui with a gamepad, see the explanation in imgui.cpp about how to use the navigation feature (short version: map your gamepad inputs into the `io.NavInputs[]` array and set `io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad`). -You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). +You can share your computer mouse seamlessy with your console/tablet/phone using [Synergy](http://synergy-project.org). This is the prefered solution for developer productivity. In particular, their [micro-synergy-client](https://github.com/symless/micro-synergy-client) repo there is _uSynergy.c_ sources for a small embeddable that you can use on any platform to connect to your host PC using Synergy 1.x. You may also use a third party solution such as [Remote ImGui](https://github.com/JordiRos/remoteimgui). For touch inputs, you can increase the hit box of widgets (via the _style.TouchPadding_ setting) to accommodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse or gamepad to allow optimising for screen real-estate and precision. diff --git a/imgui.cpp b/imgui.cpp index bfbac41f..64c2f4f9 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -23,18 +23,17 @@ - API BREAKING CHANGES (read me when you update!) - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS - - How can I help? + - How can I tell whether to dispatch mouse/keyboard to imgui or to my application? - How can I display an image? What is ImTextureID, how does it works? - How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on labels and the ID stack. - - How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - How can I load a different font than the default? - How can I easily use icons in my application? - How can I load multiple fonts? - How can I display and input non-latin characters such as Chinese, Japanese, Korean, Cyrillic? - - How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - I integrated Dear ImGui in my engine and the text or lines are blurry.. - I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around.. + - How can I help? - ISSUES & TODO-LIST - CODE @@ -234,7 +233,7 @@ Please reach out if you think the game vs navigation input sharing could be improved. - Mouse: - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - - Consoles/Tablet/Phone users: Consider using Synergy host (on your computer) + uSynergy.c (in your console/tablet/phone app) to use your PC mouse/keyboard. + - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (in your console/tablet/phone app) to share your PC mouse/keyboard. - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavMoveMouse flag. Enabling ImGuiConfigFlags_NavMoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantMoveMouse' to notify you that it wants the mouse cursor to be moved. @@ -405,13 +404,18 @@ FREQUENTLY ASKED QUESTIONS (FAQ), TIPS ====================================== - Q: How can I help? - A: - If you are experienced with Dear ImGui and C++, look at the github issues, or TODO.txt and see how you want/can help! - - Convince your company to fund development time! Individual users: you can also become a Patron (patreon.com/imgui) or donate on PayPal! See README. - - Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. - You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/1269). Visuals are ideal as they inspire other programmers. - But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. - - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). + Q: How can I tell whether to dispatch mouse/keyboard to imgui or to my application? + A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'io.WantTextInput' flags from the ImGuiIO structure. + - When 'io.WantCaptureMouse' is set, imgui wants to use your mouse state, and you may want to discard/hide the inputs from the rest of your application. + - When 'io.WantCaptureKeyboard' is set, imgui wants to use your keyboard state, and you may want to discard/hide the inputs from the rest of your application. + - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). + The 'io.WantCaptureMouse' is more accurate that any attempt to "check if the mouse is hovering a window" (don't do that!). + It handle mouse dragging correctly (both dragging that started over your application or over an imgui window) and handle e.g. modal windows blocking inputs. + Those flags are updated by ImGui::NewFrame(). Preferably read the flags after calling NewFrame() if you can afford it, but reading them before is also + perfectly fine, as the bool toggle fairly rarely. + (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically + have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs + were for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) Q: How can I display an image? What is ImTextureID, how does it works? A: ImTextureID is a void* used to pass renderer-agnostic texture references around until it hits your render function. @@ -521,18 +525,6 @@ e.g. when displaying a list of objects, using indices or pointers as ID will preserve the node open/closed state differently. experiment and see what makes more sense! - Q: How can I tell when Dear ImGui wants my mouse/keyboard inputs VS when I can pass them to my application? - A: You can read the 'io.WantCaptureMouse'/'io.WantCaptureKeyboard'/'ioWantTextInput' flags from the ImGuiIO structure. - - When 'io.WantCaptureMouse' or 'io.WantCaptureKeyboard' flags are set you may want to discard/hide the inputs from the rest of your application. - - When 'io.WantTextInput' is set to may want to notify your OS to popup an on-screen keyboard, if available (e.g. on a mobile phone, or console OS). - Preferably read the flags after calling ImGui::NewFrame() to avoid them lagging by one frame. But reading those flags before calling NewFrame() is - also generally ok, as the bool toggles fairly rarely and you don't generally expect to interact with either Dear ImGui or your application during - the same frame when that transition occurs. Dear ImGui is tracking dragging and widget activity that may occur outside the boundary of a window, - so 'io.WantCaptureMouse' is more accurate and correct than checking if a window is hovered. - (Advanced note: text input releases focus on Return 'KeyDown', so the following Return 'KeyUp' event that your application receive will typically - have 'io.WantCaptureKeyboard=false'. Depending on your application logic it may or not be inconvenient. You might want to track which key-downs - were for Dear ImGui, e.g. with an array of bool, and filter out the corresponding key-ups.) - Q: How can I load a different font than the default? (default is an embedded version of ProggyClean.ttf, rendered at size 13) A: Use the font atlas to load the TTF/OTF file you want: ImGuiIO& io = ImGui::GetIO(); @@ -599,13 +591,9 @@ For languages using IME, on Windows you can copy the Hwnd of your application to io.ImeWindowHandle. The default implementation of io.ImeSetInputScreenPosFn() on Windows will set your IME position correctly. - Q: How can I preserve my Dear ImGui context across reloading a DLL? (loss of the global/static variables) - A: Create your own context 'ctx = CreateContext()' + 'SetCurrentContext(ctx)' and your own font atlas 'ctx->GetIO().Fonts = new ImFontAtlas()' - so you don't rely on the default globals. - Q: How can I use the drawing facilities without an ImGui window? (using ImDrawList API) - A: - You can create a dummy window. Call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flag, - push a ImGuiCol_WindowBg with zero alpha, then retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. + A: - You can create a dummy window. Call SetNextWindowBgAlpha(0.0f), call Begin() with NoTitleBar|NoResize|NoMove|NoScrollbar|NoSavedSettings|NoInputs flags. + Then you can retrieve the ImDrawList* via GetWindowDrawList() and draw to it in any way you like. - You can call ImGui::GetOverlayDrawList() and use this draw list to display contents over every other imgui windows. - You can create your own ImDrawList instance. You'll need to initialize them ImGui::GetDrawListSharedData(), or create your own ImDrawListSharedData. @@ -617,6 +605,13 @@ A: You are probably mishandling the clipping rectangles in your render function. Rectangles provided by ImGui are defined as (x1=left,y1=top,x2=right,y2=bottom) and NOT as (x1,y1,width,height). + Q: How can I help? + A: - If you are experienced with Dear ImGui and C++, look at the github issues, or TODO.txt and see how you want/can help! + - Convince your company to fund development time! Individual users: you can also become a Patron (patreon.com/imgui) or donate on PayPal! See README. + - Disclose your usage of dear imgui via a dev blog post, a tweet, a screenshot, a mention somewhere etc. + You may post screenshot or links in the gallery threads (github.com/ocornut/imgui/issues/1269). Visuals are ideal as they inspire other programmers. + But even without visuals, disclosing your use of dear imgui help the library grow credibility, and help other teams and programmers with taking decisions. + - If you have issues or if you need to hack into the library, even if you don't expect any support it is useful that you share your issues (on github or privately). - tip: you can call Begin() multiple times with the same name during the same frame, it will keep appending to the same window. this is also useful to set yourself in the context of another window (to get/set other settings) diff --git a/imgui.h b/imgui.h index e6b3fe39..11110142 100644 --- a/imgui.h +++ b/imgui.h @@ -487,7 +487,7 @@ namespace ImGui IMGUI_API ImVec2 GetItemRectSize(); // get size of last item, in screen space IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. - IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. + IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. NB: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that! Please read the FAQ! IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. IMGUI_API float GetTime(); @@ -656,6 +656,7 @@ enum ImGuiFocusedFlags_ }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() +// Note: If you are trying to check whether your mouse should be dispatched to imgui or to your app, you should use the 'io.WantCaptureMouse' boolean for that. Please read the FAQ! enum ImGuiHoveredFlags_ { ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. @@ -1665,10 +1666,10 @@ struct ImFontAtlas IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership. IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. - IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. - IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) - IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) - IMGUI_API void Clear(); // Clear all + IMGUI_API void ClearInputData(); // Clear input data (all ImFontConfig structures including sizes, TTF data, glyph ranges, etc.) = all the data used to build the texture and fonts. + IMGUI_API void ClearTexData(); // Clear output texture data (CPU side). Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearFonts(); // Clear output font data (glyphs storage, UV coordinates). + IMGUI_API void Clear(); // Clear all input and output. // Build atlas, retrieve pixel data. // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). diff --git a/imgui_draw.cpp b/imgui_draw.cpp index c939733d..1a15a140 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1391,7 +1391,7 @@ void ImFontAtlas::ClearInputData() ConfigData[i].FontData = NULL; } - // When clearing this we lose access to the font name and other information used to build the font. + // When clearing this we lose access to the font name and other information used to build the font. for (int i = 0; i < Fonts.Size; i++) if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) { From 51afaf7117b9835376ac6f242453c492dc8843cb Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 13:15:15 +0100 Subject: [PATCH 78/87] Fixed type cast warning. --- imgui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 64c2f4f9..31e7ff9e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13216,7 +13216,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) for (int n = 0; n < window->ColumnsStorage.Size; n++) { const ImGuiColumnsSet* columns = &window->ColumnsStorage[n]; - if (ImGui::TreeNode((void*)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) + if (ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) { ImGui::BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns->MaxX - columns->MinX, columns->MinX, columns->MaxX); for (int column_n = 0; column_n < columns->Columns.Size; column_n++) From 945f4d1ecd5806268de9674c3753feb7911fb935 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 16:16:27 +0100 Subject: [PATCH 79/87] Removed redundant semi colons. (#1653) --- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fe6d208c..713a929d 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2239,7 +2239,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref) { ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); - const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n));; + const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n)); draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 1a15a140..53f8160b 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -2056,7 +2056,7 @@ const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() // Unpack int codepoint = 0x4e00; memcpy(full_ranges, base_ranges, sizeof(base_ranges)); - ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges);; + ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges); for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); dst[0] = 0; From cea7492babfbd561589a41858159b14f0ca2373e Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 5 Mar 2018 22:47:53 +0100 Subject: [PATCH 80/87] Render: Removed the code that disable render if style.Alpha is 0.0f, it is both incorrect (as style Alpha can be modified mid-frame), not really necessary (just tested that full Alpha = 0 will lead to empty draw lists!) and misleading (bulk of the work was already done). --- imgui.cpp | 83 ++++++++++++++++++++++++++----------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 31e7ff9e..775d61e3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4028,52 +4028,47 @@ void ImGui::Render() ImGui::EndFrame(); g.FrameCountRendered = g.FrameCount; - // Skip render altogether if alpha is 0.0 - // Note that vertex buffers have been created and are wasted, so it is best practice that you don't create windows in the first place, or consistently respond to Begin() returning false. - if (g.Style.Alpha > 0.0f) + // Gather windows to render + g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; + g.DrawDataBuilder.Clear(); + ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; + for (int n = 0; n != g.Windows.Size; n++) { - // Gather windows to render - g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; - g.DrawDataBuilder.Clear(); - ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; - for (int n = 0; n != g.Windows.Size; n++) - { - ImGuiWindow* window = g.Windows[n]; - if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0 && window != window_to_render_front_most) - AddWindowToDrawDataSelectLayer(window); - } - if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window - AddWindowToDrawDataSelectLayer(window_to_render_front_most); - g.DrawDataBuilder.FlattenIntoSingleLayer(); - - // Draw software mouse cursor if requested - ImVec2 offset, size, uv[4]; - if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) - { - const ImVec2 pos = g.IO.MousePos - offset; - const ImTextureID tex_id = g.IO.Fonts->TexID; - const float sc = g.Style.MouseCursorScale; - g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill - g.OverlayDrawList.PopTextureID(); - } - if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); - - // Setup ImDrawData structure for end-user - SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); - g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; - g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; - - // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) - g.IO.RenderDrawListsFn(&g.DrawData); -#endif + ImGuiWindow* window = g.Windows[n]; + if (window->Active && window->HiddenFrames <= 0 && (window->Flags & ImGuiWindowFlags_ChildWindow) == 0 && window != window_to_render_front_most) + AddWindowToDrawDataSelectLayer(window); } + if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window + AddWindowToDrawDataSelectLayer(window_to_render_front_most); + g.DrawDataBuilder.FlattenIntoSingleLayer(); + + // Draw software mouse cursor if requested + ImVec2 offset, size, uv[4]; + if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) + { + const ImVec2 pos = g.IO.MousePos - offset; + const ImTextureID tex_id = g.IO.Fonts->TexID; + const float sc = g.Style.MouseCursorScale; + g.OverlayDrawList.PushTextureID(tex_id); + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill + g.OverlayDrawList.PopTextureID(); + } + if (!g.OverlayDrawList.VtxBuffer.empty()) + AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); + + // Setup ImDrawData structure for end-user + SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); + g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; + g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; + + // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) + g.IO.RenderDrawListsFn(&g.DrawData); +#endif } const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) From a2ed3ee2cfdf3a763bc97e9eaf2d43b1be87364d Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 6 Mar 2018 19:48:30 +0100 Subject: [PATCH 81/87] Examples: OpenGL3: Added a way to override the glsl version number through the Init call. (#1667, #1466) --- .../opengl3_example/imgui_impl_glfw_gl3.cpp | 29 ++++++++++++++----- .../opengl3_example/imgui_impl_glfw_gl3.h | 2 +- .../imgui_impl_sdl_gl3.cpp | 24 +++++++++++---- .../sdl_opengl3_example/imgui_impl_sdl_gl3.h | 2 +- 4 files changed, 43 insertions(+), 14 deletions(-) diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp index e7571942..8a8b8ed9 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.cpp +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.cpp @@ -13,6 +13,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplGlfwGL3_Init() so user can override the GLSL version e.g. "#version 150". // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling). // 2018-02-20: Inputs: Renamed GLFW callbacks exposed in .h to not include GL3 in their name. @@ -31,6 +32,10 @@ // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-04-30: OpenGL: Fixed save and restore of current GL_ACTIVE_TEXTURE. +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + #include "imgui.h" #include "imgui_impl_glfw_gl3.h" @@ -51,6 +56,7 @@ static bool g_MouseJustPressed[3] = { false, false, false }; static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL3 data +static char g_GlslVersion[32] = "#version 150"; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -258,8 +264,7 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &last_array_buffer); glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); - const GLchar *vertex_shader = - "#version 150\n" + const GLchar* vertex_shader = "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -274,7 +279,6 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" @@ -284,11 +288,14 @@ bool ImGui_ImplGlfwGL3_CreateDeviceObjects() " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" "}\n"; + const GLchar* vertex_shader_with_version[2] = { g_GlslVersion, vertex_shader }; + const GLchar* fragment_shader_with_version[2] = { g_GlslVersion, fragment_shader }; + g_ShaderHandle = glCreateProgram(); g_VertHandle = glCreateShader(GL_VERTEX_SHADER); g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); glCompileShader(g_VertHandle); glCompileShader(g_FragHandle); glAttachShader(g_ShaderHandle, g_VertHandle); @@ -347,12 +354,20 @@ static void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); } -bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks, const char* glsl_version) { g_Window = window; + // Store GL version string so we can refer to it later in case we recreate shaders. + if (glsl_version == NULL) + glsl_version = "#version 150"; + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersion)); + strcpy(g_GlslVersion, glsl_version); + strcat(g_GlslVersion, "\n"); + + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. ImGuiIO& io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. + io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; diff --git a/examples/opengl3_example/imgui_impl_glfw_gl3.h b/examples/opengl3_example/imgui_impl_glfw_gl3.h index 6cbbe4a5..33b5329d 100644 --- a/examples/opengl3_example/imgui_impl_glfw_gl3.h +++ b/examples/opengl3_example/imgui_impl_glfw_gl3.h @@ -13,7 +13,7 @@ struct GLFWwindow; -IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API bool ImGui_ImplGlfwGL3_Init(GLFWwindow* window, bool install_callbacks, const char* glsl_version = NULL); IMGUI_API void ImGui_ImplGlfwGL3_Shutdown(); IMGUI_API void ImGui_ImplGlfwGL3_NewFrame(); IMGUI_API void ImGui_ImplGlfwGL3_RenderDrawData(ImDrawData* draw_data); diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp index a0ca7e62..995948d0 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.cpp @@ -12,6 +12,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-03-06: OpenGL: Added const char* glsl_version parameter to ImGui_ImplSdlGL3_Init() so user can override the GLSL version e.g. "#version 150". // 2018-02-23: OpenGL: Create the VAO in the render function so the setup can more easily be used with multiple shared GL context. // 2018-02-16: Inputs: Added support for mouse cursors, honoring ImGui::GetMouseCursor() value. // 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplSdlGL3_RenderDrawData() in the .h file so you can call it yourself. @@ -31,6 +32,10 @@ // 2016-09-05: OpenGL: Fixed save and restore of current scissor rectangle. // 2016-07-29: OpenGL: Explicitly setting GL_UNPACK_ROW_LENGTH to reduce issues because SDL changes it. (#752) +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + #include "imgui.h" #include "imgui_impl_sdl_gl3.h" @@ -45,6 +50,7 @@ static bool g_MousePressed[3] = { false, false, false }; static SDL_Cursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = { 0 }; // OpenGL data +static char g_GlslVersion[32] = "#version 150"; static GLuint g_FontTexture = 0; static int g_ShaderHandle = 0, g_VertHandle = 0, g_FragHandle = 0; static int g_AttribLocationTex = 0, g_AttribLocationProjMtx = 0; @@ -261,7 +267,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &last_vertex_array); const GLchar *vertex_shader = - "#version 150\n" "uniform mat4 ProjMtx;\n" "in vec2 Position;\n" "in vec2 UV;\n" @@ -276,7 +281,6 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() "}\n"; const GLchar* fragment_shader = - "#version 150\n" "uniform sampler2D Texture;\n" "in vec2 Frag_UV;\n" "in vec4 Frag_Color;\n" @@ -286,11 +290,14 @@ bool ImGui_ImplSdlGL3_CreateDeviceObjects() " Out_Color = Frag_Color * texture( Texture, Frag_UV.st);\n" "}\n"; + const GLchar* vertex_shader_with_version[2] = { g_GlslVersion, vertex_shader }; + const GLchar* fragment_shader_with_version[2] = { g_GlslVersion, fragment_shader }; + g_ShaderHandle = glCreateProgram(); g_VertHandle = glCreateShader(GL_VERTEX_SHADER); g_FragHandle = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(g_VertHandle, 1, &vertex_shader, 0); - glShaderSource(g_FragHandle, 1, &fragment_shader, 0); + glShaderSource(g_VertHandle, 2, vertex_shader_with_version, NULL); + glShaderSource(g_FragHandle, 2, fragment_shader_with_version, NULL); glCompileShader(g_VertHandle); glCompileShader(g_FragHandle); glAttachShader(g_ShaderHandle, g_VertHandle); @@ -341,8 +348,15 @@ void ImGui_ImplSdlGL3_InvalidateDeviceObjects() } } -bool ImGui_ImplSdlGL3_Init(SDL_Window* window) +bool ImGui_ImplSdlGL3_Init(SDL_Window* window, const char* glsl_version) { + // Store GL version string so we can refer to it later in case we recreate shaders. + if (glsl_version == NULL) + glsl_version = "#version 150"; + IM_ASSERT((int)strlen(glsl_version) + 2 < IM_ARRAYSIZE(g_GlslVersion)); + strcpy(g_GlslVersion, glsl_version); + strcat(g_GlslVersion, "\n"); + // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. ImGuiIO& io = ImGui::GetIO(); io.KeyMap[ImGuiKey_Tab] = SDL_SCANCODE_TAB; diff --git a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h index fa111a17..3aa00c3d 100644 --- a/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h +++ b/examples/sdl_opengl3_example/imgui_impl_sdl_gl3.h @@ -13,7 +13,7 @@ struct SDL_Window; typedef union SDL_Event SDL_Event; -IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window); +IMGUI_API bool ImGui_ImplSdlGL3_Init(SDL_Window* window, const char* glsl_version = NULL); IMGUI_API void ImGui_ImplSdlGL3_Shutdown(); IMGUI_API void ImGui_ImplSdlGL3_NewFrame(SDL_Window* window); IMGUI_API void ImGui_ImplSdlGL3_RenderDrawData(ImDrawData* draw_data); From 6190d794d40fd6c7776aca6989297a35f3356e73 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 7 Mar 2018 10:01:20 +0100 Subject: [PATCH 82/87] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b5f43563..5773278a 100644 --- a/README.md +++ b/README.md @@ -145,8 +145,7 @@ Frameworks: - Unreal Engine 4: [segross/UnrealImGui](https://github.com/segross/UnrealImGui) or [sronsse/UnrealEngine_ImGui](https://github.com/sronsse/UnrealEngine_ImGui) - SFML: [imgui-sfml](https://github.com/EliasD/imgui-sfml) or [imgui-backends](https://github.com/Mischa-Alff/imgui-backends) -For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/). -Please contact me with the Issues tracker or Twitter to fix/update this list. +For other bindings: see [this page](https://github.com/ocornut/imgui/wiki/Links/). Also see [wiki](https://github.com/ocornut/imgui/wiki) for a few other links and ideas. Contact me if you would like to add to those lists. Roadmap ------- From 7fd62baa426b3f4a2d98c1510161bf1135dde7bc Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 7 Mar 2018 11:50:56 +0100 Subject: [PATCH 83/87] Examples: Added Makefile for SDL+OpenGL2 example. (#1668) --- examples/sdl_opengl2_example/Makefile | 66 +++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 examples/sdl_opengl2_example/Makefile diff --git a/examples/sdl_opengl2_example/Makefile b/examples/sdl_opengl2_example/Makefile new file mode 100644 index 00000000..dc4d69f1 --- /dev/null +++ b/examples/sdl_opengl2_example/Makefile @@ -0,0 +1,66 @@ +# +# Cross Platform Makefile +# Compatible with MSYS2/MINGW, Ubuntu 14.04.1 and Mac OS X +# +# You will need SDL2 (http://www.libsdl.org): +# Linux: +# apt-get install libsdl2-dev +# Mac OS X: +# brew install sdl2 +# MSYS2: +# pacman -S mingw-w64-i686-SDL +# + +#CXX = g++ +#CXX = clang++ + +EXE = sdl_opengl2_example +SOURCES = main.cpp imgui_impl_sdl_gl2.cpp +SOURCES += ../../imgui.cpp ../../imgui_demo.cpp ../../imgui_draw.cpp +OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES)))) + +UNAME_S := $(shell uname -s) + + +ifeq ($(UNAME_S), Linux) #LINUX + ECHO_MESSAGE = "Linux" + LIBS = -lGL -ldl `sdl2-config --libs` + + CXXFLAGS = -I../../ `sdl2-config --cflags` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(UNAME_S), Darwin) #APPLE + ECHO_MESSAGE = "Mac OS X" + LIBS = -framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo `sdl2-config --libs` + + CXXFLAGS = -I../../ -I/usr/local/include `sdl2-config --cflags` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + +ifeq ($(findstring MINGW,$(UNAME_S)),MINGW) + ECHO_MESSAGE = "Windows" + LIBS = -lgdi32 -lopengl32 -limm32 `pkg-config --static --libs sdl2` + + CXXFLAGS = -I../../ `pkg-config --cflags sdl2` + CXXFLAGS += -Wall -Wformat + CFLAGS = $(CXXFLAGS) +endif + + +%.o:%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +%.o:../../%.cpp + $(CXX) $(CXXFLAGS) -c -o $@ $< + +all: $(EXE) + @echo Build complete for $(ECHO_MESSAGE) + +$(EXE): $(OBJS) + $(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS) + +clean: + rm -f $(EXE) $(OBJS) From a1f3949d7174e4500308a6211c9781f85900bb16 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Mar 2018 10:42:51 +0100 Subject: [PATCH 84/87] Drag and Drop: Increased payload data type to 32 characters. (#143) --- CHANGELOG.txt | 2 +- imgui.h | 4 ++-- imgui_internal.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6ce0cd55..012f0fde 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -111,7 +111,7 @@ Other Changes: - Columns: Fixed a memory leak of ImGuiColumnsSet's Columns vector. (#1529) [@unprompted] - MenuBar: Fixed menu bar pushing a clipping rect outside of its allocated bound (usually unnoticeable). - TreeNode: nodes with the ImGuiTreeNodeFlags_Leaf flag correctly disable highlight when DragDrop is active. (#143, #581) -- Drag and Drop: Increased payload type string to 12 characters instead of 8. (#143) +- Drag and Drop: Increased payload type string to 32 characters instead of 8. (#143) - Drag and Drop: TreeNode as drop target displays rectangle over full frame. (#1597, #143) - DragFloat: Fix/workaround for backends which do not preserve a valid mouse position when dragged out of bounds. (#1559) - Slider, Combo: Use ImGuiCol_FrameBgHovered color when hovered. (#1456) [@stfx] diff --git a/imgui.h b/imgui.h index 11110142..d1934ae8 100644 --- a/imgui.h +++ b/imgui.h @@ -458,7 +458,7 @@ namespace ImGui // Drag and Drop // [BETA API] Missing Demo code. API may evolve. IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. + IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 32 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. @@ -1348,7 +1348,7 @@ struct ImGuiPayload ImGuiID SourceId; // Source item id ImGuiID SourceParentId; // Source parent id (if available) int DataFrameCount; // Data timestamp - char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max) + char DataType[32+1]; // Data type tag (short user-supplied string, 32 characters max) bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. diff --git a/imgui_internal.h b/imgui_internal.h index 79fc4d95..1ffa1600 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -662,7 +662,7 @@ struct ImGuiContext ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly - unsigned char DragDropPayloadBufLocal[8]; + unsigned char DragDropPayloadBufLocal[8]; // Local buffer for small payloads // Widget state ImGuiTextEditState InputTextState; From 642c6748ac858099cf1994b5f5936d5f6db95c62 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Mar 2018 11:15:27 +0100 Subject: [PATCH 85/87] Comments, Changelog --- CHANGELOG.txt | 16 ++++++++++------ imgui.cpp | 13 +++++++------ imgui.h | 2 +- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 012f0fde..a33696e3 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -104,11 +104,13 @@ Other Changes: - Popup: Better handling of user mistakenly calling OpenPopup() every frame (with reopen_existing option). The error will now be more visible and easier to understand. (#1497) - Popup: BeginPopup(): Exposed extra_flags parameter that are passed through to Begin(). (#1533) - Popup: BeginPopupModal: fixed the conditional test for SetNextWindowPos() which was polling the wrong window, which in practice made the test succeed all the time. -- Tooltip: BeginTooltip() sets NoInputs flag. +- Tooltip: BeginTooltip() sets ImGuiWindowFlags_NoInputs flag. - Scrollbar: Fixed ScrollbarY enable test after ScrollbarX has been enabled being a little off (small regression from Nov 2017). (#1574) - Scrollbar: Fixed ScrollbarX enable test subtracting WindowPadding.x (this has been there since the addition of horizontal scroll bar!). - Columns: Clear offsets data when columns count changed. (#1525) - Columns: Fixed a memory leak of ImGuiColumnsSet's Columns vector. (#1529) [@unprompted] +- Columns: Fixed resizing a window very small breaking some columns positioning (broken in 1.53). +- Columns: The available column extent takes consideration of the right-most clipped pixel, so the right-most column may look a little wider but will contain the same amount of visible contents. - MenuBar: Fixed menu bar pushing a clipping rect outside of its allocated bound (usually unnoticeable). - TreeNode: nodes with the ImGuiTreeNodeFlags_Leaf flag correctly disable highlight when DragDrop is active. (#143, #581) - Drag and Drop: Increased payload type string to 32 characters instead of 8. (#143) @@ -124,6 +126,9 @@ Other Changes: - ImFontAtlas: Added ImFontAtlasFlags_NoPowerOfTwoHeight flag to disable padding font height to nearest power of two. (#1613) - ImFontAtlas: Added ImFontAtlasFlags_NoMouseCursors flag to disable baking software mouse cursors, mostly to save texture memory on very low end hardware. (#1613) - ImDrawList: Fixed AddRect() with antialiasing disabled (lower-right corner pixel was often missing, rounding looks a little better.) (#1646) +- Fonts: Updated stb_truetype from 1.14 to stb_truetype 1.19. (w/ include fix from some platforms #1622) +- Fonts: Added optional FreeType rasterizer in misc/freetype. Moved from imgui_club repo. (#618) [@Vuhdo, @mikesart, @ocornut] +- Fonts: Moved extra_fonts/ to misc/fonts/. - Misc: Functions passed to libc qsort are explicitely marked cdecl to support compiling with vectorcall as the default calling convention. (#1230, #1611) [@RandyGaul] - Misc: ImVec2: added [] operator. This is becoming desirable for some types of code, better added sooner than later. - Misc: Exposed IM_OFFSETOF() helper in imgui.h. @@ -134,18 +139,17 @@ Other Changes: - Misc: Updated stb_rect_pack from 0.10 to 0.11 (minor changes). - Misc: Added ImGuiConfigFlags_IsSRGB and ImGuiConfigFlags_IsTouchScreen user flags (for io.ConfigFlags). (Those flags are not used by ImGui itself, they only exists to make it easy for the engine/back-end to pass information to the application in a standard manner.) -- Fonts: Updated stb_truetype from 1.14 to stb_truetype 1.19. (w/ include fix from some platforms #1622) -- Fonts: Added optional FreeType rasterizer in misc/freetype. Moved from imgui_club repo. (#618) [@Vuhdo, @mikesart, @ocornut] -- Fonts: Moved extra_fonts/ to misc/fonts/. +- Metrics: Added display of Columns state. - Demo: Improved Selectable() examples. (#1528) - Demo: Tweaked the Child demos, added a menu bar to the second child to test some navigation functions. - Demo: Console: Using ImGuiCol_Text to be more friendly to color changes. - Demo: Using IM_COL32() instead of ImColor() in ImDrawList centric contexts. Trying to phase out use of the ImColor helper whenever possible. - Examples: Files in examples/ now include their own changelog so it is easier to occasionally update your bindings if needed. - Examples: Using Dark theme by default. (#707). Tweaked demo code. -- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) +- Examples: Added support for horizontal mouse wheel for API that allows it. (#1463) [@tseeker] - Examples: DirectX12: Added DirectX 12 example. (#301) [@jdm3] -- Examples: OpenGL3+GLFW,SDL: Changed GLSL shader version to 150 (#1466, #1504). +- Examples: OpenGL3+GLFW,SDL: Changed GLSL shader version from 330 to 150. (#1466, #1504) +- Examples: OpenGL3+GLFW,SDL: Added a way to override the GLSL version string in the Init function. (#1466, #1504). - Examples: OpenGL3+GLFW,SDL: Creating VAO in the render function so it can be more easily used by multiple shared OpenGL contexts. (#1217) - Examples: OpenGL3+GLFW: Using 3.2 context instead of 3.3. (#1466) - Examples: OpenGL: Setting up glPixelStorei() explicitly before uploading texture. diff --git a/imgui.cpp b/imgui.cpp index 775d61e3..3d8ef3df 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -19,7 +19,7 @@ - Read first - How to update to a newer version of Dear ImGui - Getting started with integrating Dear ImGui in your code/engine - - Using gamepad/keyboard navigation [BETA] + - Using gamepad/keyboard navigation controls [BETA] - API BREAKING CHANGES (read me when you update!) - ISSUES & TODO LIST - FREQUENTLY ASKED QUESTIONS (FAQ), TIPS @@ -76,7 +76,8 @@ - ESCAPE to revert text to its original value. - You can apply arithmetic operators +,*,/ on numerical values. Use +- to subtract (because - would set a negative value!) - Controls are automatically adjusted for OSX to match standard OSX text editing operations. - - Gamepad navigation: see suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at goo.gl/9LgVZW. + - General Keyboard controls: enable with ImGuiConfigFlags_NavEnableKeyboard. + - General Gamepad controls: enable with ImGuiConfigFlags_NavEnableGamepad. See suggested mappings in imgui.h ImGuiNavInput_ + download PNG/PSD at goo.gl/9LgVZW. PROGRAMMER GUIDE @@ -210,9 +211,9 @@ They tell you if ImGui intends to use your inputs. So for example, if 'io.WantCaptureMouse' is set you would typically want to hide mouse inputs from the rest of your application. Read the FAQ below for more information about those flags. - USING GAMEPAD/KEYBOARD NAVIGATION [BETA] + USING GAMEPAD/KEYBOARD NAVIGATION CONTROLS [BETA] - - Ask questions and report issues at https://github.com/ocornut/imgui/issues/787 + - The gamepad/keyboard navigation is in Beta. Ask questions and report issues at https://github.com/ocornut/imgui/issues/787 - The initial focus was to support game controllers, but keyboard is becoming increasingly and decently usable. - Keyboard: - Set io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard to enable. NewFrame() will automatically fill io.NavInputs[] based on your io.KeyDown[] + io.KeyMap[] arrays. @@ -227,13 +228,13 @@ - See 'enum ImGuiNavInput_' in imgui.h for a description of inputs. For each entry of io.NavInputs[], set the following values: 0.0f= not held. 1.0f= fully held. Pass intermediate 0.0f..1.0f values for analog triggers/sticks. - We uses a simple >0.0f test for activation testing, and won't attempt to test for a dead-zone. - Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, maybe a power curve, etc.). + Your code will probably need to transform your raw inputs (such as e.g. remapping your 0.2..0.9 raw input range to 0.0..1.0 imgui range, etc.). - You can download PNG/PSD files depicting the gamepad controls for common controllers at: goo.gl/9LgVZW. - If you need to share inputs between your game and the imgui parts, the easiest approach is to go all-or-nothing, with a buttons combo to toggle the target. Please reach out if you think the game vs navigation input sharing could be improved. - Mouse: - PS4 users: Consider emulating a mouse cursor with DualShock4 touch pad or a spare analog stick as a mouse-emulation fallback. - - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (in your console/tablet/phone app) to share your PC mouse/keyboard. + - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + uSynergy.c (on your console/tablet/phone app) to share your PC mouse/keyboard. - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavMoveMouse flag. Enabling ImGuiConfigFlags_NavMoveMouse instructs dear imgui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantMoveMouse' to notify you that it wants the mouse cursor to be moved. diff --git a/imgui.h b/imgui.h index d1934ae8..1273e0a2 100644 --- a/imgui.h +++ b/imgui.h @@ -753,7 +753,7 @@ enum ImGuiNavInput_ ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. - // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) may be directly reading from io.KeyDown[] instead of io.NavInputs[]. + // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) will be directly reading from io.KeyDown[] instead of io.NavInputs[]. ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt ImGuiNavInput_KeyLeft_, // move left // = Arrow keys ImGuiNavInput_KeyRight_, // move right From 3dfac93ebe0fc4d63fb46f676263b9da64226100 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Mar 2018 15:58:56 +0100 Subject: [PATCH 86/87] Fonts: Fixed debug name not being zero-terminated if longer than storage buffer + made buffer slightly longer as well. --- imgui.h | 2 +- imgui_draw.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.h b/imgui.h index 1273e0a2..282365e4 100644 --- a/imgui.h +++ b/imgui.h @@ -1628,7 +1628,7 @@ struct ImFontConfig float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. // [Internal] - char Name[32]; // Name (strictly to ease debugging) + char Name[40]; // Name (strictly to ease debugging) ImFont* DstFont; IMGUI_API ImFontConfig(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 53f8160b..8d8d90f5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1543,7 +1543,7 @@ ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, // Store a short copy of filename into into the font name for convenience const char* p; for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} - snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); + ImFormatString(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); } return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); } From 1ef1acbd8d7d46ac6fe083b331dadf9324dc7e07 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 8 Mar 2018 16:47:41 +0100 Subject: [PATCH 87/87] Font: Fixed MergeMode adding duplicate glyphs data instead of reusing existing (broken by 072d6d8cb5a8bb66318ae5db7d23b3be74bf5ffe) --- CHANGELOG.txt | 3 ++- TODO.txt | 5 ++++- imgui.h | 1 + imgui_draw.cpp | 8 +++++++- misc/freetype/imgui_freetype.cpp | 2 ++ 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a33696e3..b492255c 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -268,8 +268,9 @@ Other Changes: - NewFrame(): using literal strings in the most-frequently firing IM_ASSERT expressions to increase the odd of programmers seeing them (especially those who don't use a debugger). - NewFrame() now asserts if neither Render or EndFrame have been called. Exposed EndFrame(). Made it legal to call EndFrame() more than one. (#1423) - ImGuiStorage: Added BuildSortByKey() helper to rebuild storage from stratch. -- ImFont: Added GetDebugName() helper. +- ImFont: Added GetDebugName() helper. - ImFontAtlas: Added missing Thai punctuation in the GetGlyphRangesThai() ranges. (#1396) [@nProtect] +- ImFontAtlas: Fixed cfg.MergeMode not reusing existing glyphs if available (always overwrote). - ImDrawList: Removed 'bool anti_aliased = true' final parameter of ImDrawList::AddPolyline() and ImDrawList::AddConvexPolyFilled(). Anti-aliasing is controlled via the regular style.AntiAliased flags. - ImDrawList: Added ImDrawList::AddImageRounded() helper. (#845) [@thedmd] - ImDrawList: Refactored to make ImDrawList independant of ImGui. Removed static variable in PathArcToFast() which caused linking issues to some. diff --git a/TODO.txt b/TODO.txt index 939393ba..5c58f63f 100644 --- a/TODO.txt +++ b/TODO.txt @@ -212,7 +212,10 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - pie menus patterns (#434) - markup: simple markup language for color change? (#902) - - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. +!- font: need handling of missing glyphs by not packing/rasterizing glyph 0 of a given font. + - font: MergeMode: flags to select overwriting or not. + - font: MergeMode: duplicate glyphs are stored in the atlas texture which is suboptimal. + - font: better vertical centering (based e.g on height of lowercase 'x'?). currently Roboto-Medium size 16 px isn't currently centered. (#1619) - font: free the Alpha buffer if user only requested RGBA. !- font: better CalcTextSizeA() API, at least for simple use cases. current one is horrible (perhaps have simple vs extended versions). - font: enforce monospace through ImFontConfig (for icons?) + create dual ImFont output from same input, reusing rasterized data but with different glyphs/AdvanceX diff --git a/imgui.h b/imgui.h index 282365e4..4302de93 100644 --- a/imgui.h +++ b/imgui.h @@ -1775,6 +1775,7 @@ struct ImFont ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData ImFontAtlas* ContainerAtlas; // // What we has been loaded into float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] + bool DirtyLookupTables; int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) // Methods diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 8d8d90f5..07253317 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1817,6 +1817,8 @@ bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontConfig& cfg = atlas->ConfigData[input_i]; ImFontTempBuildData& tmp = tmp_array[input_i]; ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) + if (cfg.MergeMode) + dst_font->BuildLookupTable(); const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); int unscaled_ascent, unscaled_descent, unscaled_line_gap; @@ -1960,7 +1962,8 @@ void ImFontAtlasBuildFinish(ImFontAtlas* atlas) // Build all fonts lookup tables for (int i = 0; i < atlas->Fonts.Size; i++) - atlas->Fonts[i]->BuildLookupTable(); + if (atlas->Fonts[i]->DirtyLookupTables) + atlas->Fonts[i]->BuildLookupTable(); } // Retrieve list of range (2 int per range, values are inclusive) @@ -2165,6 +2168,7 @@ void ImFont::ClearOutputData() ConfigData = NULL; ContainerAtlas = NULL; Ascent = Descent = 0.0f; + DirtyLookupTables = true; MetricsTotalSurface = 0; } @@ -2177,6 +2181,7 @@ void ImFont::BuildLookupTable() IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved IndexAdvanceX.clear(); IndexLookup.clear(); + DirtyLookupTables = false; GrowIndex(max_codepoint + 1); for (int i = 0; i < Glyphs.Size; i++) { @@ -2241,6 +2246,7 @@ void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) + DirtyLookupTables = true; MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); } diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 0a80bbdf..54957112 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -315,6 +315,8 @@ bool ImGuiFreeType::BuildFontAtlas(ImFontAtlas* atlas, unsigned int extra_flags) ImFontConfig& cfg = atlas->ConfigData[input_i]; FreeTypeFont& font_face = fonts[input_i]; ImFont* dst_font = cfg.DstFont; + if (cfg.MergeMode) + dst_font->BuildLookupTable(); const float ascent = font_face.Info.Ascender; const float descent = font_face.Info.Descender;