mirror of
https://github.com/ocornut/imgui.git
synced 2026-07-06 17:45:24 +00:00
Compare commits
315 Commits
v1.92.1-do
...
v1.92.4-do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7d2d636af | ||
|
|
9a5d5c45f5 | ||
|
|
25e5baf5f0 | ||
|
|
c8db91b7b4 | ||
|
|
94ed5b1408 | ||
|
|
702cc9993a | ||
|
|
96ad003000 | ||
|
|
28ed29078b | ||
|
|
2c49902159 | ||
|
|
f9571ce4d3 | ||
|
|
bad5ee167b | ||
|
|
b6e277980f | ||
|
|
878c863af4 | ||
|
|
9be4f150ef | ||
|
|
8d9c903919 | ||
|
|
00251c8921 | ||
|
|
8de97d14d8 | ||
|
|
5af650fc6d | ||
|
|
2b770a029b | ||
|
|
bee2720faa | ||
|
|
cab82d9c76 | ||
|
|
fd0873c61f | ||
|
|
ee3d16f150 | ||
|
|
4b858cf5d1 | ||
|
|
09e15e8c9d | ||
|
|
2128e2f44b | ||
|
|
8f3f428228 | ||
|
|
f6754fd812 | ||
|
|
27a9374ef3 | ||
|
|
1cdec11e24 | ||
|
|
3ac624b795 | ||
|
|
a97b0c32ab | ||
|
|
bcf722e637 | ||
|
|
a0a6639fb5 | ||
|
|
0f7f6284d7 | ||
|
|
8c22b8aef6 | ||
|
|
fc4105c8a8 | ||
|
|
ea564a6a5e | ||
|
|
9809b0b061 | ||
|
|
b987970870 | ||
|
|
6fd4cf8e49 | ||
|
|
3563f1e270 | ||
|
|
e7aa0dec5b | ||
|
|
50a8bb2711 | ||
|
|
a3d6e82dbd | ||
|
|
b4514ce64a | ||
|
|
3dafd9e898 | ||
|
|
5cd83e689e | ||
|
|
bd9a37bc60 | ||
|
|
778aadca65 | ||
|
|
1aa91ac426 | ||
|
|
5ce903af6e | ||
|
|
bab3ebec14 | ||
|
|
3ff195f702 | ||
|
|
e459e5bf0a | ||
|
|
217bc445ff | ||
|
|
1f020e526a | ||
|
|
bad3c14ff6 | ||
|
|
1c87024840 | ||
|
|
e4e3c2cc23 | ||
|
|
f3e85310e7 | ||
|
|
3470e6112b | ||
|
|
e312b99296 | ||
|
|
cc0a6690bf | ||
|
|
5fe962216a | ||
|
|
01686c6294 | ||
|
|
bf2e0b2c6f | ||
|
|
3d937beb62 | ||
|
|
15c88c4941 | ||
|
|
cee40f8af9 | ||
|
|
940627d008 | ||
|
|
28837ec642 | ||
|
|
719ea9c228 | ||
|
|
e285ecca09 | ||
|
|
f61a7ef222 | ||
|
|
e06b5dfe12 | ||
|
|
e1aea42e45 | ||
|
|
82e9a5e47d | ||
|
|
5f6eaa5278 | ||
|
|
8a0888c763 | ||
|
|
e639ff392c | ||
|
|
d701ffb478 | ||
|
|
a00e517a81 | ||
|
|
8868ad67e4 | ||
|
|
301e652376 | ||
|
|
5a66d8fd57 | ||
|
|
a1c0836bec | ||
|
|
dfe308bc53 | ||
|
|
dc0198a7e4 | ||
|
|
ef6fe2ecee | ||
|
|
46e6382b69 | ||
|
|
087fbf08f6 | ||
|
|
1ad9de5aae | ||
|
|
aa9476a38a | ||
|
|
d4f722d5b2 | ||
|
|
3dd51651e3 | ||
|
|
16b2d20115 | ||
|
|
8ccff82153 | ||
|
|
0e7cd694eb | ||
|
|
03f3c8d385 | ||
|
|
62275e877a | ||
|
|
bf75bfec48 | ||
|
|
f4a3529ffc | ||
|
|
34bff4672c | ||
|
|
1c544ee941 | ||
|
|
70a43f3088 | ||
|
|
9cf9d2be83 | ||
|
|
7e473d38d3 | ||
|
|
6d834d325e | ||
|
|
f6890ed007 | ||
|
|
431f2c5abd | ||
|
|
6274ca4266 | ||
|
|
d92c8c6aff | ||
|
|
72c00f39c1 | ||
|
|
2675b7ca26 | ||
|
|
10d0162378 | ||
|
|
3c6c5692b8 | ||
|
|
e044d99710 | ||
|
|
22a6a83c54 | ||
|
|
09e7870497 | ||
|
|
cd476b27f8 | ||
|
|
9f13684d70 | ||
|
|
a4cd45f44c | ||
|
|
6d25cb844b | ||
|
|
586da87728 | ||
|
|
36133d8ac4 | ||
|
|
8c6096fcfe | ||
|
|
b6a33f8ce1 | ||
|
|
78c1d4a92c | ||
|
|
7f1e2bb8dd | ||
|
|
2f3e85bc37 | ||
|
|
e8ca7af4c0 | ||
|
|
0457a09bb9 | ||
|
|
71f45c12e9 | ||
|
|
8a94422246 | ||
|
|
ae832ce532 | ||
|
|
1e52e7b90c | ||
|
|
67085d732a | ||
|
|
f36c65661c | ||
|
|
e2b7d84e96 | ||
|
|
271f476d08 | ||
|
|
e2f314d613 | ||
|
|
8eb22ea620 | ||
|
|
55f590c1d1 | ||
|
|
dae66eb3b5 | ||
|
|
37b18acdf5 | ||
|
|
6b2cdf29bc | ||
|
|
5e5658e68f | ||
|
|
3dcd17f402 | ||
|
|
013c4ed476 | ||
|
|
2f1d1c8b2f | ||
|
|
1cd08b883c | ||
|
|
4e98fb20e2 | ||
|
|
045645e5f1 | ||
|
|
8e4955bb23 | ||
|
|
e66afbbbe0 | ||
|
|
2841c5135d | ||
|
|
bf52f4a83c | ||
|
|
14e076c5bb | ||
|
|
ea8a5a9e17 | ||
|
|
ab760992ad | ||
|
|
230418a75d | ||
|
|
16415aa39f | ||
|
|
985723ed94 | ||
|
|
a82f66a9b0 | ||
|
|
e422a38e4c | ||
|
|
11fff1ccf5 | ||
|
|
3cc7d1c81a | ||
|
|
56189cd814 | ||
|
|
a9945899c6 | ||
|
|
bc6478f651 | ||
|
|
34ab6c8a89 | ||
|
|
c63b5bd8fb | ||
|
|
8a35ce0e98 | ||
|
|
f77f68a5ed | ||
|
|
bed08daede | ||
|
|
09ebcf1779 | ||
|
|
a959617d2e | ||
|
|
02af06ea5f | ||
|
|
f937a32742 | ||
|
|
fdcd351488 | ||
|
|
026d47cd35 | ||
|
|
c63714822f | ||
|
|
26aa81a8b1 | ||
|
|
1ecc34a0b1 | ||
|
|
ee03cef14f | ||
|
|
e51d93e2f5 | ||
|
|
7d33524042 | ||
|
|
605a751571 | ||
|
|
b7cb3d93a4 | ||
|
|
20160ff1d5 | ||
|
|
3766d40394 | ||
|
|
0dd3c845eb | ||
|
|
740c566305 | ||
|
|
8dc457fda2 | ||
|
|
0ef9610e70 | ||
|
|
5c92699f5f | ||
|
|
771fae623d | ||
|
|
6351f00ff1 | ||
|
|
55cbc66508 | ||
|
|
9f969944d5 | ||
|
|
4d216d4510 | ||
|
|
aa2f40c3bb | ||
|
|
a309d2dcac | ||
|
|
87c1ab7988 | ||
|
|
319c481abb | ||
|
|
229d56e37a | ||
|
|
7d230594de | ||
|
|
75a4a48d1f | ||
|
|
9e864012ae | ||
|
|
783f1e62cc | ||
|
|
e728b96600 | ||
|
|
fe03035112 | ||
|
|
a28cb615ff | ||
|
|
515c0b526f | ||
|
|
03e39ca7f5 | ||
|
|
7c6fa8f8f7 | ||
|
|
4ebfe1cba5 | ||
|
|
42656b3aa1 | ||
|
|
89b7fc906a | ||
|
|
0c4f50090a | ||
|
|
720e94f3da | ||
|
|
321e9eb919 | ||
|
|
655601169b | ||
|
|
361e370fe0 | ||
|
|
86ec5c8342 | ||
|
|
1f7f1f54af | ||
|
|
160e3683ab | ||
|
|
45acd5e0e8 | ||
|
|
774ddb58bd | ||
|
|
4dee11a089 | ||
|
|
43e3ac0dc6 | ||
|
|
02f654cbce | ||
|
|
e1baadba84 | ||
|
|
e2a662eed8 | ||
|
|
e1a93805db | ||
|
|
af920e1e6f | ||
|
|
863e989c25 | ||
|
|
031a18c417 | ||
|
|
2b24f5fa71 | ||
|
|
e10300ed3c | ||
|
|
104f58fc48 | ||
|
|
5a6fa33b88 | ||
|
|
8239a0e0c4 | ||
|
|
50115596dc | ||
|
|
1c57dc21c2 | ||
|
|
47c41483bd | ||
|
|
ea075ed973 | ||
|
|
b431114194 | ||
|
|
cbf9e3f554 | ||
|
|
b6614f6c7c | ||
|
|
9ee3d731b5 | ||
|
|
e7d0ad092c | ||
|
|
412daf7362 | ||
|
|
c22af8c346 | ||
|
|
1bf41a0762 | ||
|
|
284283615b | ||
|
|
d163e20f63 | ||
|
|
f7eae45ae9 | ||
|
|
ff2dfc8422 | ||
|
|
7e701c18c8 | ||
|
|
90025a62c7 | ||
|
|
902b8cc39a | ||
|
|
70cfc02811 | ||
|
|
250bd66b76 | ||
|
|
c14d83d4e0 | ||
|
|
7d5fef8642 | ||
|
|
22fe9fce4c | ||
|
|
eda70b4e1a | ||
|
|
23c9362550 | ||
|
|
320c94bfaa | ||
|
|
3ef6c8410a | ||
|
|
cc1fbcc9a9 | ||
|
|
78d11cd781 | ||
|
|
7278cda039 | ||
|
|
7bb9db501c | ||
|
|
046a8eae0f | ||
|
|
a0cdac48e0 | ||
|
|
2ab3946ecb | ||
|
|
63f00dae6b | ||
|
|
80d78fad7c | ||
|
|
34debc733f | ||
|
|
87d7f7744e | ||
|
|
10dc1882c8 | ||
|
|
c6c0c3be08 | ||
|
|
da6c97203e | ||
|
|
853a46e021 | ||
|
|
075ad676aa | ||
|
|
19d1ad04f4 | ||
|
|
b884533957 | ||
|
|
174f37bdaf | ||
|
|
4f00774006 | ||
|
|
8403c49484 | ||
|
|
15e3bfac9d | ||
|
|
6cecd1a15b | ||
|
|
08620b7ceb | ||
|
|
fe1cee0837 | ||
|
|
06ab541e2f | ||
|
|
7babc24ad4 | ||
|
|
c96e9c8273 | ||
|
|
4a51295c9e | ||
|
|
9c392896b7 | ||
|
|
ea613e181c | ||
|
|
ed5bd1f9ef | ||
|
|
3401dbde92 | ||
|
|
c9e0208de4 | ||
|
|
57a816ae60 | ||
|
|
643f0e3abf | ||
|
|
8744d10235 | ||
|
|
336d9212fc | ||
|
|
79d88e2d0b | ||
|
|
a0d3e405a3 | ||
|
|
0e6e876f23 | ||
|
|
c680f54e6c | ||
|
|
4d745bc602 |
93
.github/workflows/build.yml
vendored
93
.github/workflows/build.yml
vendored
@@ -24,16 +24,22 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# The VulkanSDK libs for Windows is manually generated using build_windows_vulkan_libs.ps1 + attached to issue #8925.
|
||||
# (we have a .yml workflow in commit history if it becomes ever useful to create this on CI too)
|
||||
- name: Install Dependencies
|
||||
shell: powershell
|
||||
run: |
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.26.3-VC.zip" -OutFile "SDL2-devel-2.26.3-VC.zip"
|
||||
Expand-Archive -Path SDL2-devel-2.26.3-VC.zip
|
||||
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.26.3-VC\SDL2-2.26.3\" >>${env:GITHUB_ENV}
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL2-devel-2.32.8-VC.zip" -OutFile "SDL2-devel-2.32.8-VC.zip"
|
||||
Expand-Archive -Path SDL2-devel-2.32.8-VC.zip
|
||||
echo "SDL2_DIR=$(pwd)\SDL2-devel-2.32.8-VC\SDL2-2.32.8\" >>${env:GITHUB_ENV}
|
||||
|
||||
Invoke-WebRequest -Uri "https://github.com/ocornut/imgui/files/3789205/vulkan-sdk-1.1.121.2.zip" -OutFile vulkan-sdk-1.1.121.2.zip
|
||||
Expand-Archive -Path vulkan-sdk-1.1.121.2.zip
|
||||
echo "VULKAN_SDK=$(pwd)\vulkan-sdk-1.1.121.2\" >>${env:GITHUB_ENV}
|
||||
Invoke-WebRequest -Uri "https://www.libsdl.org/release/SDL3-devel-3.2.18-VC.zip" -OutFile "SDL3-devel-3.2.18-VC.zip"
|
||||
Expand-Archive -Path SDL3-devel-3.2.18-VC.zip
|
||||
echo "SDL3_DIR=$(pwd)\SDL3-devel-3.2.18-VC\SDL3-3.2.18\" >>${env:GITHUB_ENV}
|
||||
|
||||
Invoke-WebRequest -Uri "https://github.com/user-attachments/files/22464296/vulkan_windows_libs_1.4.326.zip" -OutFile vulkan_windows_libs_1.4.326.zip
|
||||
Expand-Archive -Path vulkan_windows_libs_1.4.326.zip
|
||||
echo "VULKAN_SDK=$(pwd)\vulkan_windows_libs_1.4.326\" >>${env:GITHUB_ENV}
|
||||
|
||||
- name: Fix Projects
|
||||
shell: powershell
|
||||
@@ -102,9 +108,12 @@ jobs:
|
||||
cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link
|
||||
cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
|
||||
|
||||
# Win64 examples are more frequently compilted than the Win32 examples.
|
||||
# More of the Win32 examples requires 'workflow_run' to reduce waste.
|
||||
- name: Build Win32 example_glfw_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_glfw_opengl3
|
||||
shell: cmd
|
||||
@@ -140,72 +149,111 @@ jobs:
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win32 example_sdl3_sdlgpu3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_sdlrenderer3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_sdl3_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx9
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx10
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win32 example_win32_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=Win32 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_glfw_opengl2
|
||||
# Windows 64-bits
|
||||
- name: Build Win64 example_glfw_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl2/example_glfw_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_glfw_opengl3
|
||||
- name: Build Win64 example_glfw_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_opengl3/example_glfw_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_glfw_vulkan
|
||||
- name: Build Win64 example_glfw_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_sdl2_sdlrenderer2
|
||||
- name: Build Win64 example_sdl2_sdlrenderer2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_vulkan
|
||||
- name: Build Win64 example_sdl2_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_opengl2
|
||||
- name: Build Win64 example_sdl2_opengl2
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl2/example_sdl2_opengl2.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_opengl3
|
||||
- name: Build Win64 example_sdl2_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_opengl3/example_sdl2_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_sdl2_directx11
|
||||
- name: Build Win64 example_sdl2_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl2_directx11/example_sdl2_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build x64 example_win32_directx9
|
||||
- name: Build Win64 example_sdl3_opengl3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_opengl3/example_sdl3_opengl3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win64 example_sdl3_sdlgpu3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win64 example_sdl3_sdlrenderer3
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
- name: Build Win64 example_sdl3_vulkan
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_sdl3_vulkan/example_sdl3_vulkan.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build Win64 example_win32_directx9
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx9/example_win32_directx9.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx10
|
||||
- name: Build Win64 example_win32_directx10
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx10/example_win32_directx10.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx11
|
||||
- name: Build Win64 example_win32_directx11
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx11/example_win32_directx11.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
if: github.event_name == 'workflow_run'
|
||||
|
||||
- name: Build x64 example_win32_directx12
|
||||
- name: Build Win64 example_win32_directx12
|
||||
shell: cmd
|
||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||
|
||||
@@ -433,7 +481,7 @@ jobs:
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
brew install glfw3 sdl2
|
||||
brew install glfw3 sdl2 sdl3
|
||||
|
||||
- name: Build example_null (extra warnings, clang 64-bit)
|
||||
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
||||
@@ -491,6 +539,9 @@ jobs:
|
||||
- name: Build example_sdl2_opengl3
|
||||
run: make -C examples/example_sdl2_opengl3
|
||||
|
||||
- name: Build example_sdl3_opengl3
|
||||
run: make -C examples/example_sdl3_opengl3
|
||||
|
||||
- name: Build example_apple_metal
|
||||
run: xcodebuild -project examples/example_apple_metal/example_apple_metal.xcodeproj -target example_apple_metal_macos
|
||||
|
||||
@@ -498,7 +549,7 @@ jobs:
|
||||
run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
|
||||
|
||||
iOS:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-14
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
|
||||
38
.github/workflows/build_windows_vulkan_libs.ps1
vendored
Normal file
38
.github/workflows/build_windows_vulkan_libs.ps1
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# This is current meant to be run manually, occasionally:
|
||||
# - Run then zip the contents of vulkanArtifact/ into e.g. vulkan_windows_libs_1.4.326
|
||||
# - Upload as an attachment to https://github.com/ocornut/imgui/pull/8925 then change filename in build.yml
|
||||
# - There is a build_windows_vulkan_libs.yml in commit history that we removed thinking this is run so rarely we don't need to pollute CI UI with it.
|
||||
|
||||
# Set default vulkan version if none provided
|
||||
if (-not $env:VULKAN_TAG) { $env:VULKAN_TAG = "1.4.326" }
|
||||
|
||||
# Create output folder
|
||||
mkdir vulkanArtifact
|
||||
|
||||
# Download Vulkan Headers
|
||||
|
||||
Invoke-WebRequest -Uri "https://github.com/KhronosGroup/Vulkan-Headers/archive/refs/tags/v$($env:VULKAN_TAG).zip" -OutFile Vulkan-Headers-$($env:VULKAN_TAG).zip
|
||||
Expand-Archive -Path Vulkan-Headers-$($env:VULKAN_TAG).zip
|
||||
|
||||
# Copy Vulkan Headers to artifact folder
|
||||
|
||||
cp -R Vulkan-Headers-$($env:VULKAN_TAG)\Vulkan-Headers-$($env:VULKAN_TAG)\include vulkanArtifact\Include
|
||||
|
||||
# Download Vulkan Loader
|
||||
|
||||
Invoke-WebRequest -Uri "https://github.com/KhronosGroup/Vulkan-Loader/archive/refs/tags/v$($env:VULKAN_TAG).zip" -OutFile Vulkan-Loader-$($env:VULKAN_TAG).zip
|
||||
Expand-Archive -Path Vulkan-Loader-$($env:VULKAN_TAG).zip
|
||||
|
||||
# Build Vulkan Loader x64
|
||||
|
||||
cmake -S Vulkan-Loader-$($env:VULKAN_TAG)\Vulkan-Loader-$($env:VULKAN_TAG) -B VulkanLoader-build64 -D UPDATE_DEPS=On -A x64
|
||||
cmake --build VulkanLoader-build64
|
||||
mkdir vulkanArtifact\Lib
|
||||
copy VulkanLoader-build64\loader\Debug\vulkan-1.lib vulkanArtifact\Lib
|
||||
|
||||
# Build Vulkan Loader win32
|
||||
|
||||
cmake -S Vulkan-Loader-$($env:VULKAN_TAG)\Vulkan-Loader-$($env:VULKAN_TAG) -B VulkanLoader-build32 -D UPDATE_DEPS=On -A Win32
|
||||
cmake --build VulkanLoader-build32
|
||||
mkdir vulkanArtifact\Lib32
|
||||
copy VulkanLoader-build32\loader\Debug\vulkan-1.lib vulkanArtifact\Lib32
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -68,6 +68,7 @@ examples/example_sdl2_opengl2/example_sdl2_opengl2
|
||||
examples/example_sdl2_opengl3/example_sdl2_opengl3
|
||||
examples/example_sdl2_sdlrenderer2/example_sdl2_sdlrenderer2
|
||||
examples/example_sdl2_vulkan/example_sdl2_vulkan
|
||||
examples/example_sdl3_metal/example_sdl3_metal
|
||||
examples/example_sdl3_opengl3/example_sdl3_opengl3
|
||||
examples/example_sdl3_sdlgpu3/example_sdl3_sdlgpu3
|
||||
examples/example_sdl3_sdlrenderer3/example_sdl3_sdlrenderer3
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() and platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-08-12: Inputs: fixed missing support for ImGuiKey_PrintScreen under Windows, as raw Allegro 5 does not receive it.
|
||||
// 2025-08-12: Added ImGui_ImplAllegro5_SetDisplay() function to change current ALLEGRO_DISPLAY, as Allegro applications often need to do that.
|
||||
// 2025-07-07: Fixed texture update broken on some platforms where ALLEGRO_LOCK_WRITEONLY needed all texels to be rewritten.
|
||||
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
|
||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
@@ -161,10 +164,8 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data)
|
||||
ImGui_ImplAllegro5_SetupRenderState(draw_data);
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
ImVector<ImDrawVertAllegro>& vertices = bd->BufVertices;
|
||||
#if ALLEGRO_HAS_DRAW_INDEXED_PRIM
|
||||
vertices.resize(draw_list->VtxBuffer.Size);
|
||||
@@ -270,8 +271,6 @@ void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex)
|
||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE);
|
||||
ALLEGRO_BITMAP* cpu_bitmap = al_create_bitmap(tex->Width, tex->Height);
|
||||
al_set_new_bitmap_flags(new_bitmap_flags);
|
||||
al_set_new_bitmap_format(new_bitmap_format);
|
||||
IM_ASSERT(cpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||
|
||||
// Upload pixels
|
||||
@@ -281,10 +280,15 @@ void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex)
|
||||
al_unlock_bitmap(cpu_bitmap);
|
||||
|
||||
// Convert software texture to hardware texture.
|
||||
al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
|
||||
al_set_new_bitmap_format(ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA);
|
||||
ALLEGRO_BITMAP* gpu_bitmap = al_clone_bitmap(cpu_bitmap);
|
||||
al_destroy_bitmap(cpu_bitmap);
|
||||
IM_ASSERT(gpu_bitmap != nullptr && "Backend failed to create texture!");
|
||||
|
||||
al_set_new_bitmap_flags(new_bitmap_flags);
|
||||
al_set_new_bitmap_format(new_bitmap_format);
|
||||
|
||||
// Store identifiers
|
||||
tex->SetTexID((ImTextureID)(intptr_t)gpu_bitmap);
|
||||
tex->SetStatus(ImTextureStatus_OK);
|
||||
@@ -479,20 +483,9 @@ bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||
|
||||
bd->Display = display;
|
||||
bd->LastCursor = ALLEGRO_SYSTEM_MOUSE_CURSOR_NONE;
|
||||
|
||||
// Create custom vertex declaration.
|
||||
// Unfortunately Allegro doesn't support 32-bit packed colors so we have to convert them to 4 floats.
|
||||
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] =
|
||||
{
|
||||
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
|
||||
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
|
||||
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||
ImGui_ImplAllegro5_SetDisplay(display);
|
||||
|
||||
#if ALLEGRO_HAS_CLIPBOARD
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
@@ -508,6 +501,7 @@ void ImGui_ImplAllegro5_Shutdown()
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplAllegro5_InvalidateDeviceObjects();
|
||||
if (bd->VertexDecl)
|
||||
@@ -518,9 +512,38 @@ void ImGui_ImplAllegro5_Shutdown()
|
||||
io.BackendPlatformName = io.BackendRendererName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_RendererHasTextures);
|
||||
platform_io.ClearRendererHandlers();
|
||||
platform_io.ClearPlatformHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplAllegro5_SetDisplay(ALLEGRO_DISPLAY* display)
|
||||
{
|
||||
ImGui_ImplAllegro5_Data* bd = ImGui_ImplAllegro5_GetBackendData();
|
||||
bd->Display = display;
|
||||
|
||||
if (bd->VertexDecl)
|
||||
{
|
||||
al_destroy_vertex_decl(bd->VertexDecl);
|
||||
bd->VertexDecl = NULL;
|
||||
}
|
||||
|
||||
if (bd->Display && !bd->VertexDecl)
|
||||
{
|
||||
// Create custom vertex declaration.
|
||||
// Unfortunately Allegro doesn't support 32-bits packed colors so we have to convert them to 4 floats.
|
||||
// We still use a custom declaration to use 'ALLEGRO_PRIM_TEX_COORD' instead of 'ALLEGRO_PRIM_TEX_COORD_PIXEL' else we can't do a reliable conversion.
|
||||
ALLEGRO_VERTEX_ELEMENT elems[] =
|
||||
{
|
||||
{ ALLEGRO_PRIM_POSITION, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, pos) },
|
||||
{ ALLEGRO_PRIM_TEX_COORD, ALLEGRO_PRIM_FLOAT_2, offsetof(ImDrawVertAllegro, uv) },
|
||||
{ ALLEGRO_PRIM_COLOR_ATTR, 0, offsetof(ImDrawVertAllegro, col) },
|
||||
{ 0, 0, 0 }
|
||||
};
|
||||
bd->VertexDecl = al_create_vertex_decl(elems, sizeof(ImDrawVertAllegro));
|
||||
}
|
||||
}
|
||||
|
||||
// ev->keyboard.modifiers seems always zero so using that...
|
||||
static void ImGui_ImplAllegro5_UpdateKeyModifiers()
|
||||
{
|
||||
@@ -662,6 +685,11 @@ void ImGui_ImplAllegro5_NewFrame()
|
||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||
bd->Time = current_time;
|
||||
|
||||
// Allegro 5 doesn't receive PrintScreen under Windows
|
||||
#ifdef _WIN32
|
||||
io.AddKeyEvent(ImGuiKey_PrintScreen, (::GetAsyncKeyState(VK_SNAPSHOT) & 0x8000) != 0);
|
||||
#endif
|
||||
|
||||
// Setup mouse cursor shape
|
||||
ImGui_ImplAllegro5_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ IMGUI_IMPL_API void ImGui_ImplAllegro5_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data);
|
||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT* event);
|
||||
IMGUI_IMPL_API void ImGui_ImplAllegro5_SetDisplay(ALLEGRO_DISPLAY* display);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API bool ImGui_ImplAllegro5_CreateDeviceObjects();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: DirectX10: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||
// 2025-05-07: DirectX10: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||
// 2025-01-06: DirectX10: Expose selected render state in ImGui_ImplDX10_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
@@ -75,7 +76,7 @@ struct ImGui_ImplDX10_Data
|
||||
ID3D10InputLayout* pInputLayout;
|
||||
ID3D10Buffer* pVertexConstantBuffer;
|
||||
ID3D10PixelShader* pPixelShader;
|
||||
ID3D10SamplerState* pFontSampler;
|
||||
ID3D10SamplerState* pTexSamplerLinear;
|
||||
ID3D10RasterizerState* pRasterizerState;
|
||||
ID3D10BlendState* pBlendState;
|
||||
ID3D10DepthStencilState* pDepthStencilState;
|
||||
@@ -146,7 +147,7 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
||||
device->VSSetShader(bd->pVertexShader);
|
||||
device->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device->PSSetShader(bd->pPixelShader);
|
||||
device->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device->PSSetSamplers(0, 1, &bd->pTexSamplerLinear);
|
||||
device->GSSetShader(nullptr);
|
||||
|
||||
// Setup render state
|
||||
@@ -206,9 +207,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
ImDrawIdx* idx_dst = nullptr;
|
||||
bd->pVB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&vtx_dst);
|
||||
bd->pIB->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&idx_dst);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -264,7 +264,7 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplDX10_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.SamplerDefault = bd->pTexSamplerLinear;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
@@ -274,9 +274,8 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -332,18 +331,18 @@ void ImGui_ImplDX10_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
static void ImGui_ImplDX10_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID);
|
||||
backend_tex->pTexture->Release();
|
||||
backend_tex->pTextureView->Release();
|
||||
IM_DELETE(backend_tex);
|
||||
if (ImGui_ImplDX10_Texture* backend_tex = (ImGui_ImplDX10_Texture*)tex->BackendUserData)
|
||||
{
|
||||
IM_ASSERT(backend_tex->pTextureView == (ID3D10ShaderResourceView*)(intptr_t)tex->TexID);
|
||||
backend_tex->pTextureView->Release();
|
||||
backend_tex->pTexture->Release();
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_UpdateTexture(ImTextureData* tex)
|
||||
@@ -571,7 +570,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
||||
desc.ComparisonFunc = D3D10_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pTexSamplerLinear);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -587,7 +586,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects()
|
||||
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||
if (tex->RefCount == 1)
|
||||
ImGui_ImplDX10_DestroyTexture(tex);
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pTexSamplerLinear) { bd->pTexSamplerLinear->Release(); bd->pTexSamplerLinear = nullptr; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
@@ -641,14 +640,17 @@ void ImGui_ImplDX10_Shutdown()
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -706,6 +708,7 @@ static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
|
||||
|
||||
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
||||
bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||
bd->pFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES); // Disable e.g. Alt+Enter
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain)
|
||||
@@ -767,7 +770,8 @@ static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*)
|
||||
static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
void ImGui_ImplDX10_InitMultiViewportSupport()
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: DirectX11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||
// 2025-05-07: DirectX11: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||
// 2025-02-24: [Docking] Added undocumented ImGui_ImplDX11_SetSwapChainDescs() to configure swap chain creation for secondary viewports.
|
||||
@@ -79,7 +80,7 @@ struct ImGui_ImplDX11_Data
|
||||
ID3D11InputLayout* pInputLayout;
|
||||
ID3D11Buffer* pVertexConstantBuffer;
|
||||
ID3D11PixelShader* pPixelShader;
|
||||
ID3D11SamplerState* pFontSampler;
|
||||
ID3D11SamplerState* pTexSamplerLinear;
|
||||
ID3D11RasterizerState* pRasterizerState;
|
||||
ID3D11BlendState* pBlendState;
|
||||
ID3D11DepthStencilState* pDepthStencilState;
|
||||
@@ -107,7 +108,7 @@ static void ImGui_ImplDX11_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||
static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
@@ -151,7 +152,7 @@ static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceC
|
||||
device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||
device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||
device_ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
device_ctx->PSSetSamplers(0, 1, &bd->pTexSamplerLinear);
|
||||
device_ctx->GSSetShader(nullptr, nullptr, 0);
|
||||
device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
@@ -216,9 +217,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -280,7 +280,7 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
ImGui_ImplDX11_RenderState render_state;
|
||||
render_state.Device = bd->pd3dDevice;
|
||||
render_state.DeviceContext = bd->pd3dDeviceContext;
|
||||
render_state.SamplerDefault = bd->pFontSampler;
|
||||
render_state.SamplerDefault = bd->pTexSamplerLinear;
|
||||
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
@@ -290,9 +290,8 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_vtx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -350,18 +349,18 @@ void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
static void ImGui_ImplDX11_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||
backend_tex->pTextureView->Release();
|
||||
backend_tex->pTexture->Release();
|
||||
IM_DELETE(backend_tex);
|
||||
if (ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData)
|
||||
{
|
||||
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||
backend_tex->pTextureView->Release();
|
||||
backend_tex->pTexture->Release();
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex)
|
||||
@@ -588,7 +587,7 @@ bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pTexSamplerLinear);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -605,7 +604,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
if (tex->RefCount == 1)
|
||||
ImGui_ImplDX11_DestroyTexture(tex);
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = nullptr; }
|
||||
if (bd->pTexSamplerLinear) { bd->pTexSamplerLinear->Release(); bd->pTexSamplerLinear = nullptr; }
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||
@@ -662,15 +661,18 @@ void ImGui_ImplDX11_Shutdown()
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -736,6 +738,7 @@ static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
||||
break;
|
||||
}
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
bd->pFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES); // Disable e.g. Alt+Enter
|
||||
|
||||
// Create the render target
|
||||
if (vd->SwapChain != nullptr)
|
||||
@@ -797,7 +800,8 @@ static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
if (vd->SwapChain)
|
||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_InitMultiViewportSupport()
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-10-11: DirectX12: Reuse texture upload buffer and grow it only when necessary. (#9002)
|
||||
// 2025-09-29: DirectX12: Rework synchronization logic. (#8961)
|
||||
// 2025-09-29: DirectX12: Enable swapchain tearing to eliminate viewports framerate throttling. (#8965)
|
||||
// 2025-09-29: DirectX12: Reuse a command list and allocator for texture uploads instead of recreating them each time. (#8963)
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-19: Fixed build on MinGW. (#8702, #4594)
|
||||
// 2025-06-11: DirectX12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||
// 2025-05-07: DirectX12: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||
@@ -59,7 +64,7 @@
|
||||
|
||||
// DirectX
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_4.h>
|
||||
#include <dxgi1_5.h>
|
||||
#include <d3dcompiler.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
@@ -89,6 +94,7 @@ struct ImGui_ImplDX12_Texture
|
||||
struct ImGui_ImplDX12_Data
|
||||
{
|
||||
ImGui_ImplDX12_InitInfo InitInfo;
|
||||
IDXGIFactory5* pdxgiFactory;
|
||||
ID3D12Device* pd3dDevice;
|
||||
ID3D12RootSignature* pRootSignature;
|
||||
ID3D12PipelineState* pPipelineState;
|
||||
@@ -97,10 +103,19 @@ struct ImGui_ImplDX12_Data
|
||||
DXGI_FORMAT RTVFormat;
|
||||
DXGI_FORMAT DSVFormat;
|
||||
ID3D12DescriptorHeap* pd3dSrvDescHeap;
|
||||
ID3D12Fence* Fence;
|
||||
UINT64 FenceLastSignaledValue;
|
||||
HANDLE FenceEvent;
|
||||
UINT numFramesInFlight;
|
||||
ImGui_ImplDX12_Texture FontTexture;
|
||||
bool tearingSupport;
|
||||
bool LegacySingleDescriptorUsed;
|
||||
|
||||
ID3D12CommandAllocator* pTexCmdAllocator;
|
||||
ID3D12GraphicsCommandList* pTexCmdList;
|
||||
ID3D12Resource* pTexUploadBuffer;
|
||||
UINT pTexUploadBufferSize;
|
||||
void* pTexUploadBufferMapped;
|
||||
|
||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
@@ -123,6 +138,7 @@ struct ImGui_ImplDX12_RenderBuffers
|
||||
// Buffers used for secondary viewports created by the multi-viewports systems
|
||||
struct ImGui_ImplDX12_FrameContext
|
||||
{
|
||||
UINT64 FenceValue;
|
||||
ID3D12CommandAllocator* CommandAllocator;
|
||||
ID3D12Resource* RenderTarget;
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE RenderTargetCpuDescriptors;
|
||||
@@ -138,9 +154,7 @@ struct ImGui_ImplDX12_ViewportData
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
ID3D12DescriptorHeap* RtvDescHeap;
|
||||
IDXGISwapChain3* SwapChain;
|
||||
ID3D12Fence* Fence;
|
||||
UINT64 FenceSignaledValue;
|
||||
HANDLE FenceEvent;
|
||||
HANDLE SwapChainWaitableObject;
|
||||
UINT NumFramesInFlight;
|
||||
ImGui_ImplDX12_FrameContext* FrameCtx;
|
||||
|
||||
@@ -154,16 +168,15 @@ struct ImGui_ImplDX12_ViewportData
|
||||
CommandList = nullptr;
|
||||
RtvDescHeap = nullptr;
|
||||
SwapChain = nullptr;
|
||||
Fence = nullptr;
|
||||
FenceSignaledValue = 0;
|
||||
FenceEvent = nullptr;
|
||||
SwapChainWaitableObject = nullptr;
|
||||
NumFramesInFlight = num_frames_in_flight;
|
||||
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
|
||||
FrameIndex = UINT_MAX;
|
||||
FrameIndex = 0;
|
||||
FrameRenderBuffers = new ImGui_ImplDX12_RenderBuffers[NumFramesInFlight];
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
FrameCtx[i].FenceValue = 0;
|
||||
FrameCtx[i].CommandAllocator = nullptr;
|
||||
FrameCtx[i].RenderTarget = nullptr;
|
||||
|
||||
@@ -179,8 +192,7 @@ struct ImGui_ImplDX12_ViewportData
|
||||
IM_ASSERT(CommandQueue == nullptr && CommandList == nullptr);
|
||||
IM_ASSERT(RtvDescHeap == nullptr);
|
||||
IM_ASSERT(SwapChain == nullptr);
|
||||
IM_ASSERT(Fence == nullptr);
|
||||
IM_ASSERT(FenceEvent == nullptr);
|
||||
IM_ASSERT(SwapChainWaitableObject == nullptr);
|
||||
|
||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
||||
{
|
||||
@@ -199,8 +211,8 @@ struct VERTEX_CONSTANT_BUFFER_DX12
|
||||
};
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX12_InitPlatformInterface();
|
||||
static void ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
static void ImGui_ImplDX12_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX12_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12GraphicsCommandList* command_list, ImGui_ImplDX12_RenderBuffers* fr)
|
||||
@@ -339,9 +351,8 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -372,9 +383,8 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -414,21 +424,21 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
||||
|
||||
static void ImGui_ImplDX12_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(backend_tex->hFontSrvGpuDescHandle.ptr == (UINT64)tex->TexID);
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, backend_tex->hFontSrvCpuDescHandle, backend_tex->hFontSrvGpuDescHandle);
|
||||
SafeRelease(backend_tex->pTextureResource);
|
||||
backend_tex->hFontSrvCpuDescHandle.ptr = 0;
|
||||
backend_tex->hFontSrvGpuDescHandle.ptr = 0;
|
||||
IM_DELETE(backend_tex);
|
||||
if (ImGui_ImplDX12_Texture* backend_tex = (ImGui_ImplDX12_Texture*)tex->BackendUserData)
|
||||
{
|
||||
IM_ASSERT(backend_tex->hFontSrvGpuDescHandle.ptr == (UINT64)tex->TexID);
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
bd->InitInfo.SrvDescriptorFreeFn(&bd->InitInfo, backend_tex->hFontSrvCpuDescHandle, backend_tex->hFontSrvGpuDescHandle);
|
||||
SafeRelease(backend_tex->pTextureResource);
|
||||
backend_tex->hFontSrvCpuDescHandle.ptr = 0;
|
||||
backend_tex->hFontSrvGpuDescHandle.ptr = 0;
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex)
|
||||
@@ -507,58 +517,53 @@ void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex)
|
||||
UINT upload_pitch_dst = (upload_pitch_src + D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u) & ~(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT - 1u);
|
||||
UINT upload_size = upload_pitch_dst * upload_h;
|
||||
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = upload_size;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
if (bd->pTexUploadBuffer == nullptr || upload_size > bd->pTexUploadBufferSize)
|
||||
{
|
||||
if (bd->pTexUploadBufferMapped)
|
||||
{
|
||||
D3D12_RANGE range = { 0, bd->pTexUploadBufferSize };
|
||||
bd->pTexUploadBuffer->Unmap(0, &range);
|
||||
bd->pTexUploadBufferMapped = nullptr;
|
||||
}
|
||||
SafeRelease(bd->pTexUploadBuffer);
|
||||
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
D3D12_RESOURCE_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
|
||||
desc.Alignment = 0;
|
||||
desc.Width = upload_size;
|
||||
desc.Height = 1;
|
||||
desc.DepthOrArraySize = 1;
|
||||
desc.MipLevels = 1;
|
||||
desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.SampleDesc.Quality = 0;
|
||||
desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
|
||||
desc.Flags = D3D12_RESOURCE_FLAG_NONE;
|
||||
|
||||
// FIXME-OPT: Can upload buffer be reused?
|
||||
ID3D12Resource* uploadBuffer = nullptr;
|
||||
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&uploadBuffer));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
D3D12_HEAP_PROPERTIES props;
|
||||
memset(&props, 0, sizeof(D3D12_HEAP_PROPERTIES));
|
||||
props.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
props.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
|
||||
props.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
|
||||
|
||||
// Create temporary command list and execute immediately
|
||||
ID3D12Fence* fence = nullptr;
|
||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&fence));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
HRESULT hr = bd->pd3dDevice->CreateCommittedResource(&props, D3D12_HEAP_FLAG_NONE, &desc,
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, IID_PPV_ARGS(&bd->pTexUploadBuffer));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
HANDLE event = ::CreateEvent(0, 0, 0, 0);
|
||||
IM_ASSERT(event != nullptr);
|
||||
D3D12_RANGE range = {0, upload_size};
|
||||
hr = bd->pTexUploadBuffer->Map(0, &range, &bd->pTexUploadBufferMapped);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
bd->pTexUploadBufferSize = upload_size;
|
||||
}
|
||||
|
||||
// FIXME-OPT: Create once and reuse?
|
||||
ID3D12CommandAllocator* cmdAlloc = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&cmdAlloc));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
// FIXME-OPT: Can be use the one from user? (pass ID3D12GraphicsCommandList* to ImGui_ImplDX12_UpdateTextures)
|
||||
ID3D12GraphicsCommandList* cmdList = nullptr;
|
||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, cmdAlloc, nullptr, IID_PPV_ARGS(&cmdList));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
bd->pTexCmdAllocator->Reset();
|
||||
bd->pTexCmdList->Reset(bd->pTexCmdAllocator, nullptr);
|
||||
ID3D12GraphicsCommandList* cmdList = bd->pTexCmdList;
|
||||
|
||||
// Copy to upload buffer
|
||||
void* mapped = nullptr;
|
||||
D3D12_RANGE range = { 0, upload_size };
|
||||
hr = uploadBuffer->Map(0, &range, &mapped);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
for (int y = 0; y < upload_h; y++)
|
||||
memcpy((void*)((uintptr_t)mapped + y * upload_pitch_dst), tex->GetPixelsAt(upload_x, upload_y + y), upload_pitch_src);
|
||||
uploadBuffer->Unmap(0, &range);
|
||||
memcpy((void*)((uintptr_t)bd->pTexUploadBufferMapped + y * upload_pitch_dst), tex->GetPixelsAt(upload_x, upload_y + y), upload_pitch_src);
|
||||
|
||||
if (need_barrier_before_copy)
|
||||
{
|
||||
@@ -575,7 +580,7 @@ void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex)
|
||||
D3D12_TEXTURE_COPY_LOCATION srcLocation = {};
|
||||
D3D12_TEXTURE_COPY_LOCATION dstLocation = {};
|
||||
{
|
||||
srcLocation.pResource = uploadBuffer;
|
||||
srcLocation.pResource = bd->pTexUploadBuffer;
|
||||
srcLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
|
||||
srcLocation.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srcLocation.PlacedFootprint.Footprint.Width = upload_w;
|
||||
@@ -599,26 +604,20 @@ void ImGui_ImplDX12_UpdateTexture(ImTextureData* tex)
|
||||
cmdList->ResourceBarrier(1, &barrier);
|
||||
}
|
||||
|
||||
hr = cmdList->Close();
|
||||
HRESULT hr = cmdList->Close();
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
ID3D12CommandQueue* cmdQueue = bd->pCommandQueue;
|
||||
cmdQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmdList);
|
||||
hr = cmdQueue->Signal(fence, 1);
|
||||
hr = cmdQueue->Signal(bd->Fence, ++bd->FenceLastSignaledValue);
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
// FIXME-OPT: Suboptimal?
|
||||
// - To remove this may need to create NumFramesInFlight x ImGui_ImplDX12_FrameContext in backend data (mimick docking version)
|
||||
// - Store per-frame in flight: upload buffer?
|
||||
// - Where do cmdList and cmdAlloc fit?
|
||||
fence->SetEventOnCompletion(1, event);
|
||||
::WaitForSingleObject(event, INFINITE);
|
||||
bd->Fence->SetEventOnCompletion(bd->FenceLastSignaledValue, bd->FenceEvent);
|
||||
::WaitForSingleObject(bd->FenceEvent, INFINITE);
|
||||
|
||||
cmdList->Release();
|
||||
cmdAlloc->Release();
|
||||
::CloseHandle(event);
|
||||
fence->Release();
|
||||
uploadBuffer->Release();
|
||||
tex->SetStatus(ImTextureStatus_OK);
|
||||
}
|
||||
|
||||
@@ -634,6 +633,13 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
if (bd->pPipelineState)
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
HRESULT hr = ::CreateDXGIFactory1(IID_PPV_ARGS(&bd->pdxgiFactory));
|
||||
IM_ASSERT(hr == S_OK);
|
||||
|
||||
BOOL allow_tearing = FALSE;
|
||||
bd->pdxgiFactory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing, sizeof(allow_tearing));
|
||||
bd->tearingSupport = (allow_tearing == TRUE);
|
||||
|
||||
// Create the root signature
|
||||
{
|
||||
D3D12_DESCRIPTOR_RANGE descRange = {};
|
||||
@@ -657,26 +663,26 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
D3D12_STATIC_SAMPLER_DESC staticSampler = {};
|
||||
staticSampler.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
staticSampler.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
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 = D3D12_FLOAT32_MAX;
|
||||
staticSampler.ShaderRegister = 0;
|
||||
staticSampler.RegisterSpace = 0;
|
||||
staticSampler.ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||
D3D12_STATIC_SAMPLER_DESC staticSampler[1] = {};
|
||||
staticSampler[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
staticSampler[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler[0].AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler[0].AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||
staticSampler[0].MipLODBias = 0.f;
|
||||
staticSampler[0].MaxAnisotropy = 0;
|
||||
staticSampler[0].ComparisonFunc = D3D12_COMPARISON_FUNC_ALWAYS;
|
||||
staticSampler[0].BorderColor = D3D12_STATIC_BORDER_COLOR_TRANSPARENT_BLACK;
|
||||
staticSampler[0].MinLOD = 0.f;
|
||||
staticSampler[0].MaxLOD = D3D12_FLOAT32_MAX;
|
||||
staticSampler[0].ShaderRegister = 0;
|
||||
staticSampler[0].RegisterSpace = 0;
|
||||
staticSampler[0].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
||||
|
||||
D3D12_ROOT_SIGNATURE_DESC desc = {};
|
||||
desc.NumParameters = _countof(param);
|
||||
desc.pParameters = param;
|
||||
desc.NumStaticSamplers = 1;
|
||||
desc.pStaticSamplers = &staticSampler;
|
||||
desc.pStaticSamplers = &staticSampler[0];
|
||||
desc.Flags =
|
||||
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
|
||||
D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
|
||||
@@ -855,6 +861,20 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
||||
if (result_pipeline_state != S_OK)
|
||||
return false;
|
||||
|
||||
// Create command allocator and command list for ImGui_ImplDX12_UpdateTexture()
|
||||
hr = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&bd->pTexCmdAllocator));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
hr = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, bd->pTexCmdAllocator, nullptr, IID_PPV_ARGS(&bd->pTexCmdList));
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
hr = bd->pTexCmdList->Close();
|
||||
IM_ASSERT(SUCCEEDED(hr));
|
||||
|
||||
// Create fence.
|
||||
hr = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&bd->Fence));
|
||||
IM_ASSERT(hr == S_OK);
|
||||
bd->FenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
IM_ASSERT(bd->FenceEvent != nullptr);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -871,11 +891,24 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||
if (!bd || !bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
SafeRelease(bd->pdxgiFactory);
|
||||
if (bd->commandQueueOwned)
|
||||
SafeRelease(bd->pCommandQueue);
|
||||
bd->commandQueueOwned = false;
|
||||
SafeRelease(bd->pRootSignature);
|
||||
SafeRelease(bd->pPipelineState);
|
||||
if (bd->pTexUploadBufferMapped)
|
||||
{
|
||||
D3D12_RANGE range = { 0, bd->pTexUploadBufferSize };
|
||||
bd->pTexUploadBuffer->Unmap(0, &range);
|
||||
bd->pTexUploadBufferMapped = nullptr;
|
||||
}
|
||||
SafeRelease(bd->pTexUploadBuffer);
|
||||
SafeRelease(bd->pTexCmdList);
|
||||
SafeRelease(bd->pTexCmdAllocator);
|
||||
SafeRelease(bd->Fence);
|
||||
CloseHandle(bd->FenceEvent);
|
||||
bd->FenceEvent = nullptr;
|
||||
|
||||
// Destroy all textures
|
||||
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||
@@ -923,6 +956,7 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
bd->DSVFormat = init_info->DSVFormat;
|
||||
bd->numFramesInFlight = init_info->NumFramesInFlight;
|
||||
bd->pd3dSrvDescHeap = init_info->SrvDescriptorHeap;
|
||||
bd->tearingSupport = false;
|
||||
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx12";
|
||||
@@ -931,7 +965,7 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
ImGui_ImplDX12_InitPlatformInterface();
|
||||
ImGui_ImplDX12_InitMultiViewportSupport();
|
||||
|
||||
// Create a dummy ImGui_ImplDX12_ViewportData holder for the main viewport,
|
||||
// Since this is created and managed by the application, we will only use the ->Resources[] fields.
|
||||
@@ -982,6 +1016,7 @@ void ImGui_ImplDX12_Shutdown()
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
// Manually delete main viewport render resources in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
@@ -994,13 +1029,13 @@ void ImGui_ImplDX12_Shutdown()
|
||||
main_viewport->RendererUserData = nullptr;
|
||||
}
|
||||
|
||||
// Clean up windows and device objects
|
||||
ImGui_ImplDX12_ShutdownPlatformInterface();
|
||||
ImGui_ImplDX12_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -1031,18 +1066,12 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||
IM_ASSERT(hwnd != 0);
|
||||
|
||||
vd->FrameIndex = UINT_MAX;
|
||||
|
||||
// Create command queue.
|
||||
D3D12_COMMAND_QUEUE_DESC queue_desc = {};
|
||||
queue_desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
||||
queue_desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
||||
|
||||
HRESULT res = S_OK;
|
||||
res = bd->pd3dDevice->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&vd->CommandQueue));
|
||||
IM_ASSERT(res == S_OK);
|
||||
// Use shared command queue from init info
|
||||
vd->FrameIndex = 0;
|
||||
vd->CommandQueue = bd->pCommandQueue;
|
||||
|
||||
// Create command allocator.
|
||||
HRESULT res = S_OK;
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; ++i)
|
||||
{
|
||||
res = bd->pd3dDevice->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&vd->FrameCtx[i].CommandAllocator));
|
||||
@@ -1054,13 +1083,6 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
IM_ASSERT(res == S_OK);
|
||||
vd->CommandList->Close();
|
||||
|
||||
// Create fence.
|
||||
res = bd->pd3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&vd->Fence));
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
vd->FenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
|
||||
IM_ASSERT(vd->FenceEvent != nullptr);
|
||||
|
||||
// Create swap chain
|
||||
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
|
||||
DXGI_SWAP_CHAIN_DESC1 sd1;
|
||||
@@ -1076,23 +1098,23 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
||||
sd1.Scaling = DXGI_SCALING_NONE;
|
||||
sd1.Stereo = FALSE;
|
||||
sd1.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
|
||||
|
||||
IDXGIFactory4* dxgi_factory = nullptr;
|
||||
res = ::CreateDXGIFactory1(IID_PPV_ARGS(&dxgi_factory));
|
||||
IM_ASSERT(res == S_OK);
|
||||
if (bd->tearingSupport)
|
||||
sd1.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
|
||||
IDXGISwapChain1* swap_chain = nullptr;
|
||||
res = dxgi_factory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, nullptr, nullptr, &swap_chain);
|
||||
res = bd->pdxgiFactory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, nullptr, nullptr, &swap_chain);
|
||||
IM_ASSERT(res == S_OK);
|
||||
res = bd->pdxgiFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES); // Disable e.g. Alt+Enter
|
||||
IM_ASSERT(res == S_OK);
|
||||
|
||||
dxgi_factory->Release();
|
||||
|
||||
// Or swapChain.As(&mSwapChain)
|
||||
IM_ASSERT(vd->SwapChain == nullptr);
|
||||
swap_chain->QueryInterface(IID_PPV_ARGS(&vd->SwapChain));
|
||||
swap_chain->Release();
|
||||
|
||||
// Create the render targets
|
||||
// Create the render targets and waitable object
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
||||
@@ -1120,6 +1142,10 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, nullptr, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
||||
}
|
||||
|
||||
hr = vd->SwapChain->SetMaximumFrameLatency(bd->numFramesInFlight);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
vd->SwapChainWaitableObject = vd->SwapChain->GetFrameLatencyWaitableObject();
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
@@ -1128,16 +1154,31 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
||||
|
||||
static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
if (vd && vd->CommandQueue && vd->Fence && vd->FenceEvent)
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
HRESULT hr = vd->CommandQueue->Signal(bd->Fence, ++bd->FenceLastSignaledValue);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
|
||||
hr = bd->Fence->SetEventOnCompletion(bd->FenceLastSignaledValue, bd->FenceEvent);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(bd->FenceEvent, INFINITE);
|
||||
}
|
||||
|
||||
static ImGui_ImplDX12_FrameContext* ImGui_WaitForNextFrameContext(ImGui_ImplDX12_ViewportData* vd)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % vd->NumFramesInFlight];
|
||||
if (bd->Fence->GetCompletedValue() < frame_context->FenceValue)
|
||||
{
|
||||
hr = vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
HRESULT hr = bd->Fence->SetEventOnCompletion(frame_context->FenceValue, bd->FenceEvent);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, 0); // Reset any forgotten waits
|
||||
hr = vd->Fence->SetEventOnCompletion(vd->FenceSignaledValue, vd->FenceEvent);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
::WaitForSingleObject(vd->FenceEvent, INFINITE);
|
||||
HANDLE waitableObjects[] = { vd->SwapChainWaitableObject, bd->FenceEvent };
|
||||
::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
::WaitForSingleObject(vd->SwapChainWaitableObject, INFINITE);
|
||||
}
|
||||
return frame_context;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
@@ -1148,13 +1189,12 @@ static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_WaitForPendingOperations(vd);
|
||||
|
||||
SafeRelease(vd->CommandQueue);
|
||||
vd->CommandQueue = nullptr;
|
||||
::CloseHandle(vd->SwapChainWaitableObject);
|
||||
vd->SwapChainWaitableObject = nullptr;
|
||||
SafeRelease(vd->CommandList);
|
||||
SafeRelease(vd->SwapChain);
|
||||
SafeRelease(vd->RtvDescHeap);
|
||||
SafeRelease(vd->Fence);
|
||||
::CloseHandle(vd->FenceEvent);
|
||||
vd->FenceEvent = nullptr;
|
||||
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
@@ -1180,7 +1220,9 @@ static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
if (vd->SwapChain)
|
||||
{
|
||||
ID3D12Resource* back_buffer = nullptr;
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {};
|
||||
vd->SwapChain->GetDesc1(&desc);
|
||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, desc.Format, desc.Flags);
|
||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||
{
|
||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
||||
@@ -1195,7 +1237,7 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
ImGui_ImplDX12_FrameContext* frame_context = &vd->FrameCtx[vd->FrameIndex % bd->numFramesInFlight];
|
||||
ImGui_ImplDX12_FrameContext* frame_context = ImGui_WaitForNextFrameContext(vd);
|
||||
UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
@@ -1225,21 +1267,23 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
cmd_list->ResourceBarrier(1, &barrier);
|
||||
cmd_list->Close();
|
||||
|
||||
vd->CommandQueue->Wait(vd->Fence, vd->FenceSignaledValue);
|
||||
vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list);
|
||||
vd->CommandQueue->Signal(vd->Fence, ++vd->FenceSignaledValue);
|
||||
|
||||
HRESULT hr = vd->CommandQueue->Signal(bd->Fence, ++bd->FenceLastSignaledValue);
|
||||
IM_ASSERT(hr == S_OK);
|
||||
frame_context->FenceValue = bd->FenceLastSignaledValue;
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX12_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
|
||||
vd->SwapChain->Present(0, 0);
|
||||
while (vd->Fence->GetCompletedValue() < vd->FenceSignaledValue)
|
||||
::SwitchToThread();
|
||||
vd->SwapChain->Present(0, bd->tearingSupport ? DXGI_PRESENT_ALLOW_TEARING : 0);
|
||||
vd->FrameIndex++;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_InitPlatformInterface()
|
||||
void ImGui_ImplDX12_InitMultiViewportSupport()
|
||||
{
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX12_CreateWindow;
|
||||
@@ -1249,7 +1293,7 @@ void ImGui_ImplDX12_InitPlatformInterface()
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX12_SwapBuffers;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX12_ShutdownPlatformInterface()
|
||||
void ImGui_ImplDX12_ShutdownMultiViewportSupport()
|
||||
{
|
||||
ImGui::DestroyPlatformWindows();
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: DirectX9: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||
// 2024-10-07: DirectX9: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-02-12: DirectX9: Using RGBA format when supported by the driver to avoid CPU side conversion. (#6575)
|
||||
@@ -236,9 +237,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
// FIXME-OPT: This is a minor waste of resource, the ideal is to use imconfig.h and
|
||||
// 1) to avoid repacking colors: #define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
// 2) to avoid repacking vertices: #define IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { ImVec2 pos; float z; ImU32 col; ImVec2 uv; }
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_src = draw_list->VtxBuffer.Data;
|
||||
for (int i = 0; i < draw_list->VtxBuffer.Size; i++)
|
||||
{
|
||||
@@ -268,9 +268,8 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -369,13 +368,16 @@ void ImGui_ImplDX9_Shutdown()
|
||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -446,14 +448,14 @@ void ImGui_ImplDX9_UpdateTexture(ImTextureData* tex)
|
||||
}
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
{
|
||||
LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)tex->TexID;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(tex->TexID == (ImTextureID)(intptr_t)backend_tex);
|
||||
backend_tex->Release();
|
||||
if (LPDIRECT3DTEXTURE9 backend_tex = (LPDIRECT3DTEXTURE9)tex->TexID)
|
||||
{
|
||||
IM_ASSERT(tex->TexID == (ImTextureID)(intptr_t)backend_tex);
|
||||
backend_tex->Release();
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Multiple Dear ImGui contexts support.
|
||||
// Missing features or Issues:
|
||||
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Platform: Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -32,6 +32,9 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. FramebufferScale are always reported as 1.0 on X11. (#8920, #8921)
|
||||
// 2025-09-10: [Docking] Improve multi-viewport behavior in tiling WMs on X11 via the ImGui_ImplGlfw_SetWindowFloating() function. Note: using GLFW backend on Linux/BSD etc. requires linking with -lX11. (#8884, #8474, #8289)
|
||||
// 2025-07-08: Made ImGui_ImplGlfw_GetContentScaleForWindow(), ImGui_ImplGlfw_GetContentScaleForMonitor() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
|
||||
// 2025-06-18: Added support for multiple Dear ImGui contexts. (#8676, #8239, #8069)
|
||||
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
|
||||
@@ -113,21 +116,35 @@
|
||||
#endif
|
||||
|
||||
// GLFW
|
||||
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
|
||||
#define GLFW_HAS_X11_OR_WAYLAND 1
|
||||
#else
|
||||
#define GLFW_HAS_X11_OR_WAYLAND 0
|
||||
#endif
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef APIENTRY
|
||||
#ifndef GLFW_EXPOSE_NATIVE_WIN32
|
||||
#ifndef GLFW_EXPOSE_NATIVE_WIN32 // for glfwGetWin32Window()
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h> // for glfwGetWin32Window()
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
#ifndef GLFW_EXPOSE_NATIVE_COCOA
|
||||
#include <GLFW/glfw3native.h>
|
||||
#elif defined(__APPLE__)
|
||||
#ifndef GLFW_EXPOSE_NATIVE_COCOA // for glfwGetCocoaWindow()
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h> // for glfwGetCocoaWindow()
|
||||
#include <GLFW/glfw3native.h>
|
||||
#elif GLFW_HAS_X11_OR_WAYLAND
|
||||
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <X11/Xatom.h>
|
||||
#endif
|
||||
#ifndef GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
#define GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h>
|
||||
#undef Status // X11 headers are leaking this.
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h> // for usleep()
|
||||
#endif
|
||||
@@ -173,7 +190,7 @@
|
||||
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
||||
#define GLFW_HAS_GETPLATFORM (GLFW_VERSION_COMBINED >= 3400) // 3.4+ glfwGetPlatform()
|
||||
|
||||
// Map GLFWWindow* to ImGuiContext*.
|
||||
// Map GLFWWindow* to ImGuiContext*.
|
||||
// - Would be simpler if we could use glfwSetWindowUserPointer()/glfwGetWindowUserPointer(), but this is a single and shared resource.
|
||||
// - Would be simpler if we could use e.g. std::map<> as well. But we don't.
|
||||
// - This is not particularly optimized as we expect size to be small and queries to be rare.
|
||||
@@ -183,14 +200,14 @@ static void ImGui_ImplGlfw_ContextMap_Add(GLFWwindow* window, ImGuiContext* ctx)
|
||||
static void ImGui_ImplGlfw_ContextMap_Remove(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) { g_ContextMap.erase_unsorted(&entry); return; } }
|
||||
static ImGuiContext* ImGui_ImplGlfw_ContextMap_Get(GLFWwindow* window) { for (ImGui_ImplGlfw_WindowToContext& entry : g_ContextMap) if (entry.Window == window) return entry.Context; return nullptr; }
|
||||
|
||||
// GLFW data
|
||||
enum GlfwClientApi
|
||||
{
|
||||
GlfwClientApi_Unknown,
|
||||
GlfwClientApi_OpenGL,
|
||||
GlfwClientApi_Vulkan,
|
||||
GlfwClientApi_Unknown, // Anything else fits here.
|
||||
};
|
||||
|
||||
// GLFW data
|
||||
struct ImGui_ImplGlfw_Data
|
||||
{
|
||||
ImGuiContext* Context;
|
||||
@@ -203,6 +220,7 @@ struct ImGui_ImplGlfw_Data
|
||||
bool MouseIgnoreButtonUp;
|
||||
ImVec2 LastValidMousePos;
|
||||
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
||||
bool IsWayland;
|
||||
bool InstalledCallbacks;
|
||||
bool CallbacksChainForAllWindows;
|
||||
char BackendPlatformName[32];
|
||||
@@ -252,6 +270,23 @@ static void ImGui_ImplGlfw_InitMultiViewportSupport();
|
||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||
|
||||
// Functions
|
||||
static bool ImGui_ImplGlfw_IsWayland()
|
||||
{
|
||||
#if !GLFW_HAS_X11_OR_WAYLAND
|
||||
return false;
|
||||
#elif GLFW_HAS_GETPLATFORM
|
||||
return glfwGetPlatform() == GLFW_PLATFORM_WAYLAND;
|
||||
#else
|
||||
const char* version = glfwGetVersionString();
|
||||
if (strstr(version, "Wayland") == NULL) // e.g. Ubuntu 22.04 ships with GLFW 3.3.6 compiled without Wayland
|
||||
return false;
|
||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
||||
if (glfwGetX11Display() != NULL)
|
||||
return false;
|
||||
#endif
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Not static to allow third-party code to use that if they want to (but undocumented)
|
||||
ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int keycode, int scancode);
|
||||
@@ -619,7 +654,7 @@ void ImGui_ImplGlfw_RestoreCallbacks(GLFWwindow* window)
|
||||
bd->PrevUserCallbackMonitor = nullptr;
|
||||
}
|
||||
|
||||
// Set to 'true' to enable chaining installed callbacks for all windows (including secondary viewports created by backends or by user.
|
||||
// Set to 'true' to enable chaining installed callbacks for all windows (including secondary viewports created by backends or by user).
|
||||
// This is 'false' by default meaning we only chain callbacks for the main viewport.
|
||||
// We cannot set this to 'true' by default because user callbacks code may be not testing the 'window' parameter of their callback.
|
||||
// If you set this to 'true' your user callback code will need to make sure you are testing the 'window' parameter.
|
||||
@@ -669,6 +704,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
||||
bd->Context = ImGui::GetCurrentContext();
|
||||
bd->Window = window;
|
||||
bd->Time = 0.0;
|
||||
bd->IsWayland = ImGui_ImplGlfw_IsWayland();
|
||||
ImGui_ImplGlfw_ContextMap_Add(window, bd->Context);
|
||||
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
@@ -781,10 +817,11 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
||||
|
||||
if (bd->InstalledCallbacks)
|
||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||
@@ -806,6 +843,7 @@ void ImGui_ImplGlfw_Shutdown()
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
platform_io.ClearPlatformHandlers();
|
||||
ImGui_ImplGlfw_ContextMap_Remove(bd->Window);
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
@@ -1004,6 +1042,11 @@ static void ImGui_ImplGlfw_UpdateMonitors()
|
||||
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
|
||||
float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
|
||||
{
|
||||
#if GLFW_HAS_X11_OR_WAYLAND
|
||||
if (ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window))
|
||||
if (bd->IsWayland)
|
||||
return 1.0f;
|
||||
#endif
|
||||
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
|
||||
float x_scale, y_scale;
|
||||
glfwGetWindowContentScale(window, &x_scale, &y_scale);
|
||||
@@ -1016,6 +1059,10 @@ float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
|
||||
|
||||
float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor)
|
||||
{
|
||||
#if GLFW_HAS_X11_OR_WAYLAND
|
||||
if (ImGui_ImplGlfw_IsWayland()) // We can't access our bd->IsWayland cache for a monitor.
|
||||
return 1.0f;
|
||||
#endif
|
||||
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
|
||||
float x_scale, y_scale;
|
||||
glfwGetMonitorContentScale(monitor, &x_scale, &y_scale);
|
||||
@@ -1032,10 +1079,17 @@ static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window,
|
||||
int display_w, display_h;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
glfwGetFramebufferSize(window, &display_w, &display_h);
|
||||
float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f;
|
||||
float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f;
|
||||
#if GLFW_HAS_X11_OR_WAYLAND
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
|
||||
if (!bd->IsWayland)
|
||||
fb_scale_x = fb_scale_y = 1.0f;
|
||||
#endif
|
||||
if (out_size != nullptr)
|
||||
*out_size = ImVec2((float)w, (float)h);
|
||||
if (out_framebuffer_scale != nullptr)
|
||||
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / (float)w, (float)display_h / (float)h) : ImVec2(1.0f, 1.0f);
|
||||
*out_framebuffer_scale = ImVec2(fb_scale_x, fb_scale_y);
|
||||
}
|
||||
|
||||
void ImGui_ImplGlfw_NewFrame()
|
||||
@@ -1190,6 +1244,30 @@ static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && GLFW_HAS_GETPLATFORM
|
||||
#define IMGUI_GLFW_HAS_SETWINDOWFLOATING
|
||||
static void ImGui_ImplGlfw_SetWindowFloating(GLFWwindow* window)
|
||||
{
|
||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
||||
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
|
||||
{
|
||||
Display* display = glfwGetX11Display();
|
||||
Window xwindow = glfwGetX11Window(window);
|
||||
Atom wm_type = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
||||
Atom wm_type_dialog = XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
||||
XChangeProperty(display, xwindow, wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wm_type_dialog, 1);
|
||||
XSetWindowAttributes attrs;
|
||||
attrs.override_redirect = False;
|
||||
XChangeWindowAttributes(display, xwindow, CWOverrideRedirect, &attrs);
|
||||
XFlush(display);
|
||||
}
|
||||
#endif // GLFW_EXPOSE_NATIVE_X11
|
||||
#ifdef GLFW_EXPOSE_NATIVE_WAYLAND
|
||||
// FIXME: Help needed, see #8884, #8474 for discussions about this.
|
||||
#endif // GLFW_EXPOSE_NATIVE_X11
|
||||
}
|
||||
#endif // IMGUI_GLFW_HAS_SETWINDOWFLOATING
|
||||
|
||||
static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
@@ -1207,7 +1285,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
glfwWindowHint(GLFW_FOCUSED, false);
|
||||
#if GLFW_HAS_FOCUS_ON_SHOW
|
||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, false);
|
||||
#endif
|
||||
#endif
|
||||
glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true);
|
||||
#if GLFW_HAS_WINDOW_TOPMOST
|
||||
glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false);
|
||||
@@ -1217,6 +1295,9 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
vd->WindowOwned = true;
|
||||
ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context);
|
||||
viewport->PlatformHandle = (void*)vd->Window;
|
||||
#ifdef IMGUI_GLFW_HAS_SETWINDOWFLOATING
|
||||
ImGui_ImplGlfw_SetWindowFloating(vd->Window);
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
|
||||
::SetPropA((HWND)viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", bd);
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// [X] Multiple Dear ImGui contexts support.
|
||||
// Missing features or Issues:
|
||||
// [ ] Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Touch events are only correctly identified as Touch on Windows. This create issues with some interactions. GLFW doesn't provide a way to identify touch inputs from mouse inputs, we cannot call io.AddMouseSourceEvent() to identify the source. We provide a Windows-specific workaround.
|
||||
// [ ] Platform: Missing ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress cursors.
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplMetal_CreateFontsTexture() and ImGui_ImplMetal_DestroyFontsTexture().
|
||||
// 2025-02-03: Metal: Crash fix. (#8367)
|
||||
// 2025-01-08: Metal: Fixed memory leaks when using metal-cpp (#8276, #8166) or when using multiple contexts (#7419).
|
||||
@@ -159,14 +160,17 @@ void ImGui_ImplMetal_Shutdown()
|
||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
||||
IM_UNUSED(bd);
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||
ImGui_ImplMetal_DestroyBackendData();
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_NewFrame(MTLRenderPassDescriptor* renderPassDescriptor)
|
||||
@@ -235,7 +239,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||
@@ -271,10 +275,8 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
// Render command lists
|
||||
size_t vertexBufferOffset = 0;
|
||||
size_t indexBufferOffset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
memcpy((char*)vertexBuffer.buffer.contents + vertexBufferOffset, draw_list->VtxBuffer.Data, (size_t)draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy((char*)indexBuffer.buffer.contents + indexBufferOffset, draw_list->IdxBuffer.Data, (size_t)draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
|
||||
@@ -348,16 +350,16 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
|
||||
static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
MetalTexture* backend_tex = (__bridge_transfer MetalTexture*)(tex->BackendUserData);
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(backend_tex.metalTexture == (__bridge id<MTLTexture>)(void*)(intptr_t)tex->TexID);
|
||||
backend_tex.metalTexture = nil;
|
||||
if (MetalTexture* backend_tex = (__bridge_transfer MetalTexture*)(tex->BackendUserData))
|
||||
{
|
||||
IM_ASSERT(backend_tex.metalTexture == (__bridge id<MTLTexture>)(void*)(intptr_t)tex->TexID);
|
||||
backend_tex.metalTexture = nil;
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplMetal_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures. (#8802)
|
||||
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL2_CreateFontsTexture() and ImGui_ImplOpenGL2_DestroyFontsTexture().
|
||||
// 2024-10-07: OpenGL: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||
// 2024-06-28: OpenGL: ImGui_ImplOpenGL2_NewFrame() recreates font texture if it has been destroyed by ImGui_ImplOpenGL2_DestroyFontsTexture(). (#7748)
|
||||
@@ -123,12 +125,15 @@ void ImGui_ImplOpenGL2_Shutdown()
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -218,9 +223,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (const GLvoid*)((const char*)vtx_buffer + offsetof(ImDrawVert, pos)));
|
||||
@@ -296,6 +300,7 @@ void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store identifiers
|
||||
@@ -315,6 +320,7 @@ void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
||||
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
for (ImTextureRect& r : tex->Updates)
|
||||
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-07-22: OpenGL: Add and call embedded loader shutdown during ImGui_ImplOpenGL3_Shutdown() to facilitate multiple init/shutdown cycles in same process. (#8792)
|
||||
// 2025-07-15: OpenGL: Set GL_UNPACK_ALIGNMENT to 1 before updating textures (#8802) + restore non-WebGL/ES update path that doesn't require a CPU-side copy.
|
||||
// 2025-06-11: OpenGL: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplOpenGL3_CreateFontsTexture() and ImGui_ImplOpenGL3_DestroyFontsTexture().
|
||||
// 2025-06-04: OpenGL: Made GLES 3.20 contexts not access GL_CONTEXT_PROFILE_MASK nor GL_PRIMITIVE_RESTART. (#8664)
|
||||
// 2025-02-18: OpenGL: Lazily reinitialize embedded GL loader for when calling backend from e.g. other DLL boundaries. (#8406)
|
||||
@@ -246,6 +249,7 @@ struct ImGui_ImplOpenGL3_Data
|
||||
GLsizeiptr VertexBufferSize;
|
||||
GLsizeiptr IndexBufferSize;
|
||||
bool HasPolygonMode;
|
||||
bool HasBindSampler;
|
||||
bool HasClipOrigin;
|
||||
bool UseBufferSubData;
|
||||
ImVector<char> TempBuffer;
|
||||
@@ -401,6 +405,9 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
// Detect extensions we support
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_POLYGON_MODE
|
||||
bd->HasPolygonMode = (!bd->GlProfileIsES2 && !bd->GlProfileIsES3);
|
||||
#endif
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
bd->HasBindSampler = (bd->GlVersion >= 330 || bd->GlProfileIsES3);
|
||||
#endif
|
||||
bd->HasClipOrigin = (bd->GlVersion >= 450);
|
||||
#ifdef IMGUI_IMPL_OPENGL_HAS_EXTENSIONS
|
||||
@@ -424,13 +431,20 @@ void ImGui_ImplOpenGL3_Shutdown()
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||
imgl3wShutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ImGui_ImplOpenGL3_NewFrame()
|
||||
@@ -499,7 +513,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
|
||||
if (bd->HasBindSampler)
|
||||
glBindSampler(0, 0); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
|
||||
#endif
|
||||
|
||||
@@ -547,7 +561,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
GLuint last_program; glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)&last_program);
|
||||
GLuint last_texture; glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint*)&last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
GLuint last_sampler; if (bd->GlVersion >= 330 || bd->GlProfileIsES3) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
||||
GLuint last_sampler; if (bd->HasBindSampler) { glGetIntegerv(GL_SAMPLER_BINDING, (GLint*)&last_sampler); } else { last_sampler = 0; }
|
||||
#endif
|
||||
GLuint last_array_buffer; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, (GLint*)&last_array_buffer);
|
||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||
@@ -594,10 +608,8 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
|
||||
// Upload vertex/index buffers
|
||||
// - OpenGL drivers are in a very sorry state nowadays....
|
||||
// During 2021 we attempted to switch from glBufferData() to orphaning+glBufferSubData() following reports
|
||||
@@ -674,7 +686,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
if (last_program == 0 || glIsProgram(last_program)) glUseProgram(last_program);
|
||||
glBindTexture(GL_TEXTURE_2D, last_texture);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (bd->GlVersion >= 330 || bd->GlProfileIsES3)
|
||||
if (bd->HasBindSampler)
|
||||
glBindSampler(0, last_sampler);
|
||||
#endif
|
||||
glActiveTexture(last_active_texture);
|
||||
@@ -721,6 +733,17 @@ static void ImGui_ImplOpenGL3_DestroyTexture(ImTextureData* tex)
|
||||
|
||||
void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
{
|
||||
// FIXME: Consider backing up and restoring
|
||||
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
#ifdef GL_UNPACK_ALIGNMENT
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||
#endif
|
||||
}
|
||||
|
||||
if (tex->Status == ImTextureStatus_WantCreate)
|
||||
{
|
||||
// Create and upload new texture to graphics system
|
||||
@@ -740,9 +763,6 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||
#ifdef GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
|
||||
#endif
|
||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->Width, tex->Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels));
|
||||
|
||||
// Store identifiers
|
||||
@@ -761,7 +781,7 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
GLuint gl_tex_id = (GLuint)(intptr_t)tex->TexID;
|
||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, gl_tex_id));
|
||||
#if 0// GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
#if GL_UNPACK_ROW_LENGTH // Not on WebGL/ES
|
||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, tex->Width));
|
||||
for (ImTextureRect& r : tex->Updates)
|
||||
GL_CALL(glTexSubImage2D(GL_TEXTURE_2D, 0, r.x, r.y, r.w, r.h, GL_RGBA, GL_UNSIGNED_BYTE, tex->GetPixelsAt(r.x, r.y)));
|
||||
|
||||
@@ -166,6 +166,7 @@ typedef khronos_uint8_t GLubyte;
|
||||
#define GL_SCISSOR_BOX 0x0C10
|
||||
#define GL_SCISSOR_TEST 0x0C11
|
||||
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||
#define GL_PACK_ALIGNMENT 0x0D05
|
||||
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||
#define GL_TEXTURE_2D 0x0DE1
|
||||
@@ -179,6 +180,7 @@ typedef khronos_uint8_t GLubyte;
|
||||
#define GL_RENDERER 0x1F01
|
||||
#define GL_VERSION 0x1F02
|
||||
#define GL_EXTENSIONS 0x1F03
|
||||
#define GL_NEAREST 0x2600
|
||||
#define GL_LINEAR 0x2601
|
||||
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||
@@ -399,9 +401,15 @@ GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum
|
||||
#ifndef GL_VERSION_3_3
|
||||
#define GL_VERSION_3_3 1
|
||||
#define GL_SAMPLER_BINDING 0x8919
|
||||
typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
|
||||
typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
|
||||
typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
|
||||
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
|
||||
#ifdef GL_GLEXT_PROTOTYPES
|
||||
GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
|
||||
GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
|
||||
GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
|
||||
GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
|
||||
#endif
|
||||
#endif /* GL_VERSION_3_3 */
|
||||
#ifndef GL_VERSION_4_1
|
||||
@@ -476,12 +484,13 @@ typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
|
||||
/* gl3w api */
|
||||
GL3W_API int imgl3wInit(void);
|
||||
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
||||
GL3W_API void imgl3wShutdown(void);
|
||||
GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||
|
||||
/* gl3w internal state */
|
||||
union ImGL3WProcs {
|
||||
GL3WglProc ptr[60];
|
||||
GL3WglProc ptr[63];
|
||||
struct {
|
||||
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||
PFNGLATTACHSHADERPROC AttachShader;
|
||||
@@ -501,6 +510,7 @@ union ImGL3WProcs {
|
||||
PFNGLCREATESHADERPROC CreateShader;
|
||||
PFNGLDELETEBUFFERSPROC DeleteBuffers;
|
||||
PFNGLDELETEPROGRAMPROC DeleteProgram;
|
||||
PFNGLDELETESAMPLERSPROC DeleteSamplers;
|
||||
PFNGLDELETESHADERPROC DeleteShader;
|
||||
PFNGLDELETETEXTURESPROC DeleteTextures;
|
||||
PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays;
|
||||
@@ -513,6 +523,7 @@ union ImGL3WProcs {
|
||||
PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
|
||||
PFNGLFLUSHPROC Flush;
|
||||
PFNGLGENBUFFERSPROC GenBuffers;
|
||||
PFNGLGENSAMPLERSPROC GenSamplers;
|
||||
PFNGLGENTEXTURESPROC GenTextures;
|
||||
PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
|
||||
PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
|
||||
@@ -533,6 +544,7 @@ union ImGL3WProcs {
|
||||
PFNGLPIXELSTOREIPROC PixelStorei;
|
||||
PFNGLPOLYGONMODEPROC PolygonMode;
|
||||
PFNGLREADPIXELSPROC ReadPixels;
|
||||
PFNGLSAMPLERPARAMETERIPROC SamplerParameteri;
|
||||
PFNGLSCISSORPROC Scissor;
|
||||
PFNGLSHADERSOURCEPROC ShaderSource;
|
||||
PFNGLTEXIMAGE2DPROC TexImage2D;
|
||||
@@ -567,6 +579,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
||||
#define glCreateShader imgl3wProcs.gl.CreateShader
|
||||
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
|
||||
#define glDeleteProgram imgl3wProcs.gl.DeleteProgram
|
||||
#define glDeleteSamplers imgl3wProcs.gl.DeleteSamplers
|
||||
#define glDeleteShader imgl3wProcs.gl.DeleteShader
|
||||
#define glDeleteTextures imgl3wProcs.gl.DeleteTextures
|
||||
#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays
|
||||
@@ -579,6 +592,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
||||
#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray
|
||||
#define glFlush imgl3wProcs.gl.Flush
|
||||
#define glGenBuffers imgl3wProcs.gl.GenBuffers
|
||||
#define glGenSamplers imgl3wProcs.gl.GenSamplers
|
||||
#define glGenTextures imgl3wProcs.gl.GenTextures
|
||||
#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays
|
||||
#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation
|
||||
@@ -599,6 +613,7 @@ GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
||||
#define glPixelStorei imgl3wProcs.gl.PixelStorei
|
||||
#define glPolygonMode imgl3wProcs.gl.PolygonMode
|
||||
#define glReadPixels imgl3wProcs.gl.ReadPixels
|
||||
#define glSamplerParameteri imgl3wProcs.gl.SamplerParameteri
|
||||
#define glScissor imgl3wProcs.gl.Scissor
|
||||
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
||||
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
||||
@@ -631,7 +646,7 @@ extern "C" {
|
||||
#endif
|
||||
#include <windows.h>
|
||||
|
||||
static HMODULE libgl;
|
||||
static HMODULE libgl = NULL;
|
||||
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
||||
static GL3WglGetProcAddr wgl_get_proc_address;
|
||||
|
||||
@@ -644,7 +659,7 @@ static int open_libgl(void)
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { FreeLibrary(libgl); }
|
||||
static void close_libgl(void) { FreeLibrary(libgl); libgl = NULL; }
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
GL3WglProc res;
|
||||
@@ -656,7 +671,7 @@ static GL3WglProc get_proc(const char *proc)
|
||||
#elif defined(__APPLE__)
|
||||
#include <dlfcn.h>
|
||||
|
||||
static void *libgl;
|
||||
static void *libgl = NULL;
|
||||
static int open_libgl(void)
|
||||
{
|
||||
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
||||
@@ -665,7 +680,7 @@ static int open_libgl(void)
|
||||
return GL3W_OK;
|
||||
}
|
||||
|
||||
static void close_libgl(void) { dlclose(libgl); }
|
||||
static void close_libgl(void) { dlclose(libgl); libgl = NULL; }
|
||||
|
||||
static GL3WglProc get_proc(const char *proc)
|
||||
{
|
||||
@@ -699,7 +714,11 @@ static void close_libgl(void)
|
||||
|
||||
static int is_library_loaded(const char* name, void** lib)
|
||||
{
|
||||
#if defined(__HAIKU__)
|
||||
*lib = NULL; // no support for RTLD_NOLOAD on Haiku.
|
||||
#else
|
||||
*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
||||
#endif
|
||||
return *lib != NULL;
|
||||
}
|
||||
|
||||
@@ -833,6 +852,11 @@ int imgl3wInit2(GL3WGetProcAddressProc proc)
|
||||
return parse_version();
|
||||
}
|
||||
|
||||
void imgl3wShutdown(void)
|
||||
{
|
||||
close_libgl();
|
||||
}
|
||||
|
||||
int imgl3wIsSupported(int major, int minor)
|
||||
{
|
||||
if (major < 2)
|
||||
@@ -863,6 +887,7 @@ static const char *proc_names[] = {
|
||||
"glCreateShader",
|
||||
"glDeleteBuffers",
|
||||
"glDeleteProgram",
|
||||
"glDeleteSamplers",
|
||||
"glDeleteShader",
|
||||
"glDeleteTextures",
|
||||
"glDeleteVertexArrays",
|
||||
@@ -875,6 +900,7 @@ static const char *proc_names[] = {
|
||||
"glEnableVertexAttribArray",
|
||||
"glFlush",
|
||||
"glGenBuffers",
|
||||
"glGenSamplers",
|
||||
"glGenTextures",
|
||||
"glGenVertexArrays",
|
||||
"glGetAttribLocation",
|
||||
@@ -895,6 +921,7 @@ static const char *proc_names[] = {
|
||||
"glPixelStorei",
|
||||
"glPolygonMode",
|
||||
"glReadPixels",
|
||||
"glSamplerParameteri",
|
||||
"glScissor",
|
||||
"glShaderSource",
|
||||
"glTexImage2D",
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// Missing features or Issues:
|
||||
// [ ] Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// [X] Platform: IME support.
|
||||
// [x] Platform: Multi-viewport / platform windows.
|
||||
// Missing features or Issues:
|
||||
// [ ] Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: Window size not correctly reported when enabling io.ConfigViewportsNoDecoration
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -34,6 +34,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-07-08: [Docking] Fixed multi-viewport handling broken on 2025-06-02. (#8644, #8777)
|
||||
// 2025-06-27: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||
// 2025-06-12: ImGui_ImplOSX_HandleEvent() only process event for window containing our view. (#8644)
|
||||
@@ -550,9 +551,12 @@ void ImGui_ImplOSX_Shutdown()
|
||||
ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplOSX_DestroyBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports);
|
||||
platform_io.ClearPlatformHandlers();
|
||||
}
|
||||
|
||||
static void ImGui_ImplOSX_UpdateMouseCursor()
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
@@ -26,6 +26,9 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-24: Skip using the SDL_GetGlobalMouseState() state when one of our window is hovered, as the SDL_MOUSEMOTION data is reliable. Fix macOS notch mouse coordinates issue in fullscreen mode + better perf on X11. (#7919, #7786)
|
||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. (#8921)
|
||||
// 2025-07-08: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return 1.0f on Emscripten and Android platforms, matching macOS logic. (#8742, #8733)
|
||||
// 2025-06-11: Added ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window) and ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index) helper to facilitate making DPI-aware apps.
|
||||
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
||||
@@ -701,9 +704,9 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplSDL2_ShutdownMultiViewportSupport();
|
||||
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
@@ -713,6 +716,7 @@ void ImGui_ImplSDL2_Shutdown()
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
platform_io.ClearPlatformHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -755,13 +759,16 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||
// (Optional) Fallback to provide unclamped mouse position when focused but not hovered (SDL_MOUSEMOTION already provides this when hovered or captured)
|
||||
// Note that SDL_GetGlobalMouseState() is in theory slow on X11, but this only runs on rather specific cases. If a problem we may provide a way to opt-out this feature.
|
||||
SDL_Window* hovered_window = SDL_GetMouseFocus();
|
||||
const bool is_relative_mouse_mode = SDL_GetRelativeMouseMode() != 0;
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
if (hovered_window == NULL && bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
int mouse_x, mouse_y, window_x, window_y;
|
||||
int mouse_x, mouse_y;
|
||||
int window_x, window_y;
|
||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
@@ -825,6 +832,9 @@ float ImGui_ImplSDL2_GetContentScaleForWindow(SDL_Window* window)
|
||||
|
||||
float ImGui_ImplSDL2_GetContentScaleForDisplay(int display_index)
|
||||
{
|
||||
const char* sdl_driver = SDL_GetCurrentVideoDriver();
|
||||
if (sdl_driver && strcmp(sdl_driver, "wayland") == 0)
|
||||
return 1.0f;
|
||||
#if SDL_HAS_PER_MONITOR_DPI
|
||||
#if !defined(__APPLE__) && !defined(__EMSCRIPTEN__) && !defined(__ANDROID__)
|
||||
float dpi = 0.0f;
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// Missing features or Issues:
|
||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||
// [ ] Platform: Multi-viewport: ParentViewportID not honored, and so io.ConfigViewportsNoDefaultParent has no effect (minor).
|
||||
// [ ] Platform: Multi-viewport: Missing ImGuiBackendFlags_HasParentViewport support. The viewport->ParentViewportID field is ignored, and therefore io.ConfigViewportsNoDefaultParent has no effect either.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-24: Skip using the SDL_GetGlobalMouseState() state when one of our window is hovered, as the SDL_EVENT_MOUSE_MOTION data is reliable. Fix macOS notch mouse coordinates issue in fullscreen mode + better perf on X11. (#7919, #7786)
|
||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-09-15: Use SDL_GetWindowDisplayScale() on Mac to output DisplayFrameBufferScale. The function is more reliable during resolution changes e.g. going fullscreen. (#8703, #4414)
|
||||
// 2025-06-27: IME: avoid calling SDL_StartTextInput() again if already active. (#8727)
|
||||
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
||||
// 2025-05-06: [Docking] macOS: fixed secondary viewports not appearing on other monitors before of parenting.
|
||||
@@ -531,7 +534,8 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
io.BackendPlatformName = bd->BackendPlatformName;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
// (ImGuiBackendFlags_PlatformHasViewports may be set just below)
|
||||
// (ImGuiBackendFlags_PlatformHasViewports and ImGuiBackendFlags_HasParentViewport may be set just below)
|
||||
// (ImGuiBackendFlags_HasMouseHoveredViewport is set dynamically in our _NewFrame function)
|
||||
|
||||
bd->Window = window;
|
||||
bd->WindowID = SDL_GetWindowID(window);
|
||||
@@ -557,7 +561,10 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
||||
bd->MouseCanUseGlobalState = bd->MouseCanUseCapture = true;
|
||||
#endif
|
||||
if (bd->MouseCanUseGlobalState)
|
||||
{
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasParentViewport; // We can honor viewport->ParentViewportId by applying the corresponding parent/child relationship at platform level (optional)
|
||||
}
|
||||
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||
@@ -661,9 +668,9 @@ void ImGui_ImplSDL3_Shutdown()
|
||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplSDL3_ShutdownMultiViewportSupport();
|
||||
|
||||
if (bd->ClipboardTextData)
|
||||
SDL_free(bd->ClipboardTextData);
|
||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||
@@ -672,7 +679,8 @@ void ImGui_ImplSDL3_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewport);
|
||||
platform_io.ClearPlatformHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -714,9 +722,11 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||
}
|
||||
|
||||
// (Optional) Fallback to provide mouse position when focused (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
||||
// (Optional) Fallback to provide unclamped mouse position when focused but not hovered (SDL_EVENT_MOUSE_MOTION already provides this when hovered or captured)
|
||||
// Note that SDL_GetGlobalMouseState() is in theory slow on X11, but this only runs on rather specific cases. If a problem we may provide a way to opt-out this feature.
|
||||
SDL_Window* hovered_window = SDL_GetMouseFocus();
|
||||
const bool is_relative_mouse_mode = SDL_GetWindowRelativeMouseMode(bd->Window);
|
||||
if (bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
if (hovered_window == NULL && bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
||||
{
|
||||
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||
@@ -729,7 +739,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
||||
mouse_x -= window_x;
|
||||
mouse_y -= window_y;
|
||||
}
|
||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||
io.AddMousePosEvent(mouse_x, mouse_y);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -913,15 +923,24 @@ static void ImGui_ImplSDL3_UpdateMonitors()
|
||||
static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||
{
|
||||
int w, h;
|
||||
int display_w, display_h;
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
w = h = 0;
|
||||
|
||||
#if defined(__APPLE__)
|
||||
float fb_scale_x = SDL_GetWindowDisplayScale(window); // Seems more reliable during resolution change (#8703)
|
||||
float fb_scale_y = fb_scale_x;
|
||||
#else
|
||||
int display_w, display_h;
|
||||
SDL_GetWindowSizeInPixels(window, &display_w, &display_h);
|
||||
float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f;
|
||||
float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f;
|
||||
#endif
|
||||
|
||||
if (out_size != nullptr)
|
||||
*out_size = ImVec2((float)w, (float)h);
|
||||
if (out_framebuffer_scale != nullptr)
|
||||
*out_framebuffer_scale = (w > 0 && h > 0) ? ImVec2((float)display_w / w, (float)display_h / h) : ImVec2(1.0f, 1.0f);
|
||||
*out_framebuffer_scale = ImVec2(fb_scale_x, fb_scale_y);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDL3_NewFrame()
|
||||
@@ -989,14 +1008,13 @@ struct ImGui_ImplSDL3_ViewportData
|
||||
~ImGui_ImplSDL3_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
||||
};
|
||||
|
||||
static SDL_Window* ImGui_ImplSDL3_GetSDLWindowFromViewportID(ImGuiID viewport_id)
|
||||
static SDL_Window* ImGui_ImplSDL3_GetSDLWindowFromViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
if (viewport_id != 0)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
|
||||
{
|
||||
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
||||
return SDL_GetWindowFromID(window_id);
|
||||
}
|
||||
if (viewport != nullptr)
|
||||
{
|
||||
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
||||
return SDL_GetWindowFromID(window_id);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1006,7 +1024,7 @@ static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
|
||||
ImGui_ImplSDL3_ViewportData* vd = IM_NEW(ImGui_ImplSDL3_ViewportData)();
|
||||
viewport->PlatformUserData = vd;
|
||||
|
||||
vd->ParentWindow = ImGui_ImplSDL3_GetSDLWindowFromViewportID(viewport->ParentViewportId);
|
||||
vd->ParentWindow = ImGui_ImplSDL3_GetSDLWindowFromViewport(viewport->ParentViewport);
|
||||
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
ImGui_ImplSDL3_ViewportData* main_viewport_data = (ImGui_ImplSDL3_ViewportData*)main_viewport->PlatformUserData;
|
||||
@@ -1095,7 +1113,7 @@ static void ImGui_ImplSDL3_UpdateWindow(ImGuiViewport* viewport)
|
||||
#ifndef __APPLE__ // On Mac, SDL3 Parenting appears to prevent viewport from appearing in another monitor
|
||||
// Update SDL3 parent if it changed _after_ creation.
|
||||
// This is for advanced apps that are manipulating ParentViewportID manually.
|
||||
SDL_Window* new_parent = ImGui_ImplSDL3_GetSDLWindowFromViewportID(viewport->ParentViewportId);
|
||||
SDL_Window* new_parent = ImGui_ImplSDL3_GetSDLWindowFromViewport(viewport->ParentViewport);
|
||||
if (new_parent != vd->ParentWindow)
|
||||
{
|
||||
vd->ParentWindow = new_parent;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
@@ -24,6 +24,10 @@
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-08-20: Added ImGui_ImplSDLGPU3_InitInfo::SwapchainComposition and ImGui_ImplSDLGPU3_InitInfo::PresentMode to configure how secondary viewports are created.
|
||||
// 2025-08-08: *BREAKING* Changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*, which is more natural and easier for user to manage. If you need to change the current sampler, you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
|
||||
// 2025-08-08: Expose SamplerDefault and SamplerCurrent in ImGui_ImplSDLGPU3_RenderState. Allow callback to change sampler.
|
||||
// 2025-06-25: Mapping transfer buffer for texture update use cycle=true. Fixes artifacts e.g. on Metal backend.
|
||||
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLGPU3_CreateFontsTexture() and ImGui_ImplSDLGPU3_DestroyFontsTexture().
|
||||
// 2025-04-28: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
@@ -38,11 +42,6 @@
|
||||
#include "imgui_impl_sdlgpu3_shaders.h"
|
||||
|
||||
// SDL_GPU Data
|
||||
struct ImGui_ImplSDLGPU3_Texture
|
||||
{
|
||||
SDL_GPUTexture* Texture = nullptr;
|
||||
SDL_GPUTextureSamplerBinding TextureSamplerBinding = { nullptr, nullptr };
|
||||
};
|
||||
|
||||
// Reusable buffers used for rendering 1 current in-flight frame, for ImGui_ImplSDLGPU3_RenderDrawData()
|
||||
struct ImGui_ImplSDLGPU3_FrameData
|
||||
@@ -63,7 +62,7 @@ struct ImGui_ImplSDLGPU3_Data
|
||||
SDL_GPUShader* VertexShader = nullptr;
|
||||
SDL_GPUShader* FragmentShader = nullptr;
|
||||
SDL_GPUGraphicsPipeline* Pipeline = nullptr;
|
||||
SDL_GPUSampler* TexSampler = nullptr;
|
||||
SDL_GPUSampler* TexSamplerLinear = nullptr;
|
||||
SDL_GPUTransferBuffer* TexTransferBuffer = nullptr;
|
||||
uint32_t TexTransferBufferSize = 0;
|
||||
|
||||
@@ -86,12 +85,13 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass * render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, ImGui_ImplSDLGPU3_RenderState* render_state, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||
{
|
||||
//ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
render_state->SamplerCurrent = bd->TexSamplerLinear;
|
||||
|
||||
// Bind graphics pipeline
|
||||
SDL_BindGPUGraphicsPipeline(render_pass,pipeline);
|
||||
SDL_BindGPUGraphicsPipeline(render_pass, pipeline);
|
||||
|
||||
// Bind Vertex And Index Buffers
|
||||
if (draw_data->TotalVtxCount > 0)
|
||||
@@ -182,9 +182,8 @@ void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuff
|
||||
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)SDL_MapGPUTransferBuffer(v->Device, fd->VertexTransferBuffer, true);
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)SDL_MapGPUTransferBuffer(v->Device, fd->IndexTransferBuffer, true);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -230,19 +229,25 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
if (pipeline == nullptr)
|
||||
pipeline = bd->Pipeline;
|
||||
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
|
||||
// Will project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplSDLGPU3_RenderState render_state;
|
||||
render_state.Device = bd->InitInfo.Device;
|
||||
render_state.SamplerDefault = render_state.SamplerCurrent = bd->TexSamplerLinear;
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -251,7 +256,7 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
ImGui_ImplSDLGPU3_SetupRenderState(draw_data, &render_state, pipeline, command_buffer, render_pass, fd, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
}
|
||||
@@ -278,9 +283,14 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
SDL_SetGPUScissor(render_pass,&scissor_rect);
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
SDL_BindGPUFragmentSamplers(render_pass, 0, (SDL_GPUTextureSamplerBinding*)pcmd->GetTexID(), 1);
|
||||
SDL_GPUTextureSamplerBinding texture_sampler_binding;
|
||||
texture_sampler_binding.texture = (SDL_GPUTexture*)(intptr_t)pcmd->GetTexID();
|
||||
texture_sampler_binding.sampler = render_state.SamplerCurrent;
|
||||
SDL_BindGPUFragmentSamplers(render_pass, 0, &texture_sampler_binding, 1);
|
||||
|
||||
// Draw
|
||||
// **IF YOU GET A CRASH HERE** In 1.92.2 on 2025/08/08 we have changed ImTextureID to store 'SDL_GPUTexture*' instead of storing 'SDL_GPUTextureSamplerBinding'.
|
||||
// Any code loading custom texture using this backend needs to be updated.
|
||||
SDL_DrawGPUIndexedPrimitives(render_pass, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
}
|
||||
}
|
||||
@@ -299,18 +309,12 @@ void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffe
|
||||
static void ImGui_ImplSDLGPU3_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
SDL_GPUTextureSamplerBinding* binding = (SDL_GPUTextureSamplerBinding*)(intptr_t)tex->BackendUserData;
|
||||
IM_ASSERT(backend_tex->Texture == binding->texture);
|
||||
SDL_ReleaseGPUTexture(bd->InitInfo.Device, backend_tex->Texture);
|
||||
IM_DELETE(backend_tex);
|
||||
if (SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID())
|
||||
SDL_ReleaseGPUTexture(bd->InitInfo.Device, raw_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||
@@ -324,7 +328,6 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||
ImGui_ImplSDLGPU3_Texture* backend_tex = IM_NEW(ImGui_ImplSDLGPU3_Texture)();
|
||||
|
||||
// Create texture
|
||||
SDL_GPUTextureCreateInfo texture_info = {};
|
||||
@@ -337,19 +340,16 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||
texture_info.num_levels = 1;
|
||||
texture_info.sample_count = SDL_GPU_SAMPLECOUNT_1;
|
||||
|
||||
backend_tex->Texture = SDL_CreateGPUTexture(v->Device, &texture_info);
|
||||
backend_tex->TextureSamplerBinding.texture = backend_tex->Texture;
|
||||
backend_tex->TextureSamplerBinding.sampler = bd->TexSampler;
|
||||
IM_ASSERT(backend_tex->Texture && "Failed to create font texture, call SDL_GetError() for more info");
|
||||
SDL_GPUTexture* raw_tex = SDL_CreateGPUTexture(v->Device, &texture_info);
|
||||
IM_ASSERT(raw_tex != nullptr && "Failed to create texture, call SDL_GetError() for more info");
|
||||
|
||||
// Store identifiers
|
||||
tex->SetTexID((ImTextureID)(intptr_t)&backend_tex->TextureSamplerBinding);
|
||||
tex->BackendUserData = backend_tex;
|
||||
tex->SetTexID((ImTextureID)(intptr_t)raw_tex);
|
||||
}
|
||||
|
||||
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Texture* backend_tex = (ImGui_ImplSDLGPU3_Texture*)tex->BackendUserData;
|
||||
SDL_GPUTexture* raw_tex = (SDL_GPUTexture*)(intptr_t)tex->GetTexID();
|
||||
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||
|
||||
// Update full texture or selected blocks. We only ever write to textures regions which have never been used before!
|
||||
@@ -371,7 +371,7 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||
transferbuffer_info.size = upload_size + 1024;
|
||||
bd->TexTransferBufferSize = upload_size + 1024;
|
||||
bd->TexTransferBuffer = SDL_CreateGPUTransferBuffer(v->Device, &transferbuffer_info);
|
||||
IM_ASSERT(bd->TexTransferBuffer != nullptr && "Failed to create font transfer buffer, call SDL_GetError() for more information");
|
||||
IM_ASSERT(bd->TexTransferBuffer != nullptr && "Failed to create transfer buffer, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
// Copy to transfer buffer
|
||||
@@ -387,7 +387,7 @@ void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex)
|
||||
transfer_info.transfer_buffer = bd->TexTransferBuffer;
|
||||
|
||||
SDL_GPUTextureRegion texture_region = {};
|
||||
texture_region.texture = backend_tex->Texture;
|
||||
texture_region.texture = raw_tex;
|
||||
texture_region.x = (Uint32)upload_x;
|
||||
texture_region.y = (Uint32)upload_y;
|
||||
texture_region.w = (Uint32)upload_w;
|
||||
@@ -560,7 +560,7 @@ void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
|
||||
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
|
||||
if (bd->TexSampler == nullptr)
|
||||
if (bd->TexSamplerLinear == nullptr)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
SDL_GPUSamplerCreateInfo sampler_info = {};
|
||||
@@ -577,8 +577,8 @@ void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
||||
sampler_info.max_anisotropy = 1.0f;
|
||||
sampler_info.enable_compare = false;
|
||||
|
||||
bd->TexSampler = SDL_CreateGPUSampler(v->Device, &sampler_info);
|
||||
IM_ASSERT(bd->TexSampler != nullptr && "Failed to create font sampler, call SDL_GetError() for more information");
|
||||
bd->TexSamplerLinear = SDL_CreateGPUSampler(v->Device, &sampler_info);
|
||||
IM_ASSERT(bd->TexSamplerLinear != nullptr && "Failed to create sampler, call SDL_GetError() for more information");
|
||||
}
|
||||
|
||||
ImGui_ImplSDLGPU3_CreateGraphicsPipeline();
|
||||
@@ -613,7 +613,7 @@ void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
||||
if (bd->TexTransferBuffer) { SDL_ReleaseGPUTransferBuffer(v->Device, bd->TexTransferBuffer); bd->TexTransferBuffer = nullptr; }
|
||||
if (bd->VertexShader) { SDL_ReleaseGPUShader(v->Device, bd->VertexShader); bd->VertexShader = nullptr; }
|
||||
if (bd->FragmentShader) { SDL_ReleaseGPUShader(v->Device, bd->FragmentShader); bd->FragmentShader = nullptr; }
|
||||
if (bd->TexSampler) { SDL_ReleaseGPUSampler(v->Device, bd->TexSampler); bd->TexSampler = nullptr; }
|
||||
if (bd->TexSamplerLinear) { SDL_ReleaseGPUSampler(v->Device, bd->TexSamplerLinear); bd->TexSamplerLinear = nullptr; }
|
||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr; }
|
||||
}
|
||||
|
||||
@@ -649,12 +649,15 @@ void ImGui_ImplSDLGPU3_Shutdown()
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
|
||||
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -663,7 +666,7 @@ void ImGui_ImplSDLGPU3_NewFrame()
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplSDLGPU3_Init()?");
|
||||
|
||||
if (!bd->TexSampler)
|
||||
if (!bd->TexSamplerLinear)
|
||||
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
@@ -678,6 +681,7 @@ static void ImGui_ImplSDLGPU3_CreateWindow(ImGuiViewport* viewport)
|
||||
ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
|
||||
SDL_ClaimWindowForGPUDevice(data->InitInfo.Device, window);
|
||||
SDL_SetGPUSwapchainParameters(data->InitInfo.Device, window, data->InitInfo.SwapchainComposition, data->InitInfo.PresentMode);
|
||||
viewport->RendererUserData = (void*)1;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// This needs to be used along with the SDL3 Platform Backend
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use simply cast a reference to your SDL_GPUTextureSamplerBinding to ImTextureID.
|
||||
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
@@ -28,12 +28,14 @@
|
||||
#include <SDL3/SDL_gpu.h>
|
||||
|
||||
// Initialization data, for ImGui_ImplSDLGPU_Init()
|
||||
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
|
||||
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat() to query the right value
|
||||
struct ImGui_ImplSDLGPU3_InitInfo
|
||||
{
|
||||
SDL_GPUDevice* Device = nullptr;
|
||||
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
SDL_GPUDevice* Device = nullptr;
|
||||
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
|
||||
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
SDL_GPUSwapchainComposition SwapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR; // Only used in multi-viewports mode.
|
||||
SDL_GPUPresentMode PresentMode = SDL_GPU_PRESENTMODE_VSYNC; // Only used in multi-viewports mode.
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
@@ -50,4 +52,14 @@ IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_UpdateTexture(ImTextureData* tex);
|
||||
|
||||
// [BETA] Selected render state data shared with callbacks.
|
||||
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLGPU3_RenderDrawData() call.
|
||||
// (Please open an issue if you feel you need access to more data)
|
||||
struct ImGui_ImplSDLGPU3_RenderState
|
||||
{
|
||||
SDL_GPUDevice* Device;
|
||||
SDL_GPUSampler* SamplerDefault; // Default sampler (bilinear filtering)
|
||||
SDL_GPUSampler* SamplerCurrent; // Current sampler (may be changed by callback)
|
||||
};
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLRenderer2_CreateFontsTexture() and ImGui_ImplSDLRenderer2_DestroyFontsTexture().
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
@@ -96,12 +97,14 @@ void ImGui_ImplSDLRenderer2_Shutdown()
|
||||
ImGui_ImplSDLRenderer2_Data* bd = ImGui_ImplSDLRenderer2_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplSDLRenderer2_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -171,9 +174,8 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
@@ -267,10 +269,8 @@ void ImGui_ImplSDLRenderer2_UpdateTexture(ImTextureData* tex)
|
||||
}
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
{
|
||||
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||
if (sdl_texture == nullptr)
|
||||
return;
|
||||
SDL_DestroyTexture(sdl_texture);
|
||||
if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID)
|
||||
SDL_DestroyTexture(sdl_texture);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
// CHANGELOG
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplSDLRenderer3_CreateFontsTexture() and ImGui_ImplSDLRenderer3_DestroyFontsTexture().
|
||||
// 2025-01-18: Use endian-dependent RGBA32 texture format, to match SDL_Color.
|
||||
// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||
@@ -94,12 +95,14 @@ void ImGui_ImplSDLRenderer3_Shutdown()
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplSDLRenderer3_DestroyDeviceObjects();
|
||||
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -191,9 +194,8 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
ImVec2 clip_scale = render_scale;
|
||||
|
||||
// Render command lists
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data;
|
||||
const ImDrawIdx* idx_buffer = draw_list->IdxBuffer.Data;
|
||||
|
||||
@@ -283,10 +285,8 @@ void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
||||
}
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
{
|
||||
SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID;
|
||||
if (sdl_texture == nullptr)
|
||||
return;
|
||||
SDL_DestroyTexture(sdl_texture);
|
||||
if (SDL_Texture* sdl_texture = (SDL_Texture*)(intptr_t)tex->TexID)
|
||||
SDL_DestroyTexture(sdl_texture);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
|
||||
@@ -29,6 +29,14 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-26: *BREAKING CHANGE*: moved some fields in ImGui_ImplVulkan_InitInfo: init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass, init_info.Subpass --> init_info.PipelineInfoMain.Subpass, init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples, init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo.
|
||||
// 2025-09-26: *BREAKING CHANGE*: renamed ImGui_ImplVulkan_MainPipelineCreateInfo to ImGui_ImplVulkan_PipelineInfo. Introduced very recently so shouldn't affect many users.
|
||||
// 2025-09-26: *BREAKING CHANGE*: helper ImGui_ImplVulkanH_CreateOrResizeWindow() added a VkImageUsageFlags image_usage` argument, default to VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT if 0.
|
||||
// 2025-09-26: Vulkan: Added a way to customize shaders by filling ImGui_ImplVulkan_InitInfo::CustomShaderVertCreateInfo/CustomShaderFragCreateInfo. (#8585)
|
||||
// 2025-09-22: [Docking] Added ImGui_ImplVulkanH_GetWindowDataFromViewport() accessor/helper. (#8946, #8940)
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-09-04: Vulkan: Added ImGui_ImplVulkan_CreateMainPipeline(). (#8110, #8111)
|
||||
// 2025-07-27: Vulkan: Fixed texture update corruption introduced on 2025-06-11. (#8801, #8755, #8840)
|
||||
// 2025-07-07: Vulkan: Fixed texture synchronization issue introduced on 2025-06-11. (#8772)
|
||||
// 2025-06-27: Vulkan: Fixed validation errors during texture upload/update by aligning upload size to 'nonCoherentAtomSize'. (#8743, #8744)
|
||||
// 2025-06-11: Vulkan: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. Removed ImGui_ImplVulkan_CreateFontsTexture() and ImGui_ImplVulkan_DestroyFontsTexture().
|
||||
@@ -117,11 +125,11 @@ void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulk
|
||||
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH_FrameSemaphores* fsd, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count, VkImageUsageFlags image_usage);
|
||||
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||
|
||||
// Vulkan prototypes for use with custom loaders
|
||||
// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h
|
||||
// (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h)
|
||||
#if defined(VK_NO_PROTOTYPES) && !defined(VOLK_H_)
|
||||
#define IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
static bool g_FunctionsLoaded = false;
|
||||
@@ -278,9 +286,10 @@ struct ImGui_ImplVulkan_Data
|
||||
VkShaderModule ShaderModuleVert;
|
||||
VkShaderModule ShaderModuleFrag;
|
||||
VkDescriptorPool DescriptorPool;
|
||||
ImVector<VkFormat> PipelineRenderingCreateInfoColorAttachmentFormats; // Deep copy of format array
|
||||
|
||||
// Texture management
|
||||
VkSampler TexSampler;
|
||||
VkSampler TexSamplerLinear;
|
||||
VkCommandPool TexCommandPool;
|
||||
VkCommandBuffer TexCommandBuffer;
|
||||
|
||||
@@ -579,9 +588,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
check_vk_result(err);
|
||||
err = vkMapMemory(v->Device, rb->IndexBufferMemory, 0, index_size, 0, (void**)&idx_dst);
|
||||
check_vk_result(err);
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -617,11 +625,11 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
VkDescriptorSet last_desc_set = VK_NULL_HANDLE;
|
||||
int global_vtx_offset = 0;
|
||||
int global_idx_offset = 0;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -633,6 +641,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height);
|
||||
else
|
||||
pcmd->UserCallback(draw_list, pcmd);
|
||||
last_desc_set = VK_NULL_HANDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -658,7 +667,9 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
|
||||
// Bind DescriptorSet with font or user texture
|
||||
VkDescriptorSet desc_set = (VkDescriptorSet)pcmd->GetTexID();
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr);
|
||||
if (desc_set != last_desc_set)
|
||||
vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, &desc_set, 0, nullptr);
|
||||
last_desc_set = desc_set;
|
||||
|
||||
// Draw
|
||||
vkCmdDrawIndexed(command_buffer, pcmd->ElemCount, 1, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset, 0);
|
||||
@@ -682,22 +693,22 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
||||
|
||||
static void ImGui_ImplVulkan_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplVulkan_Texture* backend_tex = (ImGui_ImplVulkan_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
IM_ASSERT(backend_tex->DescriptorSet == (VkDescriptorSet)tex->TexID);
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
ImGui_ImplVulkan_RemoveTexture(backend_tex->DescriptorSet);
|
||||
vkDestroyImageView(v->Device, backend_tex->ImageView, v->Allocator);
|
||||
vkDestroyImage(v->Device, backend_tex->Image, v->Allocator);
|
||||
vkFreeMemory(v->Device, backend_tex->Memory, v->Allocator);
|
||||
IM_DELETE(backend_tex);
|
||||
if (ImGui_ImplVulkan_Texture* backend_tex = (ImGui_ImplVulkan_Texture*)tex->BackendUserData)
|
||||
{
|
||||
IM_ASSERT(backend_tex->DescriptorSet == (VkDescriptorSet)tex->TexID);
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
ImGui_ImplVulkan_RemoveTexture(backend_tex->DescriptorSet);
|
||||
vkDestroyImageView(v->Device, backend_tex->ImageView, v->Allocator);
|
||||
vkDestroyImage(v->Device, backend_tex->Image, v->Allocator);
|
||||
vkFreeMemory(v->Device, backend_tex->Memory, v->Allocator);
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex)
|
||||
@@ -761,7 +772,7 @@ void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex)
|
||||
}
|
||||
|
||||
// Create the Descriptor Set
|
||||
backend_tex->DescriptorSet = ImGui_ImplVulkan_AddTexture(bd->TexSampler, backend_tex->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
backend_tex->DescriptorSet = ImGui_ImplVulkan_AddTexture(bd->TexSamplerLinear, backend_tex->ImageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
|
||||
|
||||
// Store identifiers
|
||||
tex->SetTexID((ImTextureID)backend_tex->DescriptorSet);
|
||||
@@ -849,7 +860,7 @@ void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex)
|
||||
VkImageMemoryBarrier copy_barrier[1] = {};
|
||||
copy_barrier[0].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
||||
copy_barrier[0].dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
|
||||
copy_barrier[0].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
copy_barrier[0].oldLayout = (tex->Status == ImTextureStatus_WantCreate) ? VK_IMAGE_LAYOUT_UNDEFINED : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
|
||||
copy_barrier[0].newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
|
||||
copy_barrier[0].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
copy_barrier[0].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
|
||||
@@ -910,29 +921,35 @@ void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex)
|
||||
|
||||
static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAllocationCallbacks* allocator)
|
||||
{
|
||||
// Create the shader modules
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (bd->ShaderModuleVert == VK_NULL_HANDLE)
|
||||
{
|
||||
VkShaderModuleCreateInfo vert_info = {};
|
||||
vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
vert_info.codeSize = sizeof(__glsl_shader_vert_spv);
|
||||
vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv;
|
||||
VkResult err = vkCreateShaderModule(device, &vert_info, allocator, &bd->ShaderModuleVert);
|
||||
VkShaderModuleCreateInfo default_vert_info = {};
|
||||
default_vert_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
default_vert_info.codeSize = sizeof(__glsl_shader_vert_spv);
|
||||
default_vert_info.pCode = (uint32_t*)__glsl_shader_vert_spv;
|
||||
VkShaderModuleCreateInfo* p_vert_info = (v->CustomShaderVertCreateInfo.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO) ? &v->CustomShaderVertCreateInfo : &default_vert_info;
|
||||
VkResult err = vkCreateShaderModule(device, p_vert_info, allocator, &bd->ShaderModuleVert);
|
||||
check_vk_result(err);
|
||||
}
|
||||
if (bd->ShaderModuleFrag == VK_NULL_HANDLE)
|
||||
{
|
||||
VkShaderModuleCreateInfo frag_info = {};
|
||||
frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
frag_info.codeSize = sizeof(__glsl_shader_frag_spv);
|
||||
frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv;
|
||||
VkResult err = vkCreateShaderModule(device, &frag_info, allocator, &bd->ShaderModuleFrag);
|
||||
VkShaderModuleCreateInfo default_frag_info = {};
|
||||
default_frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
|
||||
default_frag_info.codeSize = sizeof(__glsl_shader_frag_spv);
|
||||
default_frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv;
|
||||
VkShaderModuleCreateInfo* p_frag_info = (v->CustomShaderFragCreateInfo.sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO) ? &v->CustomShaderFragCreateInfo : &default_frag_info;
|
||||
VkResult err = vkCreateShaderModule(device, p_frag_info, allocator, &bd->ShaderModuleFrag);
|
||||
check_vk_result(err);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass)
|
||||
#if !defined(IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING) && !(defined(VK_VERSION_1_3) || defined(VK_KHR_dynamic_rendering))
|
||||
typedef void VkPipelineRenderingCreateInfoKHR;
|
||||
#endif
|
||||
|
||||
static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, const ImGui_ImplVulkan_PipelineInfo* info)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_CreateShaderModules(device, allocator);
|
||||
@@ -990,7 +1007,7 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
|
||||
|
||||
VkPipelineMultisampleStateCreateInfo ms_info = {};
|
||||
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||
ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT;
|
||||
ms_info.rasterizationSamples = (info->MSAASamples != 0) ? info->MSAASamples : VK_SAMPLE_COUNT_1_BIT;
|
||||
|
||||
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
|
||||
color_attachment[0].blendEnable = VK_TRUE;
|
||||
@@ -1016,35 +1033,36 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC
|
||||
dynamic_state.dynamicStateCount = (uint32_t)IM_ARRAYSIZE(dynamic_states);
|
||||
dynamic_state.pDynamicStates = dynamic_states;
|
||||
|
||||
VkGraphicsPipelineCreateInfo info = {};
|
||||
info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
info.flags = bd->PipelineCreateFlags;
|
||||
info.stageCount = 2;
|
||||
info.pStages = stage;
|
||||
info.pVertexInputState = &vertex_info;
|
||||
info.pInputAssemblyState = &ia_info;
|
||||
info.pViewportState = &viewport_info;
|
||||
info.pRasterizationState = &raster_info;
|
||||
info.pMultisampleState = &ms_info;
|
||||
info.pDepthStencilState = &depth_info;
|
||||
info.pColorBlendState = &blend_info;
|
||||
info.pDynamicState = &dynamic_state;
|
||||
info.layout = bd->PipelineLayout;
|
||||
info.renderPass = renderPass;
|
||||
info.subpass = subpass;
|
||||
VkGraphicsPipelineCreateInfo create_info = {};
|
||||
create_info.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
|
||||
create_info.flags = bd->PipelineCreateFlags;
|
||||
create_info.stageCount = 2;
|
||||
create_info.pStages = stage;
|
||||
create_info.pVertexInputState = &vertex_info;
|
||||
create_info.pInputAssemblyState = &ia_info;
|
||||
create_info.pViewportState = &viewport_info;
|
||||
create_info.pRasterizationState = &raster_info;
|
||||
create_info.pMultisampleState = &ms_info;
|
||||
create_info.pDepthStencilState = &depth_info;
|
||||
create_info.pColorBlendState = &blend_info;
|
||||
create_info.pDynamicState = &dynamic_state;
|
||||
create_info.layout = bd->PipelineLayout;
|
||||
create_info.renderPass = info->RenderPass;
|
||||
create_info.subpass = info->Subpass;
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
if (bd->VulkanInitInfo.UseDynamicRendering)
|
||||
{
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
|
||||
IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be nullptr");
|
||||
info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo;
|
||||
info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
|
||||
IM_ASSERT(info->PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo::sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR");
|
||||
IM_ASSERT(info->PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo::pNext must be nullptr");
|
||||
create_info.pNext = &info->PipelineRenderingCreateInfo;
|
||||
create_info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr.
|
||||
}
|
||||
#endif
|
||||
|
||||
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline);
|
||||
VkPipeline pipeline;
|
||||
VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &create_info, allocator, &pipeline);
|
||||
check_vk_result(err);
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
@@ -1053,7 +1071,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
VkResult err;
|
||||
|
||||
if (!bd->TexSampler)
|
||||
if (!bd->TexSamplerLinear)
|
||||
{
|
||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
||||
VkSamplerCreateInfo info = {};
|
||||
@@ -1067,7 +1085,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
info.minLod = -1000;
|
||||
info.maxLod = 1000;
|
||||
info.maxAnisotropy = 1.0f;
|
||||
err = vkCreateSampler(v->Device, &info, v->Allocator, &bd->TexSampler);
|
||||
err = vkCreateSampler(v->Device, &info, v->Allocator, &bd->TexSamplerLinear);
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
@@ -1118,7 +1136,13 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
check_vk_result(err);
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, &bd->Pipeline, v->Subpass);
|
||||
// Create pipeline
|
||||
bool create_main_pipeline = (v->PipelineInfoMain.RenderPass != VK_NULL_HANDLE);
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
create_main_pipeline |= (v->UseDynamicRendering && v->PipelineInfoMain.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR);
|
||||
#endif
|
||||
if (create_main_pipeline)
|
||||
ImGui_ImplVulkan_CreateMainPipeline(&v->PipelineInfoMain);
|
||||
|
||||
// Create command pool/buffer for texture upload
|
||||
if (!bd->TexCommandPool)
|
||||
@@ -1143,6 +1167,34 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo* pipeline_info_in)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (bd->Pipeline)
|
||||
{
|
||||
vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator);
|
||||
bd->Pipeline = VK_NULL_HANDLE;
|
||||
}
|
||||
ImGui_ImplVulkan_PipelineInfo* pipeline_info = &v->PipelineInfoMain;
|
||||
if (pipeline_info != pipeline_info_in)
|
||||
*pipeline_info = *pipeline_info_in;
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR* pipeline_rendering_create_info = &pipeline_info->PipelineRenderingCreateInfo;
|
||||
if (v->UseDynamicRendering && pipeline_rendering_create_info->pColorAttachmentFormats != NULL)
|
||||
{
|
||||
// Deep copy buffer to reduce error-rate for end user (#8282)
|
||||
ImVector<VkFormat> formats;
|
||||
formats.resize((int)pipeline_rendering_create_info->colorAttachmentCount);
|
||||
memcpy(formats.Data, pipeline_rendering_create_info->pColorAttachmentFormats, (size_t)formats.size_in_bytes());
|
||||
formats.swap(bd->PipelineRenderingCreateInfoColorAttachmentFormats);
|
||||
pipeline_rendering_create_info->pColorAttachmentFormats = bd->PipelineRenderingCreateInfoColorAttachmentFormats.Data;
|
||||
}
|
||||
#endif
|
||||
bd->Pipeline = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, pipeline_info);
|
||||
}
|
||||
|
||||
void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
@@ -1156,7 +1208,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
||||
|
||||
if (bd->TexCommandBuffer) { vkFreeCommandBuffers(v->Device, bd->TexCommandPool, 1, &bd->TexCommandBuffer); bd->TexCommandBuffer = VK_NULL_HANDLE; }
|
||||
if (bd->TexCommandPool) { vkDestroyCommandPool(v->Device, bd->TexCommandPool, v->Allocator); bd->TexCommandPool = VK_NULL_HANDLE; }
|
||||
if (bd->TexSampler) { vkDestroySampler(v->Device, bd->TexSampler, v->Allocator); bd->TexSampler = VK_NULL_HANDLE; }
|
||||
if (bd->TexSamplerLinear) { vkDestroySampler(v->Device, bd->TexSamplerLinear, v->Allocator); bd->TexSamplerLinear = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleVert) { vkDestroyShaderModule(v->Device, bd->ShaderModuleVert, v->Allocator); bd->ShaderModuleVert = VK_NULL_HANDLE; }
|
||||
if (bd->ShaderModuleFrag) { vkDestroyShaderModule(v->Device, bd->ShaderModuleFrag, v->Allocator); bd->ShaderModuleFrag = VK_NULL_HANDLE; }
|
||||
if (bd->DescriptorSetLayout) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayout, v->Allocator); bd->DescriptorSetLayout = VK_NULL_HANDLE; }
|
||||
@@ -1257,18 +1309,19 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||
|
||||
// Sanity checks
|
||||
IM_ASSERT(info->Instance != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->PhysicalDevice != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->Device != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->Queue != VK_NULL_HANDLE);
|
||||
IM_ASSERT(info->MinImageCount >= 2);
|
||||
IM_ASSERT(info->ImageCount >= info->MinImageCount);
|
||||
if (info->DescriptorPool != VK_NULL_HANDLE) // Either DescriptorPool or DescriptorPoolSize must be set, not both!
|
||||
IM_ASSERT(info->DescriptorPoolSize == 0);
|
||||
else
|
||||
IM_ASSERT(info->DescriptorPoolSize > 0);
|
||||
IM_ASSERT(info->MinImageCount >= 2);
|
||||
IM_ASSERT(info->ImageCount >= info->MinImageCount);
|
||||
if (info->UseDynamicRendering == false)
|
||||
IM_ASSERT(info->RenderPass != VK_NULL_HANDLE);
|
||||
if (info->UseDynamicRendering)
|
||||
IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE && info->PipelineInfoForViewports.RenderPass == VK_NULL_HANDLE);
|
||||
|
||||
bd->VulkanInitInfo = *info;
|
||||
|
||||
@@ -1276,17 +1329,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
||||
vkGetPhysicalDeviceProperties(info->PhysicalDevice, &properties);
|
||||
bd->NonCoherentAtomSize = properties.limits.nonCoherentAtomSize;
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
if (v->PipelineRenderingCreateInfo.pColorAttachmentFormats != NULL)
|
||||
{
|
||||
// Deep copy buffer to reduce error-rate for end user (#8282)
|
||||
VkFormat* formats_copy = (VkFormat*)IM_ALLOC(sizeof(VkFormat) * v->PipelineRenderingCreateInfo.colorAttachmentCount);
|
||||
memcpy(formats_copy, v->PipelineRenderingCreateInfo.pColorAttachmentFormats, sizeof(VkFormat) * v->PipelineRenderingCreateInfo.colorAttachmentCount);
|
||||
v->PipelineRenderingCreateInfo.pColorAttachmentFormats = formats_copy;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ImGui_ImplVulkan_CreateDeviceObjects())
|
||||
IM_ASSERT(0 && "ImGui_ImplVulkan_CreateDeviceObjects() failed!"); // <- Can't be hit yet.
|
||||
|
||||
@@ -1304,12 +1346,10 @@ void ImGui_ImplVulkan_Shutdown()
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
// First destroy objects in all viewports
|
||||
ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
IM_FREE((void*)const_cast<VkFormat*>(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pColorAttachmentFormats));
|
||||
#endif
|
||||
|
||||
// Manually delete main viewport render data in-case we haven't initialized for viewports
|
||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||
@@ -1323,6 +1363,7 @@ void ImGui_ImplVulkan_Shutdown()
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -1415,7 +1456,7 @@ void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulk
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own app.)
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. PROBABLY NOT used by your own engine/app.)
|
||||
//-------------------------------------------------------------------------
|
||||
// You probably do NOT need to use or care about those functions.
|
||||
// Those functions only exist because:
|
||||
@@ -1425,7 +1466,7 @@ void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulk
|
||||
// but it is too much code to duplicate everywhere so we exceptionally expose them.
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain, render pass, frame buffers, etc.).
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// You may read this code to learn about Vulkan, but it is recommended you use your own custom tailored code to do equivalent work.
|
||||
// (The ImGui_ImplVulkanH_XXX functions do not interact with any of the state used by the regular ImGui_ImplVulkan_XXX functions)
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@@ -1603,7 +1644,7 @@ int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_m
|
||||
}
|
||||
|
||||
// Also destroy old swap chain and in-flight frames data, if any.
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count)
|
||||
void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count, VkImageUsageFlags image_usage)
|
||||
{
|
||||
VkResult err;
|
||||
VkSwapchainKHR old_swapchain = wd->Swapchain;
|
||||
@@ -1640,7 +1681,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
info.imageFormat = wd->SurfaceFormat.format;
|
||||
info.imageColorSpace = wd->SurfaceFormat.colorSpace;
|
||||
info.imageArrayLayers = 1;
|
||||
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
|
||||
info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | image_usage;
|
||||
info.imageSharingMode = VK_SHARING_MODE_EXCLUSIVE; // Assume that graphics family == present family
|
||||
info.preTransform = (cap.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) ? VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR : cap.currentTransform;
|
||||
info.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
|
||||
@@ -1768,12 +1809,12 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
||||
}
|
||||
|
||||
// Create or resize window
|
||||
void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count)
|
||||
// - 2025/09/26: v1.92.4 added a trailing 'VkImageUsageFlags image_usage' parameter which is usually VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT.
|
||||
void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count, VkImageUsageFlags image_usage)
|
||||
{
|
||||
IM_ASSERT(g_FunctionsLoaded && "Need to call ImGui_ImplVulkan_LoadFunctions() if IMGUI_IMPL_VULKAN_NO_PROTOTYPES or VK_NO_PROTOTYPES are set!");
|
||||
(void)instance;
|
||||
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count);
|
||||
//ImGui_ImplVulkan_CreatePipeline(device, allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &wd->Pipeline, g_VulkanInitInfo.Subpass);
|
||||
ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count, image_usage);
|
||||
ImGui_ImplVulkanH_CreateWindowCommandBuffers(physical_device, device, wd, queue_family, allocator);
|
||||
|
||||
// FIXME: to submit the command buffer, we need a queue. In the examples folder, the ImGui_ImplVulkanH_CreateOrResizeWindow function is called
|
||||
@@ -1899,6 +1940,12 @@ void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const V
|
||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(device, &vd->RenderBuffers, allocator);
|
||||
}
|
||||
|
||||
ImGui_ImplVulkanH_Window* ImGui_ImplVulkanH_GetWindowDataFromViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
||||
return vd ? &vd->Window : nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||
@@ -1928,10 +1975,11 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
||||
}
|
||||
|
||||
// Select Surface Format
|
||||
ImGui_ImplVulkan_PipelineInfo* pipeline_info = &v->PipelineInfoForViewports;
|
||||
ImVector<VkFormat> requestSurfaceImageFormats;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
for (uint32_t n = 0; n < v->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
|
||||
requestSurfaceImageFormats.push_back(v->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);
|
||||
for (uint32_t n = 0; n < pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount; n++)
|
||||
requestSurfaceImageFormats.push_back(pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats[n]);
|
||||
#endif
|
||||
const VkFormat defaultFormats[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM };
|
||||
for (VkFormat format : defaultFormats)
|
||||
@@ -1949,12 +1997,26 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
wd->ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
wd->UseDynamicRendering = v->UseDynamicRendering;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount, pipeline_info->SwapChainImageUsage);
|
||||
vd->WindowOwned = true;
|
||||
|
||||
// Create pipeline (shared by all secondary viewports)
|
||||
if (bd->PipelineForViewports == VK_NULL_HANDLE)
|
||||
ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, VK_NULL_HANDLE, wd->RenderPass, VK_SAMPLE_COUNT_1_BIT, &bd->PipelineForViewports, 0);
|
||||
{
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
if (wd->UseDynamicRendering)
|
||||
{
|
||||
pipeline_info->PipelineRenderingCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
|
||||
pipeline_info->PipelineRenderingCreateInfo.colorAttachmentCount = 1;
|
||||
pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats = &wd->SurfaceFormat.format;
|
||||
}
|
||||
else
|
||||
{
|
||||
pipeline_info->RenderPass = wd->RenderPass;
|
||||
}
|
||||
#endif
|
||||
bd->PipelineForViewports = ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, VK_NULL_HANDLE, &v->PipelineInfoForViewports);
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
|
||||
@@ -1980,7 +2042,7 @@ static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
return;
|
||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||
vd->Window.ClearEnable = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? false : true;
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, &vd->Window, v->QueueFamily, v->Allocator, (int)size.x, (int)size.y, v->MinImageCount, v->PipelineInfoForViewports.SwapChainImageUsage);
|
||||
}
|
||||
|
||||
static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
@@ -1993,7 +2055,7 @@ static void ImGui_ImplVulkan_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
|
||||
if (vd->SwapChainNeedRebuild || vd->SwapChainSuboptimal)
|
||||
{
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(v->Instance, v->PhysicalDevice, v->Device, wd, v->QueueFamily, v->Allocator, (int)viewport->Size.x, (int)viewport->Size.y, v->MinImageCount, v->PipelineInfoForViewports.SwapChainImageUsage);
|
||||
vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,23 @@
|
||||
// Backend uses a small number of descriptors per font atlas + as many as additional calls done to ImGui_ImplVulkan_AddTexture().
|
||||
#define IMGUI_IMPL_VULKAN_MINIMUM_IMAGE_SAMPLER_POOL_SIZE (8) // Minimum per atlas
|
||||
|
||||
// Specify settings to create pipeline and swapchain
|
||||
struct ImGui_ImplVulkan_PipelineInfo
|
||||
{
|
||||
// For Main viewport only
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
|
||||
// For Main and Secondary viewports
|
||||
uint32_t Subpass; //
|
||||
VkSampleCountFlagBits MSAASamples = {}; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
|
||||
#endif
|
||||
|
||||
// For Secondary viewports only (created/managed by backend)
|
||||
VkImageUsageFlags SwapChainImageUsage; // Extra flags for vkCreateSwapchainKHR() calls for secondary viewports. We automatically add VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT. You can add e.g. VK_IMAGE_USAGE_TRANSFER_SRC_BIT if you need to capture from viewports.
|
||||
};
|
||||
|
||||
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||
// [Please zero-clear before use!]
|
||||
// - About descriptor pool:
|
||||
@@ -83,29 +100,33 @@ struct ImGui_ImplVulkan_InitInfo
|
||||
uint32_t QueueFamily;
|
||||
VkQueue Queue;
|
||||
VkDescriptorPool DescriptorPool; // See requirements in note above; ignored if using DescriptorPoolSize > 0
|
||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||
uint32_t DescriptorPoolSize; // Optional: set to create internal descriptor pool automatically instead of using DescriptorPool.
|
||||
uint32_t MinImageCount; // >= 2
|
||||
uint32_t ImageCount; // >= MinImageCount
|
||||
VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||
VkPipelineCache PipelineCache; // Optional
|
||||
|
||||
// (Optional)
|
||||
VkPipelineCache PipelineCache;
|
||||
uint32_t Subpass;
|
||||
|
||||
// (Optional) Set to create internal descriptor pool instead of using DescriptorPool
|
||||
uint32_t DescriptorPoolSize;
|
||||
// Pipeline
|
||||
ImGui_ImplVulkan_PipelineInfo PipelineInfoMain; // Infos for Main Viewport (created by app/user)
|
||||
ImGui_ImplVulkan_PipelineInfo PipelineInfoForViewports; // Infos for Secondary Viewports (created by backend)
|
||||
//VkRenderPass RenderPass; // --> Since 2025/09/26: set 'PipelineInfoMain.RenderPass' instead
|
||||
//uint32_t Subpass; // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
|
||||
//VkSampleCountFlagBits MSAASamples; // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
|
||||
//VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
|
||||
|
||||
// (Optional) Dynamic Rendering
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3.
|
||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo and PipelineInfoViewports.PipelineRenderingCreateInfo.
|
||||
bool UseDynamicRendering;
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo;
|
||||
#endif
|
||||
|
||||
// (Optional) Allocation, Debugging
|
||||
const VkAllocationCallbacks* Allocator;
|
||||
void (*CheckVkResultFn)(VkResult err);
|
||||
VkDeviceSize MinAllocationSize; // Minimum allocation size. Set to 1024*1024 to satisfy zealous best practices validation layer and waste a little memory.
|
||||
|
||||
// (Optional) Customize default vertex/fragment shaders.
|
||||
// - if .sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO we use specified structs, otherwise we use defaults.
|
||||
// - Shader inputs/outputs need to match ours. Code/data pointed to by the structure needs to survive for whole during of backend usage.
|
||||
VkShaderModuleCreateInfo CustomShaderVertCreateInfo;
|
||||
VkShaderModuleCreateInfo CustomShaderFragCreateInfo;
|
||||
};
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
@@ -115,6 +136,11 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated)
|
||||
|
||||
// (Advanced) Use e.g. if you need to recreate pipeline without reinitializing the backend (see #8110, #8111)
|
||||
// The main window pipeline will be created by ImGui_ImplVulkan_Init() if possible (== RenderPass xor (UseDynamicRendering && PipelineRenderingCreateInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR))
|
||||
// Else, the pipeline can be created, or re-created, using ImGui_ImplVulkan_CreateMainPipeline() before rendering.
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_CreateMainPipeline(const ImGui_ImplVulkan_PipelineInfo* info);
|
||||
|
||||
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = NULL to handle this manually.
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkan_UpdateTexture(ImTextureData* tex);
|
||||
|
||||
@@ -152,25 +178,26 @@ struct ImGui_ImplVulkan_RenderState
|
||||
//
|
||||
// Your engine/app will likely _already_ have code to setup all that stuff (swap chain,
|
||||
// render pass, frame buffers, etc.). You may read this code if you are curious, but
|
||||
// it is recommended you use you own custom tailored code to do equivalent work.
|
||||
// it is recommended you use your own custom tailored code to do equivalent work.
|
||||
//
|
||||
// We don't provide a strong guarantee that we won't change those functions API.
|
||||
//
|
||||
// The ImGui_ImplVulkanH_XXX functions should NOT interact with any of the state used
|
||||
// by the regular ImGui_ImplVulkan_XXX functions).
|
||||
// by the regular ImGui_ImplVulkan_XXX functions.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct ImGui_ImplVulkanH_Frame;
|
||||
struct ImGui_ImplVulkanH_Window;
|
||||
|
||||
// Helpers
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count, VkImageUsageFlags image_usage);
|
||||
IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wd, const VkAllocationCallbacks* allocator);
|
||||
IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space);
|
||||
IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count);
|
||||
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
||||
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
||||
IMGUI_IMPL_API ImGui_ImplVulkanH_Window* ImGui_ImplVulkanH_GetWindowDataFromViewport(ImGuiViewport* viewport); // Access to Vulkan objects associated with a viewport (e.g to export a screenshot)
|
||||
|
||||
// Helper structure to hold the data needed by one rendering frame
|
||||
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
// 2025-06-12: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas. (#8465)
|
||||
// 2025-02-26: Recreate image bind groups during render. (#8426, #8046, #7765, #8027) + Update for latest webgpu-native changes.
|
||||
// 2024-10-14: Update Dawn support for change of string usages. (#8082, #8083)
|
||||
@@ -47,7 +48,7 @@
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
// When targeting native platforms (i.e. NOT emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// When targeting native platforms (i.e. NOT Emscripten), one of IMGUI_IMPL_WEBGPU_BACKEND_DAWN
|
||||
// or IMGUI_IMPL_WEBGPU_BACKEND_WGPU must be provided. See imgui_impl_wgpu.h for more details.
|
||||
#ifndef __EMSCRIPTEN__
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) == defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
@@ -369,7 +370,7 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
// Avoid rendering when minimized
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdListsCount == 0)
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||
@@ -444,9 +445,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)fr->VertexBufferHost;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)fr->IndexBufferHost;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += draw_list->VtxBuffer.Size;
|
||||
@@ -473,9 +473,8 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
int global_idx_offset = 0;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* draw_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||
@@ -536,19 +535,18 @@ void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder
|
||||
|
||||
static void ImGui_ImplWGPU_DestroyTexture(ImTextureData* tex)
|
||||
{
|
||||
ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData;
|
||||
if (backend_tex == nullptr)
|
||||
return;
|
||||
if (ImGui_ImplWGPU_Texture* backend_tex = (ImGui_ImplWGPU_Texture*)tex->BackendUserData)
|
||||
{
|
||||
IM_ASSERT(backend_tex->TextureView == (WGPUTextureView)(intptr_t)tex->TexID);
|
||||
wgpuTextureViewRelease(backend_tex->TextureView);
|
||||
wgpuTextureRelease(backend_tex->Texture);
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
IM_ASSERT(backend_tex->TextureView == (WGPUTextureView)(intptr_t)tex->TexID);
|
||||
wgpuTextureViewRelease(backend_tex->TextureView);
|
||||
wgpuTextureRelease(backend_tex->Texture);
|
||||
IM_DELETE(backend_tex);
|
||||
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||
tex->SetTexID(ImTextureID_Invalid);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||
tex->BackendUserData = nullptr;
|
||||
}
|
||||
|
||||
void ImGui_ImplWGPU_UpdateTexture(ImTextureData* tex)
|
||||
@@ -884,6 +882,7 @@ void ImGui_ImplWGPU_Shutdown()
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
delete[] bd->pFrameResources;
|
||||
@@ -896,6 +895,7 @@ void ImGui_ImplWGPU_Shutdown()
|
||||
io.BackendRendererName = nullptr;
|
||||
io.BackendRendererUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||
platform_io.ClearRendererHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
// Initialization data, for ImGui_ImplWGPU_Init()
|
||||
struct ImGui_ImplWGPU_InitInfo
|
||||
{
|
||||
WGPUDevice Device;
|
||||
WGPUDevice Device = nullptr;
|
||||
int NumFramesInFlight = 3;
|
||||
WGPUTextureFormat RenderTargetFormat = WGPUTextureFormat_Undefined;
|
||||
WGPUTextureFormat DepthStencilFormat = WGPUTextureFormat_Undefined;
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2025-09-23: Inputs: Minor optimization not submitting gamepad input if packet number has not changed.
|
||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||
// 2025-06-02: [Docking] WM_DPICHANGED also apply io.ConfigDpiScaleViewports for main viewport instead of letting it be done by application code.
|
||||
// 2025-04-30: Inputs: Fixed an issue where externally losing mouse capture (due to e.g. focus loss) would fail to claim it again the next subsequent click. (#8594)
|
||||
// 2025-03-26: [Docking] Viewports: fixed an issue when closing a window from the OS close button (with io.ConfigViewportsNoDecoration = false) while user code was discarding the 'bool* p_open = false' output from Begin(). Because we allowed the Win32 window to close early, Windows destroyed it and our imgui window became not visible even though user code was still submitting it.
|
||||
@@ -137,6 +139,7 @@ struct ImGui_ImplWin32_Data
|
||||
HMODULE XInputDLL;
|
||||
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||
PFN_XInputGetState XInputGetState;
|
||||
DWORD XInputPacketNumber;
|
||||
#endif
|
||||
|
||||
ImGui_ImplWin32_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
@@ -186,6 +189,7 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasParentViewport; // We can honor viewport->ParentViewportId by applying the corresponding parent/child relationship at platform levle (optional)
|
||||
|
||||
bd->hWnd = (HWND)hwnd;
|
||||
bd->TicksPerSecond = perf_frequency;
|
||||
@@ -245,6 +249,7 @@ void ImGui_ImplWin32_Shutdown()
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
::SetPropA(bd->hWnd, "IMGUI_CONTEXT", nullptr);
|
||||
ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
||||
@@ -257,7 +262,8 @@ void ImGui_ImplWin32_Shutdown()
|
||||
|
||||
io.BackendPlatformName = nullptr;
|
||||
io.BackendPlatformUserData = nullptr;
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewport);
|
||||
platform_io.ClearPlatformHandlers();
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
@@ -415,6 +421,9 @@ static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
||||
if (!bd->HasGamepad || bd->XInputGetState == nullptr || bd->XInputGetState(0, &xinput_state) != ERROR_SUCCESS)
|
||||
return;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
if (bd->XInputPacketNumber != 0 && bd->XInputPacketNumber == xinput_state.dwPacketNumber)
|
||||
return;
|
||||
bd->XInputPacketNumber = xinput_state.dwPacketNumber;
|
||||
|
||||
#define IM_SATURATE(V) (V < 0.0f ? 0.0f : V > 1.0f ? 1.0f : V)
|
||||
#define MAP_BUTTON(KEY_NO, BUTTON_ENUM) { io.AddKeyEvent(KEY_NO, (gamepad.wButtons & BUTTON_ENUM) != 0); }
|
||||
@@ -1114,11 +1123,10 @@ static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags fl
|
||||
*out_ex_style |= WS_EX_TOPMOST;
|
||||
}
|
||||
|
||||
static HWND ImGui_ImplWin32_GetHwndFromViewportID(ImGuiID viewport_id)
|
||||
static HWND ImGui_ImplWin32_GetHwndFromViewport(ImGuiViewport* viewport)
|
||||
{
|
||||
if (viewport_id != 0)
|
||||
if (ImGuiViewport* viewport = ImGui::FindViewportByID(viewport_id))
|
||||
return (HWND)viewport->PlatformHandle;
|
||||
if (viewport != nullptr)
|
||||
return (HWND)viewport->PlatformHandle;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -1129,7 +1137,7 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
||||
|
||||
// Select style and parent window
|
||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
||||
vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
vd->HwndParent = ImGui_ImplWin32_GetHwndFromViewport(viewport->ParentViewport);
|
||||
|
||||
// Create window
|
||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
||||
@@ -1192,7 +1200,7 @@ static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
||||
|
||||
// Update Win32 parent if it changed _after_ creation
|
||||
// Unlike style settings derived from configuration flags, this is more likely to change for advanced apps that are manipulating ParentViewportID manually.
|
||||
HWND new_parent = ImGui_ImplWin32_GetHwndFromViewportID(viewport->ParentViewportId);
|
||||
HWND new_parent = ImGui_ImplWin32_GetHwndFromViewport(viewport->ParentViewport);
|
||||
if (new_parent != vd->HwndParent)
|
||||
{
|
||||
// Win32 windows can either have a "Parent" (for WS_CHILD window) or an "Owner" (which among other thing keeps window above its owner).
|
||||
|
||||
@@ -182,6 +182,7 @@ The Platform backends in impl_impl_XXX.cpp files contain many implementations.
|
||||
- `ImGuiBackendFlags_HasSetMousePos`: supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set).
|
||||
- `ImGuiBackendFlags_PlatformHasViewports` supports multiple viewports. (multi-viewports only)
|
||||
- `ImGuiBackendFlags_HasMouseHoveredViewport` supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag. If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under mouse position, as it doesn't know about foreign windows. (multi-viewports only)
|
||||
- `ImGuiBackendFlags_HasParentViewport` supports honoring viewport->ParentViewportId value, by applying the corresponding parent/child relation at the Platform level.
|
||||
|
||||
**In your `ImGui_ImplXXX_NewFrame()` function:**
|
||||
- Set `io.DeltaTime` to the time elapsed (in seconds) since last frame.
|
||||
@@ -245,9 +246,8 @@ void MyImGuiBackend_RenderDrawData(ImDrawData* draw_data)
|
||||
// Render command lists
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
const ImDrawVert* vtx_buffer = cmd_list->VtxBuffer.Data; // vertex buffer generated by Dear ImGui
|
||||
const ImDrawIdx* idx_buffer = cmd_list->IdxBuffer.Data; // index buffer generated by Dear ImGui
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
|
||||
@@ -35,6 +35,399 @@ HOW TO UPDATE?
|
||||
and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users.
|
||||
- Please report any issue!
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.4 (Released 2025-10-14)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.4
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Viewports: for consistency with other config flags, renamed
|
||||
io.ConfigViewportPlatformFocusSetsImGuiFocus
|
||||
to io.ConfigViewportsPlatformFocusSetsImGuiFocus. (#6299, #6462)
|
||||
It was really a typo in the first place, and introduced in 1.92.2.
|
||||
- Backends:
|
||||
- TreeNode, Selectable, Clipper: commented out legacy names obsoleted in
|
||||
1.89.7 (July 2023) and 1.89.9 (Sept 2023):
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap --> ImGuiTreeNodeFlags_AllowOverlap
|
||||
ImGuiSelectableFlags_AllowItemOverlap --> ImGuiSelectableFlags_AllowOverlap
|
||||
ImGuiListClipper::IncludeRangeByIndices() --> ImGuiListClipper::IncludeItemsByIndex()
|
||||
- Vulkan: moved some fields in ImGui_ImplVulkan_InitInfo:
|
||||
init_info.RenderPass --> init_info.PipelineInfoMain.RenderPass
|
||||
init_info.Subpass --> init_info.PipelineInfoMain.Subpass
|
||||
init_info.MSAASamples --> init_info.PipelineInfoMain.MSAASamples
|
||||
init_info.PipelineRenderingCreateInfo --> init_info.PipelineInfoMain.PipelineRenderingCreateInfo
|
||||
It makes things more consistent and was desirable to introduce new settings for
|
||||
secondary viewports. (#8946, #8110, #8111, #8686) [@ocornut, @SuperRonan, @sylmroz]
|
||||
- Vulkan: renamed ImGui_ImplVulkan_MainPipelineCreateInfo --> ImGui_ImplVulkan_PipelineInfo
|
||||
(introduced very recently and only used by `ImGui_ImplVulkan_CreateMainPipeline()`
|
||||
so it should not affect many users). (#8110, #8111)
|
||||
- Vulkan: helper ImGui_ImplVulkanH_CreateOrResizeWindow() added a
|
||||
`VkImageUsageFlags image_usage` argument.
|
||||
It was previously hardcoded to `VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT` and defaults
|
||||
to that when the value is 0. In theory the function is an internal helper but
|
||||
since it's used by our examples some may have used it. (#8946, #8111, #8686)
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Windows: added lower-right resize grip on child windows using both
|
||||
ImGuiChildFlags_ResizeX and ImGuiChildFlags_ResizeY flags. (#8501) [@aleksijuvani]
|
||||
The grip is not visible before hovering to reduce clutter.
|
||||
- Style: added ImGuiCol_UnsavedMarker, color of the unsaved document marker when
|
||||
using ImGuiWindowFlags_UnsavedDocument/ImGuiTabItemFlags_UnsavedDocument. (#8983)
|
||||
- IO: added ImGuiPlatformIO::ClearPlatformHandlers(), ClearRendererHandlers()
|
||||
helpers to null all handlers. (#8945, #2769)
|
||||
- Inputs:
|
||||
- Shortcuts: added support for combining ImGuiInputFlags_RouteFocused
|
||||
(which is the default route) with ImGuiInputFlags_RouteOverActive, allowing
|
||||
to steal shortcuts from active item without using global routing. (#9004)
|
||||
- InputText:
|
||||
- Fixed single-line InputText() not applying fine character clipping
|
||||
properly (regression in 1.92.3). (#8967) [@Cyphall]
|
||||
- Fixed an infinite loop error happening if a custom input text
|
||||
callback modifies/clear BufTextLen before calling InsertChars().
|
||||
(regression from 1.92.3). Note that this never really worked correctly, but
|
||||
previously it would only temporary wreck cursor position, and since 1.92.3 it
|
||||
would go in an infinite loop. (#8994, #3237)
|
||||
- Textures:
|
||||
- Fixed a crash if texture status is set to ImTextureStatus_WantDestroy by a backend
|
||||
after it had already been destroyed. This would typically happen when calling
|
||||
ImGui_ImplXXXX_InvalidateDeviceObjects() helpers twice in a row. (#8977, #8811)
|
||||
- Allowed backend to destroy texture while inside the NewFrame/EndFrame
|
||||
scope. Basically if a backend decide to destroy a texture that we didn't request
|
||||
to destroy (for e.g. freeing resources) the texture is immediately set to
|
||||
a ImTextureStatus_WantCreate status again. (#8811)
|
||||
- Fixed an issue preventing multi-contexts sharing a ImFontAtlas from
|
||||
being possible to destroy in any order.
|
||||
- Fixed not updating ImTextureData's RefCount when destroying a context
|
||||
using a shared ImFontAtlas, leading standard backends to not properly
|
||||
free texture resources. (#8975) [@icrashstuff]
|
||||
- Demo: fixed layout issue in "Layout & Scrolling -> Scrolling" section.
|
||||
- Misc: Relaxed internal assert in MarkItemEdited() to allow for more use cases. (#8997)
|
||||
- Misc: Debuggers: added type formatters for the LLDB debuggers (e.g. Xcode,
|
||||
Android Studio & more) to provide nicer display for ImVec2, ImVec4, ImVector etc.
|
||||
See misc/debuggers/ for details. (#8950) [@mentlerd]
|
||||
- CI: updated Windows CI scripts to generate/use VulkanSDK. (#8925, #8778) [@yaz0r]
|
||||
- Docs: updated FAQ with new "What is the difference between Dear ImGui and
|
||||
traditional UI toolkits?" entry. (#8862)
|
||||
- Backends:
|
||||
- All backends call ImGuiPlatformIO::ClearPlatformHandlers() and
|
||||
ClearRendererHandlers() on shutdown, so as not to leave function pointers
|
||||
which may be dangling when using backend in e.g. DLL. (#8945, #2769)
|
||||
- DirectX12: reuse a command list and allocator for texture uploads instead
|
||||
of recreating them each time. (#8963, #8465) [@RT2Code]
|
||||
- DirectX12: Rework synchronization logic. (#8961) [@RT2Code]
|
||||
(presumably fixes old hard-to-repro crash issues such as #3463, #5018)
|
||||
- DirectX12: Reuse texture upload buffer and grow it only when
|
||||
necessary. (#9002) [@RT2Code]
|
||||
- DirectX12: Enable swapchain tearing if available. (#8965) [@RT2Code]
|
||||
- OpenGL3: fixed GL loader to work on Haiku OS which does not support
|
||||
`RTLD_NOLOAD`. (#8952) [@Xottab-DUTY, @threedeyes]
|
||||
- GLFW: fixed build on platform that are neither Windows, macOS or
|
||||
known Unixes (Regression in 1.92.3). (#8969, #8920, #8921) [@oktonion]
|
||||
- SDL2,SDL3: avoid using the SDL_GetGlobalMouseState() path when one of our
|
||||
window is hovered, as the event data is reliable and enough in this case.
|
||||
- Fix mouse coordinates issue in fullscreen apps with macOS notch. (#7919, #7786)
|
||||
- Essentially a workaround for SDL3 bug which will be fixed in SDL 3.3.0.
|
||||
- Better perf on X11 as querying global position requires a round trip to X11 server.
|
||||
- Win32: minor optimization not submitting gamepad io again if
|
||||
XInput's dwPacketNumber has not changed. (#8556) [@MidTerm-CN]
|
||||
- Vulkan: added a way to specify custom shaders by filling init fields
|
||||
CustomShaderVertCreateInfo and CustomShaderFragCreateInfo. (#8585, #8271) [@johan0A]
|
||||
- DX9,DX10,DX11,DX12,Metal,Vulkan,WGPU,SDLRenderer2,SDLRenderer3:
|
||||
ensure that a texture in ImTextureStatus_WantDestroy state always turn to
|
||||
ImTextureStatus_Destroyed even if your underlying graphics data was already
|
||||
destroyed. (#8977)
|
||||
- Examples:
|
||||
- SDL2+DirectX11: Try WARP software driver if hardware driver is
|
||||
not available. (#5924, #5562)
|
||||
- SDL3+DirectX11: Added SDL3+DirectX11 example. (#8956, #8957) [@tomaz82]
|
||||
- Win32+DirectX12: Rework synchronization logic. (#8961) [@RT2Code]
|
||||
- Made examples's main.cpp consistent with returning 1 on error.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Nav, Docking, Selection: Fixed tab change from reinitializing navigation state,
|
||||
which would erroneously clear selection when using ImGuiSelectableFlags_SelectOnNav
|
||||
or clear multi-selection when not using ImGuiMultiSelectFlags_NoAutoSelect. (#8997)
|
||||
- Nav: Fixed a crash that could occur when opening a popup following the processing
|
||||
of a global shortcut while no windows were focused (the fix done in 1.92.3 was
|
||||
incomplete for docking branch).
|
||||
- Viewports:
|
||||
- Added ImGuiBackendFlags_HasParentViewport backend flag for
|
||||
backend to specify if it can honor the viewport->ParentViewportId value by
|
||||
applying the corresponding parent/child relation at the Platform level. (#8948)
|
||||
- SDL3, Win32 backends: supported.
|
||||
- SDL2, GLFW, OSX backends: unsupported.
|
||||
- Fixed a bug where ImGuiWindowFlags_NoBringToFrontOnFocus would effectivey
|
||||
be ignored when windows first appear and viewports are enabled. (#7008) [@jshofmann]
|
||||
- Changed default value of io.ConfigViewportsNoDefaultParent to true. (#8948)
|
||||
- Fixed an issue inferring Z-order when attempting to merge a viewport
|
||||
back in the the main/hosting viewport. (#8948)
|
||||
Note that for GLFW/SDL2/OSX backends, which do not support honoring ParentViewportID.
|
||||
Setting io.ConfigViewportsNoDefaultParent=true will align imgui's expectation
|
||||
with what the backend does.
|
||||
- Storing `ImGuiViewport* ParentViewport` pointer along with ParentViewportID.
|
||||
- DestroyContext() does not call DestroyPlatformWindows() anymore at it is
|
||||
assumed to be unnecessary as backends should have done it and we check that
|
||||
backends have been shutdown since 1.90.4. Changed into asserts. (#7175, #8945)
|
||||
- Backends:
|
||||
- DirectX10, DirectX11, DirectX12: Disabled DXGI's Alt+Enter default behavior on
|
||||
secondary viewports managed by the backend. (#4350) [@PathogenDavid]
|
||||
- DirectX10, DirectX11: avoid ImGui_ImplXXXX_SwapBuffers() handlers for secondary
|
||||
viewports crashing if SwapChain could not be created.
|
||||
- Vulkan: Added a way to configure secondary viewport pipeline creation by
|
||||
setting init_info.PipelineInfoForViewports fields. (#8946, #8110, #8111, #8686)
|
||||
- Vulkan: Added a way to configure secondary viewport swapchain VkImageUsageFlags
|
||||
to e.g. capture rendering. (#8946, #8940) [@olivier-gerard, @ocornut]
|
||||
Usage example: `init_info.PipelineInfoForViewports.SwapChainImageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;`
|
||||
- Vulkan: pipeline created for secondary viewport automatically match
|
||||
surface format. (#8686) [@sylmroz]
|
||||
- Vulkan: Added ImGui_ImplVulkanH_GetWindowDataFromViewport() accessor/helper. (#8946, #8940) [@olivier-gerard]
|
||||
- Docs: improve docking API comments and demo. (#9000)
|
||||
- Examples: DX10, DX11: Disabled DXGI's Alt+Enter default behavior in examples.
|
||||
Applications are free to leave this enabled, but it does not work properly with
|
||||
multiple viewports. (#4350) [@PathogenDavid]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.3 (Released 2025-09-17)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.3
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Fonts: fixed merging a font and specifying a font target in DstFont
|
||||
that's not the last added font (regression in 1.92). (#8912)
|
||||
- Fonts: fixed an assertion failure when a rectangle entry has been reused
|
||||
1024 times (e.g. due to constant change of font size). (#8906) [@cfillion]
|
||||
- Clipper, Tables: added ImGuiListClipperFlags_NoSetTableRowCounters as a way to
|
||||
disable the assumption that 1 clipper item == 1 table row, which breaks when
|
||||
e.g. using clipper with ItemsHeight=1 in order to clip in pixel units. (#8886)
|
||||
- Scrollbar, Style: added configurable style.ScrollbarPadding value and corresponding
|
||||
ImGuiStyleVar_ScrollbarPadding enum, instead of an hard-coded computed default. (#8895)
|
||||
- Nav: fixed Ctrl+Tab window appearing as empty when the sole active and focused
|
||||
window has the ImGuiWindowFlags_NoNavFocus flag. (#8914)
|
||||
- Nav: fixed a crash that could occur when opening a popup following the processing
|
||||
of a global shortcut while no windows were focused.
|
||||
- Bullet: fixed tessellation which looked out of place in very large sizes.
|
||||
- InputText: added ImGuiInputTextFlags_WordWrap flag to word-wrap multi-line buffers.
|
||||
(#3237, #952, #1062, #7363). Current caveats:
|
||||
- This is marked as beta because not being tested enough.
|
||||
Please report any incorrect cursor movement, selection behavior etc. bug to #3237.
|
||||
- Wrapping style is not ideal. Wrapping of long words/sections (e.g. words
|
||||
larger than total available width) may be particularly unpleasing.
|
||||
- Wrapping width needs to always account for the possibility of a vertical scrollbar.
|
||||
- It is currently much slower than regular text fields:
|
||||
- Ballpark estimate of cost on my 2019 desktop PC:
|
||||
For a 100 KB text buffer: +~0.3 ms/+~1.0 ms (Optimized vs Debug builds).
|
||||
- The CPU cost is very roughly proportional to text length, so a 10 KB buffer
|
||||
should cost about ten times less.
|
||||
- InputText, InputInt, InputFloat: fixed an issue where using Escape to revert
|
||||
would not write back the reverted value during the IsItemDeactivatedAfterEdit()
|
||||
frame if the provided input buffer doesn't store temporary edits.
|
||||
(regression in 1.91.7) (#8915, #8273)
|
||||
- InputText: fixed an issue where using Escape with ImGuiInputTextFlags_EscapeClearsAll
|
||||
would not write back the cleared value during the IsItemDeactivatedAfterEdit()
|
||||
frame if the provided input buffer doesn't store temporary edits. (#8915, #8273)
|
||||
- InputText: allow passing an empty string with buf_size==0. (#8907)
|
||||
In theory the buffer size should always account for a zero-terminator, but idioms
|
||||
such as using InputTextMultiline() with ImGuiInputTextFlags_ReadOnly to display
|
||||
a text blob are facilitated by allowing this.
|
||||
- InputText: refactored internals to simplify and optimizing rendering of selection.
|
||||
Very large selection (e.g. 1 MB) now take less overhead.
|
||||
- InputText: revert a change in 1.79 where pressing Down or PageDown on the last line
|
||||
of a multi-line buffer without a trailing carriage return would keep the cursor
|
||||
unmoved. We revert back to move to the end of line in this situation.
|
||||
- InputText: fixed pressing End (without Shift) in a multi-line selection from
|
||||
mistakenly moving cursor based on selection start.
|
||||
- Focus, InputText: fixed an issue where SetKeyboardFocusHere() did not work
|
||||
on InputTextMultiline() fields with ImGuiInputTextFlags_AllowTabInput, since
|
||||
they normally inhibit activation to allow tabbing through multiple items. (#8928)
|
||||
- Selectable: added ImGuiSelectableFlags_SelectOnNav to auto-select an item when
|
||||
moved into, unless Ctrl is held. (automatic when in a BeginMultiSelect() block).
|
||||
- TabBar: fixed an issue were forcefully selecting a tab using internal API would
|
||||
be ignored on first/appearing frame before tabs are submitted (#8929, #6681)
|
||||
- DrawList: fixed CloneOutput() unnecessarily taking a copy of the ImDrawListSharedData
|
||||
pointer, which could to issue when deleting the cloned list. (#8894, #1860)
|
||||
- DrawList: made AddCallback() assert when passing a null callback.
|
||||
- Debug Tools: ID Stack Tool: fixed using fixed-size buffers preventing long identifiers
|
||||
from being displayed in the tool. (#8905, #4631)
|
||||
- Debug Tools: ID Stack Tool: when ### is used, uncontributing prefix before the ###
|
||||
is now skipped. (#8904, #4631)
|
||||
- Debug Tools: ID Stack Tool: added option to hex-encode non-ASCII characters in
|
||||
output path. (#8904, #4631)
|
||||
- Debug Tools: ID Stack Tool: fixed a crash when using PushOverrideID(0) during
|
||||
a query. (#8937, #4631)
|
||||
- Debug Tools: Fixed assertion failure when opening a combo box while using
|
||||
io.ConfigDebugBeginReturnValueOnce/ConfigDebugBeginReturnValueLoop. (#8931) [@harrymander]
|
||||
- Demo: tweaked ShowFontSelector() and ShowStyleSelector() to update selection
|
||||
while navigating and to not close popup automatically.
|
||||
- CI: Updates Windows CI to use a more recent VulkanSDK. (#8925, #8778) [@yaz0r]
|
||||
- Examples: Android: Android+OpenGL3: update Gradle project (#8888, #8878) [@scribam]
|
||||
- Examples: GLFW+OpenGL2, GLFW+Vulkan, GLFW+Metal, Win32+Vulkan: Fixed not applying
|
||||
content scale consistently with other examples. (#8921, #8756)
|
||||
- Backends: GLFW: distinguish X11 vs Wayland to fix various scaling issues.
|
||||
(#8920, #8921) [@TheBrokenRail, @pthom, @ocornut]
|
||||
- window/monitor content scales are always reported as 1.0 on Wayland.
|
||||
- framebuffer scales are always reported as 1.0 on X11.
|
||||
- Backends: SDL2: window/monitor content scales are always reported as 1.0 on Wayland.
|
||||
(#8920, #8921) [@TheBrokenRail, @pthom, @ocornut]
|
||||
- Backends: SDL3: use SDL_GetWindowDisplayScale() on Mac to obtain DisplayFrameBufferScale,
|
||||
fixing incorrect values during resolution changes e.g. going fullscreen.
|
||||
(#8703, #4414) [@jclounge]
|
||||
- Backends: SDL_GPU: Added ImGui_ImplSDLGPU3_InitInfo::SwapchainComposition and
|
||||
PresentMode to configure how secondary viewports are created. Currently only used
|
||||
multi-viewport mode. (#8892) [@PTSVU]
|
||||
- Backends: Vulkan: added ImGui_ImplVulkan_CreateMainPipeline() to recreate pipeline
|
||||
without reinitializing backend. (#8110, #8111) [@SuperRonan]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- DPI: fixed io.ConfigDpiScaleFonts from ever working since 1.92 (the irony
|
||||
being that it is when it started to make sense!). As a reminder, the option
|
||||
automatically copy the _current_ viewport DpiScale to style.FontScaleDpi.
|
||||
This is why we separated the style.FontScaleMain and style.FontScaleDpi scaling
|
||||
factor, as the later is meant to be overwritten. (#8832, #8465)
|
||||
- DPI: Fixed obsoleted ImGuiConfigFlags_DpiEnableScaleFonts/_DpiEnableScaleViewports
|
||||
names from setting the equivalent io.ConfigDpiScaleFonts/io.ConfigDpiScaleViewports
|
||||
flag correctly (regression in 1.92).
|
||||
- Docking, Style: added style.DockingNodeHasCloseButton option to hide the
|
||||
Close Button attached to each docking node. (#8933)
|
||||
- Backends: GLFW: improve multi-viewport behavior in tiling WMs on X11.
|
||||
Note: using GLFW backend on Linux/BSD etc. requires linking with `-lX11`.
|
||||
(#8884, #8474, #8289, #2117) [@Ikos3k, @Madman10K]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.2b (Released 2025-08-13)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.2b
|
||||
|
||||
Changes:
|
||||
|
||||
- Fixed IsItemHovered() failing on disabled items and items that have no
|
||||
identifier (e.g. Text() calls) when holding mouse button. (#8877, #8883)
|
||||
[Regression in 1.92.2].
|
||||
- Made IsItemHovered() on holding mouse button down on disabled items not
|
||||
leak between items when the window cannot be moved.
|
||||
- Backends: Allegro5: Fixed texture format setup which didn't work on all
|
||||
setups/drivers. (#8770, #8465)
|
||||
- Backends: Allegro5: Added ImGui_ImplAllegro5_SetDisplay() function to
|
||||
change current ALLEGRO_DISPLAY, as Allegro applications often need to do that.
|
||||
- Backends: Allegro5: Fixed missing support for ImGuiKey_PrintScreen
|
||||
under Windows, as raw Allegro 5 does not receive it.
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Fixed a bug where closing a viewport using OS facility (e.g. ALT+F4, Close Button)
|
||||
would erroneously close all windows located in the viewport, even ones docked
|
||||
into nested dockspaces. Only top-most windows should be closed. (#8887) [@lailoken]
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.2 (Released 2025-08-11)
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.92.2
|
||||
|
||||
Breaking Changes:
|
||||
|
||||
- Tabs: Renamed ImGuiTabBarFlags_FittingPolicyResizeDown to ImGuiTabBarFlags_FittingPolicyShrink.
|
||||
Kept inline redirection enum (will obsolete). (#261, #351)
|
||||
- Backends: SDL_GPU3: changed ImTextureID type from SDL_GPUTextureSamplerBinding* to SDL_GPUTexture*,
|
||||
which is more natural and easier for user to manage. If you need to change the current sampler,
|
||||
you can access the ImGui_ImplSDLGPU3_RenderState struct. (#8866, #8163, #7998, #7988)
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Fixed an old inconsistency between IsItemHovered() and internal hovering check,
|
||||
where IsItemHovered() would return true to mouse was first clicked on the
|
||||
background of a non-moveable window then moved over the item or button.
|
||||
Note that while it is consistent with other logic, there is a possibility
|
||||
that some third-party code may accidentally relied on this. One can always use
|
||||
ImGuiHoveredFlags_AllowWhenBlockedByActiveItem to bypass the active id check.
|
||||
(#8877) [@achabense, @ocornut]
|
||||
- Fonts: fixed an issue when a font using MergeMode has a reference size
|
||||
specified but the target font doesn't. Usually either all fonts should
|
||||
have a reference size (only required when specifying e.g. GlyphOffset),
|
||||
or none should have a reference size.
|
||||
- Fonts: fixed a crash when changing texture format when using a legacy
|
||||
backend. Most commonly would happen when calling GetTexDataAsRGBA32()
|
||||
then immediately calling GetTexDataAsAlpha8(). (#8824)
|
||||
- Windows: fixed an issue where resizable child windows would emit border
|
||||
logic when hidden/non-visible (e.g. when in a docked window that is not
|
||||
selected), impacting code not checking for BeginChild() return value. (#8815)
|
||||
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
|
||||
ImFontAtlas() was incorrectly cleared with zeroes. (#8860, #8745) [@cfillion]
|
||||
- Tables: fixed TableGetRowIndex() which never correctly worked when using
|
||||
a clipper (it exists for consistency but is almost never used, as it is
|
||||
often more convenient to use index in caller-code, whereas TableGetRowIndex()
|
||||
includes header rows).
|
||||
- Tables: fixed imgui_internal.h's TableGetHoveredRow() the same way. (#7350, #6588, #6250)
|
||||
- Tabs: added new fitting policy ImGuiTabBarFlags_FittingPolicyMixed
|
||||
and made it the default. This policy shrink tab width down to a given amount,
|
||||
and then beyond that it enable scrolling buttons. (#3421, #8800)
|
||||
- Tabs: added style.TabMinWidthShrink, ImGuiStyleVar_TabMinWidthShrink to
|
||||
control the width to shrink to in ImGuiTabBarFlags_FittingPolicyMixed mode.
|
||||
(#3421, #8800).
|
||||
- Tabs: when scrolling is enabled, track selected tabs when resizing down
|
||||
parent container. This does not prevent to horizontally scroll it out of
|
||||
view during normal operations. (#3421, #8800)
|
||||
- Tabs: added style.TabMinWidthBase, ImGuiStyleVar_TabMinWidthBase to control
|
||||
the base minimum width of a tab (default to 1.0f). This is the size before
|
||||
any potential shrinking is applied.
|
||||
- Tabs: fixed tab bar underline not drawing below scroll buttons, when
|
||||
they are enabled (minor regression from 1.90). (#6820, #4859, #5022, #5239)
|
||||
- Tabs: made scrolling buttons never keyboard/gamepad navigation candidates.
|
||||
- Nav, Tables: fixed navigation within scrolling tables when item boundaries
|
||||
goes beyond columns limits. The fix done in 1.89.6 didn't work correctly
|
||||
on scrolling windows. (#8816, #2221)
|
||||
- Nav: fixed a bug where ImGuiKey_NavGamepadMenu (==ImGuiKey_GamepadFaceLeft)
|
||||
button couldn't toggle between main and menu layers while navigating a Modal
|
||||
window. (#8834)
|
||||
- Error Handling: minor improvements to error handling for TableGetSortSpecs()
|
||||
and TableSetBgColor() calls. (#1651, #8499)
|
||||
- Misc: fixed building with IMGUI_DISABLE_DEBUG_TOOLS only. (#8796)
|
||||
- Misc: fixed building with IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION. (#8794)
|
||||
- Misc: removed more redundant inline static linkage from imgui_internal.h to
|
||||
facilitate using in C++ modules. (#8813, #8682, #8358) [@stripe2933]
|
||||
- Misc: ImVector: skip memcpy in operator= if `Data` isn't initialized in order
|
||||
to play nice with -fsanitize=undefined. (#8874) [@i25e]
|
||||
- CI: Added SDL3 builds to MacOS and Windows. (#8819, #8778) [@scribam]
|
||||
- CI: Updated Windows CI to use a more recent SDL2. (#8819, #8778) [@scribam]
|
||||
- Examples: SDL3+Metal: added SDL3+Metal example. (#8827, #8825) [@shi-yan]
|
||||
- Examples: SDL3+SDL_GPU: use SDL_WaitAndAcquireGPUSwapchainTexture() instead
|
||||
of SDL_AcquireGPUSwapchainTexture(). (#8830) [@itsdanott]
|
||||
- Examples: SDL3+SDL_GPU: use SDL_GPU_PRESENTMODE_VSYNC present mode.
|
||||
- Backends: OpenGL3: add and call embedded loader shutdown in ImGui_ImplOpenGL3_Shutdown()
|
||||
to facilitate multiple init/shutdown cycles in same process. (#8792) [@tim-rex]
|
||||
- Backends: OpenGL2, OpenGL3: set GL_UNPACK_ALIGNMENT to 1 before updating
|
||||
textures. (#8802) [@Daandelange]
|
||||
- Backends: SDL_GPU3: expose current SDL_GPUSampler* in the ImGui_ImplSDLGPU3_RenderState
|
||||
struct. (#8866, #8163, #7998, #7988)
|
||||
- Backends: Vulkan: Fixed texture update corruption introduced in 1.92.0,
|
||||
affecting some drivers/setups. (#8801, #8755, #8840) [@Retro52, @Miolith]
|
||||
- Backends: Vulkan: Avoid calling vkCmdBindDescriptorSets() when texture
|
||||
has not changed. (#8666) [@micb25]
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Windows, Viewport: fixed an issue where interrupting a viewport move with
|
||||
e.g. a ClearActiveID() call would leave the dragged viewport with the
|
||||
normally temporary ImGuiViewportFlags_NoInputs flag, preventing further
|
||||
interactions with the viewport. (#5324) (thanks @mdelaharpe)
|
||||
- Viewports: added io.ConfigViewportPlatformFocusSetsImGuiFocus to opt-out
|
||||
of focusing imgui windows When a platform window is focused (e.g. using Alt+Tab,
|
||||
clicking Platform Title Bar). In principle this is better enabled but we
|
||||
provide an opt-out because some Linux window managers tend to eagerly focus
|
||||
windows (on e.g. mouse hover, or even on a simple window pos/size change).
|
||||
(#6299, #6462)
|
||||
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
VERSION 1.92.1 (Released 2025-07-09)
|
||||
-----------------------------------------------------------------------
|
||||
@@ -56,6 +449,8 @@ Changes:
|
||||
to pass full range of information into e.g. FreeType's face_index, as higher
|
||||
bits are used from FreeType 2.6.1. (#8775) [@Valakor]
|
||||
(the field has been erroneously reduced from 32-bits to 8-bit in 1.92.0)
|
||||
- Fonts, Tables: fixed PushFont() having no effect when called after submitting
|
||||
a hidden column. (#8865)
|
||||
- Textures: Fixed support for `#define ImTextureID_Invalid` to non-zero value:
|
||||
ImTextureData() was incorrectly cleared with zeroes. (#8745) [@rachit7645]
|
||||
- Demo: Added "Text -> Font Size" demo section. (#8738) [@Demonese]
|
||||
@@ -64,13 +459,13 @@ Changes:
|
||||
- Debug Tools: added IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS to detect
|
||||
id conflicts _before_ hovering. This is very slow and should only be used
|
||||
temporarily. (#8651, #7961, #7669)
|
||||
- Examples: GLFW+OpenGL3, GLFW+WGPU: Emscripten Makefiles uses GLFW port
|
||||
- Examples: GLFW+OpenGL3, GLFW+WGPU: Emscripten Makefiles uses GLFW port
|
||||
'contrib.glfw3' which offers better HiDPI support. (#8742) [@pthom]
|
||||
- Backends: GLFW, SDL2 made ImGui_ImplGLFW_GetContentScaleXXX() and
|
||||
ImGui_ImplSDL2_GetContentScaleXXXX() helpers return 1.0f on Emscripten
|
||||
- Backends: GLFW, SDL2 made ImGui_ImplGLFW_GetContentScaleXXX() and
|
||||
ImGui_ImplSDL2_GetContentScaleXXXX() helpers return 1.0f on Emscripten
|
||||
and Android platforms, matching macOS logic. (#8742, #8733) [@pthom]
|
||||
- Backends: SDL3: avoid calling SDL_StartTextInput() again if already active.
|
||||
(fixes e.g.: an issue on iOS where the keyboard animation will popup every
|
||||
(fixes e.g.: an issue on iOS where the keyboard animation will popup every
|
||||
time the user types a key + probably other things) (#8727) [@morrazzzz]
|
||||
- Backends: OSX: added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress
|
||||
mouse cursor support. (#8739) [@cfillion]
|
||||
@@ -166,6 +561,10 @@ Breaking changes:
|
||||
- You can use `Metrics/Debugger->Fonts->Font->Input Glyphs Overlap Detection Tool` to
|
||||
see list of glyphs available in multiple font sources. This can facilitate understanding
|
||||
which font input is providing which glyph.
|
||||
- Fonts: **IMPORTANT** on Thread Safety:
|
||||
- A few functions such as font->CalcTextSizeA() were by sheer luck (== accidentally)
|
||||
thread-safe even thou we had never provided that guarantee before. They are
|
||||
definitively not thread-safe anymore as new glyphs may be loaded.
|
||||
|
||||
- Textures:
|
||||
- All API functions taking a 'ImTextureID' parameter are now taking a 'ImTextureRef':
|
||||
@@ -202,7 +601,7 @@ Breaking changes:
|
||||
to 4096 but that limit isn't necessary anymore, and Renderer_TextureMaxWidth covers this)
|
||||
However you may set TexMinWidth = TexMaxWidth for the same effect.
|
||||
- Fonts: if you create and manage ImFontAtlas instances yourself (instead of relying on
|
||||
ImGuiContext to create one, you'll need to call ImFontAtlasUpdateNewFrame() yourself.
|
||||
ImGuiContext to create one), you'll need to call ImFontAtlasUpdateNewFrame() yourself.
|
||||
An assert will trigger if you don't.
|
||||
- Fonts: obsoleted ImGui::SetWindowFontScale() which is not useful anymore. Prefer using
|
||||
PushFont(NULL, style.FontSizeBase * factor) or to manipulate other scaling factors.
|
||||
@@ -553,8 +952,8 @@ Docking+Viewports Branch:
|
||||
- Viewports: fixed handling of simultaneous move + resize (e.g. toggling maximized)
|
||||
when ImGuiConfigFlags_DpiEnableScaleViewports is enabled.
|
||||
- Backends: Win32: Viewports: fixed an issue when closing a window from
|
||||
the OS close button (with io.ConfigViewportsNoDecoration=false) while
|
||||
user code is discarding the 'bool *p_open=false output' from Begin().
|
||||
the OS close button (with io.ConfigViewportsNoDecoration=false) while
|
||||
user code is discarding the 'bool *p_open=false output' from Begin().
|
||||
Because we allowed the Win32 window to close early, Windows destroyed
|
||||
it and our imgui window became not visible even though user code was
|
||||
still submitting it. (#8670)
|
||||
@@ -705,7 +1104,7 @@ Other changes:
|
||||
with asserts enabled. (#8452)
|
||||
- Backends: SDL2, SDL3: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn
|
||||
handler. (#7660) [@achabense]
|
||||
- Backends: SDL2, SDL3: Use display bounds when SDL_GetDisplayUsableBounds()
|
||||
- Backends: SDL2, SDL3: Use display bounds when SDL_GetDisplayUsableBounds()
|
||||
fails or return a zero size. (#8415, #3457)
|
||||
- Backends: SDL2, SDL3, Win32, Allegro5: Added support for ImGuiMouseCursor_Wait
|
||||
and ImGuiMouseCursor_Progress cursors.
|
||||
@@ -733,9 +1132,9 @@ Docking+Viewports Branch:
|
||||
|
||||
- Docking: Removed legacy assert preventing to call DockBuilderSplitNode() on an existing
|
||||
split node. This makes using DockBuilder a little more flexible and bearable! (#8472) [@MegaMech]
|
||||
- Viewports: fixed an issue where in certain cases, a window repositioning leading
|
||||
to a monitor change could have the window incorrectly get clamped within the boundaries
|
||||
of its previous monitor. Would happen e.g. when loading .ini data during runtime. (#8484)
|
||||
- Viewports: fixed an issue where in certain cases, a window repositioning leading
|
||||
to a monitor change could have the window incorrectly get clamped within the boundaries
|
||||
of its previous monitor. Would happen e.g. when loading .ini data during runtime. (#8484)
|
||||
- Viewports: fixed an assert when a window load settings with a position outside
|
||||
monitor bounds, when there are multiple monitors. (#8393, #8385) [@gaborodriguez]
|
||||
- Viewports + Backends: Win32: Fixed setting title bar text when application
|
||||
@@ -1060,7 +1459,7 @@ Breaking changes:
|
||||
allows casting any pointer/integer type without warning:
|
||||
- May warn: ImGui::Image((void*)MyTextureData, ...);
|
||||
- May warn: ImGui::Image((void*)(intptr_t)MyTextureData, ...);
|
||||
- Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData), ...);
|
||||
- Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData, ...);
|
||||
- Note that you can always define ImTextureID to be your own high-level structures
|
||||
(with dedicated constructors and extra render parameters) if you like.
|
||||
- IO: moved ImGuiConfigFlags_NavEnableSetMousePos to standalone io.ConfigNavMoveSetMousePos bool.
|
||||
@@ -4870,7 +5269,7 @@ Breaking Changes:
|
||||
- ShowTestWindow() -> use ShowDemoWindow()
|
||||
- IsRootWindowFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootWindow)
|
||||
- IsRootWindowOrAnyChildFocused() -> use IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows)
|
||||
- SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f)
|
||||
- SetNextWindowContentWidth(w) -> use SetNextWindowContentSize(ImVec2(w, 0.0f))
|
||||
- GetItemsLineHeightWithSpacing() -> use GetFrameHeightWithSpacing()
|
||||
- ImGuiCol_ChildWindowBg -> use ImGuiCol_ChildBg
|
||||
- ImGuiStyleVar_ChildWindowRounding -> use ImGuiStyleVar_ChildRounding
|
||||
|
||||
@@ -149,6 +149,14 @@ SDL2 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
|
||||
This is quite long and tedious, because: Vulkan. <BR>
|
||||
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.
|
||||
|
||||
[example_sdl3_directx11/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_directx11/) <BR>
|
||||
SDL3 + DirectX11 examples, Windows only. <BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_dx11.cpp <BR>
|
||||
|
||||
[example_sdl3_metal/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_metal/) <BR>
|
||||
SDL3 + Metal example, Mac only. <BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_metal.mm <BR>
|
||||
|
||||
[example_sdl3_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_opengl3/) <BR>
|
||||
SDL3 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR>
|
||||
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_opengl3.cpp <BR>
|
||||
|
||||
97
docs/FAQ.md
97
docs/FAQ.md
@@ -13,13 +13,14 @@ or view this file with any Markdown viewer.
|
||||
:---------------------------------------------------------- |
|
||||
| [Where is the documentation?](#q-where-is-the-documentation) |
|
||||
| [What is this library called?](#q-what-is-this-library-called) |
|
||||
| [What is the difference between Dear ImGui and traditional UI toolkits?](#q-what-is-the-difference-between-dear-imgui-and-traditional-ui-toolkits) |
|
||||
| [Which version should I get?](#q-which-version-should-i-get) |
|
||||
| **Q&A: Integration** |
|
||||
| **[How to get started?](#q-how-to-get-started)** |
|
||||
| **[How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?](#q-how-can-i-tell-whether-to-dispatch-mousekeyboard-to-dear-imgui-or-my-application)** |
|
||||
| [How can I enable keyboard or gamepad controls?](#q-how-can-i-enable-keyboard-or-gamepad-controls) |
|
||||
| [How can I use this on a machine without mouse, keyboard or screen? (input share, remote display)](#q-how-can-i-use-this-on-a-machine-without-mouse-keyboard-or-screen-input-share-remote-display) |
|
||||
| [How can I create my own backend?](q-how-can-i-create-my-own-backend)
|
||||
| [How can I create my own backend?](#q-how-can-i-create-my-own-backend)
|
||||
| [I integrated Dear ImGui in my engine and little squares are showing instead of text...](#q-i-integrated-dear-imgui-in-my-engine-and-little-squares-are-showing-instead-of-text) |
|
||||
| [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) |
|
||||
| [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) |
|
||||
@@ -75,6 +76,60 @@ or view this file with any Markdown viewer.
|
||||
|
||||
---
|
||||
|
||||
### Q: What is the difference between Dear ImGui and traditional UI toolkits?
|
||||
|
||||
Here's a very simplified comparison between the approach taken by Dear ImGui vs traditional toolkits:
|
||||
|
||||
| Dear ImGui | Qt/GTK/WPF... |
|
||||
|--------------------------|--------------------------|
|
||||
| UI fully issued on every update. | UI issued once then later modified. |
|
||||
| UI layout is fully dynamic and can change at any time.<BR>UI is generally emitted programmatically, which empowers reflecting a dynamic set of data. | UI layout is mostly static.<BR>UI may be emitted programmatically or from data created by offline tools. UI need extra code to evolve, which is often tedious and error-prone if it needs to be reflecting dynamic data and systems. |
|
||||
| Application can submit UI based on arbitrary logic and then forget about it. | Application needs more bookkeeping of UI elements. |
|
||||
| UI library stores minimal amounts of data. At one point in time, it typically doesn't know or remember which other widgets are displayed and which widgets are coming next. As a result, certain layout features (alignment, resizing) are not as easy to implement or require ad-hoc code. | UI library stores entire widgets tree and state. UI library can use this retained data to easily layout things. |
|
||||
| UI code may be added anywhere.<BR>You can even create UI to edit a local variable! | UI code needs to be added in dedicated spots. |
|
||||
| UI layout/logic/action/data bindings are all nearby in the code. | UI layout/logic/action/data bindings in distinct functions, files or formats. |
|
||||
| Data is naturally always synchronized. | Use callback/signal/slot for synchronizing data (error-prone). |
|
||||
| API is simple and easy to learn. In particular, doing basic things is very easy. | API is more complex and specialized. |
|
||||
| API is low-level (raw language types). | API are higher-level (more abstractions, advanced language features). |
|
||||
| Less fancy look and feel. | Standard look and feel. |
|
||||
| Compile yourself. Easy to debug, hack, modify, study. | Mostly use precompiled libraries. Compiling, modifying or studying is daunting if not impossible. |
|
||||
| Run on every platform. | Run on limited desktop platforms. |
|
||||
|
||||
Idiomatic Dear ImGui code:
|
||||
```cpp
|
||||
if (ImGui::Button("Save"))
|
||||
MySaveFunction();
|
||||
|
||||
ImGui::SliderFloat("Slider", &m_MyValue, 0.0f, 1.0f);
|
||||
```
|
||||
Idiomatic code with traditional toolkit:
|
||||
```cpp
|
||||
UiButton* button = new UiButton("Save");
|
||||
button->OnClick = &MySaveFunction;
|
||||
parent->Add(button);
|
||||
|
||||
UiSlider* slider = new UiSlider("Slider");
|
||||
slider->SetRange(0.0f, 1.0f);
|
||||
slider->BindData<float>(&m_MyValue);
|
||||
parent->Add(slider);
|
||||
```
|
||||
This is only meant to give you a intuitive feeling of the main differences, but pros & cons go deeper than that.
|
||||
|
||||
Some of those properties are typically associated to the umbrella term "IMGUI", but the term has no simple and well-agreed definition. There are many erroneous statements and misunderstandings with what IMGUI means. It is partly caused by the fact that most popular IMGUI implementations (including Dear ImGui) have originated from game industry needs and have targeted specific use cases, causing people to conflate IMGUI properties with what a specific library does. However, it is perfectly possible to implement an IMGUI library that would have very different properties than e.g. Dear ImGui. My take on defining what an IMGUI is:
|
||||
|
||||
**IMGUI refers to the API: literally the interface between the application and the UI system.**
|
||||
- An IMGUI API favors the application code owning its data and being the single source of truth for it.
|
||||
- An IMGUI API tries to minimize the application having to retain/manage data related to the UI system.
|
||||
- An IMGUI API tries to minimize the UI system having to retain/manage data related to the application.
|
||||
- Synchronization between application data and UI data is natural and less error-prone.
|
||||
|
||||
**IMGUI does NOT refer to the implementation. Whatever happens inside the UI library code doesn't matter.**
|
||||
<BR>Also see: [Links to many articles about the IMGUI paradigm](https://github.com/ocornut/imgui/wiki/#about-the-imgui-paradigm).
|
||||
|
||||
##### [Return to Index](#index)
|
||||
|
||||
---
|
||||
|
||||
### Q: Which version should I get?
|
||||
I occasionally tag [Releases](https://github.com/ocornut/imgui/releases) but it is generally safe and recommended to sync to master/latest. The library is fairly stable and regressions tend to be fixed fast when reported.
|
||||
|
||||
@@ -389,8 +444,8 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
### Q: What are ImTextureID/ImTextureRef?
|
||||
|
||||
**Short explanation:**
|
||||
- Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki).
|
||||
- You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures.
|
||||
- To load and display your own textures, refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki).
|
||||
- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as an opaque ImTextureID value.
|
||||
- By default ImTextureID can store up to 64-bits. You may `#define` it to a custom type/structure if you need.
|
||||
- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason), but the examples linked above may be useful references.
|
||||
@@ -398,12 +453,20 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
**Details:**
|
||||
|
||||
1.92 introduced `ImTextureRef` in June 2025.
|
||||
- Most drawing functions using ImTextureID were changed to use ImTextureRef.
|
||||
- We intentionally do not provide an implicit ImTextureRef -> ImTextureID cast operator because it is technically lossy to convert ImTextureRef to ImTextureID before rendering.
|
||||
- All drawing functions using `ImTextureID` were changed to use `ImTextureRef`.
|
||||
- You can trivially create a `ImTextureRef` from a `ImTextureID`.
|
||||
- **If you use Image functions with textures that you have loaded/created yourself, you will mostly likely only ever store/manipulate `ImTextureID` and then pass them as `ImTextureRef`.**
|
||||
- You only NEED to manipulate `ImTextureRef` when dealing with textures managed by the backend itself, aka mainly the atlas texture for now.
|
||||
- We intentionally do not provide an implicit `ImTextureRef` -> `ImTextureID` cast operator because it is technically lossy to convert ImTextureRef to ImTextureID before rendering.
|
||||
|
||||
**ImTextureID = backend specific, low-level identifier for a texture uploaded in GPU/graphics system.**
|
||||
```cpp
|
||||
#ifndef ImTextureID
|
||||
typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or integer). A majority of backends are ok with that.
|
||||
#endif
|
||||
```
|
||||
- When a Rendered Backend creates a texture, it store its native identifier into a ImTextureID value (e.g. Used by DX11 backend to a `ID3D11ShaderResourceView*`; Used by OpenGL backends to store `GLuint`; Used by SDLGPU backend to store a `SDL_GPUTextureSamplerBinding*`, etc.).
|
||||
- User may submit their own textures to e.g. ImGui::Image() function by passing the same type.
|
||||
- User may submit their own textures to e.g. `ImGui::Image()` function by passing this value.
|
||||
- During the rendering loop, the Renderer Backend retrieve the ImTextureID, which stored inside a ImTextureRef, which is stored inside ImDrawCmd.
|
||||
- Compile-time type configuration:
|
||||
- To use something other than a 64-bit value: add '#define ImTextureID MyTextureType*' in your imconfig.h file.
|
||||
@@ -411,13 +474,29 @@ node open/closed state differently. See what makes more sense in your situation!
|
||||
- You may decide to store a higher-level structure containing texture, sampler, shader etc. with various constructors if you like. You will need to implement ==/!= operators.
|
||||
|
||||
**ImTextureRef = higher-level identifier for a texture.**
|
||||
```cpp
|
||||
// Store a ImTextureID _or_ a ImTextureData*.
|
||||
struct ImTextureRef
|
||||
{
|
||||
ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; }
|
||||
ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; }
|
||||
inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; }
|
||||
|
||||
// Members (either are set, never both!)
|
||||
ImTextureData* _TexData; // A texture, generally owned by a ImFontAtlas. Will convert to ImTextureID during render loop, after texture has been uploaded.
|
||||
ImTextureID _TexID; // _OR_ Low-level backend texture identifier, if already uploaded or created by user/app. Generally provided to e.g. ImGui::Image() calls.
|
||||
};
|
||||
```
|
||||
- The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
- This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
- This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
- When a texture is created by user code (e.g. custom images), we directly stores the low-level `ImTextureID`.
|
||||
- When a texture is created by the backend, we stores a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened.
|
||||
- There is no constructor to create a `ImTextureID` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- If you want to bind the current atlas when using custom rectangle, you can use `io.Fonts->TexRef`.
|
||||
- When a texture is created by user code (e.g. custom images), we directly store the low-level `ImTextureID`.
|
||||
- Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
- When a texture is created by the backend, we store a `ImTextureData*` which becomes an indirection to extract the `ImTextureID` value during rendering, after texture upload has happened.
|
||||
- To create a `ImTextureRef` from a `ImTextureData*` you can use `ImTextureData::GetTexRef()`.
|
||||
We intentionally do not provide an `ImTextureRef` constructor for this: we don't expect this to be frequently useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- There is no constructor to create a `ImTextureRef` from a `ImTextureData*` as we don't expect this to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
- If you want to bind the current atlas when using custom rectangles, you can use `io.Fonts->TexRef`.
|
||||
- Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g. `inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }`
|
||||
|
||||
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
|
||||
|
||||
@@ -150,7 +150,6 @@ ImFontConfig config;
|
||||
config.MergeMode = true;
|
||||
io.Fonts->AddFontFromFileTTF("DroidSans.ttf", 0.0f, &config); // Merge into first font to add e.g. Asian characters
|
||||
io.Fonts->AddFontFromFileTTF("fontawesome-webfont.ttf", 0.0f, &config); // Merge into first font to add Icons
|
||||
io.Fonts->Build();
|
||||
```
|
||||
:rewind: **Before 1.92, or without an up to date backend:**
|
||||
```cpp
|
||||
@@ -588,15 +587,18 @@ Some fonts files are available in the `misc/fonts/` folder:
|
||||
|
||||
#### MONOSPACE FONTS
|
||||
|
||||
<img width="1172" height="715" alt="image" src="https://github.com/user-attachments/assets/c9702534-4877-41c9-ae0d-252933c26ced" />
|
||||
|
||||
Pixel Perfect:
|
||||
- Proggy Fonts, by Tristan Grimmer http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
- Sweet16, Sweet16 Mono, by Martin Sedlak (Latin + Supplemental + Extended A) https://github.com/kmar/Sweet16Font (also include an .inl file to use directly in dear imgui.)
|
||||
|
||||
Regular:
|
||||
- Google Noto Mono Fonts https://www.google.com/get/noto/
|
||||
- Typefaces for source code beautification https://github.com/chrissimpkins/codeface
|
||||
- Programmation fonts http://s9w.github.io/font_compare/
|
||||
- Inconsolata http://www.levien.com/type/myfonts/inconsolata.html
|
||||
- ProggyVector if you want the old school Dear ImGui font to scale: https://github.com/bluescan/proggyfonts
|
||||
- Google Noto Mono Fonts: https://www.google.com/get/noto/
|
||||
- Typefaces for source code beautification: https://github.com/chrissimpkins/codeface
|
||||
- Programmation fonts: http://s9w.github.io/font_compare/
|
||||
- Inconsolata: http://www.levien.com/type/myfonts/inconsolata.html
|
||||
- Adobe Source Code Pro: Monospaced font family for ui & coding environments https://github.com/adobe-fonts/source-code-pro
|
||||
- Monospace/Fixed Width Programmer's Fonts http://www.lowing.org/fonts/
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Businesses: support continued development and maintenance via invoiced sponsorin
|
||||
| [The Pitch](#the-pitch) - [Usage](#usage) - [How it works](#how-it-works) - [Releases & Changelogs](#releases--changelogs) - [Demo](#demo) - [Getting Started & Integration](#getting-started--integration) |
|
||||
:----------------------------------------------------------: |
|
||||
| [Gallery](#gallery) - [Support, FAQ](#support-frequently-asked-questions-faq) - [How to help](#how-to-help) - **[Funding & Sponsors](https://github.com/ocornut/imgui/wiki/Funding)** - [Credits](#credits) - [License](#license) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Languages bindings & frameworks backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||
| [Wiki](https://github.com/ocornut/imgui/wiki) - [Extensions](https://github.com/ocornut/imgui/wiki/Useful-Extensions) - [Language bindings & framework backends](https://github.com/ocornut/imgui/wiki/Bindings) - [Software using Dear ImGui](https://github.com/ocornut/imgui/wiki/Software-using-dear-imgui) - [User quotes](https://github.com/ocornut/imgui/wiki/Quotes) |
|
||||
|
||||
### The Pitch
|
||||
|
||||
@@ -107,22 +107,26 @@ Reading the changelogs is a good way to keep up to date with the things Dear ImG
|
||||
|
||||
### Demo
|
||||
|
||||
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`. [Here's how the demo looks](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
||||
Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcasing a variety of features and examples. The code is always available for reference in `imgui_demo.cpp`.
|
||||
- [Web version of the demo](https://pthom.github.io/imgui_manual_online/manual/imgui_manual.html) courtesy of [@pthom](https://github.com/pthom).
|
||||
- [Screenshot of the demo](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v167/v167-misc.png).
|
||||
|
||||
You should be able to build the examples from sources. If you don't, let us know! If you want to have a quick look at some Dear ImGui features, you can download Windows binaries of the demo app here:
|
||||
- [imgui-demo-binaries-20250625.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20250625.zip) (Windows, 1.92.0, built 2025/06/25, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||
|
||||
The demo applications are not DPI aware so expect some blurriness on a 4K screen. For DPI awareness in your application, you can load/reload your font at a different scale and scale your style with `style.ScaleAllSizes()` (see [FAQ](https://www.dearimgui.com/faq)).
|
||||
|
||||
### Getting Started & Integration
|
||||
|
||||
See the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide for details.
|
||||
|
||||
On most platforms and when using C++, **you should be able to use a combination of the [imgui_impl_xxxx](https://github.com/ocornut/imgui/tree/master/backends) backends without modification** (e.g. `imgui_impl_win32.cpp` + `imgui_impl_dx11.cpp`). If your engine supports multiple platforms, consider using more imgui_impl_xxxx files instead of rewriting them: this will be less work for you, and you can get Dear ImGui running immediately. You can _later_ decide to rewrite a custom backend using your custom engine functions if you wish so.
|
||||
|
||||
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide it should in theory take you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
|
||||
Integrating Dear ImGui within your custom engine is a matter of mainly 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can create/update textures and render textured triangles. This is exactly what backends are doing.
|
||||
- The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications setting up a window and using standard backends.
|
||||
- The [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide has instructions to integrate imgui into an existing application using standard backends. It should in theory take you less than an hour to integrate Dear ImGui into your existing codebase where support libraries are linked. Less if you read carefully.
|
||||
- The [Backends](https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md) guide explains what backends are doing, and has instructions to implement a custom backend. You can also refer to the source code of our ~20 backends to understand how they work.
|
||||
- Generally, **make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**
|
||||
|
||||
Officially maintained backends/bindings (in repository):
|
||||
Officially maintained backends (in repository):
|
||||
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_GPU, SDL_Renderer2/3, Vulkan, WebGPU.
|
||||
- Platforms: GLFW, SDL2/SDL3, Win32, Glut, OSX, Android.
|
||||
- Frameworks: Allegro5, Emscripten.
|
||||
@@ -130,7 +134,7 @@ Officially maintained backends/bindings (in repository):
|
||||
[Third-party backends/bindings](https://github.com/ocornut/imgui/wiki/Bindings) wiki page:
|
||||
- Languages: C, C# and: Beef, ChaiScript, CovScript, Crystal, D, Go, Haskell, Haxe/hxcpp, Java, JavaScript, Julia, Kotlin, Lobster, Lua, Nim, Odin, Pascal, PureBasic, Python, ReaScript, Ruby, Rust, Swift, Zig...
|
||||
- Frameworks: AGS/Adventure Game Studio, Amethyst, Blender, bsf, Cinder, Cocos2d-x, Defold, Diligent Engine, Ebiten, Flexium, GML/Game Maker Studio, GLEQ, Godot, GTK3, Irrlicht Engine, JUCE, LÖVE+LUA, Mach Engine, Magnum, Marmalade, Monogame, NanoRT, nCine, Nim Game Lib, Nintendo 3DS/Switch/WiiU (homebrew), Ogre, openFrameworks, OSG/OpenSceneGraph, Orx, Photoshop, px_render, Qt/QtDirect3D, raylib, SFML, Sokol, Unity, Unreal Engine 4/5, UWP, vtk, VulkanHpp, VulkanSceneGraph, Win32 GDI, WxWidgets.
|
||||
- Many bindings are auto-generated (by good old [cimgui](https://github.com/cimgui/cimgui) or newer/experimental [dear_bindings](https://github.com/dearimgui/dear_bindings)), you can use their metadata output to generate bindings for other languages.
|
||||
- Many bindings are auto-generated (by good old [cimgui](https://github.com/cimgui/cimgui) or our newer [dear_bindings](https://github.com/dearimgui/dear_bindings)), you can use their metadata output to generate bindings for other languages.
|
||||
|
||||
[Useful Extensions/Widgets](https://github.com/ocornut/imgui/wiki/Useful-Extensions) wiki page:
|
||||
- Automation/testing, Text editors, node editors, timeline editors, plotting, software renderers, remote network access, memory editors, gizmos, etc. Notable and well supported extensions include [ImPlot](https://github.com/epezent/implot) and [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine).
|
||||
@@ -184,7 +188,7 @@ How to help
|
||||
- See [GitHub Forum/Issues](https://github.com/ocornut/imgui/issues).
|
||||
- You may help with development and submit pull requests! Please understand that by submitting a PR you are also submitting a request for the maintainer to review your code and then take over its maintenance forever. PR should be crafted both in the interest of the end-users and also to ease the maintainer into understanding and accepting it.
|
||||
- See [Help wanted](https://github.com/ocornut/imgui/wiki/Help-Wanted) on the [Wiki](https://github.com/ocornut/imgui/wiki/) for some more ideas.
|
||||
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: omar AT dearimgui DOT com).
|
||||
- Be a [Funding Supporter](https://github.com/ocornut/imgui/wiki/Funding)! Have your company financially support this project via invoiced sponsors/maintenance or by buying a license for [Dear ImGui Test Engine](https://github.com/ocornut/imgui_test_engine) (please reach out: contact AT dearimgui DOT com).
|
||||
|
||||
Sponsors
|
||||
--------
|
||||
@@ -214,7 +218,7 @@ Omar: "I first discovered the IMGUI paradigm at [Q-Games](https://www.q-games.co
|
||||
Embeds [ProggyClean.ttf](https://www.proggyfonts.net) font by Tristan Grimmer (MIT license).
|
||||
<br>Embeds [stb_textedit.h, stb_truetype.h, stb_rect_pack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain).
|
||||
|
||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
||||
Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. Special thanks to Alex Evans, Patrick Doane, Marco Koegler for kindly helping. Also thank you to everyone posting feedback, questions and patches on GitHub.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
@@ -87,7 +87,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
||||
- input text multi-line: line numbers? status bar? (follow up on #200)
|
||||
- input text multi-line: behave better when user changes input buffer while editing is active (even though it is illegal behavior). namely, the change of buffer can create a scrollbar glitch (#725)
|
||||
- input text multi-line: better horizontal scrolling support (#383, #1224)
|
||||
- input text multi-line: single call to AddText() should be coarse clipped on InputTextEx() end.
|
||||
- input number: optional range min/max for Input*() functions
|
||||
- input number: holding [-]/[+] buttons could increase the step speed non-linearly (or user-controlled)
|
||||
- input number: use mouse wheel to step up/down
|
||||
|
||||
@@ -28,7 +28,7 @@ int main(int, char**)
|
||||
al_install_mouse();
|
||||
al_init_primitives_addon();
|
||||
al_set_new_display_flags(ALLEGRO_RESIZABLE);
|
||||
ALLEGRO_DISPLAY* display = al_create_display(1280, 720);
|
||||
ALLEGRO_DISPLAY* display = al_create_display(1280, 800);
|
||||
al_set_window_title(display, "Dear ImGui Allegro 5 example");
|
||||
ALLEGRO_EVENT_QUEUE* queue = al_create_event_queue();
|
||||
al_register_event_source(queue, al_get_display_event_source(display));
|
||||
@@ -54,7 +54,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
.cxx
|
||||
.externalNativeBuild
|
||||
build/
|
||||
*.iml
|
||||
|
||||
.idea
|
||||
.gradle
|
||||
.idea
|
||||
.DS_Store
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
|
||||
# Android Studio puts a Gradle wrapper here, that we don't want:
|
||||
gradle/
|
||||
!gradle/libs.versions.toml
|
||||
gradlew*
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
alias(libs.plugins.kotlin.android)
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 33
|
||||
buildToolsVersion "33.0.2"
|
||||
ndkVersion "25.2.9519653"
|
||||
namespace 'imgui.example.android'
|
||||
compileSdk 36
|
||||
|
||||
defaultConfig {
|
||||
applicationId "imgui.example.android"
|
||||
namespace "imgui.example.android"
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 33
|
||||
minSdk 24
|
||||
targetSdk 36
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
}
|
||||
@@ -21,26 +21,17 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_11
|
||||
targetCompatibility JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget="11"
|
||||
jvmTarget = '11'
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path "../../CMakeLists.txt"
|
||||
path file('../../CMakeLists.txt')
|
||||
version '3.22.1'
|
||||
}
|
||||
}
|
||||
}
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<application
|
||||
android:label="ImGuiExample"
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.8.0'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
alias(libs.plugins.kotlin.android) apply false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
[versions]
|
||||
agp = "8.12.0"
|
||||
kotlin = "2.0.21"
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
||||
|
||||
@@ -1 +1,22 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google {
|
||||
content {
|
||||
includeGroupByRegex("com\\.android.*")
|
||||
includeGroupByRegex("com\\.google.*")
|
||||
includeGroupByRegex("androidx.*")
|
||||
}
|
||||
}
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
include ':app'
|
||||
|
||||
@@ -154,7 +154,7 @@ void Init(struct android_app* app)
|
||||
// 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.
|
||||
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Android: The TTF files have to be placed into the assets/ directory (android/app/src/main/assets), we use our GetAssetData() helper to retrieve them.
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -104,7 +104,7 @@
|
||||
|
||||
-(void)loadView
|
||||
{
|
||||
self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 720)];
|
||||
self.view = [[MTKView alloc] initWithFrame:CGRectMake(0, 0, 1200, 800)];
|
||||
}
|
||||
|
||||
-(void)viewDidLoad
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -190,7 +190,7 @@
|
||||
if (_window != nil)
|
||||
return (_window);
|
||||
|
||||
NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 720.0);
|
||||
NSRect viewRect = NSMakeRect(100.0, 100.0, 100.0 + 1280.0, 100 + 800.0);
|
||||
|
||||
_window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSWindowStyleMaskTitled|NSWindowStyleMaskMiniaturizable|NSWindowStyleMaskResizable|NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:YES];
|
||||
[_window setTitle:@"Dear ImGui OSX+OpenGL2 Example"];
|
||||
|
||||
@@ -27,33 +27,57 @@ static void glfw_error_callback(int error, const char* description)
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
|
||||
// Create window with graphics context
|
||||
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+Metal example", nullptr, nullptr);
|
||||
if (window == nullptr)
|
||||
return 1;
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
|
||||
// Setup style
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
id <MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||
ImGui_ImplMetal_Init(device);
|
||||
|
||||
// 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -64,24 +88,6 @@ int main(int, char**)
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||
//IM_ASSERT(font != nullptr);
|
||||
|
||||
// Setup window
|
||||
glfwSetErrorCallback(glfw_error_callback);
|
||||
if (!glfwInit())
|
||||
return 1;
|
||||
|
||||
// Create window with graphics context
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Metal example", nullptr, nullptr);
|
||||
if (window == nullptr)
|
||||
return 1;
|
||||
|
||||
id <MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
ImGui_ImplMetal_Init(device);
|
||||
|
||||
NSWindow *nswin = glfwGetCocoaWindow(window);
|
||||
CAMetalLayer *layer = [CAMetalLayer layer];
|
||||
layer.device = device;
|
||||
|
||||
@@ -21,6 +21,7 @@ SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_glfw.cpp $(IMGUI_DIR)/backends/imgui_impl_opengl2.cpp
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
UNAME_S := $(shell uname -s)
|
||||
LINUX_GL_LIBS = -lGL
|
||||
|
||||
CXXFLAGS = -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -g -Wall -Wformat
|
||||
@@ -32,7 +33,7 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += -lGL `pkg-config --static --libs glfw3`
|
||||
LIBS += $(LINUX_GL_LIBS) -lX11 `pkg-config --static --libs glfw3`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags glfw3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
@@ -40,7 +40,8 @@ int main(int, char**)
|
||||
return 1;
|
||||
|
||||
// Create window with graphics context
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL2 example", nullptr, nullptr);
|
||||
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
|
||||
GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+OpenGL2 example", nullptr, nullptr);
|
||||
if (window == nullptr)
|
||||
return 1;
|
||||
glfwMakeContextCurrent(window);
|
||||
@@ -61,8 +62,14 @@ int main(int, char**)
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
@@ -78,7 +85,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -41,7 +41,7 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3`
|
||||
LIBS += $(LINUX_GL_LIBS) -lX11 `pkg-config --static --libs glfw3`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags glfw3`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
@@ -121,7 +121,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||
//style.FontSizeBase = 20.0f;
|
||||
|
||||
@@ -36,6 +36,7 @@ find_package(Vulkan REQUIRED)
|
||||
#NAMES vulkan vulkan-1)
|
||||
#set(LIBRARIES "glfw;${VULKAN_LIBRARY}")
|
||||
set(LIBRARIES "glfw;Vulkan::Vulkan")
|
||||
# FIXME: Linux needs linking with "X11" as well?
|
||||
|
||||
# Use vulkan headers from glfw:
|
||||
include_directories(${GLFW_DIR}/deps)
|
||||
|
||||
@@ -33,7 +33,7 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += $(LINUX_GL_LIBS) `pkg-config --static --libs glfw3 vulkan`
|
||||
LIBS += $(LINUX_GL_LIBS) -lX11 `pkg-config --static --libs glfw3 vulkan`
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags glfw3 vulkan`
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
@@ -239,7 +239,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
IM_ASSERT(g_MinImageCount >= 2);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0);
|
||||
}
|
||||
|
||||
static void CleanupVulkan()
|
||||
@@ -357,7 +357,8 @@ int main(int, char**)
|
||||
|
||||
// Create window with Vulkan context
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+Vulkan example", nullptr, nullptr);
|
||||
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
|
||||
GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "Dear ImGui GLFW+Vulkan example", nullptr, nullptr);
|
||||
if (!glfwVulkanSupported())
|
||||
{
|
||||
printf("GLFW: Vulkan Not Supported\n");
|
||||
@@ -397,8 +398,14 @@ int main(int, char**)
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
@@ -416,12 +423,12 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
|
||||
init_info.PipelineInfoMain.Subpass = 0;
|
||||
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
@@ -430,7 +437,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -462,7 +469,7 @@ int main(int, char**)
|
||||
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
||||
{
|
||||
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0);
|
||||
g_MainWindowData.FrameIndex = 0;
|
||||
g_SwapChainRebuild = false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for using GLFW + WebGPU
|
||||
// Dear ImGui: standalone example application for GLFW + WebGPU
|
||||
// - Emscripten is supported for publishing on web. See https://emscripten.org.
|
||||
// - Dawn is used as a WebGPU implementation on desktop.
|
||||
|
||||
@@ -12,36 +12,32 @@
|
||||
#include "imgui_impl_glfw.h"
|
||||
#include "imgui_impl_wgpu.h"
|
||||
#include <stdio.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/html5_webgpu.h>
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#else
|
||||
#include <webgpu/webgpu_glfw.h>
|
||||
#endif
|
||||
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <webgpu/webgpu.h>
|
||||
#include <webgpu/webgpu_cpp.h>
|
||||
|
||||
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "../libs/emscripten/emscripten_mainloop_stub.h"
|
||||
#endif
|
||||
|
||||
// Global WebGPU required states
|
||||
// Data
|
||||
static WGPUInstance wgpu_instance = nullptr;
|
||||
static WGPUDevice wgpu_device = nullptr;
|
||||
static WGPUSurface wgpu_surface = nullptr;
|
||||
static WGPUTextureFormat wgpu_preferred_fmt = WGPUTextureFormat_RGBA8Unorm;
|
||||
static WGPUSwapChain wgpu_swap_chain = nullptr;
|
||||
static int wgpu_swap_chain_width = 1280;
|
||||
static int wgpu_swap_chain_height = 720;
|
||||
static int wgpu_surface_width = 1280;
|
||||
static int wgpu_surface_height = 800;
|
||||
|
||||
// Forward declarations
|
||||
static bool InitWGPU(GLFWwindow* window);
|
||||
static void CreateSwapChain(int width, int height);
|
||||
static void ResizeSurface(int width, int height);
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
{
|
||||
@@ -72,19 +68,23 @@ int main(int, char**)
|
||||
// Make sure GLFW does not initialize any graphics context.
|
||||
// This needs to be done explicitly later.
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
GLFWwindow* window = glfwCreateWindow(wgpu_swap_chain_width, wgpu_swap_chain_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
|
||||
|
||||
// Create window
|
||||
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
|
||||
wgpu_surface_width *= main_scale;
|
||||
wgpu_surface_height *= main_scale;
|
||||
GLFWwindow* window = glfwCreateWindow(wgpu_surface_width, wgpu_surface_height, "Dear ImGui GLFW+WebGPU example", nullptr, nullptr);
|
||||
if (window == nullptr)
|
||||
return 1;
|
||||
|
||||
// Initialize the WebGPU environment
|
||||
if (!InitWGPU(window))
|
||||
{
|
||||
if (window)
|
||||
glfwDestroyWindow(window);
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 1;
|
||||
}
|
||||
CreateSwapChain(wgpu_swap_chain_width, wgpu_swap_chain_height);
|
||||
ResizeSurface(wgpu_surface_width, wgpu_surface_height);
|
||||
glfwShowWindow(window);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
@@ -99,6 +99,11 @@ int main(int, char**)
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
@@ -116,17 +121,16 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Emscripten allows preloading a file or folder to be accessible at runtime. See Makefile for details.
|
||||
//io.Fonts->AddFontDefault();
|
||||
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||
//io.Fonts->AddFontFromFileTTF("fonts/segoeui.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("fonts/DroidSans.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("fonts/Roboto-Medium.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("fonts/Cousine-Regular.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("fonts/ProggyTiny.ttf");
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("fonts/ArialUni.ttf");
|
||||
//IM_ASSERT(font != nullptr);
|
||||
#endif
|
||||
@@ -161,10 +165,10 @@ int main(int, char**)
|
||||
// React to changes in screen size
|
||||
int width, height;
|
||||
glfwGetFramebufferSize((GLFWwindow*)window, &width, &height);
|
||||
if (width != wgpu_swap_chain_width || height != wgpu_swap_chain_height)
|
||||
if (width != wgpu_surface_width || height != wgpu_surface_height)
|
||||
{
|
||||
ImGui_ImplWGPU_InvalidateDeviceObjects();
|
||||
CreateSwapChain(width, height);
|
||||
ResizeSurface(width, height);
|
||||
ImGui_ImplWGPU_CreateDeviceObjects();
|
||||
}
|
||||
|
||||
@@ -239,8 +243,8 @@ int main(int, char**)
|
||||
|
||||
WGPUCommandBufferDescriptor cmd_buffer_desc = {};
|
||||
WGPUCommandBuffer cmd_buffer = wgpuCommandEncoderFinish(encoder, &cmd_buffer_desc);
|
||||
WGPUQueue queue = wgpuDeviceGetQueue(wgpu_device);
|
||||
wgpuQueueSubmit(queue, 1, &cmd_buffer);
|
||||
WGPUQueue wgpu_queue = wgpuDeviceGetQueue(wgpu_device);
|
||||
wgpuQueueSubmit(wgpu_queue, 1, &cmd_buffer);
|
||||
|
||||
#ifndef __EMSCRIPTEN__
|
||||
wgpuSwapChainPresent(wgpu_swap_chain);
|
||||
@@ -312,10 +316,10 @@ static bool InitWGPU(GLFWwindow* window)
|
||||
#endif
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
wgpu::SurfaceDescriptorFromCanvasHTMLSelector html_surface_desc = {};
|
||||
html_surface_desc.selector = "#canvas";
|
||||
wgpu::SurfaceDescriptorFromCanvasHTMLSelector canvas_desc = {};
|
||||
canvas_desc.selector = "#canvas";
|
||||
wgpu::SurfaceDescriptor surface_desc = {};
|
||||
surface_desc.nextInChain = &html_surface_desc;
|
||||
surface_desc.nextInChain = &canvas_desc;
|
||||
wgpu::Surface surface = instance.CreateSurface(&surface_desc);
|
||||
|
||||
wgpu::Adapter adapter = {};
|
||||
@@ -327,6 +331,7 @@ static bool InitWGPU(GLFWwindow* window)
|
||||
wgpu_preferred_fmt = WGPUTextureFormat_BGRA8Unorm;
|
||||
#endif
|
||||
|
||||
// Moving Dawn objects into WGPU handles
|
||||
wgpu_instance = instance.MoveToCHandle();
|
||||
wgpu_surface = surface.MoveToCHandle();
|
||||
|
||||
@@ -335,12 +340,12 @@ static bool InitWGPU(GLFWwindow* window)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void CreateSwapChain(int width, int height)
|
||||
static void ResizeSurface(int width, int height)
|
||||
{
|
||||
if (wgpu_swap_chain)
|
||||
wgpuSwapChainRelease(wgpu_swap_chain);
|
||||
wgpu_swap_chain_width = width;
|
||||
wgpu_swap_chain_height = height;
|
||||
wgpu_surface_width = width;
|
||||
wgpu_surface_height = height;
|
||||
WGPUSwapChainDescriptor swap_chain_desc = {};
|
||||
swap_chain_desc.usage = WGPUTextureUsage_RenderAttachment;
|
||||
swap_chain_desc.format = wgpu_preferred_fmt;
|
||||
|
||||
@@ -48,7 +48,7 @@ int main(int argc, char** argv)
|
||||
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
|
||||
#endif
|
||||
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_MULTISAMPLE);
|
||||
glutInitWindowSize(1280, 720);
|
||||
glutInitWindowSize(1280, 800);
|
||||
glutCreateWindow("Dear ImGui GLUT+OpenGL2 Example");
|
||||
|
||||
// Setup GLUT display function
|
||||
@@ -84,7 +84,7 @@ int main(int argc, char** argv)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -39,7 +39,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// From 2.0.18: Enable native IME.
|
||||
@@ -50,11 +50,11 @@ int main(int, char**)
|
||||
// Setup window
|
||||
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+DirectX11 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_SysWMinfo wmInfo;
|
||||
@@ -107,7 +107,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -250,9 +250,19 @@ bool CreateDeviceD3D(HWND hWnd)
|
||||
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
|
||||
if (D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK)
|
||||
HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
|
||||
res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
|
||||
// Disable DXGI's default Alt+Enter fullscreen behavior.
|
||||
// - You are free to leave this enabled, but it will not work properly with multiple viewports.
|
||||
// - This must be done for all windows associated to the device. Our DX11 backend does this automatically for secondary viewports that it creates.
|
||||
IDXGIFactory* pSwapChainFactory;
|
||||
if (SUCCEEDED(g_pSwapChain->GetParent(IID_PPV_ARGS(&pSwapChainFactory))))
|
||||
pSwapChainFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
CreateRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -61,7 +61,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Inform SDL that we will be using metal for rendering. Without this hint initialization of metal renderer may fail.
|
||||
@@ -70,7 +70,7 @@ int main(int, char**)
|
||||
// Enable native IME.
|
||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL+Metal example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 800, SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error creating window: %s\n", SDL_GetError());
|
||||
|
||||
@@ -31,7 +31,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// From 2.0.18: Enable native IME.
|
||||
@@ -47,11 +47,11 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
@@ -96,7 +96,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -36,7 +36,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Decide GL+GLSL versions
|
||||
@@ -81,18 +81,18 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
if (gl_context == nullptr)
|
||||
{
|
||||
printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GL_MakeCurrent(window, gl_context);
|
||||
@@ -136,7 +136,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||
//style.FontSizeBase = 20.0f;
|
||||
|
||||
@@ -33,7 +33,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// From 2.0.18: Enable native IME.
|
||||
@@ -44,17 +44,17 @@ int main(int, char**)
|
||||
// Create window with SDL_Renderer graphics context
|
||||
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
SDL_Log("Error creating SDL_Renderer!");
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
//SDL_RendererInfo info;
|
||||
//SDL_GetRendererInfo(renderer, &info);
|
||||
@@ -88,7 +88,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -230,7 +230,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
IM_ASSERT(g_MinImageCount >= 2);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0);
|
||||
}
|
||||
|
||||
static void CleanupVulkan()
|
||||
@@ -349,7 +349,7 @@ int main(int, char**)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
|
||||
{
|
||||
printf("Error: %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// From 2.0.18: Enable native IME.
|
||||
@@ -360,11 +360,11 @@ int main(int, char**)
|
||||
// Create window with Vulkan graphics context
|
||||
float main_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(0);
|
||||
SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ImVector<const char*> extensions;
|
||||
@@ -429,12 +429,12 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
|
||||
init_info.PipelineInfoMain.Subpass = 0;
|
||||
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
@@ -443,7 +443,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -489,7 +489,7 @@ int main(int, char**)
|
||||
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
||||
{
|
||||
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0);
|
||||
g_MainWindowData.FrameIndex = 0;
|
||||
g_SwapChainRebuild = false;
|
||||
}
|
||||
|
||||
8
examples/example_sdl3_directx11/build_win32.bat
Normal file
8
examples/example_sdl3_directx11/build_win32.bat
Normal file
@@ -0,0 +1,8 @@
|
||||
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
|
||||
@set OUT_DIR=Debug
|
||||
@set OUT_EXE=example_sdl3_directx11
|
||||
@set INCLUDES=/I..\.. /I..\..\backends /I%SDL3_DIR%\include /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" /I "%DXSDK_DIR%Include"
|
||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_sdl3.cpp ..\..\backends\imgui_impl_dx11.cpp ..\..\imgui*.cpp
|
||||
@set LIBS=/LIBPATH:%SDL3_DIR%\lib\x86 SDL3.lib /LIBPATH:"%DXSDK_DIR%/Lib/x86" d3d11.lib d3dcompiler.lib shell32.lib
|
||||
mkdir %OUT_DIR%
|
||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console
|
||||
187
examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj
Normal file
187
examples/example_sdl3_directx11/example_sdl3_directx11.vcxproj
Normal file
@@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{009DAC16-1A9C-47BE-9770-A30A046E8090}</ProjectGuid>
|
||||
<RootNamespace>example_sdl3_directx11</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
<ProjectName>example_sdl3_directx11</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(ProjectDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(ProjectDir)$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>msvcrt.lib</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x86;$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalLibraryDirectories>%SDL3_DIR%\lib\x64;$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>SDL3.lib;d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<IgnoreSpecificDefaultLibraries>
|
||||
</IgnoreSpecificDefaultLibraries>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp" />
|
||||
<ClCompile Include="..\..\imgui_demo.cpp" />
|
||||
<ClCompile Include="..\..\imgui_draw.cpp" />
|
||||
<ClCompile Include="..\..\imgui_tables.cpp" />
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp" />
|
||||
<ClCompile Include="..\..\backends\imgui_impl_dx11.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h" />
|
||||
<ClInclude Include="..\..\imgui.h" />
|
||||
<ClInclude Include="..\..\imgui_internal.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h" />
|
||||
<ClInclude Include="..\..\backends\imgui_impl_dx11.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\misc\debuggers\imgui.natstepfilter" />
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis" />
|
||||
<None Include="..\README.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="imgui">
|
||||
<UniqueIdentifier>{0587d7a3-f2ce-4d56-b84f-a0005d3bfce6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="sources">
|
||||
<UniqueIdentifier>{08e36723-ce4f-4cff-9662-c40801cf1acf}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\imconfig.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\imgui_internal.h">
|
||||
<Filter>imgui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_sdl3.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\backends\imgui_impl_dx11.h">
|
||||
<Filter>sources</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\imgui.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_demo.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_draw.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_tables.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\imgui_widgets.cpp">
|
||||
<Filter>imgui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_sdl3.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\backends\imgui_impl_dx11.cpp">
|
||||
<Filter>sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\README.txt" />
|
||||
<None Include="..\..\misc\debuggers\imgui.natvis">
|
||||
<Filter>imgui</Filter>
|
||||
</None>
|
||||
<None Include="..\..\misc\debuggers\imgui.natstepfilter">
|
||||
<Filter>imgui</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
284
examples/example_sdl3_directx11/main.cpp
Normal file
284
examples/example_sdl3_directx11/main.cpp
Normal file
@@ -0,0 +1,284 @@
|
||||
// Dear ImGui: standalone example application for SDL3 + DirectX 11
|
||||
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
#include <d3d11.h>
|
||||
#include <stdio.h> // printf
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
// Data
|
||||
static ID3D11Device* g_pd3dDevice = nullptr;
|
||||
static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr;
|
||||
static IDXGISwapChain* g_pSwapChain = nullptr;
|
||||
static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr;
|
||||
|
||||
// Forward declarations of helper functions
|
||||
bool CreateDeviceD3D(HWND hWnd);
|
||||
void CleanupDeviceD3D();
|
||||
void CreateRenderTarget();
|
||||
void CleanupRenderTarget();
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Setup window
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+DirectX11 example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_PropertiesID props = SDL_GetWindowProperties(window);
|
||||
HWND hwnd = (HWND)SDL_GetPointerProperty(props, SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||
|
||||
// Initialize Direct3D
|
||||
if (!CreateDeviceD3D(hwnd))
|
||||
{
|
||||
CleanupDeviceD3D();
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
||||
}
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplSDL3_InitForD3D(window);
|
||||
ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext);
|
||||
|
||||
// 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||
//IM_ASSERT(font != nullptr);
|
||||
|
||||
// Our state
|
||||
bool show_demo_window = true;
|
||||
bool show_another_window = false;
|
||||
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||
|
||||
// Main loop
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
// 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, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_RESIZED && event.window.windowID == SDL_GetWindowID(window))
|
||||
{
|
||||
// Release all outstanding references to the swap chain's buffers before resizing.
|
||||
CleanupRenderTarget();
|
||||
g_pSwapChain->ResizeBuffers(0, 0, 0, DXGI_FORMAT_UNKNOWN, 0);
|
||||
CreateRenderTarget();
|
||||
}
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
||||
if (show_demo_window)
|
||||
ImGui::ShowDemoWindow(&show_demo_window);
|
||||
|
||||
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
||||
{
|
||||
static float f = 0.0f;
|
||||
static int counter = 0;
|
||||
|
||||
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
||||
|
||||
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
||||
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
||||
ImGui::Checkbox("Another Window", &show_another_window);
|
||||
|
||||
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
|
||||
|
||||
if (ImGui::Button("Button")) // Buttons return true when clicked (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 / io.Framerate, io.Framerate);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show another simple window.
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
||||
ImGui::Text("Hello from another window!");
|
||||
if (ImGui::Button("Close Me"))
|
||||
show_another_window = false;
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w };
|
||||
g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr);
|
||||
g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha);
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
// Update and Render additional Platform Windows
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
ImGui::UpdatePlatformWindows();
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
CleanupDeviceD3D();
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Helper functions to use DirectX11
|
||||
bool CreateDeviceD3D(HWND hWnd)
|
||||
{
|
||||
// Setup swap chain
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
ZeroMemory(&sd, sizeof(sd));
|
||||
sd.BufferCount = 2;
|
||||
sd.BufferDesc.Width = 0;
|
||||
sd.BufferDesc.Height = 0;
|
||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
sd.BufferDesc.RefreshRate.Numerator = 60;
|
||||
sd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
sd.OutputWindow = hWnd;
|
||||
sd.SampleDesc.Count = 1;
|
||||
sd.SampleDesc.Quality = 0;
|
||||
sd.Windowed = TRUE;
|
||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
|
||||
UINT createDeviceFlags = 0;
|
||||
//createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
D3D_FEATURE_LEVEL featureLevel;
|
||||
const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, };
|
||||
HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available.
|
||||
res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext);
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
|
||||
// Disable DXGI's default Alt+Enter fullscreen behavior.
|
||||
// - You are free to leave this enabled, but it will not work properly with multiple viewports.
|
||||
// - This must be done for all windows associated to the device. Our DX11 backend does this automatically for secondary viewports that it creates.
|
||||
IDXGIFactory* pSwapChainFactory;
|
||||
if (SUCCEEDED(g_pSwapChain->GetParent(IID_PPV_ARGS(&pSwapChainFactory))))
|
||||
pSwapChainFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
CreateRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CleanupDeviceD3D()
|
||||
{
|
||||
CleanupRenderTarget();
|
||||
if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; }
|
||||
if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; }
|
||||
if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; }
|
||||
}
|
||||
|
||||
void CreateRenderTarget()
|
||||
{
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||
g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView);
|
||||
pBackBuffer->Release();
|
||||
}
|
||||
|
||||
void CleanupRenderTarget()
|
||||
{
|
||||
if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; }
|
||||
}
|
||||
48
examples/example_sdl3_metal/Makefile
Normal file
48
examples/example_sdl3_metal/Makefile
Normal file
@@ -0,0 +1,48 @@
|
||||
#
|
||||
# You will need SDL3 (http://www.libsdl.org):
|
||||
# brew install sdl3
|
||||
#
|
||||
|
||||
#CXX = g++
|
||||
#CXX = clang++
|
||||
|
||||
EXE = example_sdl3_metal
|
||||
IMGUI_DIR = ../..
|
||||
SOURCES = main.mm
|
||||
SOURCES += $(IMGUI_DIR)/imgui.cpp $(IMGUI_DIR)/imgui_demo.cpp $(IMGUI_DIR)/imgui_draw.cpp $(IMGUI_DIR)/imgui_tables.cpp $(IMGUI_DIR)/imgui_widgets.cpp
|
||||
SOURCES += $(IMGUI_DIR)/backends/imgui_impl_sdl3.cpp $(IMGUI_DIR)/backends/imgui_impl_metal.mm
|
||||
OBJS = $(addsuffix .o, $(basename $(notdir $(SOURCES))))
|
||||
|
||||
LIBS = -framework Metal -framework MetalKit -framework Cocoa -framework IOKit -framework CoreVideo -framework QuartzCore
|
||||
LIBS += `pkg-config --libs sdl3`
|
||||
LIBS += -L/usr/local/lib -L/opt/local/lib
|
||||
|
||||
CXXFLAGS += `pkg-config --cflags sdl3`
|
||||
CXXFLAGS += -I/usr/local/include -I/opt/local/include
|
||||
CXXFLAGS += -std=c++11 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -Wall -Wformat
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
|
||||
%.o:%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
%.o:$(IMGUI_DIR)/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
%.o:$(IMGUI_DIR)/backends/%.cpp
|
||||
$(CXX) $(CXXFLAGS) -c -o $@ $<
|
||||
|
||||
%.o:%.mm
|
||||
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
|
||||
|
||||
%.o:$(IMGUI_DIR)/backends/%.mm
|
||||
$(CXX) $(CXXFLAGS) -ObjC++ -fobjc-weak -fobjc-arc -c -o $@ $<
|
||||
|
||||
all: $(EXE)
|
||||
@echo Build complete
|
||||
|
||||
$(EXE): $(OBJS)
|
||||
$(CXX) -o $@ $^ $(CXXFLAGS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(EXE) $(OBJS)
|
||||
208
examples/example_sdl3_metal/main.mm
Normal file
208
examples/example_sdl3_metal/main.mm
Normal file
@@ -0,0 +1,208 @@
|
||||
// Dear ImGui: standalone example application for SDL3 + Metal
|
||||
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
// - Getting Started https://dearimgui.com/getting-started
|
||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||
// - Introduction, links and more at the top of imgui.cpp
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_sdl3.h"
|
||||
#include "imgui_impl_metal.h"
|
||||
#include <stdio.h> // printf, fprintf
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Setup SDL
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below until the main loop starts would likely be your SDL_AppInit() function]
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create SDL window graphics context
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_METAL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Metal example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
|
||||
// Create Metal device _before_ creating the view/layer
|
||||
id<MTLDevice> metalDevice = MTLCreateSystemDefaultDevice();
|
||||
if (!metalDevice)
|
||||
{
|
||||
printf("Error: failed to create Metal device.\n");
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
SDL_MetalView view = SDL_Metal_CreateView(window);
|
||||
CAMetalLayer* layer = (__bridge CAMetalLayer*)SDL_Metal_GetLayer(view);
|
||||
layer.device = metalDevice;
|
||||
layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
|
||||
|
||||
id<MTLCommandQueue> commandQueue = [layer.device newCommandQueue];
|
||||
MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor new];
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||
|
||||
// Setup Dear ImGui style
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
|
||||
// Setup Platform/Renderer backends
|
||||
ImGui_ImplMetal_Init(layer.device);
|
||||
ImGui_ImplSDL3_InitForMetal(window);
|
||||
|
||||
// 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
|
||||
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
|
||||
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
|
||||
//IM_ASSERT(font != nullptr);
|
||||
|
||||
// Our state
|
||||
bool show_demo_window = true;
|
||||
bool show_another_window = false;
|
||||
float clear_color[4] = { 0.45f, 0.55f, 0.60f, 1.00f };
|
||||
|
||||
// Main loop
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
@autoreleasepool
|
||||
{
|
||||
// Poll and handle events (inputs, window resize, etc.)
|
||||
// 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, or clear/overwrite your copy of the mouse data.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
|
||||
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: call ImGui_ImplSDL3_ProcessEvent() from your SDL_AppEvent() function]
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
||||
if (event.type == SDL_EVENT_QUIT)
|
||||
done = true;
|
||||
if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window))
|
||||
done = true;
|
||||
}
|
||||
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppIterate() function]
|
||||
if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED)
|
||||
{
|
||||
SDL_Delay(10);
|
||||
continue;
|
||||
}
|
||||
|
||||
int width, height;
|
||||
SDL_GetWindowSizeInPixels(window, &width, &height);
|
||||
|
||||
layer.drawableSize = CGSizeMake(width, height);
|
||||
id<CAMetalDrawable> drawable = [layer nextDrawable];
|
||||
|
||||
id<MTLCommandBuffer> commandBuffer = [commandQueue commandBuffer];
|
||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clear_color[0] * clear_color[3], clear_color[1] * clear_color[3], clear_color[2] * clear_color[3], clear_color[3]);
|
||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
||||
renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore;
|
||||
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
||||
[renderEncoder pushDebugGroup:@"ImGui demo"];
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplMetal_NewFrame(renderPassDescriptor);
|
||||
ImGui_ImplSDL3_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).
|
||||
if (show_demo_window)
|
||||
ImGui::ShowDemoWindow(&show_demo_window);
|
||||
|
||||
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
|
||||
{
|
||||
static float f = 0.0f;
|
||||
static int counter = 0;
|
||||
|
||||
ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it.
|
||||
|
||||
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too)
|
||||
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
|
||||
ImGui::Checkbox("Another Window", &show_another_window);
|
||||
|
||||
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
|
||||
|
||||
if (ImGui::Button("Button")) // Buttons return true when clicked (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 / io.Framerate, io.Framerate);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// 3. Show another simple window.
|
||||
if (show_another_window)
|
||||
{
|
||||
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
|
||||
ImGui::Text("Hello from another window!");
|
||||
if (ImGui::Button("Close Me"))
|
||||
show_another_window = false;
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
ImGui_ImplMetal_RenderDrawData(draw_data, commandBuffer, renderEncoder);
|
||||
|
||||
[renderEncoder popDebugGroup];
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
[commandBuffer presentDrawable:drawable];
|
||||
[commandBuffer commit];
|
||||
}
|
||||
}
|
||||
|
||||
// Cleanup
|
||||
// [If using SDL_MAIN_USE_CALLBACKS: all code below would likely be your SDL_AppQuit() function]
|
||||
ImGui_ImplMetal_Shutdown();
|
||||
ImGui_ImplSDL3_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_Quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -30,7 +30,7 @@ int main(int, char**)
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Decide GL+GLSL versions
|
||||
@@ -70,17 +70,17 @@ int main(int, char**)
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+OpenGL3 example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
|
||||
if (gl_context == nullptr)
|
||||
{
|
||||
printf("Error: SDL_GL_CreateContext(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GL_MakeCurrent(window, gl_context);
|
||||
@@ -126,7 +126,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||
//style.FontSizeBase = 20.0f;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// Dear ImGui: standalone example application for SDL3 + SDL_GPU
|
||||
// (SDL is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -30,17 +31,17 @@ int main(int, char**)
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create SDL window graphics context
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_GPU example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_GPU example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
@@ -50,16 +51,16 @@ int main(int, char**)
|
||||
if (gpu_device == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateGPUDevice(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Claim window for GPU Device
|
||||
if (!SDL_ClaimWindowForGPUDevice(gpu_device, window))
|
||||
{
|
||||
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_MAILBOX);
|
||||
SDL_SetGPUSwapchainParameters(gpu_device, window, SDL_GPU_SWAPCHAINCOMPOSITION_SDR, SDL_GPU_PRESENTMODE_VSYNC);
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
@@ -93,7 +94,9 @@ int main(int, char**)
|
||||
ImGui_ImplSDLGPU3_InitInfo init_info = {};
|
||||
init_info.Device = gpu_device;
|
||||
init_info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpu_device, window);
|
||||
init_info.MSAASamples = SDL_GPU_SAMPLECOUNT_1;
|
||||
init_info.MSAASamples = SDL_GPU_SAMPLECOUNT_1; // Only used in multi-viewports mode.
|
||||
init_info.SwapchainComposition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR; // Only used in multi-viewports mode.
|
||||
init_info.PresentMode = SDL_GPU_PRESENTMODE_VSYNC;
|
||||
ImGui_ImplSDLGPU3_Init(&init_info);
|
||||
|
||||
// Load Fonts
|
||||
@@ -101,7 +104,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -165,7 +168,7 @@ int main(int, char**)
|
||||
ImGui::Checkbox("Another Window", &show_another_window);
|
||||
|
||||
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
|
||||
ImGui::ColorEdit4("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
|
||||
|
||||
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
|
||||
counter++;
|
||||
@@ -194,7 +197,7 @@ int main(int, char**)
|
||||
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); // Acquire a GPU command buffer
|
||||
|
||||
SDL_GPUTexture* swapchain_texture;
|
||||
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture
|
||||
SDL_WaitAndAcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture
|
||||
|
||||
if (swapchain_texture != nullptr && !is_minimized)
|
||||
{
|
||||
|
||||
@@ -28,24 +28,24 @@ int main(int, char**)
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create window with SDL_Renderer graphics context
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_Renderer example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_Renderer* renderer = SDL_CreateRenderer(window, nullptr);
|
||||
SDL_SetRenderVSync(renderer, 1);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
@@ -78,7 +78,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
|
||||
//style.FontSizeBase = 20.0f;
|
||||
|
||||
@@ -232,7 +232,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
IM_ASSERT(g_MinImageCount >= 2);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0);
|
||||
}
|
||||
|
||||
static void CleanupVulkan()
|
||||
@@ -349,17 +349,17 @@ int main(int, char**)
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD))
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create window with Vulkan graphics context
|
||||
float main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
|
||||
SDL_WindowFlags window_flags = SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Vulkan example", (int)(1280 * main_scale), (int)(720 * main_scale), window_flags);
|
||||
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+Vulkan example", (int)(1280 * main_scale), (int)(800 * main_scale), window_flags);
|
||||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ImVector<const char*> extensions;
|
||||
@@ -428,12 +428,12 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
|
||||
init_info.PipelineInfoMain.Subpass = 0;
|
||||
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
@@ -442,7 +442,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -491,7 +491,7 @@ int main(int, char**)
|
||||
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
||||
{
|
||||
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, fb_height, fb_height, g_MinImageCount, 0);
|
||||
g_MainWindowData.FrameIndex = 0;
|
||||
g_SwapChainRebuild = false;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for DirectX 10
|
||||
// Dear ImGui: standalone example application for Windows API + DirectX 10
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -89,7 +89,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -241,6 +241,13 @@ bool CreateDeviceD3D(HWND hWnd)
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
|
||||
// Disable DXGI's default Alt+Enter fullscreen behavior.
|
||||
// - You are free to leave this enabled, but it will not work properly with multiple viewports.
|
||||
// - This must be done for all windows associated to the device. Our DX11 backend does this automatically for secondary viewports that it creates.
|
||||
IDXGIFactory* pSwapChainFactory;
|
||||
if (SUCCEEDED(g_pSwapChain->GetParent(IID_PPV_ARGS(&pSwapChainFactory))))
|
||||
pSwapChainFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
CreateRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for DirectX 11
|
||||
// Dear ImGui: standalone example application for Windows API + DirectX 11
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -61,7 +61,6 @@ int main(int, char**)
|
||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
||||
//io.ConfigViewportsNoAutoMerge = true;
|
||||
//io.ConfigViewportsNoTaskBarIcon = true;
|
||||
//io.ConfigViewportsNoDefaultParent = true;
|
||||
//io.ConfigDockingAlwaysTabBar = true;
|
||||
//io.ConfigDockingTransparentPayload = true;
|
||||
|
||||
@@ -92,7 +91,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -246,6 +245,13 @@ bool CreateDeviceD3D(HWND hWnd)
|
||||
if (res != S_OK)
|
||||
return false;
|
||||
|
||||
// Disable DXGI's default Alt+Enter fullscreen behavior.
|
||||
// - You are free to leave this enabled, but it will not work properly with multiple viewports.
|
||||
// - This must be done for all windows associated to the device. Our DX11 backend does this automatically for secondary viewports that it creates.
|
||||
IDXGIFactory* pSwapChainFactory;
|
||||
if (SUCCEEDED(g_pSwapChain->GetParent(IID_PPV_ARGS(&pSwapChainFactory))))
|
||||
pSwapChainFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
CreateRenderTarget();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for DirectX 12
|
||||
// Dear ImGui: standalone example application for Windows API + DirectX 12
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "imgui_impl_win32.h"
|
||||
#include "imgui_impl_dx12.h"
|
||||
#include <d3d12.h>
|
||||
#include <dxgi1_4.h>
|
||||
#include <dxgi1_5.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#ifdef _DEBUG
|
||||
@@ -92,6 +92,7 @@ static ID3D12Fence* g_fence = nullptr;
|
||||
static HANDLE g_fenceEvent = nullptr;
|
||||
static UINT64 g_fenceLastSignaledValue = 0;
|
||||
static IDXGISwapChain3* g_pSwapChain = nullptr;
|
||||
static bool g_SwapChainTearingSupport = false;
|
||||
static bool g_SwapChainOccluded = false;
|
||||
static HANDLE g_hSwapChainWaitableObject = nullptr;
|
||||
static ID3D12Resource* g_mainRenderTargetResource[APP_NUM_BACK_BUFFERS] = {};
|
||||
@@ -102,8 +103,8 @@ bool CreateDeviceD3D(HWND hWnd);
|
||||
void CleanupDeviceD3D();
|
||||
void CreateRenderTarget();
|
||||
void CleanupRenderTarget();
|
||||
void WaitForLastSubmittedFrame();
|
||||
FrameContext* WaitForNextFrameResources();
|
||||
void WaitForPendingOperations();
|
||||
FrameContext* WaitForNextFrameContext();
|
||||
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// Main code
|
||||
@@ -183,7 +184,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -269,7 +270,7 @@ int main(int, char**)
|
||||
// Rendering
|
||||
ImGui::Render();
|
||||
|
||||
FrameContext* frameCtx = WaitForNextFrameResources();
|
||||
FrameContext* frameCtx = WaitForNextFrameContext();
|
||||
UINT backBufferIdx = g_pSwapChain->GetCurrentBackBufferIndex();
|
||||
frameCtx->CommandAllocator->Reset();
|
||||
|
||||
@@ -303,18 +304,17 @@ int main(int, char**)
|
||||
ImGui::RenderPlatformWindowsDefault();
|
||||
}
|
||||
|
||||
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
|
||||
frameCtx->FenceValue = g_fenceLastSignaledValue;
|
||||
|
||||
// Present
|
||||
HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync
|
||||
//HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync
|
||||
//HRESULT hr = g_pSwapChain->Present(0, g_SwapChainTearingSupport ? DXGI_PRESENT_ALLOW_TEARING : 0); // Present without vsync
|
||||
g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED);
|
||||
|
||||
UINT64 fenceValue = g_fenceLastSignaledValue + 1;
|
||||
g_pd3dCommandQueue->Signal(g_fence, fenceValue);
|
||||
g_fenceLastSignaledValue = fenceValue;
|
||||
frameCtx->FenceValue = fenceValue;
|
||||
g_frameIndex++;
|
||||
}
|
||||
|
||||
WaitForLastSubmittedFrame();
|
||||
WaitForPendingOperations();
|
||||
|
||||
// Cleanup
|
||||
ImGui_ImplDX12_Shutdown();
|
||||
@@ -428,14 +428,24 @@ bool CreateDeviceD3D(HWND hWnd)
|
||||
return false;
|
||||
|
||||
{
|
||||
IDXGIFactory4* dxgiFactory = nullptr;
|
||||
IDXGIFactory5* dxgiFactory = nullptr;
|
||||
IDXGISwapChain1* swapChain1 = nullptr;
|
||||
if (CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory)) != S_OK)
|
||||
return false;
|
||||
|
||||
BOOL allow_tearing = FALSE;
|
||||
dxgiFactory->CheckFeatureSupport(DXGI_FEATURE_PRESENT_ALLOW_TEARING, &allow_tearing, sizeof(allow_tearing));
|
||||
g_SwapChainTearingSupport = (allow_tearing == TRUE);
|
||||
if (g_SwapChainTearingSupport)
|
||||
sd.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
||||
|
||||
if (dxgiFactory->CreateSwapChainForHwnd(g_pd3dCommandQueue, hWnd, &sd, nullptr, nullptr, &swapChain1) != S_OK)
|
||||
return false;
|
||||
if (swapChain1->QueryInterface(IID_PPV_ARGS(&g_pSwapChain)) != S_OK)
|
||||
return false;
|
||||
if (g_SwapChainTearingSupport)
|
||||
dxgiFactory->MakeWindowAssociation(hWnd, DXGI_MWA_NO_ALT_ENTER);
|
||||
|
||||
swapChain1->Release();
|
||||
dxgiFactory->Release();
|
||||
g_pSwapChain->SetMaximumFrameLatency(APP_NUM_BACK_BUFFERS);
|
||||
@@ -484,49 +494,33 @@ void CreateRenderTarget()
|
||||
|
||||
void CleanupRenderTarget()
|
||||
{
|
||||
WaitForLastSubmittedFrame();
|
||||
WaitForPendingOperations();
|
||||
|
||||
for (UINT i = 0; i < APP_NUM_BACK_BUFFERS; i++)
|
||||
if (g_mainRenderTargetResource[i]) { g_mainRenderTargetResource[i]->Release(); g_mainRenderTargetResource[i] = nullptr; }
|
||||
}
|
||||
|
||||
void WaitForLastSubmittedFrame()
|
||||
void WaitForPendingOperations()
|
||||
{
|
||||
FrameContext* frameCtx = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
||||
g_pd3dCommandQueue->Signal(g_fence, ++g_fenceLastSignaledValue);
|
||||
|
||||
UINT64 fenceValue = frameCtx->FenceValue;
|
||||
if (fenceValue == 0)
|
||||
return; // No fence was signaled
|
||||
|
||||
frameCtx->FenceValue = 0;
|
||||
if (g_fence->GetCompletedValue() >= fenceValue)
|
||||
return;
|
||||
|
||||
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
|
||||
WaitForSingleObject(g_fenceEvent, INFINITE);
|
||||
g_fence->SetEventOnCompletion(g_fenceLastSignaledValue, g_fenceEvent);
|
||||
::WaitForSingleObject(g_fenceEvent, INFINITE);
|
||||
}
|
||||
|
||||
FrameContext* WaitForNextFrameResources()
|
||||
FrameContext* WaitForNextFrameContext()
|
||||
{
|
||||
UINT nextFrameIndex = g_frameIndex + 1;
|
||||
g_frameIndex = nextFrameIndex;
|
||||
|
||||
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, nullptr };
|
||||
DWORD numWaitableObjects = 1;
|
||||
|
||||
FrameContext* frameCtx = &g_frameContext[nextFrameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
||||
UINT64 fenceValue = frameCtx->FenceValue;
|
||||
if (fenceValue != 0) // means no fence was signaled
|
||||
FrameContext* frame_context = &g_frameContext[g_frameIndex % APP_NUM_FRAMES_IN_FLIGHT];
|
||||
if (g_fence->GetCompletedValue() < frame_context->FenceValue)
|
||||
{
|
||||
frameCtx->FenceValue = 0;
|
||||
g_fence->SetEventOnCompletion(fenceValue, g_fenceEvent);
|
||||
waitableObjects[1] = g_fenceEvent;
|
||||
numWaitableObjects = 2;
|
||||
g_fence->SetEventOnCompletion(frame_context->FenceValue, g_fenceEvent);
|
||||
HANDLE waitableObjects[] = { g_hSwapChainWaitableObject, g_fenceEvent };
|
||||
::WaitForMultipleObjects(2, waitableObjects, TRUE, INFINITE);
|
||||
}
|
||||
else
|
||||
::WaitForSingleObject(g_hSwapChainWaitableObject, INFINITE);
|
||||
|
||||
WaitForMultipleObjects(numWaitableObjects, waitableObjects, TRUE, INFINITE);
|
||||
|
||||
return frameCtx;
|
||||
return frame_context;
|
||||
}
|
||||
|
||||
// Forward declare message handler from imgui_impl_win32.cpp
|
||||
@@ -547,9 +541,10 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
case WM_SIZE:
|
||||
if (g_pd3dDevice != nullptr && wParam != SIZE_MINIMIZED)
|
||||
{
|
||||
WaitForLastSubmittedFrame();
|
||||
CleanupRenderTarget();
|
||||
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), DXGI_FORMAT_UNKNOWN, DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT);
|
||||
DXGI_SWAP_CHAIN_DESC1 desc = {};
|
||||
g_pSwapChain->GetDesc1(&desc);
|
||||
HRESULT result = g_pSwapChain->ResizeBuffers(0, (UINT)LOWORD(lParam), (UINT)HIWORD(lParam), desc.Format, desc.Flags);
|
||||
assert(SUCCEEDED(result) && "Failed to resize swapchain.");
|
||||
CreateRenderTarget();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for DirectX 9
|
||||
// Dear ImGui: standalone example application for Windows API + DirectX 9
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -87,7 +87,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for Win32 + OpenGL 3
|
||||
// Dear ImGui: standalone example application for Windows API + OpenGL
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -15,7 +15,7 @@
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <GL/GL.h>
|
||||
#include <GL/gl.h>
|
||||
#include <tchar.h>
|
||||
|
||||
// Data stored per platform window
|
||||
@@ -72,11 +72,14 @@ static void Hook_Renderer_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Make process DPI aware and obtain main monitor scale
|
||||
//ImGui_ImplWin32_EnableDpiAwareness(); // FIXME: This somehow doesn't work in the Win32+OpenGL example. Why?
|
||||
float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
|
||||
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEXW wc = { sizeof(wc), CS_OWNDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr };
|
||||
::RegisterClassExW(&wc);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+OpenGL3 Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr);
|
||||
|
||||
// Initialize OpenGL
|
||||
if (!CreateDeviceWGL(hwnd, &g_MainWindow))
|
||||
@@ -105,8 +108,14 @@ int main(int, char**)
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsClassic();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
@@ -136,7 +145,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Dear ImGui: standalone example application for Win32 + Vulkan
|
||||
// Dear ImGui: standalone example application for Windows API + Vulkan
|
||||
|
||||
// Learn about Dear ImGui:
|
||||
// - FAQ https://dearimgui.com/faq
|
||||
@@ -228,7 +228,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface
|
||||
|
||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
||||
IM_ASSERT(g_MinImageCount >= 2);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount, 0);
|
||||
}
|
||||
|
||||
static void CleanupVulkan()
|
||||
@@ -352,11 +352,14 @@ static int ImGui_ImplWin32_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_ins
|
||||
// Main code
|
||||
int main(int, char**)
|
||||
{
|
||||
// Make process DPI aware and obtain main monitor scale
|
||||
ImGui_ImplWin32_EnableDpiAwareness();
|
||||
float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY));
|
||||
|
||||
// Create application window
|
||||
//ImGui_ImplWin32_EnableDpiAwareness();
|
||||
WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr };
|
||||
::RegisterClassExW(&wc);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, 1280, 800, nullptr, nullptr, wc.hInstance, nullptr);
|
||||
HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui Win32+Vulkan Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr);
|
||||
|
||||
ImVector<const char*> extensions;
|
||||
extensions.push_back("VK_KHR_surface");
|
||||
@@ -379,7 +382,7 @@ int main(int, char**)
|
||||
// Show the window
|
||||
// FIXME: Retrieve client size from window itself.
|
||||
ImGui_ImplVulkanH_Window* wd = &g_MainWindowData;
|
||||
SetupVulkanWindow(wd, surface, 1280, 800);
|
||||
SetupVulkanWindow(wd, surface, (int)(1280 * main_scale), (int)(800 * main_scale));
|
||||
::ShowWindow(hwnd, SW_SHOWDEFAULT);
|
||||
::UpdateWindow(hwnd);
|
||||
|
||||
@@ -398,8 +401,14 @@ int main(int, char**)
|
||||
ImGui::StyleColorsDark();
|
||||
//ImGui::StyleColorsLight();
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
// Setup scaling
|
||||
ImGuiStyle& style = ImGui::GetStyle();
|
||||
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
|
||||
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
|
||||
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
|
||||
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
|
||||
|
||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
||||
{
|
||||
style.WindowRounding = 0.0f;
|
||||
@@ -419,12 +428,12 @@ int main(int, char**)
|
||||
init_info.Queue = g_Queue;
|
||||
init_info.PipelineCache = g_PipelineCache;
|
||||
init_info.DescriptorPool = g_DescriptorPool;
|
||||
init_info.RenderPass = wd->RenderPass;
|
||||
init_info.Subpass = 0;
|
||||
init_info.MinImageCount = g_MinImageCount;
|
||||
init_info.ImageCount = wd->ImageCount;
|
||||
init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.Allocator = g_Allocator;
|
||||
init_info.PipelineInfoMain.RenderPass = wd->RenderPass;
|
||||
init_info.PipelineInfoMain.Subpass = 0;
|
||||
init_info.PipelineInfoMain.MSAASamples = VK_SAMPLE_COUNT_1_BIT;
|
||||
init_info.CheckVkResultFn = check_vk_result;
|
||||
ImGui_ImplVulkan_Init(&init_info);
|
||||
|
||||
@@ -433,7 +442,7 @@ int main(int, char**)
|
||||
// - 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 a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
|
||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||
// - Read 'docs/FONTS.md' for more instructions and details. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author!
|
||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||
//style.FontSizeBase = 20.0f;
|
||||
//io.Fonts->AddFontDefault();
|
||||
@@ -573,7 +582,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height))
|
||||
{
|
||||
ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount);
|
||||
ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount, 0);
|
||||
g_MainWindowData.FrameIndex = 0;
|
||||
g_SwapChainRebuild = false;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_vulkan", "exa
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_sdlgpu3", "example_sdl3_sdlgpu3\example_sdl3_sdlgpu3.vcxproj", "{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_sdl3_directx11", "example_sdl3_directx11\example_sdl3_directx11.vcxproj", "{009DAC16-1A9C-47BE-9770-A30A046E8090}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
@@ -191,6 +193,14 @@ Global
|
||||
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|Win32.Build.0 = Release|Win32
|
||||
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|x64.ActiveCfg = Release|x64
|
||||
{C22CB6F8-39A5-4DDA-90ED-4ACA4E81E1E5}.Release|x64.Build.0 = Release|x64
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Debug|x64.Build.0 = Debug|x64
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|Win32.Build.0 = Release|Win32
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|x64.ActiveCfg = Release|x64
|
||||
{009DAC16-1A9C-47BE-9770-A30A046E8090}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -83,6 +83,7 @@
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// Note that imgui_freetype.cpp may be used _without_ this define, if you manually call ImFontAtlas::SetFontLoader(). The define is simply a convenience.
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
|
||||
194
imgui.h
194
imgui.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.4
|
||||
// (headers)
|
||||
|
||||
// Help:
|
||||
@@ -28,8 +28,8 @@
|
||||
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.92.1"
|
||||
#define IMGUI_VERSION_NUM 19210
|
||||
#define IMGUI_VERSION "1.92.4"
|
||||
#define IMGUI_VERSION_NUM 19240
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||
@@ -102,8 +102,10 @@ Index of this file:
|
||||
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
|
||||
|
||||
// Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions.
|
||||
// (MSVC provides an equivalent mechanism via SAL Annotations but it would require the macros in a different
|
||||
// location. e.g. #include <sal.h> + void myprintf(_Printf_format_string_ const char* format, ...))
|
||||
// (MSVC provides an equivalent mechanism via SAL Annotations but it requires the macros in a different
|
||||
// location. e.g. #include <sal.h> + void myprintf(_Printf_format_string_ const char* format, ...),
|
||||
// and only works when using Code Analysis, rather than just normal compiling).
|
||||
// (see https://github.com/ocornut/imgui/issues/8871 for a patch to enable this for MSVC's Code Analysis)
|
||||
#if !defined(IMGUI_USE_STB_SPRINTF) && defined(__MINGW32__) && !defined(__clang__)
|
||||
#define IM_FMTARGS(FMT) __attribute__((format(gnu_printf, FMT, FMT+1)))
|
||||
#define IM_FMTLIST(FMT) __attribute__((format(gnu_printf, FMT, 0)))
|
||||
@@ -235,6 +237,7 @@ typedef int ImGuiTableBgTarget; // -> enum ImGuiTableBgTarget_ // Enum: A
|
||||
// - In VS Code, CLion, etc.: CTRL+click can follow symbols inside comments.
|
||||
typedef int ImDrawFlags; // -> enum ImDrawFlags_ // Flags: for ImDrawList functions
|
||||
typedef int ImDrawListFlags; // -> enum ImDrawListFlags_ // Flags: for ImDrawList instance
|
||||
typedef int ImDrawTextFlags; // -> enum ImDrawTextFlags_ // Internal, do not use!
|
||||
typedef int ImFontFlags; // -> enum ImFontFlags_ // Flags: for ImFont
|
||||
typedef int ImFontAtlasFlags; // -> enum ImFontAtlasFlags_ // Flags: for ImFontAtlas
|
||||
typedef int ImGuiBackendFlags; // -> enum ImGuiBackendFlags_ // Flags: for io.BackendFlags
|
||||
@@ -251,6 +254,7 @@ typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: f
|
||||
typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline()
|
||||
typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), shared by all items
|
||||
typedef int ImGuiKeyChord; // -> ImGuiKey | ImGuiMod_XXX // Flags: for IsKeyChordPressed(), Shortcut() etc. an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values.
|
||||
typedef int ImGuiListClipperFlags; // -> enum ImGuiListClipperFlags_// Flags: for ImGuiListClipper
|
||||
typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen()
|
||||
typedef int ImGuiMultiSelectFlags; // -> enum ImGuiMultiSelectFlags_// Flags: for BeginMultiSelect()
|
||||
typedef int ImGuiSelectableFlags; // -> enum ImGuiSelectableFlags_ // Flags: for Selectable()
|
||||
@@ -322,7 +326,7 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
// - When a Rendered Backend creates a texture, it store its native identifier into a ImTextureID value.
|
||||
// (e.g. Used by DX11 backend to a `ID3D11ShaderResourceView*`; Used by OpenGL backends to store `GLuint`;
|
||||
// Used by SDLGPU backend to store a `SDL_GPUTextureSamplerBinding*`, etc.).
|
||||
// - User may submit their own textures to e.g. ImGui::Image() function by passing the same type.
|
||||
// - User may submit their own textures to e.g. ImGui::Image() function by passing this value.
|
||||
// - During the rendering loop, the Renderer Backend retrieve the ImTextureID, which stored inside a
|
||||
// ImTextureRef, which is stored inside a ImDrawCmd.
|
||||
// - Compile-time type configuration:
|
||||
@@ -342,15 +346,17 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or
|
||||
#define ImTextureID_Invalid ((ImTextureID)0)
|
||||
#endif
|
||||
|
||||
// ImTextureRef = higher-level identifier for a texture.
|
||||
// ImTextureRef = higher-level identifier for a texture. Store a ImTextureID _or_ a ImTextureData*.
|
||||
// The identifier is valid even before the texture has been uploaded to the GPU/graphics system.
|
||||
// This is what gets passed to functions such as `ImGui::Image()`, `ImDrawList::AddImage()`.
|
||||
// This is what gets stored in draw commands (`ImDrawCmd`) to identify a texture during rendering.
|
||||
// - When a texture is created by user code (e.g. custom images), we directly stores the low-level ImTextureID.
|
||||
// Because of this, when displaying your own texture you are likely to ever only manage ImTextureID values on your side.
|
||||
// - When a texture is created by the backend, we stores a ImTextureData* which becomes an indirection
|
||||
// to extract the ImTextureID value during rendering, after texture upload has happened.
|
||||
// - There is no constructor to create a ImTextureID from a ImTextureData* as we don't expect this
|
||||
// to be useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
// - To create a ImTextureRef from a ImTextureData you can use ImTextureData::GetTexRef().
|
||||
// We intentionally do not provide an ImTextureRef constructor for this: we don't expect this
|
||||
// to be frequently useful to the end-user, and it would be erroneously called by many legacy code.
|
||||
// - If you want to bind the current atlas when using custom rectangle, you can use io.Fonts->TexRef.
|
||||
// - Binding generators for languages such as C (which don't have constructors), should provide a helper, e.g.
|
||||
// inline ImTextureRef ImTextureRefFromID(ImTextureID tex_id) { ImTextureRef tex_ref = { ._TexData = NULL, .TexID = tex_id }; return tex_ref; }
|
||||
@@ -922,7 +928,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable().
|
||||
IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable)
|
||||
IMGUI_API int TableGetColumnIndex(); // return current column index.
|
||||
IMGUI_API int TableGetRowIndex(); // return current row index.
|
||||
IMGUI_API int TableGetRowIndex(); // return current row index (header rows are accounted for)
|
||||
IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column.
|
||||
IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column.
|
||||
IMGUI_API void TableSetColumnEnabled(int column_n, bool v);// change user accessible enabled/disabled state of a column. Set to false to hide the column. User can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
|
||||
@@ -950,18 +956,24 @@ namespace ImGui
|
||||
IMGUI_API void SetTabItemClosed(const char* tab_or_docked_window_label); // notify TabBar or Docking system of a closed tab/window ahead (useful to reduce visual flicker on reorderable tab bars). For tab-bar: call after BeginTabBar() and before Tab submissions. Otherwise call with a window name.
|
||||
|
||||
// Docking
|
||||
// [BETA API] Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable.
|
||||
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
|
||||
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
|
||||
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
|
||||
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
|
||||
// About dockspaces:
|
||||
// - Use DockSpaceOverViewport() to create a window covering the screen or a specific viewport + a dockspace inside it.
|
||||
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode to make it transparent.
|
||||
// - Use DockSpace() to create an explicit dock node _within_ an existing window. See Docking demo for details.
|
||||
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame!
|
||||
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
|
||||
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Docking for details.
|
||||
// - Enable with io.ConfigFlags |= ImGuiConfigFlags_DockingEnable.
|
||||
// - You can use most Docking facilities without calling any API. You don't necessarily need to call a DockSpaceXXX function to use Docking!
|
||||
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
|
||||
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
|
||||
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
|
||||
// - Dockspaces:
|
||||
// - If you want to dock windows into the edge of your screen, most application can simply call DockSpaceOverViewport():
|
||||
// e.g. ImGui::NewFrame(); then ImGui::DockSpaceOverViewport(); // Create a dockspace in main viewport.
|
||||
// or: ImGui::NewFrame(); then ImGui::DockSpaceOverViewport(0, nullptr, ImGuiDockNodeFlags_PassthruCentralNode); // Create a dockspace in main viewport, where central node is transparent.
|
||||
// - A dockspace is an explicit dock node within an existing window.
|
||||
// - DockSpaceOverViewport() basically creates an invisible window covering a viewport, and submit a DockSpace() into it.
|
||||
// - IMPORTANT: Dockspaces need to be submitted _before_ any window they can host. Submit them early in your frame!
|
||||
// - IMPORTANT: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
|
||||
// If you have e.g. multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
|
||||
// - Programmatic docking:
|
||||
// - There is no public API yet other than the very limited SetNextWindowDockID() function. Sorry for that!
|
||||
// - Read https://github.com/ocornut/imgui/wiki/Docking for examples of how to use current internal API.
|
||||
IMGUI_API ImGuiID DockSpace(ImGuiID dockspace_id, const ImVec2& size = ImVec2(0, 0), ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
|
||||
IMGUI_API ImGuiID DockSpaceOverViewport(ImGuiID dockspace_id = 0, const ImGuiViewport* viewport = NULL, ImGuiDockNodeFlags flags = 0, const ImGuiWindowClass* window_class = NULL);
|
||||
IMGUI_API void SetNextWindowDockID(ImGuiID dock_id, ImGuiCond cond = 0); // set next window dock id
|
||||
@@ -1079,8 +1091,8 @@ namespace ImGui
|
||||
|
||||
// Inputs Utilities: Shortcut Testing & Routing [BETA]
|
||||
// - ImGuiKeyChord = a ImGuiKey + optional ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super.
|
||||
// ImGuiKey_C // Accepted by functions taking ImGuiKey or ImGuiKeyChord arguments)
|
||||
// ImGuiMod_Ctrl | ImGuiKey_C // Accepted by functions taking ImGuiKeyChord arguments)
|
||||
// ImGuiKey_C // Accepted by functions taking ImGuiKey or ImGuiKeyChord arguments
|
||||
// ImGuiMod_Ctrl | ImGuiKey_C // Accepted by functions taking ImGuiKeyChord arguments
|
||||
// only ImGuiMod_XXX values are legal to combine with an ImGuiKey. You CANNOT combine two ImGuiKey values.
|
||||
// - The general idea is that several callers may register interest in a shortcut, and only one owner gets it.
|
||||
// Parent -> call Shortcut(Ctrl+S) // When Parent is focused, Parent gets the shortcut.
|
||||
@@ -1219,7 +1231,7 @@ enum ImGuiWindowFlags_
|
||||
};
|
||||
|
||||
// Flags for ImGui::BeginChild()
|
||||
// (Legacy: bit 0 must always correspond to ImGuiChildFlags_Borders to be backward compatible with old API using 'bool border = false'.
|
||||
// (Legacy: bit 0 must always correspond to ImGuiChildFlags_Borders to be backward compatible with old API using 'bool border = false'.)
|
||||
// About using AutoResizeX/AutoResizeY flags:
|
||||
// - May be combined with SetNextWindowSizeConstraints() to set a min/max size for each axis (see "Demo->Child->Auto-resize with Constraints").
|
||||
// - Size measurement for a given axis is only performed when the child window is within visible boundaries, or is just appearing.
|
||||
@@ -1298,6 +1310,15 @@ enum ImGuiInputTextFlags_
|
||||
ImGuiInputTextFlags_CallbackResize = 1 << 22, // Callback on buffer capacity changes request (beyond 'buf_size' parameter value), allowing the string to grow. Notify when the string wants to be resized (for string types which hold a cache of their Size). You will be provided a new BufSize in the callback and NEED to honor it. (see misc/cpp/imgui_stdlib.h for an example of using this)
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 << 23, // Callback on any edit. Note that InputText() already returns true on edit + you can always use IsItemEdited(). The callback is useful to manipulate the underlying buffer while focus is active.
|
||||
|
||||
// Multi-line Word-Wrapping [BETA]
|
||||
// - Not well tested yet. Please report any incorrect cursor movement, selection behavior etc. bug to https://github.com/ocornut/imgui/issues/3237.
|
||||
// - Wrapping style is not ideal. Wrapping of long words/sections (e.g. words larger than total available width) may be particularly unpleasing.
|
||||
// - Wrapping width needs to always account for the possibility of a vertical scrollbar.
|
||||
// - It is much slower than regular text fields.
|
||||
// Ballpark estimate of cost on my 2019 desktop PC: for a 100 KB text buffer: +~0.3 ms (Optimized) / +~1.0 ms (Debug build).
|
||||
// The CPU cost is very roughly proportional to text length, so a 10 KB buffer should cost about ten times less.
|
||||
ImGuiInputTextFlags_WordWrap = 1 << 24, // InputTextMultine(): word-wrap lines that are too long.
|
||||
|
||||
// Obsolete names
|
||||
//ImGuiInputTextFlags_AlwaysInsertMode = ImGuiInputTextFlags_AlwaysOverwrite // [renamed in 1.82] name was not matching behavior
|
||||
};
|
||||
@@ -1335,7 +1356,7 @@ enum ImGuiTreeNodeFlags_
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiTreeNodeFlags_NavLeftJumpsBackHere = ImGuiTreeNodeFlags_NavLeftJumpsToParent, // Renamed in 1.92.0
|
||||
ImGuiTreeNodeFlags_SpanTextWidth = ImGuiTreeNodeFlags_SpanLabelWidth, // Renamed in 1.90.7
|
||||
ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
//ImGuiTreeNodeFlags_AllowItemOverlap = ImGuiTreeNodeFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1374,10 +1395,11 @@ enum ImGuiSelectableFlags_
|
||||
ImGuiSelectableFlags_Disabled = 1 << 3, // Cannot be selected, display grayed out text
|
||||
ImGuiSelectableFlags_AllowOverlap = 1 << 4, // (WIP) Hit testing to allow subsequent widgets to overlap this one
|
||||
ImGuiSelectableFlags_Highlight = 1 << 5, // Make the item be displayed as if it is hovered
|
||||
ImGuiSelectableFlags_SelectOnNav = 1 << 6, // Auto-select when moved into, unless Ctrl is held. Automatic when in a BeginMultiSelect() block.
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiSelectableFlags_DontClosePopups = ImGuiSelectableFlags_NoAutoClosePopups, // Renamed in 1.91.0
|
||||
ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
//ImGuiSelectableFlags_AllowItemOverlap = ImGuiSelectableFlags_AllowOverlap, // Renamed in 1.89.7
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1407,10 +1429,17 @@ enum ImGuiTabBarFlags_
|
||||
ImGuiTabBarFlags_NoTabListScrollingButtons = 1 << 4, // Disable scrolling buttons (apply when fitting policy is ImGuiTabBarFlags_FittingPolicyScroll)
|
||||
ImGuiTabBarFlags_NoTooltip = 1 << 5, // Disable tooltips when hovering a tab
|
||||
ImGuiTabBarFlags_DrawSelectedOverline = 1 << 6, // Draw selected overline markers over selected tab
|
||||
ImGuiTabBarFlags_FittingPolicyResizeDown = 1 << 7, // Resize tabs when they don't fit
|
||||
ImGuiTabBarFlags_FittingPolicyScroll = 1 << 8, // Add scroll buttons when tabs don't fit
|
||||
ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyResizeDown | ImGuiTabBarFlags_FittingPolicyScroll,
|
||||
ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyResizeDown,
|
||||
|
||||
// Fitting/Resize policy
|
||||
ImGuiTabBarFlags_FittingPolicyMixed = 1 << 7, // Shrink down tabs when they don't fit, until width is style.TabMinWidthShrink, then enable scrolling buttons.
|
||||
ImGuiTabBarFlags_FittingPolicyShrink = 1 << 8, // Shrink down tabs when they don't fit
|
||||
ImGuiTabBarFlags_FittingPolicyScroll = 1 << 9, // Enable scrolling buttons when tabs don't fit
|
||||
ImGuiTabBarFlags_FittingPolicyMask_ = ImGuiTabBarFlags_FittingPolicyMixed | ImGuiTabBarFlags_FittingPolicyShrink | ImGuiTabBarFlags_FittingPolicyScroll,
|
||||
ImGuiTabBarFlags_FittingPolicyDefault_ = ImGuiTabBarFlags_FittingPolicyMixed,
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGuiTabBarFlags_FittingPolicyResizeDown = ImGuiTabBarFlags_FittingPolicyShrink, // Renamed in 1.92.2
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for ImGui::BeginTabItem()
|
||||
@@ -1762,10 +1791,11 @@ enum ImGuiBackendFlags_
|
||||
ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices.
|
||||
ImGuiBackendFlags_RendererHasTextures = 1 << 4, // Backend Renderer supports ImTextureData requests to create/update/destroy textures. This enables incremental texture updates and texture reloads. See https://github.com/ocornut/imgui/blob/master/docs/BACKENDS.md for instructions on how to upgrade your custom backend.
|
||||
|
||||
// [BETA] Viewports
|
||||
ImGuiBackendFlags_PlatformHasViewports = 1 << 10, // Backend Platform supports multiple viewports.
|
||||
ImGuiBackendFlags_HasMouseHoveredViewport=1 << 11, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under.
|
||||
ImGuiBackendFlags_RendererHasViewports = 1 << 12, // Backend Renderer supports multiple viewports.
|
||||
// [BETA] Multi-Viewports
|
||||
ImGuiBackendFlags_RendererHasViewports = 1 << 10, // Backend Renderer supports multiple viewports.
|
||||
ImGuiBackendFlags_PlatformHasViewports = 1 << 11, // Backend Platform supports multiple viewports.
|
||||
ImGuiBackendFlags_HasMouseHoveredViewport=1 << 12, // Backend Platform supports calling io.AddMouseViewportEvent() with the viewport under the mouse. IF POSSIBLE, ignore viewports with the ImGuiViewportFlags_NoInputs flag (Win32 backend, GLFW 3.30+ backend can do this, SDL backend cannot). If this cannot be done, Dear ImGui needs to use a flawed heuristic to find the viewport under.
|
||||
ImGuiBackendFlags_HasParentViewport = 1 << 13, // Backend Platform supports honoring viewport->ParentViewport/ParentViewportId value, by applying the corresponding parent/child relation at the Platform level.
|
||||
};
|
||||
|
||||
// Enumeration for PushStyleColor() / PopStyleColor()
|
||||
@@ -1827,6 +1857,7 @@ enum ImGuiCol_
|
||||
ImGuiCol_TextSelectedBg, // Selected text inside an InputText
|
||||
ImGuiCol_TreeLines, // Tree node hierarchy outlines when using ImGuiTreeNodeFlags_DrawLines
|
||||
ImGuiCol_DragDropTarget, // Rectangle highlighting a drop target
|
||||
ImGuiCol_UnsavedMarker, // Unsaved Document marker (in window title and tabs)
|
||||
ImGuiCol_NavCursor, // Color of keyboard/gamepad navigation cursor/rectangle, when visible
|
||||
ImGuiCol_NavWindowingHighlight, // Highlight window when using CTRL+TAB
|
||||
ImGuiCol_NavWindowingDimBg, // Darken/colorize entire screen behind the CTRL+TAB window list, when active
|
||||
@@ -1872,11 +1903,14 @@ enum ImGuiStyleVar_
|
||||
ImGuiStyleVar_CellPadding, // ImVec2 CellPadding
|
||||
ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize
|
||||
ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding
|
||||
ImGuiStyleVar_ScrollbarPadding, // float ScrollbarPadding
|
||||
ImGuiStyleVar_GrabMinSize, // float GrabMinSize
|
||||
ImGuiStyleVar_GrabRounding, // float GrabRounding
|
||||
ImGuiStyleVar_ImageBorderSize, // float ImageBorderSize
|
||||
ImGuiStyleVar_TabRounding, // float TabRounding
|
||||
ImGuiStyleVar_TabBorderSize, // float TabBorderSize
|
||||
ImGuiStyleVar_TabMinWidthBase, // float TabMinWidthBase
|
||||
ImGuiStyleVar_TabMinWidthShrink, // float TabMinWidthShrink
|
||||
ImGuiStyleVar_TabBarBorderSize, // float TabBarBorderSize
|
||||
ImGuiStyleVar_TabBarOverlineSize, // float TabBarOverlineSize
|
||||
ImGuiStyleVar_TableAngledHeadersAngle, // float TableAngledHeadersAngle
|
||||
@@ -2247,7 +2281,7 @@ struct ImVector
|
||||
// Constructors, destructor
|
||||
inline ImVector() { Size = Capacity = 0; Data = NULL; }
|
||||
inline ImVector(const ImVector<T>& src) { Size = Capacity = 0; Data = NULL; operator=(src); }
|
||||
inline ImVector<T>& operator=(const ImVector<T>& src) { clear(); resize(src.Size); if (src.Data) memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; }
|
||||
inline ImVector<T>& operator=(const ImVector<T>& src) { clear(); resize(src.Size); if (Data && src.Data) memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; }
|
||||
inline ~ImVector() { if (Data) IM_FREE(Data); } // Important: does not destruct anything
|
||||
|
||||
inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } } // Important: does not destruct anything
|
||||
@@ -2337,12 +2371,15 @@ struct ImGuiStyle
|
||||
float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. Preferably > (FramePadding.x + 1).
|
||||
float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar.
|
||||
float ScrollbarRounding; // Radius of grab corners for scrollbar.
|
||||
float ScrollbarPadding; // Padding of scrollbar grab within its frame (same for both axises).
|
||||
float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar.
|
||||
float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs.
|
||||
float LogSliderDeadzone; // The size in pixels of the dead-zone around zero on logarithmic sliders that cross zero.
|
||||
float ImageBorderSize; // Thickness of border around Image() calls.
|
||||
float TabRounding; // Radius of upper corners of a tab. Set to 0.0f to have rectangular tabs.
|
||||
float TabBorderSize; // Thickness of border around tabs.
|
||||
float TabMinWidthBase; // Minimum tab width, to make tabs larger than their contents. TabBar buttons are not affected.
|
||||
float TabMinWidthShrink; // Minimum tab width after shrinking, when using ImGuiTabBarFlags_FittingPolicyMixed policy.
|
||||
float TabCloseButtonMinWidthSelected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width.
|
||||
float TabCloseButtonMinWidthUnselected; // -1: always visible. 0.0f: visible when hovered. >0.0f: visible when hovered if minimum width. FLT_MAX: never show close button when unselected.
|
||||
float TabBarBorderSize; // Thickness of tab-bar separator, which takes on the tab active color to denote focus.
|
||||
@@ -2360,6 +2397,7 @@ struct ImGuiStyle
|
||||
ImVec2 SeparatorTextPadding; // Horizontal offset of text from each edge of the separator + spacing on other axis. Generally small values. .y is recommended to be == FramePadding.y.
|
||||
ImVec2 DisplayWindowPadding; // Apply to regular windows: amount which we enforce to keep visible when moving near edges of your screen.
|
||||
ImVec2 DisplaySafeAreaPadding; // Apply to every windows, menus, popups, tooltips: amount where we avoid displaying contents. Adjust if you cannot see the edges of your screen (e.g. on a TV where scaling has not been configured).
|
||||
bool DockingNodeHasCloseButton; // Docking node has their own CloseButton() to close all docked windows.
|
||||
float DockingSeparatorSize; // Thickness of resizing border between docked windows
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
|
||||
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
@@ -2455,7 +2493,8 @@ struct ImGuiIO
|
||||
bool ConfigViewportsNoAutoMerge; // = false; // Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it. May also set ImGuiViewportFlags_NoAutoMerge on individual viewport.
|
||||
bool ConfigViewportsNoTaskBarIcon; // = false // Disable default OS task bar icon flag for secondary viewports. When a viewport doesn't want a task bar icon, ImGuiViewportFlags_NoTaskBarIcon will be set on it.
|
||||
bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size).
|
||||
bool ConfigViewportsNoDefaultParent; // = false // Disable default OS parenting to main viewport for secondary viewports. By default, viewports are marked with ParentViewportId = <main_viewport>, expecting the platform backend to setup a parent/child relationship between the OS windows (some backend may ignore this). Set to true if you want the default to be 0, then all viewports will be top-level OS windows.
|
||||
bool ConfigViewportsNoDefaultParent; // = true // When false: set secondary viewports' ParentViewportId to main viewport ID by default. Expects the platform backend to setup a parent/child relationship between the OS windows based on this value. Some backend may ignore this. Set to true if you want viewports to automatically be parent of main viewport, otherwise all viewports will be top-level OS windows.
|
||||
bool ConfigViewportsPlatformFocusSetsImGuiFocus;//= true // When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).
|
||||
|
||||
// DPI/Scaling options
|
||||
// This may keep evolving during 1.92.x releases. Expect some turbulence.
|
||||
@@ -2510,7 +2549,7 @@ struct ImGuiIO
|
||||
// Option to enable various debug tools showing buttons that will call the IM_DEBUG_BREAK() macro.
|
||||
// - The Item Picker tool will be available regardless of this being enabled, in order to maximize its discoverability.
|
||||
// - Requires a debugger being attached, otherwise IM_DEBUG_BREAK() options will appear to crash your application.
|
||||
// e.g. io.ConfigDebugIsDebuggerPresent = ::IsDebuggerPresent() on Win32, or refer to ImOsIsDebuggerPresent() imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version).
|
||||
// e.g. io.ConfigDebugIsDebuggerPresent = ::IsDebuggerPresent() on Win32, or refer to ImOsIsDebuggerPresent() imgui_test_engine/imgui_te_utils.cpp for a Unix compatible version.
|
||||
bool ConfigDebugIsDebuggerPresent; // = false // Enable various tools calling IM_DEBUG_BREAK().
|
||||
|
||||
// Tools to detect code submitting items with conflicting/duplicate IDs
|
||||
@@ -2609,13 +2648,13 @@ struct ImGuiIO
|
||||
float MouseWheelH; // Mouse wheel Horizontal. >0 scrolls Left, <0 scrolls Right. Most users don't have a mouse with a horizontal wheel, may not be filled by all backends.
|
||||
ImGuiMouseSource MouseSource; // Mouse actual input peripheral (Mouse/TouchScreen/Pen).
|
||||
ImGuiID MouseHoveredViewport; // (Optional) Modify using io.AddMouseViewportEvent(). With multi-viewports: viewport the OS mouse is hovering. If possible _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag is much better (few backends can handle that). Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will infer the value using the rectangles and last focused time of the viewports it knows about (ignoring other OS windows).
|
||||
bool KeyCtrl; // Keyboard modifier down: Control
|
||||
bool KeyCtrl; // Keyboard modifier down: Ctrl (non-macOS), Cmd (macOS)
|
||||
bool KeyShift; // Keyboard modifier down: Shift
|
||||
bool KeyAlt; // Keyboard modifier down: Alt
|
||||
bool KeySuper; // Keyboard modifier down: Cmd/Super/Windows
|
||||
bool KeySuper; // Keyboard modifier down: Windows/Super (non-macOS), Ctrl (macOS)
|
||||
|
||||
// Other state maintained from data above + IO function calls
|
||||
ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags. Read-only, updated by NewFrame()
|
||||
ImGuiKeyChord KeyMods; // Key mods flags (any of ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Alt/ImGuiMod_Super flags, same as io.KeyCtrl/KeyShift/KeyAlt/KeySuper but merged into flags). Read-only, updated by NewFrame()
|
||||
ImGuiKeyData KeysData[ImGuiKey_NamedKey_COUNT];// Key state for all known keys. MUST use 'key - ImGuiKey_NamedKey_BEGIN' as index. Use IsKeyXXX() functions to access this.
|
||||
bool WantCaptureMouseUnlessPopupClose; // Alternative to WantCaptureMouse: (WantCaptureMouse == true && WantCaptureMouseUnlessPopupClose == false) when a click over void is expected to close a popup.
|
||||
ImVec2 MousePosPrev; // Previous mouse position (note that MouseDelta is not necessary == MousePos-MousePosPrev, in case either position is invalid)
|
||||
@@ -2693,10 +2732,10 @@ struct ImGuiInputTextCallbackData
|
||||
ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only // [Completion,History]
|
||||
char* Buf; // Text buffer // Read-write // [Resize] Can replace pointer / [Completion,History,Always] Only write to pointed data, don't replace the actual pointer!
|
||||
int BufTextLen; // Text length (in bytes) // Read-write // [Resize,Completion,History,Always] Exclude zero-terminator storage. In C land: == strlen(some_text), in C++ land: string.length()
|
||||
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
||||
int BufSize; // Buffer size (in bytes) = capacity+1 // Read-only // [Resize,Completion,History,Always] Include zero-terminator storage. In C land: == ARRAYSIZE(my_char_array), in C++ land: string.capacity()+1
|
||||
bool BufDirty; // Set if you modify Buf/BufTextLen! // Write // [Completion,History,Always]
|
||||
int CursorPos; // // Read-write // [Completion,History,Always]
|
||||
int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection)
|
||||
int SelectionStart; // // Read-write // [Completion,History,Always] == to SelectionEnd when no selection
|
||||
int SelectionEnd; // // Read-write // [Completion,History,Always]
|
||||
|
||||
// Helper functions for text manipulation.
|
||||
@@ -2887,6 +2926,13 @@ struct ImGuiStorage
|
||||
#endif
|
||||
};
|
||||
|
||||
// Flags for ImGuiListClipper (currently not fully exposed in function calls: a future refactor will likely add this to ImGuiListClipper::Begin function equivalent)
|
||||
enum ImGuiListClipperFlags_
|
||||
{
|
||||
ImGuiListClipperFlags_None = 0,
|
||||
ImGuiListClipperFlags_NoSetTableRowCounters = 1 << 0, // [Internal] Disabled modifying table row counters. Avoid assumption that 1 clipper item == 1 table row.
|
||||
};
|
||||
|
||||
// Helper: Manually clip large list of items.
|
||||
// If you have lots evenly spaced items and you have random access to the list, you can perform coarse
|
||||
// clipping based on visibility to only submit items that are in view.
|
||||
@@ -2917,6 +2963,7 @@ struct ImGuiListClipper
|
||||
double StartPosY; // [Internal] Cursor position at the time of Begin() or after table frozen rows are all processed
|
||||
double StartSeekOffsetY; // [Internal] Account for frozen rows in a table and initial loss of precision in very large windows.
|
||||
void* TempData; // [Internal] Internal data
|
||||
ImGuiListClipperFlags Flags; // [Internal] Flags, currently not yet well exposed.
|
||||
|
||||
// items_count: Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step, and you can call SeekCursorForItem() manually if you need)
|
||||
// items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing().
|
||||
@@ -2937,7 +2984,7 @@ struct ImGuiListClipper
|
||||
IMGUI_API void SeekCursorForItem(int item_index);
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
|
||||
//inline void IncludeRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.9]
|
||||
//inline void ForceDisplayRangeByIndices(int item_begin, int item_end) { IncludeItemsByIndex(item_begin, item_end); } // [renamed in 1.89.6]
|
||||
//inline ImGuiListClipper(int items_count, float items_height = -1.0f) { memset(this, 0, sizeof(*this)); ItemsCount = -1; Begin(items_count, items_height); } // [removed in 1.79]
|
||||
#endif
|
||||
@@ -3227,7 +3274,7 @@ struct ImDrawCmd
|
||||
|
||||
// Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature)
|
||||
// Since 1.92: removed ImDrawCmd::TextureId field, the getter function must be used!
|
||||
inline ImTextureID GetTexID() const; // == (TexRef._TexData ? TexRef._TexData->TexID : TexRef._TexID
|
||||
inline ImTextureID GetTexID() const; // == (TexRef._TexData ? TexRef._TexData->TexID : TexRef._TexID)
|
||||
};
|
||||
|
||||
// Vertex layout
|
||||
@@ -3423,7 +3470,7 @@ struct ImDrawList
|
||||
|
||||
// Advanced: Miscellaneous
|
||||
IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible
|
||||
IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer.
|
||||
IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer. For multi-threaded rendering, consider using `imgui_threaded_rendering` from https://github.com/ocornut/imgui_club instead.
|
||||
|
||||
// Advanced: Channels
|
||||
// - Use to split render into layers. By switching channels to can render out-of-order (e.g. submit FG primitives before BG primitives)
|
||||
@@ -3479,7 +3526,7 @@ struct ImDrawList
|
||||
struct ImDrawData
|
||||
{
|
||||
bool Valid; // Only valid after Render() is called and before the next NewFrame() is called.
|
||||
int CmdListsCount; // Number of ImDrawList* to render. (== CmdLists.Size). Exists for legacy reason.
|
||||
int CmdListsCount; // == CmdLists.Size. (OBSOLETE: exists for legacy reasons). Number of ImDrawList* to render.
|
||||
int TotalIdxCount; // For convenience, sum of all ImDrawList's IdxBuffer.Size
|
||||
int TotalVtxCount; // For convenience, sum of all ImDrawList's VtxBuffer.Size
|
||||
ImVector<ImDrawList*> CmdLists; // Array of ImDrawList* to render. The ImDrawLists are owned by ImGuiContext and only pointed to from here.
|
||||
@@ -3544,7 +3591,7 @@ struct ImTextureRect
|
||||
struct ImTextureData
|
||||
{
|
||||
//------------------------------------------ core / backend ---------------------------------------
|
||||
int UniqueID; // w - // Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas.
|
||||
int UniqueID; // w - // [DEBUG] Sequential index to facilitate identifying a texture when debugging/printing. Unique per atlas.
|
||||
ImTextureStatus Status; // rw rw // ImTextureStatus_OK/_WantCreate/_WantUpdates/_WantDestroy. Always use SetStatus() to modify!
|
||||
void* BackendUserData; // - rw // Convenience storage for backend. Some backends may have enough with TexID.
|
||||
ImTextureID TexID; // r w // Backend-specific texture identifier. Always use SetTexID() to modify! The identifier will stored in ImDrawCmd::GetTexID() and passed to backend's RenderDrawData function.
|
||||
@@ -3562,7 +3609,7 @@ struct ImTextureData
|
||||
bool WantDestroyNextFrame; // rw - // [Internal] Queued to set ImTextureStatus_WantDestroy next frame. May still be used in the current frame.
|
||||
|
||||
// Functions
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); TexID = ImTextureID_Invalid; }
|
||||
ImTextureData() { memset(this, 0, sizeof(*this)); Status = ImTextureStatus_Destroyed; TexID = ImTextureID_Invalid; }
|
||||
~ImTextureData() { DestroyPixels(); }
|
||||
IMGUI_API void Create(ImTextureFormat format, int w, int h);
|
||||
IMGUI_API void DestroyPixels();
|
||||
@@ -3574,8 +3621,10 @@ struct ImTextureData
|
||||
ImTextureID GetTexID() const { return TexID; }
|
||||
|
||||
// Called by Renderer backend
|
||||
void SetTexID(ImTextureID tex_id) { TexID = tex_id; } // Call after creating or destroying the texture. Never modify TexID directly!
|
||||
void SetStatus(ImTextureStatus status) { Status = status; } // Call after honoring a request. Never modify Status directly!
|
||||
// - Call SetTexID() and SetStatus() after honoring texture requests. Never modify TexID and Status directly!
|
||||
// - A backend may decide to destroy a texture that we did not request to destroy, which is fine (e.g. freeing resources), but we immediately set the texture back in _WantCreate mode.
|
||||
void SetTexID(ImTextureID tex_id) { TexID = tex_id; }
|
||||
void SetStatus(ImTextureStatus status) { Status = status; if (status == ImTextureStatus_Destroyed && !WantDestroyNextFrame) Status = ImTextureStatus_WantCreate; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3724,7 +3773,7 @@ struct ImFontAtlas
|
||||
// - 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().
|
||||
// - The pitch is always = Width * BytesPerPixels (1 or 4)
|
||||
// - Building in RGBA32 format is provided for convenience and compatibility, but note that unless you manually manipulate or copy color data into
|
||||
// the texture (e.g. when using the AddCustomRect*** api), then the RGB pixels emitted will always be white (~75% of memory/bandwidth waste.
|
||||
// the texture (e.g. when using the AddCustomRect*** api), then the RGB pixels emitted will always be white (~75% of memory/bandwidth waste).
|
||||
// - From 1.92 with backends supporting ImGuiBackendFlags_RendererHasTextures:
|
||||
// - Calling Build(), GetTexDataAsAlpha8(), GetTexDataAsRGBA32() is not needed.
|
||||
// - In backend: replace calls to ImFontAtlas::SetTexID() with calls to ImTextureData::SetTexID() after honoring texture creation.
|
||||
@@ -3839,7 +3888,7 @@ struct ImFontAtlas
|
||||
IMGUI_API ImFontAtlasRectId AddCustomRectFontGlyphForSize(ImFont* font, float font_size, ImWchar codepoint, int w, int h, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // ADDED AND OBSOLETED in 1.92.X
|
||||
#endif
|
||||
//unsigned int FontBuilderFlags; // OBSOLETED in 1.92.X: Renamed to FontLoaderFlags.
|
||||
//int TexDesiredWidth; // OBSOLETED in 1.92.X: Force texture width before calling Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height)
|
||||
//int TexDesiredWidth; // OBSOLETED in 1.92.X: Force texture width before calling Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height.
|
||||
//typedef ImFontAtlasRect ImFontAtlasCustomRect; // OBSOLETED in 1.92.X
|
||||
//typedef ImFontAtlasCustomRect CustomRect; // OBSOLETED in 1.72+
|
||||
//typedef ImFontGlyphRangesBuilder GlyphRangesBuilder; // OBSOLETED in 1.67+
|
||||
@@ -3864,9 +3913,10 @@ struct ImFontBaked
|
||||
float Ascent, Descent; // 4+4 // out // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] (unscaled)
|
||||
unsigned int MetricsTotalSurface:26;// 3 // out // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs)
|
||||
unsigned int WantDestroy:1; // 0 // // Queued for destroy
|
||||
unsigned int LockLoadingFallback:1; // 0 // //
|
||||
int LastUsedFrame; // 4 // // Record of that time this was bounds
|
||||
ImGuiID BakedId; // 4 //
|
||||
unsigned int LoadNoFallback:1; // 0 // // Disable loading fallback in lower-level calls.
|
||||
unsigned int LoadNoRenderOnLayout:1;// 0 // // Enable a two-steps mode where CalcTextSize() calls will load AdvanceX *without* rendering/packing glyphs. Only advantagous if you know that the glyph is unlikely to actually be rendered, otherwise it is slower because we'd do one query on the first CalcTextSize and one query on the first Draw.
|
||||
int LastUsedFrame; // 4 // // Record of that time this was bounds
|
||||
ImGuiID BakedId; // 4 // // Unique ID for this baked storage
|
||||
ImFont* ContainerFont; // 4-8 // in // Parent font
|
||||
void* FontLoaderDatas; // 4-8 // // Font loader opaque storage (per baked font * sources): single contiguous buffer allocated by imgui, passed to loader.
|
||||
|
||||
@@ -3927,10 +3977,10 @@ struct ImFont
|
||||
// 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable.
|
||||
// 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable.
|
||||
IMGUI_API ImFontBaked* GetFontBaked(float font_size, float density = -1.0f); // Get or create baked data for given size
|
||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL); // utf8
|
||||
IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** out_remaining = NULL);
|
||||
IMGUI_API const char* CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width);
|
||||
IMGUI_API void RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip = NULL);
|
||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false);
|
||||
IMGUI_API void RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, ImDrawTextFlags flags = 0);
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) { return CalcWordWrapPosition(LegacySize * scale, text, text_end, wrap_width); }
|
||||
#endif
|
||||
@@ -4003,6 +4053,7 @@ struct ImGuiViewport
|
||||
ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size)
|
||||
float DpiScale; // 1.0f = 96 DPI = No extra scale.
|
||||
ImGuiID ParentViewportId; // (Advanced) 0: no parent. Instruct the platform backend to setup a parent/child relationship between platform windows.
|
||||
ImGuiViewport* ParentViewport; // (Advanced) Direct shortcut to ImGui::FindViewportByID(ParentViewportId). NULL: no parent.
|
||||
ImDrawData* DrawData; // The ImDrawData corresponding to this viewport. Valid after Render() and until the next call to NewFrame().
|
||||
|
||||
// Platform/Backend Dependent Data
|
||||
@@ -4179,6 +4230,13 @@ struct ImGuiPlatformIO
|
||||
// Viewports list (the list is updated by calling ImGui::EndFrame or ImGui::Render)
|
||||
// (in the future we will attempt to organize this feature to remove the need for a "main viewport")
|
||||
ImVector<ImGuiViewport*> Viewports; // Main viewports, followed by all secondary viewports.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Functions
|
||||
//------------------------------------------------------------------
|
||||
|
||||
void ClearPlatformHandlers(); // Clear all Platform_XXX fields. Typically called on Platform Backend shutdown.
|
||||
void ClearRendererHandlers(); // Clear all Renderer_XXX fields. Typically called on Renderer Backend shutdown.
|
||||
};
|
||||
|
||||
// (Optional) This is required when enabling multi-viewport. Represent the bounds of each connected monitor/display and their DPI.
|
||||
@@ -4214,24 +4272,24 @@ struct ImGuiPlatformImeData
|
||||
namespace ImGui
|
||||
{
|
||||
// OBSOLETED in 1.92.0 (from June 2025)
|
||||
static inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); }
|
||||
inline void PushFont(ImFont* font) { PushFont(font, font ? font->LegacySize : 0.0f); }
|
||||
IMGUI_API void SetWindowFontScale(float scale); // Set font scale factor for current window. Prefer using PushFont(NULL, style.FontSizeBase * factor) or use style.FontScaleMain to scale all windows.
|
||||
// OBSOLETED in 1.91.9 (from February 2025)
|
||||
IMGUI_API void Image(ImTextureRef tex_ref, const ImVec2& image_size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col); // <-- 'border_col' was removed in favor of ImGuiCol_ImageBorder. If you use 'tint_col', use ImageWithBg() instead.
|
||||
// OBSOLETED in 1.91.0 (from July 2024)
|
||||
static inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
|
||||
static inline void PopButtonRepeat() { PopItemFlag(); }
|
||||
static inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
|
||||
static inline void PopTabStop() { PopItemFlag(); }
|
||||
inline void PushButtonRepeat(bool repeat) { PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); }
|
||||
inline void PopButtonRepeat() { PopItemFlag(); }
|
||||
inline void PushTabStop(bool tab_stop) { PushItemFlag(ImGuiItemFlags_NoTabStop, !tab_stop); }
|
||||
inline void PopTabStop() { PopItemFlag(); }
|
||||
IMGUI_API ImVec2 GetContentRegionMax(); // Content boundaries max (e.g. window boundaries including scrolling, or current column boundaries). You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMin(); // Content boundaries min for the window (roughly (0,0)-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
IMGUI_API ImVec2 GetWindowContentRegionMax(); // Content boundaries max for the window (roughly (0,0)+Size-Scroll), in window-local coordinates. You should never need this. Always use GetCursorScreenPos() and GetContentRegionAvail()!
|
||||
// OBSOLETED in 1.90.0 (from September 2023)
|
||||
static inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
|
||||
static inline void EndChildFrame() { EndChild(); }
|
||||
//static inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//static inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
static inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
inline bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags window_flags = 0) { return BeginChild(id, size, ImGuiChildFlags_FrameStyle, window_flags); }
|
||||
inline void EndChildFrame() { EndChild(); }
|
||||
//inline bool BeginChild(const char* str_id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags){ return BeginChild(str_id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
//inline bool BeginChild(ImGuiID id, const ImVec2& size_arg, bool borders, ImGuiWindowFlags window_flags) { return BeginChild(id, size_arg, borders ? ImGuiChildFlags_Borders : ImGuiChildFlags_None, window_flags); } // Unnecessary as true == ImGuiChildFlags_Borders
|
||||
inline void ShowStackToolWindow(bool* p_open = NULL) { ShowIDStackToolWindow(p_open); }
|
||||
IMGUI_API bool Combo(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int popup_max_height_in_items = -1);
|
||||
IMGUI_API bool ListBox(const char* label, int* current_item, bool (*old_callback)(void* user_data, int idx, const char** out_text), void* user_data, int items_count, int height_in_items = -1);
|
||||
// OBSOLETED in 1.89.7 (from June 2023)
|
||||
|
||||
198
imgui_demo.cpp
198
imgui_demo.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.4
|
||||
// (demo code)
|
||||
|
||||
// Help:
|
||||
@@ -551,11 +551,13 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::Checkbox("io.ConfigViewportsNoAutoMerge", &io.ConfigViewportsNoAutoMerge);
|
||||
ImGui::SameLine(); HelpMarker("Set to make all floating imgui windows always create their own viewport. Otherwise, they are merged into the main host viewports when overlapping it.");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoTaskBarIcon", &io.ConfigViewportsNoTaskBarIcon);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the task bar icon state right away).");
|
||||
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoDecoration", &io.ConfigViewportsNoDecoration);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the decoration right away).");
|
||||
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
|
||||
ImGui::Checkbox("io.ConfigViewportsNoDefaultParent", &io.ConfigViewportsNoDefaultParent);
|
||||
ImGui::SameLine(); HelpMarker("Toggling this at runtime is normally unsupported (most platform backends won't refresh the parenting right away).");
|
||||
ImGui::SameLine(); HelpMarker("(note: some platform backends may not reflect a change of this value for existing viewports, and may need the viewport to be recreated)");
|
||||
ImGui::Checkbox("io.ConfigViewportsPlatformFocusSetsImGuiFocus", &io.ConfigViewportsPlatformFocusSetsImGuiFocus);
|
||||
ImGui::SameLine(); HelpMarker("When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).");
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
@@ -638,6 +640,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasSetMousePos", &io.BackendFlags, ImGuiBackendFlags_HasSetMousePos);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: PlatformHasViewports", &io.BackendFlags, ImGuiBackendFlags_PlatformHasViewports);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasMouseHoveredViewport",&io.BackendFlags, ImGuiBackendFlags_HasMouseHoveredViewport);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: HasParentViewport", &io.BackendFlags, ImGuiBackendFlags_HasParentViewport);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasVtxOffset", &io.BackendFlags, ImGuiBackendFlags_RendererHasVtxOffset);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasTextures", &io.BackendFlags, ImGuiBackendFlags_RendererHasTextures);
|
||||
ImGui::CheckboxFlags("io.BackendFlags: RendererHasViewports", &io.BackendFlags, ImGuiBackendFlags_RendererHasViewports);
|
||||
@@ -2236,7 +2239,7 @@ static void DemoWindowWidgetsQueryingStatuses()
|
||||
);
|
||||
ImGui::BulletText(
|
||||
"with Hovering Delay or Stationary test:\n"
|
||||
"IsItemHovered() = = %d\n"
|
||||
"IsItemHovered() = %d\n"
|
||||
"IsItemHovered(_Stationary) = %d\n"
|
||||
"IsItemHovered(_DelayShort) = %d\n"
|
||||
"IsItemHovered(_DelayNormal) = %d\n"
|
||||
@@ -3310,7 +3313,7 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
|
||||
ImGui::BeginTable("##Split", 2, ImGuiTableFlags_Resizable | ImGuiTableFlags_NoSavedSettings | ImGuiTableFlags_NoPadOuterX);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 0.70f);
|
||||
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 0.30f);
|
||||
//ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacingY, 0.0f);
|
||||
//ImGui::PushStyleVarY(ImGuiStyleVar_ItemSpacing, 0.0f);
|
||||
}
|
||||
|
||||
ImGuiListClipper clipper;
|
||||
@@ -3460,6 +3463,18 @@ static void DemoWindowWidgetsSelectionAndMultiSelect(ImGuiDemoWindowData* demo_d
|
||||
// [SECTION] DemoWindowWidgetsTabs()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void EditTabBarFittingPolicyFlags(ImGuiTabBarFlags* p_flags)
|
||||
{
|
||||
if ((*p_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
|
||||
*p_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyMixed", p_flags, ImGuiTabBarFlags_FittingPolicyMixed))
|
||||
*p_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyMixed);
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyShrink", p_flags, ImGuiTabBarFlags_FittingPolicyShrink))
|
||||
*p_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyShrink);
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", p_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
||||
*p_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
||||
}
|
||||
|
||||
static void DemoWindowWidgetsTabs()
|
||||
{
|
||||
IMGUI_DEMO_MARKER("Widgets/Tabs");
|
||||
@@ -3502,12 +3517,7 @@ static void DemoWindowWidgetsTabs()
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_NoCloseWithMiddleMouseButton", &tab_bar_flags, ImGuiTabBarFlags_NoCloseWithMiddleMouseButton);
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_DrawSelectedOverline", &tab_bar_flags, ImGuiTabBarFlags_DrawSelectedOverline);
|
||||
if ((tab_bar_flags & ImGuiTabBarFlags_FittingPolicyMask_) == 0)
|
||||
tab_bar_flags |= ImGuiTabBarFlags_FittingPolicyDefault_;
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
||||
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
||||
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
||||
EditTabBarFittingPolicyFlags(&tab_bar_flags);
|
||||
|
||||
// Tab Bar
|
||||
ImGui::AlignTextToFramePadding();
|
||||
@@ -3556,12 +3566,8 @@ static void DemoWindowWidgetsTabs()
|
||||
ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
|
||||
|
||||
// Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
|
||||
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyResizeDown;
|
||||
ImGui::CheckboxFlags("ImGuiTabBarFlags_TabListPopupButton", &tab_bar_flags, ImGuiTabBarFlags_TabListPopupButton);
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyResizeDown", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyResizeDown))
|
||||
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyResizeDown);
|
||||
if (ImGui::CheckboxFlags("ImGuiTabBarFlags_FittingPolicyScroll", &tab_bar_flags, ImGuiTabBarFlags_FittingPolicyScroll))
|
||||
tab_bar_flags &= ~(ImGuiTabBarFlags_FittingPolicyMask_ ^ ImGuiTabBarFlags_FittingPolicyScroll);
|
||||
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyShrink;
|
||||
EditTabBarFittingPolicyFlags(&tab_bar_flags);
|
||||
|
||||
if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
||||
{
|
||||
@@ -3786,6 +3792,8 @@ static void DemoWindowWidgetsTextInput()
|
||||
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_AllowTabInput;
|
||||
HelpMarker("You can use the ImGuiInputTextFlags_CallbackResize facility if you need to wire InputTextMultiline() to a dynamic string type. See misc/cpp/imgui_stdlib.h for an example. (This is not demonstrated in imgui_demo.cpp because we don't want to include <string> in here)");
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_ReadOnly", &flags, ImGuiInputTextFlags_ReadOnly);
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_WordWrap", &flags, ImGuiInputTextFlags_WordWrap);
|
||||
ImGui::SameLine(); HelpMarker("Feature is currently in Beta. Please read comments in imgui.h");
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_AllowTabInput", &flags, ImGuiInputTextFlags_AllowTabInput);
|
||||
ImGui::SameLine(); HelpMarker("When _AllowTabInput is set, passing through the widget with Tabbing doesn't automatically activate it, in order to also cycling through subsequent widgets.");
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_CtrlEnterForNewLine", &flags, ImGuiInputTextFlags_CtrlEnterForNewLine);
|
||||
@@ -3933,10 +3941,13 @@ static void DemoWindowWidgetsTextInput()
|
||||
// For this demo we are using ImVector as a string container.
|
||||
// Note that because we need to store a terminating zero character, our size/capacity are 1 more
|
||||
// than usually reported by a typical string class.
|
||||
static ImGuiInputTextFlags flags = ImGuiInputTextFlags_None;
|
||||
ImGui::CheckboxFlags("ImGuiInputTextFlags_WordWrap", &flags, ImGuiInputTextFlags_WordWrap);
|
||||
|
||||
static ImVector<char> my_str;
|
||||
if (my_str.empty())
|
||||
my_str.push_back(0);
|
||||
Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16));
|
||||
Funcs::MyInputTextMultiline("##MyStr", &my_str, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 16), flags);
|
||||
ImGui::Text("Data: %p\nSize: %d\nCapacity: %d", (void*)my_str.begin(), my_str.size(), my_str.capacity());
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -4868,15 +4879,18 @@ static void DemoWindowLayout()
|
||||
|
||||
ImGui::Checkbox("Decoration", &enable_extra_decorations);
|
||||
|
||||
ImGui::PushItemWidth(ImGui::GetFontSize() * 10);
|
||||
enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Track", &enable_track);
|
||||
ImGui::PushItemWidth(100);
|
||||
ImGui::SameLine(140); enable_track |= ImGui::DragInt("##item", &track_item, 0.25f, 0, 99, "Item = %d");
|
||||
|
||||
bool scroll_to_off = ImGui::Button("Scroll Offset");
|
||||
ImGui::SameLine(140); scroll_to_off |= ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px");
|
||||
bool scroll_to_off = ImGui::DragFloat("##off", &scroll_to_off_px, 1.00f, 0, FLT_MAX, "+%.0f px");
|
||||
ImGui::SameLine();
|
||||
scroll_to_off |= ImGui::Button("Scroll Offset");
|
||||
|
||||
bool scroll_to_pos = ImGui::Button("Scroll To Pos");
|
||||
ImGui::SameLine(140); scroll_to_pos |= ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px");
|
||||
bool scroll_to_pos = ImGui::DragFloat("##pos", &scroll_to_pos_px, 1.00f, -10, FLT_MAX, "X/Y = %.0f px");
|
||||
ImGui::SameLine();
|
||||
scroll_to_pos |= ImGui::Button("Scroll To Pos");
|
||||
ImGui::PopItemWidth();
|
||||
|
||||
if (scroll_to_off || scroll_to_pos)
|
||||
@@ -5260,7 +5274,7 @@ static void DemoWindowPopups()
|
||||
// Typical use for regular windows:
|
||||
// bool my_tool_is_active = false; if (ImGui::Button("Open")) my_tool_is_active = true; [...] if (my_tool_is_active) Begin("My Tool", &my_tool_is_active) { [...] } End();
|
||||
// Typical use for popups:
|
||||
// if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup") { [...] EndPopup(); }
|
||||
// if (ImGui::Button("Open")) ImGui::OpenPopup("MyPopup"); if (ImGui::BeginPopup("MyPopup")) { [...] EndPopup(); }
|
||||
|
||||
// With popups we have to go through a library call (here OpenPopup) to manipulate the visibility state.
|
||||
// This may be a bit confusing at first but it should quickly make sense. Follow on the examples below.
|
||||
@@ -5846,7 +5860,7 @@ static void DemoWindowTables()
|
||||
ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text);
|
||||
ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton);
|
||||
ImGui::Checkbox("Display headers", &display_headers);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers");
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers)");
|
||||
PopStyleCompact();
|
||||
|
||||
if (ImGui::BeginTable("table1", 3, flags))
|
||||
@@ -7339,7 +7353,7 @@ static void DemoWindowTables()
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_BordersH", &flags, ImGuiTableFlags_BordersH);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH);
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers");
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appear in Headers)");
|
||||
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBodyUntilResize", &flags, ImGuiTableFlags_NoBordersInBodyUntilResize); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body until hovered for resize (borders will always appear in Headers)");
|
||||
ImGui::TreePop();
|
||||
}
|
||||
@@ -8177,6 +8191,9 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
ImGui::Separator();
|
||||
ImGui::Text("sizeof(size_t): %d, sizeof(ImDrawIdx): %d, sizeof(ImDrawVert): %d", (int)sizeof(size_t), (int)sizeof(ImDrawIdx), (int)sizeof(ImDrawVert));
|
||||
ImGui::Text("define: __cplusplus=%d", (int)__cplusplus);
|
||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||
ImGui::Text("define: IMGUI_ENABLE_TEST_ENGINE");
|
||||
#endif
|
||||
#ifdef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
ImGui::Text("define: IMGUI_DISABLE_OBSOLETE_FUNCTIONS");
|
||||
#endif
|
||||
@@ -8285,6 +8302,7 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos) ImGui::Text(" HasSetMousePos");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports) ImGui::Text(" PlatformHasViewports");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)ImGui::Text(" HasMouseHoveredViewport");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_HasParentViewport) ImGui::Text(" HasParentViewport");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) ImGui::Text(" RendererHasVtxOffset");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_RendererHasTextures) ImGui::Text(" RendererHasTextures");
|
||||
if (io.BackendFlags & ImGuiBackendFlags_RendererHasViewports) ImGui::Text(" RendererHasViewports");
|
||||
@@ -8320,22 +8338,34 @@ void ImGui::ShowAboutWindow(bool* p_open)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options.
|
||||
// Here we use the simplified Combo() api that packs items into a single literal string.
|
||||
// Useful for quick combo boxes where the choices are known locally.
|
||||
bool ImGui::ShowStyleSelector(const char* label)
|
||||
{
|
||||
// FIXME: This is a bit tricky to get right as style are functions, they don't register a name nor the fact that one is active.
|
||||
// So we keep track of last active one among our limited selection.
|
||||
static int style_idx = -1;
|
||||
if (ImGui::Combo(label, &style_idx, "Dark\0Light\0Classic\0"))
|
||||
const char* style_names[] = { "Dark", "Light", "Classic" };
|
||||
bool ret = false;
|
||||
if (ImGui::BeginCombo(label, (style_idx >= 0 && style_idx < IM_ARRAYSIZE(style_names)) ? style_names[style_idx] : ""))
|
||||
{
|
||||
switch (style_idx)
|
||||
for (int n = 0; n < IM_ARRAYSIZE(style_names); n++)
|
||||
{
|
||||
case 0: ImGui::StyleColorsDark(); break;
|
||||
case 1: ImGui::StyleColorsLight(); break;
|
||||
case 2: ImGui::StyleColorsClassic(); break;
|
||||
if (ImGui::Selectable(style_names[n], style_idx == n, ImGuiSelectableFlags_SelectOnNav))
|
||||
{
|
||||
style_idx = n;
|
||||
ret = true;
|
||||
switch (style_idx)
|
||||
{
|
||||
case 0: ImGui::StyleColorsDark(); break;
|
||||
case 1: ImGui::StyleColorsLight(); break;
|
||||
case 2: ImGui::StyleColorsClassic(); break;
|
||||
}
|
||||
}
|
||||
else if (style_idx == n)
|
||||
ImGui::SetItemDefaultFocus();
|
||||
}
|
||||
return true;
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const char* GetTreeLinesFlagsName(ImGuiTreeNodeFlags flags)
|
||||
@@ -8421,7 +8451,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f");
|
||||
SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f");
|
||||
SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f");
|
||||
SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f");
|
||||
SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f");
|
||||
|
||||
SeparatorText("Borders");
|
||||
@@ -8435,16 +8464,22 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 12.0f, "%.0f");
|
||||
SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f");
|
||||
SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 12.0f, "%.0f");
|
||||
SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
||||
SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
SeparatorText("Scrollbar");
|
||||
SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f");
|
||||
SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f");
|
||||
SliderFloat("ScrollbarPadding", &style.ScrollbarPadding, 0.0f, 10.0f, "%.0f");
|
||||
|
||||
SeparatorText("Tabs");
|
||||
SliderFloat("TabBorderSize", &style.TabBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
SliderFloat("TabBarBorderSize", &style.TabBarBorderSize, 0.0f, 2.0f, "%.0f");
|
||||
SliderFloat("TabBarOverlineSize", &style.TabBarOverlineSize, 0.0f, 3.0f, "%.0f");
|
||||
SameLine(); HelpMarker("Overline is only drawn over the selected tab when ImGuiTabBarFlags_DrawSelectedOverline is set.");
|
||||
DragFloat("TabCloseButtonMinWidthSelected", &style.TabCloseButtonMinWidthSelected, 0.1f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthSelected < 0.0f) ? "%.0f (Always)" : "%.0f");
|
||||
DragFloat("TabCloseButtonMinWidthUnselected", &style.TabCloseButtonMinWidthUnselected, 0.1f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthUnselected < 0.0f) ? "%.0f (Always)" : "%.0f");
|
||||
DragFloat("TabMinWidthBase", &style.TabMinWidthBase, 0.5f, 1.0f, 500.0f, "%.0f");
|
||||
DragFloat("TabMinWidthShrink", &style.TabMinWidthShrink, 0.5f, 1.0f, 500.0f, "%0.f");
|
||||
DragFloat("TabCloseButtonMinWidthSelected", &style.TabCloseButtonMinWidthSelected, 0.5f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthSelected < 0.0f) ? "%.0f (Always)" : "%.0f");
|
||||
DragFloat("TabCloseButtonMinWidthUnselected", &style.TabCloseButtonMinWidthUnselected, 0.5f, -1.0f, 100.0f, (style.TabCloseButtonMinWidthUnselected < 0.0f) ? "%.0f (Always)" : "%.0f");
|
||||
SliderFloat("TabRounding", &style.TabRounding, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
SeparatorText("Tables");
|
||||
@@ -8487,6 +8522,8 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
SliderFloat("ImageBorderSize", &style.ImageBorderSize, 0.0f, 1.0f, "%.0f");
|
||||
|
||||
SeparatorText("Docking");
|
||||
//SetCursorPosX(GetCursorPosX() + CalcItemWidth() - GetFrameHeight());
|
||||
Checkbox("DockingNodeHasCloseButton", &style.DockingNodeHasCloseButton);
|
||||
SliderFloat("DockingSeparatorSize", &style.DockingSeparatorSize, 0.0f, 12.0f, "%.0f");
|
||||
|
||||
SeparatorText("Tooltips");
|
||||
@@ -9382,10 +9419,9 @@ static void ShowExampleAppLayout(bool* p_open)
|
||||
ImGui::BeginChild("left pane", ImVec2(150, 0), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeX);
|
||||
for (int i = 0; i < 100; i++)
|
||||
{
|
||||
// FIXME: Good candidate to use ImGuiSelectableFlags_SelectOnNav
|
||||
char label[128];
|
||||
sprintf(label, "MyObject %d", i);
|
||||
if (ImGui::Selectable(label, selected == i))
|
||||
if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SelectOnNav))
|
||||
selected = i;
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -9737,7 +9773,7 @@ static void ShowExampleAppConstrainedResize(bool* p_open)
|
||||
IMGUI_DEMO_MARKER("Examples/Constrained Resizing window");
|
||||
if (ImGui::GetIO().KeyShift)
|
||||
{
|
||||
// Display a dummy viewport (in your real app you would likely use ImageButton() to display a texture.
|
||||
// Display a dummy viewport (in your real app you would likely use ImageButton() to display a texture)
|
||||
ImVec2 avail_size = ImGui::GetContentRegionAvail();
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
ImGui::ColorButton("viewport", ImVec4(0.5f, 0.2f, 0.5f, 1.0f), ImGuiColorEditFlags_NoTooltip | ImGuiColorEditFlags_NoDragDrop, avail_size);
|
||||
@@ -10212,37 +10248,27 @@ static void ShowExampleAppCustomRendering(bool* p_open)
|
||||
// [SECTION] Example App: Docking, DockSpace / ShowExampleAppDockSpace()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Demonstrate using DockSpace() to create an explicit docking node within an existing window.
|
||||
// Note: You can use most Docking facilities without calling any API. You DO NOT need to call DockSpace() to use Docking!
|
||||
// - Drag from window title bar or their tab to dock/undock. Hold SHIFT to disable docking.
|
||||
// - Drag from window menu button (upper-left button) to undock an entire node (all windows).
|
||||
// - When io.ConfigDockingWithShift == true, you instead need to hold SHIFT to enable docking.
|
||||
// About dockspaces:
|
||||
// - Use DockSpace() to create an explicit dock node _within_ an existing window.
|
||||
// - Use DockSpaceOverViewport() to create an explicit dock node covering the screen or a specific viewport.
|
||||
// This is often used with ImGuiDockNodeFlags_PassthruCentralNode.
|
||||
// - Important: Dockspaces need to be submitted _before_ any window they can host. Submit it early in your frame! (*)
|
||||
// - Important: Dockspaces need to be kept alive if hidden, otherwise windows docked into it will be undocked.
|
||||
// e.g. if you have multiple tabs with a dockspace inside each tab: submit the non-visible dockspaces with ImGuiDockNodeFlags_KeepAliveOnly.
|
||||
// (*) because of this constraint, the implicit \"Debug\" window can not be docked into an explicit DockSpace() node,
|
||||
// because that window is submitted as part of the part of the NewFrame() call. An easy workaround is that you can create
|
||||
// your own implicit "Debug##2" window after calling DockSpace() and leave it in the window stack for anyone to use.
|
||||
// Demonstrate using DockSpace() to create an explicit docking node within an existing window, with various options.
|
||||
// THIS IS A DEMO FOR ADVANCED USAGE OF DockSpace().
|
||||
// MOST REGULAR APPLICATIONS WHO WANT TO ALLOW DOCKING WINDOWS ON THE EDGE OF YOUR SCREEN CAN SIMPLY USE:
|
||||
// ImGui::NewFrame();
|
||||
// ImGui::DockSpaceOverViewport(); // Create a dockspace in main viewport
|
||||
// OR:
|
||||
// ImGui::NewFrame();
|
||||
// ImGui::DockSpaceOverViewport(0, nullptr, ImGuiDockNodeFlags_PassthruCentralNode); // Create a dockspace in main viewport, where central node is transparent.
|
||||
// Read https://github.com/ocornut/imgui/wiki/Docking for details.
|
||||
// The reasons we do not use DockSpaceOverViewport() in this demo is because:
|
||||
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
|
||||
// which is mostly to showcase the idea that DockSpace() may be submitted anywhere.
|
||||
// - (2) we allow the host window to have padding (when opt_padding == true)
|
||||
// - (3) we expose many flags and need a way to have them visible.
|
||||
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
|
||||
// in your code, but we don't here because we allow the window to be floating)
|
||||
void ShowExampleAppDockSpace(bool* p_open)
|
||||
{
|
||||
// READ THIS !!!
|
||||
// TL;DR; this demo is more complicated than what most users you would normally use.
|
||||
// If we remove all options we are showcasing, this demo would become:
|
||||
// void ShowExampleAppDockSpace()
|
||||
// {
|
||||
// ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport());
|
||||
// }
|
||||
// In most cases you should be able to just call DockSpaceOverViewport() and ignore all the code below!
|
||||
// If we remove all options we are showcasing, this demo would become a simple call to ImGui::DockSpaceOverViewport() !!
|
||||
// In this specific demo, we are not using DockSpaceOverViewport() because:
|
||||
// - (1) we allow the host window to be floating/moveable instead of filling the viewport (when opt_fullscreen == false)
|
||||
// - (2) we allow the host window to have padding (when opt_padding == true)
|
||||
// - (3) we expose many flags and need a way to have them visible.
|
||||
// - (4) we have a local menu bar in the host window (vs. you could use BeginMainMenuBar() + DockSpaceOverViewport()
|
||||
// in your code, but we don't here because we allow the window to be floating)
|
||||
|
||||
static bool opt_fullscreen = true;
|
||||
static bool opt_padding = false;
|
||||
@@ -10287,6 +10313,8 @@ void ShowExampleAppDockSpace(bool* p_open)
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
// Submit the DockSpace
|
||||
// REMINDER: THIS IS A DEMO FOR ADVANCED USAGE OF DockSpace()!
|
||||
// MOST REGULAR APPLICATIONS WILL SIMPLY WANT TO CALL DockSpaceOverViewport(). READ COMMENTS ABOVE.
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_DockingEnable)
|
||||
{
|
||||
@@ -10298,6 +10326,7 @@ void ShowExampleAppDockSpace(bool* p_open)
|
||||
ShowDockingDisabledMessage();
|
||||
}
|
||||
|
||||
// Show demo options and help
|
||||
if (ImGui::BeginMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("Options"))
|
||||
@@ -10320,16 +10349,23 @@ void ShowExampleAppDockSpace(bool* p_open)
|
||||
*p_open = false;
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
HelpMarker(
|
||||
"When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
|
||||
"- Drag from window title bar or their tab to dock/undock." "\n"
|
||||
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
|
||||
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
|
||||
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)" "\n"
|
||||
"This demo app has nothing to do with enabling docking!" "\n\n"
|
||||
"This demo app only demonstrate the use of ImGui::DockSpace() which allows you to manually create a docking node _within_ another window." "\n\n"
|
||||
"Read comments in ShowExampleAppDockSpace() for more details.");
|
||||
|
||||
if (ImGui::BeginMenu("Help"))
|
||||
{
|
||||
ImGui::TextUnformatted(
|
||||
"This demo has nothing to do with enabling docking!" "\n"
|
||||
"This demo only demonstrate the use of ImGui::DockSpace() which allows you to manually\ncreate a docking node _within_ another window." "\n"
|
||||
"Most application can simply call ImGui::DockSpaceOverViewport() and be done with it.");
|
||||
ImGui::Separator();
|
||||
ImGui::TextUnformatted("When docking is enabled, you can ALWAYS dock MOST window into another! Try it now!" "\n"
|
||||
"- Drag from window title bar or their tab to dock/undock." "\n"
|
||||
"- Drag from window menu button (upper-left button) to undock an entire node (all windows)." "\n"
|
||||
"- Hold SHIFT to disable docking (if io.ConfigDockingWithShift == false, default)" "\n"
|
||||
"- Hold SHIFT to enable docking (if io.ConfigDockingWithShift == true)");
|
||||
ImGui::Separator();
|
||||
ImGui::TextUnformatted("More details:"); ImGui::Bullet(); ImGui::SameLine(); ImGui::TextLinkOpenURL("Docking Wiki page", "https://github.com/ocornut/imgui/wiki/Docking");
|
||||
ImGui::BulletText("Read comments in ShowExampleAppDockSpace()");
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
ImGui::EndMenuBar();
|
||||
}
|
||||
|
||||
|
||||
218
imgui_draw.cpp
218
imgui_draw.cpp
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.4
|
||||
// (drawing and font code)
|
||||
|
||||
/*
|
||||
@@ -48,7 +48,7 @@ Index of this file:
|
||||
#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff)
|
||||
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
|
||||
#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
|
||||
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
|
||||
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
|
||||
#endif
|
||||
|
||||
// Clang/GCC warnings with -Weverything
|
||||
@@ -242,6 +242,7 @@ void ImGui::StyleColorsDark(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_UnsavedMarker] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
@@ -309,6 +310,7 @@ void ImGui::StyleColorsClassic(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f);
|
||||
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
|
||||
colors[ImGuiCol_UnsavedMarker] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f);
|
||||
colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
|
||||
@@ -377,6 +379,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
|
||||
colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border];
|
||||
colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
|
||||
colors[ImGuiCol_UnsavedMarker] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f);
|
||||
colors[ImGuiCol_NavCursor] = colors[ImGuiCol_HeaderHovered];
|
||||
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f);
|
||||
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.20f, 0.20f, 0.20f, 0.20f);
|
||||
@@ -484,9 +487,10 @@ void ImDrawList::_ClearFreeMemory()
|
||||
_Splitter.ClearFreeMemory();
|
||||
}
|
||||
|
||||
// Note: For multi-threaded rendering, consider using `imgui_threaded_rendering` from https://github.com/ocornut/imgui_club
|
||||
ImDrawList* ImDrawList::CloneOutput() const
|
||||
{
|
||||
ImDrawList* dst = IM_NEW(ImDrawList(_Data));
|
||||
ImDrawList* dst = IM_NEW(ImDrawList(NULL));
|
||||
dst->CmdBuffer = CmdBuffer;
|
||||
dst->IdxBuffer = IdxBuffer;
|
||||
dst->VtxBuffer = VtxBuffer;
|
||||
@@ -523,6 +527,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* userdata, size_t use
|
||||
{
|
||||
IM_ASSERT_PARANOID(CmdBuffer.Size > 0);
|
||||
ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1];
|
||||
IM_ASSERT(callback != NULL);
|
||||
IM_ASSERT(curr_cmd->UserCallback == NULL);
|
||||
if (curr_cmd->ElemCount != 0)
|
||||
{
|
||||
@@ -1723,7 +1728,7 @@ void ImDrawList::AddText(ImFont* font, float font_size, const ImVec2& pos, ImU32
|
||||
clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z);
|
||||
clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w);
|
||||
}
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL);
|
||||
font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, (cpu_fine_clip_rect != NULL) ? ImDrawTextFlags_CpuFineClip : ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end)
|
||||
@@ -2318,17 +2323,16 @@ void ImDrawData::DeIndexAllBuffers()
|
||||
{
|
||||
ImVector<ImDrawVert> new_vtx_buffer;
|
||||
TotalVtxCount = TotalIdxCount = 0;
|
||||
for (int i = 0; i < CmdListsCount; i++)
|
||||
for (ImDrawList* draw_list : CmdLists)
|
||||
{
|
||||
ImDrawList* cmd_list = CmdLists[i];
|
||||
if (cmd_list->IdxBuffer.empty())
|
||||
if (draw_list->IdxBuffer.empty())
|
||||
continue;
|
||||
new_vtx_buffer.resize(cmd_list->IdxBuffer.Size);
|
||||
for (int j = 0; j < cmd_list->IdxBuffer.Size; j++)
|
||||
new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]];
|
||||
cmd_list->VtxBuffer.swap(new_vtx_buffer);
|
||||
cmd_list->IdxBuffer.resize(0);
|
||||
TotalVtxCount += cmd_list->VtxBuffer.Size;
|
||||
new_vtx_buffer.resize(draw_list->IdxBuffer.Size);
|
||||
for (int j = 0; j < draw_list->IdxBuffer.Size; j++)
|
||||
new_vtx_buffer[j] = draw_list->VtxBuffer[draw_list->IdxBuffer[j]];
|
||||
draw_list->VtxBuffer.swap(new_vtx_buffer);
|
||||
draw_list->IdxBuffer.resize(0);
|
||||
TotalVtxCount += draw_list->VtxBuffer.Size;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2463,8 +2467,10 @@ const char* ImTextureDataGetFormatName(ImTextureFormat format)
|
||||
|
||||
void ImTextureData::Create(ImTextureFormat format, int w, int h)
|
||||
{
|
||||
IM_ASSERT(Status == ImTextureStatus_Destroyed);
|
||||
DestroyPixels();
|
||||
Format = format;
|
||||
Status = ImTextureStatus_WantCreate;
|
||||
Width = w;
|
||||
Height = h;
|
||||
BytesPerPixel = ImTextureDataGetFormatBytesPerPixel(format);
|
||||
@@ -2636,6 +2642,7 @@ ImFontAtlas::ImFontAtlas()
|
||||
TexMinHeight = 128;
|
||||
TexMaxWidth = 8192;
|
||||
TexMaxHeight = 8192;
|
||||
TexRef._TexID = ImTextureID_Invalid;
|
||||
RendererHasTextures = false; // Assumed false by default, as apps can call e.g Atlas::Build() after backend init and before ImGui can update.
|
||||
TexNextUniqueID = 1;
|
||||
FontNextUniqueID = 1;
|
||||
@@ -2745,10 +2752,9 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
||||
if (atlas->Builder == NULL) // This will only happen if fonts were not already loaded.
|
||||
ImFontAtlasBuildMain(atlas);
|
||||
}
|
||||
else // Legacy backend
|
||||
{
|
||||
// Legacy backend
|
||||
if (!atlas->RendererHasTextures)
|
||||
IM_ASSERT_USER_ERROR(atlas->TexIsBuilt, "Backend does not support ImGuiBackendFlags_RendererHasTextures, and font atlas is not built! Update backend OR make sure you called ImGui_ImplXXXX_NewFrame() function for renderer backend, which should call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8().");
|
||||
}
|
||||
if (atlas->TexIsBuilt && atlas->Builder->PreloadedAllGlyphsRanges)
|
||||
IM_ASSERT_USER_ERROR(atlas->RendererHasTextures == false, "Called ImFontAtlas::Build() before ImGuiBackendFlags_RendererHasTextures got set! With new backends: you don't need to call Build().");
|
||||
|
||||
@@ -2793,20 +2799,29 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
||||
if (tex->Status == ImTextureStatus_WantCreate && atlas->RendererHasTextures)
|
||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture's TexID/BackendUserData but did not update Status to OK.");
|
||||
|
||||
// Request destroy
|
||||
// - Keep bool to true in order to differentiate a planned destroy vs a destroy decided by the backend.
|
||||
// - We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
||||
if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_Destroyed && tex->Status != ImTextureStatus_WantDestroy)
|
||||
{
|
||||
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
|
||||
tex->Status = ImTextureStatus_WantDestroy;
|
||||
}
|
||||
|
||||
// If a texture has never reached the backend, they don't need to know about it.
|
||||
// (note: backends between 1.92.0 and 1.92.4 could set an already destroyed texture to ImTextureStatus_WantDestroy
|
||||
// when invalidating graphics objects twice, which would previously remove it from the list and crash.)
|
||||
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
|
||||
tex->Status = ImTextureStatus_Destroyed;
|
||||
|
||||
// Process texture being destroyed
|
||||
if (tex->Status == ImTextureStatus_Destroyed)
|
||||
{
|
||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL && "Backend set texture Status to Destroyed but did not clear TexID/BackendUserData!");
|
||||
if (tex->WantDestroyNextFrame)
|
||||
remove_from_list = true; // Destroy was scheduled by us
|
||||
else
|
||||
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend (e.g. freed resources mid-run)
|
||||
}
|
||||
else if (tex->WantDestroyNextFrame && tex->Status != ImTextureStatus_WantDestroy)
|
||||
{
|
||||
// Request destroy. Keep bool as it allows us to keep track of things.
|
||||
// We don't destroy pixels right away, as backend may have an in-flight copy from RAM.
|
||||
IM_ASSERT(tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantUpdates);
|
||||
tex->Status = ImTextureStatus_WantDestroy;
|
||||
tex->Status = ImTextureStatus_WantCreate; // Destroy was done was backend: recreate it (e.g. freed resources mid-run)
|
||||
}
|
||||
|
||||
// The backend may need defer destroying by a few frames, to handle texture used by previous in-flight rendering.
|
||||
@@ -2814,13 +2829,10 @@ void ImFontAtlasUpdateNewFrame(ImFontAtlas* atlas, int frame_count, bool rendere
|
||||
if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
tex->UnusedFrames++;
|
||||
|
||||
// If a texture has never reached the backend, they don't need to know about it.
|
||||
if (tex->Status == ImTextureStatus_WantDestroy && tex->TexID == ImTextureID_Invalid && tex->BackendUserData == NULL)
|
||||
remove_from_list = true;
|
||||
|
||||
// Destroy and remove
|
||||
if (remove_from_list)
|
||||
{
|
||||
IM_ASSERT(atlas->TexData != tex);
|
||||
tex->DestroyPixels();
|
||||
IM_DELETE(tex);
|
||||
atlas->TexList.erase(atlas->TexList.begin() + tex_n);
|
||||
@@ -2960,7 +2972,7 @@ void ImFontAtlasTextureBlockQueueUpload(ImFontAtlas* atlas, ImTextureData* tex,
|
||||
tex->UsedRect.h = (unsigned short)(ImMax(tex->UsedRect.y + tex->UsedRect.h, req.y + req.h) - tex->UsedRect.y);
|
||||
atlas->TexIsBuilt = false;
|
||||
|
||||
// No need to queue if status is _WantCreate
|
||||
// No need to queue if status is == ImTextureStatus_WantCreate
|
||||
if (tex->Status == ImTextureStatus_OK || tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
tex->Status = ImTextureStatus_WantUpdates;
|
||||
@@ -3029,7 +3041,7 @@ ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg_in)
|
||||
else
|
||||
{
|
||||
IM_ASSERT(Fonts.Size > 0 && "Cannot use MergeMode for the first font"); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font.
|
||||
font = Fonts.back();
|
||||
font = font_cfg_in->DstFont ? font_cfg_in->DstFont : Fonts.back();
|
||||
}
|
||||
|
||||
// Add to list
|
||||
@@ -3100,6 +3112,7 @@ static const char* GetDefaultCompressedFontDataTTF(int* out_size);
|
||||
#endif
|
||||
|
||||
// Load embedded ProggyClean.ttf at size 13, disable oversampling
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
{
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
@@ -3118,9 +3131,7 @@ ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template)
|
||||
|
||||
int ttf_compressed_size = 0;
|
||||
const char* ttf_compressed = GetDefaultCompressedFontDataTTF(&ttf_compressed_size);
|
||||
const ImWchar* glyph_ranges = font_cfg.GlyphRanges != NULL ? font_cfg.GlyphRanges : GetGlyphRangesDefault();
|
||||
ImFont* font = AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg, glyph_ranges);
|
||||
return font;
|
||||
return AddFontFromMemoryCompressedTTF(ttf_compressed, ttf_compressed_size, font_cfg.SizePixels, &font_cfg);
|
||||
#else
|
||||
IM_ASSERT(0 && "AddFontDefault() disabled in this build.");
|
||||
IM_UNUSED(font_cfg_template);
|
||||
@@ -3367,11 +3378,7 @@ void ImFontAtlasBuildMain(ImFontAtlas* atlas)
|
||||
{
|
||||
IM_ASSERT(!atlas->Locked && "Cannot modify a locked ImFontAtlas!");
|
||||
if (atlas->TexData && atlas->TexData->Format != atlas->TexDesiredFormat)
|
||||
{
|
||||
ImVec2i new_tex_size = ImFontAtlasTextureGetSizeEstimate(atlas);
|
||||
ImFontAtlasBuildDestroy(atlas);
|
||||
ImFontAtlasTextureAdd(atlas, new_tex_size.x, new_tex_size.y);
|
||||
}
|
||||
ImFontAtlasBuildClear(atlas);
|
||||
|
||||
if (atlas->Builder == NULL)
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
@@ -3977,7 +3984,6 @@ ImTextureData* ImFontAtlasTextureAdd(ImFontAtlas* atlas, int w, int h)
|
||||
}
|
||||
|
||||
new_tex->Create(atlas->TexDesiredFormat, w, h);
|
||||
new_tex->Status = ImTextureStatus_WantCreate;
|
||||
atlas->TexIsBuilt = false;
|
||||
|
||||
ImFontAtlasBuildSetTexture(atlas, new_tex);
|
||||
@@ -4302,6 +4308,8 @@ void ImFontAtlasPackDiscardRect(ImFontAtlas* atlas, ImFontAtlasRectId id)
|
||||
index_entry->IsUsed = false;
|
||||
index_entry->TargetIndex = builder->RectsIndexFreeListStart;
|
||||
index_entry->Generation++;
|
||||
if (index_entry->Generation == 0)
|
||||
index_entry->Generation++; // Keep non-zero on overflow
|
||||
|
||||
const int pack_padding = atlas->TexGlyphPadding;
|
||||
builder->RectsIndexFreeListStart = index_idx;
|
||||
@@ -4381,6 +4389,7 @@ ImTextureRect* ImFontAtlasPackGetRectSafe(ImFontAtlas* atlas, ImFontAtlasRectId
|
||||
if (atlas->Builder == NULL)
|
||||
ImFontAtlasBuildInit(atlas);
|
||||
ImFontAtlasBuilder* builder = (ImFontAtlasBuilder*)atlas->Builder;
|
||||
IM_MSVC_WARNING_SUPPRESS(28182); // Static Analysis false positive "warning C28182: Dereferencing NULL pointer 'builder'"
|
||||
if (index_idx >= builder->RectsIndex.Size)
|
||||
return NULL;
|
||||
ImFontAtlasRectEntry* index_entry = &builder->RectsIndex[index_idx];
|
||||
@@ -4423,7 +4432,7 @@ static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codep
|
||||
if (atlas->Locked || (font->Flags & ImFontFlags_NoLoadGlyphs))
|
||||
{
|
||||
// Lazily load fallback glyph
|
||||
if (baked->FallbackGlyphIndex == -1 && baked->LockLoadingFallback == 0)
|
||||
if (baked->FallbackGlyphIndex == -1 && baked->LoadNoFallback == 0)
|
||||
ImFontAtlasBuildSetupFontBakedFallback(baked);
|
||||
return NULL;
|
||||
}
|
||||
@@ -4475,7 +4484,7 @@ static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codep
|
||||
}
|
||||
|
||||
// Lazily load fallback glyph
|
||||
if (baked->LockLoadingFallback)
|
||||
if (baked->LoadNoFallback)
|
||||
return NULL;
|
||||
if (baked->FallbackGlyphIndex == -1)
|
||||
ImFontAtlasBuildSetupFontBakedFallback(baked);
|
||||
@@ -4489,7 +4498,7 @@ static ImFontGlyph* ImFontBaked_BuildLoadGlyph(ImFontBaked* baked, ImWchar codep
|
||||
|
||||
static float ImFontBaked_BuildLoadGlyphAdvanceX(ImFontBaked* baked, ImWchar codepoint)
|
||||
{
|
||||
if (baked->Size >= IMGUI_FONT_SIZE_THRESHOLD_FOR_LOADADVANCEXONLYMODE)
|
||||
if (baked->Size >= IMGUI_FONT_SIZE_THRESHOLD_FOR_LOADADVANCEXONLYMODE || baked->LoadNoRenderOnLayout)
|
||||
{
|
||||
// First load AdvanceX value used by CalcTextSize() API then load the rest when loaded by drawing API.
|
||||
float only_advance_x = 0.0f;
|
||||
@@ -4524,16 +4533,16 @@ void ImFontAtlasDebugLogTextureRequests(ImFontAtlas* atlas)
|
||||
if (tex->Status == ImTextureStatus_WantCreate)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: create %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||
else if (tex->Status == ImTextureStatus_WantDestroy)
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, tex->TexID, tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: destroy %dx%d, texid=0x%" IM_PRIX64 ", backend_data=%p\n", tex->UniqueID, tex->Width, tex->Height, IM_TEXTUREID_TO_U64(tex->TexID), tex->BackendUserData);
|
||||
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||
{
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, tex->TexID, (ImU64)(intptr_t)tex->BackendUserData);
|
||||
IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update %d regions, texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, tex->Updates.Size, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
for (const ImTextureRect& r : tex->Updates)
|
||||
{
|
||||
IM_UNUSED(r);
|
||||
IM_ASSERT(r.x >= 0 && r.y >= 0);
|
||||
IM_ASSERT(r.x + r.w <= tex->Width && r.y + r.h <= tex->Height); // In theory should subtract PackPadding but it's currently part of atlas and mid-frame change would wreck assert.
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, tex->TexID, (ImU64)(intptr_t)tex->BackendUserData);
|
||||
//IMGUI_DEBUG_LOG_FONT("[font] Texture #%03d: update (% 4d..%-4d)->(% 4d..%-4d), texid=0x%" IM_PRIX64 ", backend_data=0x%" IM_PRIX64 "\n", tex->UniqueID, r.x, r.y, r.x + r.w, r.y + r.h, IM_TEXTUREID_TO_U64(tex->TexID), (ImU64)(intptr_t)tex->BackendUserData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4578,15 +4587,16 @@ static bool ImGui_ImplStbTrueType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig*
|
||||
}
|
||||
src->FontLoaderData = bd_font_data;
|
||||
|
||||
const float ref_size = src->DstFont->Sources[0]->SizePixels;
|
||||
if (src->MergeMode && src->SizePixels == 0.0f)
|
||||
src->SizePixels = src->DstFont->Sources[0]->SizePixels;
|
||||
src->SizePixels = ref_size;
|
||||
|
||||
if (src->SizePixels >= 0.0f)
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForPixelHeight(&bd_font_data->FontInfo, 1.0f);
|
||||
else
|
||||
bd_font_data->ScaleFactor = stbtt_ScaleForMappingEmToPixels(&bd_font_data->FontInfo, 1.0f);
|
||||
if (src->MergeMode && src->SizePixels != 0.0f)
|
||||
bd_font_data->ScaleFactor *= src->SizePixels / src->DstFont->Sources[0]->SizePixels; // FIXME-NEWATLAS: Should tidy up that a bit
|
||||
if (src->MergeMode && src->SizePixels != 0.0f && ref_size != 0.0f)
|
||||
bd_font_data->ScaleFactor *= src->SizePixels / ref_size; // FIXME-NEWATLAS: Should tidy up that a bit
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -4685,15 +4695,12 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
|
||||
builder->TempBuffer.resize(w * h * 1);
|
||||
unsigned char* bitmap_pixels = builder->TempBuffer.Data;
|
||||
memset(bitmap_pixels, 0, w * h * 1);
|
||||
stbtt_MakeGlyphBitmapSubpixel(&bd_font_data->FontInfo, bitmap_pixels, r->w - oversample_h + 1, r->h - oversample_v + 1, w,
|
||||
scale_for_raster_x, scale_for_raster_y, 0, 0, glyph_index);
|
||||
|
||||
// Oversampling
|
||||
// Render with oversampling
|
||||
// (those functions conveniently assert if pixels are not cleared, which is another safety layer)
|
||||
if (oversample_h > 1)
|
||||
stbtt__h_prefilter(bitmap_pixels, r->w, r->h, r->w, oversample_h);
|
||||
if (oversample_v > 1)
|
||||
stbtt__v_prefilter(bitmap_pixels, r->w, r->h, r->w, oversample_v);
|
||||
float sub_x, sub_y;
|
||||
stbtt_MakeGlyphBitmapSubpixelPrefilter(&bd_font_data->FontInfo, bitmap_pixels, w, h, w,
|
||||
scale_for_raster_x, scale_for_raster_y, 0, 0, oversample_h, oversample_v, &sub_x, &sub_y, glyph_index);
|
||||
|
||||
const float ref_size = baked->ContainerFont->Sources[0]->SizePixels;
|
||||
const float offsets_scale = (ref_size != 0.0f) ? (baked->Size / ref_size) : 1.0f;
|
||||
@@ -4703,8 +4710,8 @@ static bool ImGui_ImplStbTrueType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontC
|
||||
font_off_x = IM_ROUND(font_off_x);
|
||||
if (src->PixelSnapV)
|
||||
font_off_y = IM_ROUND(font_off_y);
|
||||
font_off_x += stbtt__oversample_shift(oversample_h);
|
||||
font_off_y += stbtt__oversample_shift(oversample_v) + IM_ROUND(baked->Ascent);
|
||||
font_off_x += sub_x;
|
||||
font_off_y += sub_y + IM_ROUND(baked->Ascent);
|
||||
float recip_h = 1.0f / (oversample_h * rasterizer_density);
|
||||
float recip_v = 1.0f / (oversample_v * rasterizer_density);
|
||||
|
||||
@@ -5231,9 +5238,9 @@ ImFontGlyph* ImFontBaked::FindGlyphNoFallback(ImWchar c)
|
||||
if (i != IM_FONTGLYPH_INDEX_UNUSED)
|
||||
return &Glyphs.Data[i];
|
||||
}
|
||||
LockLoadingFallback = true; // This is actually a rare call, not done in hot-loop, so we prioritize not adding extra cruft to ImFontBaked_BuildLoadGlyph() call sites.
|
||||
LoadNoFallback = true; // This is actually a rare call, not done in hot-loop, so we prioritize not adding extra cruft to ImFontBaked_BuildLoadGlyph() call sites.
|
||||
ImFontGlyph* glyph = ImFontBaked_BuildLoadGlyph(this, c, NULL);
|
||||
LockLoadingFallback = false;
|
||||
LoadNoFallback = false;
|
||||
return glyph;
|
||||
}
|
||||
|
||||
@@ -5348,10 +5355,11 @@ ImFontBaked* ImFontAtlasBakedGetOrAdd(ImFontAtlas* atlas, ImFont* font, float fo
|
||||
}
|
||||
|
||||
// Trim trailing space and find beginning of next line
|
||||
static inline const char* CalcWordWrapNextLineStartA(const char* text, const char* text_end)
|
||||
const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_end, ImDrawTextFlags flags)
|
||||
{
|
||||
while (text < text_end && ImCharIsBlankA(*text))
|
||||
text++;
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) == 0)
|
||||
while (text < text_end && ImCharIsBlankA(*text))
|
||||
text++;
|
||||
if (*text == '\n')
|
||||
text++;
|
||||
return text;
|
||||
@@ -5360,7 +5368,7 @@ static inline const char* CalcWordWrapNextLineStartA(const char* text, const cha
|
||||
// Simple word-wrapping for English, not full-featured. Please submit failing cases!
|
||||
// This will return the next location to wrap from. If no wrapping if necessary, this will fast-forward to e.g. text_end.
|
||||
// FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.)
|
||||
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
|
||||
const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// For references, possible wrap point marked with ^
|
||||
// "aaa bbb, ccc,ddd. eee fff. ggg!"
|
||||
@@ -5374,7 +5382,7 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
|
||||
// Cut words that cannot possibly fit within one line.
|
||||
// e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish"
|
||||
|
||||
ImFontBaked* baked = GetFontBaked(size);
|
||||
ImFontBaked* baked = font->GetFontBaked(size);
|
||||
const float scale = size / baked->Size;
|
||||
|
||||
float line_width = 0.0f;
|
||||
@@ -5400,12 +5408,7 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
|
||||
if (c < 32)
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
line_width = word_width = blank_width = 0.0f;
|
||||
inside_word = true;
|
||||
s = next_s;
|
||||
continue;
|
||||
}
|
||||
return s; // Direct return, skip "Wrap_width is too small to fit anything" path.
|
||||
if (c == '\r')
|
||||
{
|
||||
s = next_s;
|
||||
@@ -5440,6 +5443,8 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
|
||||
{
|
||||
prev_word_end = word_end;
|
||||
line_width += word_width + blank_width;
|
||||
if ((flags & ImDrawTextFlags_WrapKeepBlanks) && line_width <= wrap_width)
|
||||
prev_word_end = s;
|
||||
word_width = blank_width = 0.0f;
|
||||
}
|
||||
|
||||
@@ -5466,14 +5471,21 @@ const char* ImFont::CalcWordWrapPosition(float size, const char* text, const cha
|
||||
return s;
|
||||
}
|
||||
|
||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining)
|
||||
const char* ImFont::CalcWordWrapPosition(float size, const char* text, const char* text_end, float wrap_width)
|
||||
{
|
||||
return ImFontCalcWordWrapPositionEx(this, size, text, text_end, wrap_width, ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining, ImVec2* out_offset, ImDrawTextFlags flags)
|
||||
{
|
||||
if (!text_end)
|
||||
text_end = text_begin + ImStrlen(text_begin); // FIXME-OPT: Need to avoid this.
|
||||
if (!text_end_display)
|
||||
text_end_display = text_end;
|
||||
|
||||
ImFontBaked* baked = font->GetFontBaked(size);
|
||||
const float line_height = size;
|
||||
ImFontBaked* baked = GetFontBaked(size);
|
||||
const float scale = size / baked->Size;
|
||||
const float scale = line_height / baked->Size;
|
||||
|
||||
ImVec2 text_size = ImVec2(0, 0);
|
||||
float line_width = 0.0f;
|
||||
@@ -5482,13 +5494,14 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
const char* word_wrap_eol = NULL;
|
||||
|
||||
const char* s = text_begin;
|
||||
while (s < text_end)
|
||||
while (s < text_end_display)
|
||||
{
|
||||
// Word-wrapping
|
||||
if (word_wrap_enabled)
|
||||
{
|
||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||
if (!word_wrap_eol)
|
||||
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - line_width);
|
||||
word_wrap_eol = ImFontCalcWordWrapPositionEx(font, size, s, text_end, wrap_width - line_width, flags);
|
||||
|
||||
if (s >= word_wrap_eol)
|
||||
{
|
||||
@@ -5496,8 +5509,10 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
text_size.x = line_width;
|
||||
text_size.y += line_height;
|
||||
line_width = 0.0f;
|
||||
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags); // Wrapping skips upcoming blanks
|
||||
if (flags & ImDrawTextFlags_StopOnNewLine)
|
||||
break;
|
||||
word_wrap_eol = NULL;
|
||||
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -5510,18 +5525,17 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
else
|
||||
s += ImTextCharFromUtf8(&c, s, text_end);
|
||||
|
||||
if (c < 32)
|
||||
if (c == '\n')
|
||||
{
|
||||
if (c == '\n')
|
||||
{
|
||||
text_size.x = ImMax(text_size.x, line_width);
|
||||
text_size.y += line_height;
|
||||
line_width = 0.0f;
|
||||
continue;
|
||||
}
|
||||
if (c == '\r')
|
||||
continue;
|
||||
text_size.x = ImMax(text_size.x, line_width);
|
||||
text_size.y += line_height;
|
||||
line_width = 0.0f;
|
||||
if (flags & ImDrawTextFlags_StopOnNewLine)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (c == '\r')
|
||||
continue;
|
||||
|
||||
// Optimized inline version of 'float char_width = GetCharAdvance((ImWchar)c);'
|
||||
float char_width = (c < (unsigned int)baked->IndexAdvanceX.Size) ? baked->IndexAdvanceX.Data[c] : -1.0f;
|
||||
@@ -5541,15 +5555,23 @@ ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, cons
|
||||
if (text_size.x < line_width)
|
||||
text_size.x = line_width;
|
||||
|
||||
if (line_width > 0 || text_size.y == 0.0f)
|
||||
if (out_offset != NULL)
|
||||
*out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n
|
||||
|
||||
if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n
|
||||
text_size.y += line_height;
|
||||
|
||||
if (remaining)
|
||||
*remaining = s;
|
||||
if (out_remaining != NULL)
|
||||
*out_remaining = s;
|
||||
|
||||
return text_size;
|
||||
}
|
||||
|
||||
ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** out_remaining)
|
||||
{
|
||||
return ImFontCalcTextSizeEx(this, size, max_width, wrap_width, text_begin, text_end, text_end, out_remaining, NULL, ImDrawTextFlags_None);
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, ImWchar c, const ImVec4* cpu_fine_clip)
|
||||
{
|
||||
@@ -5590,7 +5612,8 @@ void ImFont::RenderChar(ImDrawList* draw_list, float size, const ImVec2& pos, Im
|
||||
}
|
||||
|
||||
// Note: as with every ImDrawList drawing function, this expects that the font atlas texture is bound.
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip)
|
||||
// DO NOT CALL DIRECTLY THIS WILL CHANGE WILDLY IN 2025-2025. Use ImDrawList::AddText().
|
||||
void ImFont::RenderText(ImDrawList* draw_list, float size, const ImVec2& pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, ImDrawTextFlags flags)
|
||||
{
|
||||
// Align to be pixel perfect
|
||||
begin:
|
||||
@@ -5620,8 +5643,8 @@ begin:
|
||||
// FIXME-OPT: This is not optimal as do first do a search for \n before calling CalcWordWrapPosition().
|
||||
// If the specs for CalcWordWrapPosition() were reworked to optionally return on \n we could combine both.
|
||||
// However it is still better than nothing performing the fast-forward!
|
||||
s = CalcWordWrapPosition(size, s, line_end ? line_end : text_end, wrap_width);
|
||||
s = CalcWordWrapNextLineStartA(s, text_end);
|
||||
s = ImFontCalcWordWrapPositionEx(this, size, s, line_end ? line_end : text_end, wrap_width, flags);
|
||||
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5656,6 +5679,7 @@ begin:
|
||||
ImDrawIdx* idx_write = draw_list->_IdxWritePtr;
|
||||
unsigned int vtx_index = draw_list->_VtxCurrentIdx;
|
||||
const int cmd_count = draw_list->CmdBuffer.Size;
|
||||
const bool cpu_fine_clip = (flags & ImDrawTextFlags_CpuFineClip) != 0;
|
||||
|
||||
const ImU32 col_untinted = col | ~IM_COL32_A_MASK;
|
||||
const char* word_wrap_eol = NULL;
|
||||
@@ -5666,7 +5690,7 @@ begin:
|
||||
{
|
||||
// Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature.
|
||||
if (!word_wrap_eol)
|
||||
word_wrap_eol = CalcWordWrapPosition(size, s, text_end, wrap_width - (x - origin_x));
|
||||
word_wrap_eol = ImFontCalcWordWrapPositionEx(this, size, s, text_end, wrap_width - (x - origin_x), flags);
|
||||
|
||||
if (s >= word_wrap_eol)
|
||||
{
|
||||
@@ -5675,7 +5699,7 @@ begin:
|
||||
if (y > clip_rect.w)
|
||||
break; // break out of main loop
|
||||
word_wrap_eol = NULL;
|
||||
s = CalcWordWrapNextLineStartA(s, text_end); // Wrapping skips upcoming blanks
|
||||
s = ImTextCalcWordWrapNextLineStart(s, text_end, flags); // Wrapping skips upcoming blanks
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -5844,8 +5868,9 @@ void ImGui::RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImU32 col, ImGuiDir d
|
||||
|
||||
void ImGui::RenderBullet(ImDrawList* draw_list, ImVec2 pos, ImU32 col)
|
||||
{
|
||||
// FIXME-OPT: This should be baked in font.
|
||||
draw_list->AddCircleFilled(pos, draw_list->_Data->FontSize * 0.20f, col, 8);
|
||||
// FIXME-OPT: This should be baked in font now that it's easier.
|
||||
float font_size = draw_list->_Data->FontSize;
|
||||
draw_list->AddCircleFilled(pos, font_size * 0.20f, col, (font_size < 22) ? 8 : (font_size < 40) ? 12 : 0); // Hardcode optimal/nice tessellation threshold
|
||||
}
|
||||
|
||||
void ImGui::RenderCheckMark(ImDrawList* draw_list, ImVec2 pos, ImU32 col, float sz)
|
||||
@@ -6147,6 +6172,7 @@ static unsigned int stb_decompress(unsigned char *output, const unsigned char *i
|
||||
// Copyright (c) 2004, 2005 Tristan Grimmer
|
||||
// MIT license (see License.txt in http://www.proggyfonts.net/index.php?menu=download)
|
||||
// Download and more information at http://www.proggyfonts.net or http://upperboundsinteractive.com/fonts.php
|
||||
// If you want a similar font which may be better scaled, consider using ProggyVector from the same author!
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FONT
|
||||
|
||||
222
imgui_internal.h
222
imgui_internal.h
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.4
|
||||
// (internal structures/api)
|
||||
|
||||
// You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility.
|
||||
@@ -77,8 +77,8 @@ Index of this file:
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport)
|
||||
#pragma warning (disable: 26812) // The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3). [MSVC Static Analyzer)
|
||||
#pragma warning (disable: 26495) // [Static Analyzer] Variable 'XXX' is uninitialized. Always initialize a member variable (type.6).
|
||||
#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
|
||||
#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types
|
||||
#endif
|
||||
@@ -199,6 +199,7 @@ typedef int ImGuiDataAuthority; // -> enum ImGuiDataAuthority_ // E
|
||||
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
|
||||
|
||||
// Flags
|
||||
typedef int ImDrawTextFlags; // -> enum ImDrawTextFlags_ // Flags: for ImTextCalcWordWrapPositionEx()
|
||||
typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later)
|
||||
typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags
|
||||
typedef int ImGuiFocusRequestFlags; // -> enum ImGuiFocusRequestFlags_ // Flags: for FocusWindow()
|
||||
@@ -346,6 +347,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
#define IM_PRIu64 "llu"
|
||||
#define IM_PRIX64 "llX"
|
||||
#endif
|
||||
#define IM_TEXTUREID_TO_U64(_TEXID) ((ImU64)(intptr_t)(_TEXID))
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] Generic helpers
|
||||
@@ -377,20 +379,21 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
// Helpers: Hashing
|
||||
IMGUI_API ImGuiID ImHashData(const void* data, size_t data_size, ImGuiID seed = 0);
|
||||
IMGUI_API ImGuiID ImHashStr(const char* data, size_t data_size = 0, ImGuiID seed = 0);
|
||||
IMGUI_API const char* ImHashSkipUncontributingPrefix(const char* label);
|
||||
|
||||
// Helpers: Sorting
|
||||
#ifndef ImQsort
|
||||
static inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
|
||||
inline void ImQsort(void* base, size_t count, size_t size_of_element, int(IMGUI_CDECL *compare_func)(void const*, void const*)) { if (count > 1) qsort(base, count, size_of_element, compare_func); }
|
||||
#endif
|
||||
|
||||
// Helpers: Color Blending
|
||||
IMGUI_API ImU32 ImAlphaBlendColors(ImU32 col_a, ImU32 col_b);
|
||||
|
||||
// Helpers: Bit manipulation
|
||||
static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
static inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
|
||||
inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
inline bool ImIsPowerOfTwo(ImU64 v) { return v != 0 && (v & (v - 1)) == 0; }
|
||||
inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; }
|
||||
inline unsigned int ImCountSetBits(unsigned int v) { unsigned int count = 0; while (v > 0) { v = v & (v - 1); count++; } return count; }
|
||||
|
||||
// Helpers: String
|
||||
#define ImStrlen strlen
|
||||
@@ -409,10 +412,10 @@ IMGUI_API const char* ImStrSkipBlank(const char* str);
|
||||
IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string)
|
||||
IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
static inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
static inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
static inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
static inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
||||
inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Formatting
|
||||
@@ -428,7 +431,7 @@ IMGUI_API const char* ImParseFormatSanitizeForScanning(const char* fmt_in, cha
|
||||
IMGUI_API int ImParseFormatPrecision(const char* format, int default_value);
|
||||
|
||||
// Helpers: UTF-8 <> wchar conversions
|
||||
IMGUI_API const char* ImTextCharToUtf8(char out_buf[5], unsigned int c); // return out_buf
|
||||
IMGUI_API int ImTextCharToUtf8(char out_buf[5], unsigned int c); // return output UTF-8 bytes count
|
||||
IMGUI_API int ImTextStrToUtf8(char* out_buf, int out_buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count
|
||||
IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // read one character. return input UTF-8 bytes count
|
||||
IMGUI_API int ImTextStrFromUtf8(ImWchar* out_buf, int out_buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count
|
||||
@@ -438,15 +441,27 @@ IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, cons
|
||||
IMGUI_API const char* ImTextFindPreviousUtf8Codepoint(const char* in_text_start, const char* in_text_curr); // return previous UTF-8 code-point.
|
||||
IMGUI_API int ImTextCountLines(const char* in_text, const char* in_text_end); // return number of lines taken by text. trailing carriage return doesn't count as an extra line.
|
||||
|
||||
// Helpers: High-level text functions (DO NOT USE!!! THIS IS A MINIMAL SUBSET OF LARGER UPCOMING CHANGES)
|
||||
enum ImDrawTextFlags_
|
||||
{
|
||||
ImDrawTextFlags_None = 0,
|
||||
ImDrawTextFlags_CpuFineClip = 1 << 0, // Must be == 1/true for legacy with 'bool cpu_fine_clip' arg to RenderText()
|
||||
ImDrawTextFlags_WrapKeepBlanks = 1 << 1,
|
||||
ImDrawTextFlags_StopOnNewLine = 1 << 2,
|
||||
};
|
||||
IMGUI_API ImVec2 ImFontCalcTextSizeEx(ImFont* font, float size, float max_width, float wrap_width, const char* text_begin, const char* text_end_display, const char* text_end, const char** out_remaining, ImVec2* out_offset, ImDrawTextFlags flags);
|
||||
IMGUI_API const char* ImFontCalcWordWrapPositionEx(ImFont* font, float size, const char* text, const char* text_end, float wrap_width, ImDrawTextFlags flags = 0);
|
||||
IMGUI_API const char* ImTextCalcWordWrapNextLineStart(const char* text, const char* text_end, ImDrawTextFlags flags = 0); // trim trailing space and find beginning of next line
|
||||
|
||||
// Helpers: File System
|
||||
#ifdef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||
#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
typedef void* ImFileHandle;
|
||||
static inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; }
|
||||
static inline bool ImFileClose(ImFileHandle) { return false; }
|
||||
static inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; }
|
||||
static inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
static inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
inline ImFileHandle ImFileOpen(const char*, const char*) { return NULL; }
|
||||
inline bool ImFileClose(ImFileHandle) { return false; }
|
||||
inline ImU64 ImFileGetSize(ImFileHandle) { return (ImU64)-1; }
|
||||
inline ImU64 ImFileRead(void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
inline ImU64 ImFileWrite(const void*, ImU64, ImU64, ImFileHandle) { return 0; }
|
||||
#endif
|
||||
#ifndef IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS
|
||||
typedef FILE* ImFileHandle;
|
||||
@@ -473,56 +488,56 @@ IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
#define ImAtan2(Y, X) atan2f((Y), (X))
|
||||
#define ImAtof(STR) atof(STR)
|
||||
#define ImCeil(X) ceilf(X)
|
||||
static inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
|
||||
static inline double ImPow(double x, double y) { return pow(x, y); }
|
||||
static inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
|
||||
static inline double ImLog(double x) { return log(x); }
|
||||
static inline int ImAbs(int x) { return x < 0 ? -x : x; }
|
||||
static inline float ImAbs(float x) { return fabsf(x); }
|
||||
static inline double ImAbs(double x) { return fabs(x); }
|
||||
static inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||
static inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
|
||||
inline float ImPow(float x, float y) { return powf(x, y); } // DragBehaviorT/SliderBehaviorT uses ImPow with either float/double and need the precision
|
||||
inline double ImPow(double x, double y) { return pow(x, y); }
|
||||
inline float ImLog(float x) { return logf(x); } // DragBehaviorT/SliderBehaviorT uses ImLog with either float/double and need the precision
|
||||
inline double ImLog(double x) { return log(x); }
|
||||
inline int ImAbs(int x) { return x < 0 ? -x : x; }
|
||||
inline float ImAbs(float x) { return fabsf(x); }
|
||||
inline double ImAbs(double x) { return fabs(x); }
|
||||
inline float ImSign(float x) { return (x < 0.0f) ? -1.0f : (x > 0.0f) ? 1.0f : 0.0f; } // Sign operator - returns -1, 0 or 1 based on sign of argument
|
||||
inline double ImSign(double x) { return (x < 0.0) ? -1.0 : (x > 0.0) ? 1.0 : 0.0; }
|
||||
#ifdef IMGUI_ENABLE_SSE
|
||||
static inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
|
||||
inline float ImRsqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); }
|
||||
#else
|
||||
static inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
inline float ImRsqrt(float x) { return 1.0f / sqrtf(x); }
|
||||
#endif
|
||||
static inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
inline double ImRsqrt(double x) { return 1.0 / sqrt(x); }
|
||||
#endif
|
||||
// - ImMin/ImMax/ImClamp/ImLerp/ImSwap are used by widgets which support variety of types: signed/unsigned int/long long float/double
|
||||
// (Exceptionally using templates here but we could also redefine them for those types)
|
||||
template<typename T> static inline T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> static inline T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> static inline T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> static inline void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> static inline T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> static inline T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
template<typename T> T ImMin(T lhs, T rhs) { return lhs < rhs ? lhs : rhs; }
|
||||
template<typename T> T ImMax(T lhs, T rhs) { return lhs >= rhs ? lhs : rhs; }
|
||||
template<typename T> T ImClamp(T v, T mn, T mx) { return (v < mn) ? mn : (v > mx) ? mx : v; }
|
||||
template<typename T> T ImLerp(T a, T b, float t) { return (T)(a + (b - a) * t); }
|
||||
template<typename T> void ImSwap(T& a, T& b) { T tmp = a; a = b; b = tmp; }
|
||||
template<typename T> T ImAddClampOverflow(T a, T b, T mn, T mx) { if (b < 0 && (a < mn - b)) return mn; if (b > 0 && (a > mx - b)) return mx; return a + b; }
|
||||
template<typename T> T ImSubClampOverflow(T a, T b, T mn, T mx) { if (b > 0 && (a < mn + b)) return mn; if (b < 0 && (a > mx + b)) return mx; return a - b; }
|
||||
// - Misc maths helpers
|
||||
static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
static inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx) { return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||
static inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||
static inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||
static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
|
||||
static inline float ImTrunc(float f) { return (float)(int)(f); }
|
||||
static inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||
static inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
static inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
static inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
static inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
|
||||
static inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
|
||||
static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
static inline float ImExponentialMovingAverage(float avg, float sample, int n) { avg -= avg / n; avg += sample / n; return avg; }
|
||||
inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); }
|
||||
inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); }
|
||||
inline ImVec2 ImClamp(const ImVec2& v, const ImVec2&mn, const ImVec2&mx){ return ImVec2((v.x < mn.x) ? mn.x : (v.x > mx.x) ? mx.x : v.x, (v.y < mn.y) ? mn.y : (v.y > mx.y) ? mx.y : v.y); }
|
||||
inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); }
|
||||
inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); }
|
||||
inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); }
|
||||
inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; }
|
||||
inline float ImLengthSqr(const ImVec2& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y); }
|
||||
inline float ImLengthSqr(const ImVec4& lhs) { return (lhs.x * lhs.x) + (lhs.y * lhs.y) + (lhs.z * lhs.z) + (lhs.w * lhs.w); }
|
||||
inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = (lhs.x * lhs.x) + (lhs.y * lhs.y); if (d > 0.0f) return ImRsqrt(d); return fail_value; }
|
||||
inline float ImTrunc(float f) { return (float)(int)(f); }
|
||||
inline ImVec2 ImTrunc(const ImVec2& v) { return ImVec2((float)(int)(v.x), (float)(int)(v.y)); }
|
||||
inline float ImFloor(float f) { return (float)((f >= 0 || (float)(int)f == f) ? (int)f : (int)f - 1); } // Decent replacement for floorf()
|
||||
inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2(ImFloor(v.x), ImFloor(v.y)); }
|
||||
inline float ImTrunc64(float f) { return (float)(ImS64)(f); }
|
||||
inline float ImRound64(float f) { return (float)(ImS64)(f + 0.5f); }
|
||||
inline int ImModPositive(int a, int b) { return (a + b) % b; }
|
||||
inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; }
|
||||
inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); }
|
||||
inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; }
|
||||
inline float ImLinearRemapClamp(float s0, float s1, float d0, float d1, float x) { return ImSaturate((x - s0) / (s1 - s0)) * (d1 - d0) + d0; }
|
||||
inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; }
|
||||
inline float ImExponentialMovingAverage(float avg, float sample, int n){ avg -= avg / n; avg += sample / n; return avg; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
|
||||
// Helpers: Geometry
|
||||
@@ -601,6 +616,7 @@ struct IMGUI_API ImRect
|
||||
void Floor() { Min.x = IM_TRUNC(Min.x); Min.y = IM_TRUNC(Min.y); Max.x = IM_TRUNC(Max.x); Max.y = IM_TRUNC(Max.y); }
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
|
||||
const ImVec4& AsVec4() const { return *(const ImVec4*)&Min.x; }
|
||||
};
|
||||
|
||||
// Helper: ImBitArray
|
||||
@@ -799,13 +815,13 @@ struct ImChunkStream
|
||||
// Maintain a line index for a text buffer. This is a strong candidate to be moved into the public API.
|
||||
struct ImGuiTextIndex
|
||||
{
|
||||
ImVector<int> LineOffsets;
|
||||
ImVector<int> Offsets;
|
||||
int EndOffset = 0; // Because we don't own text buffer we need to maintain EndOffset (may bake in LineOffsets?)
|
||||
|
||||
void clear() { LineOffsets.clear(); EndOffset = 0; }
|
||||
int size() { return LineOffsets.Size; }
|
||||
const char* get_line_begin(const char* base, int n) { return base + LineOffsets[n]; }
|
||||
const char* get_line_end(const char* base, int n) { return base + (n + 1 < LineOffsets.Size ? (LineOffsets[n + 1] - 1) : EndOffset); }
|
||||
void clear() { Offsets.clear(); EndOffset = 0; }
|
||||
int size() { return Offsets.Size; }
|
||||
const char* get_line_begin(const char* base, int n) { return base + (Offsets.Size != 0 ? Offsets[n] : 0); }
|
||||
const char* get_line_end(const char* base, int n) { return base + (n + 1 < Offsets.Size ? (Offsets[n + 1] - 1) : EndOffset); }
|
||||
void append(const char* base, int old_size, int new_size);
|
||||
};
|
||||
|
||||
@@ -1061,7 +1077,6 @@ enum ImGuiSelectableFlagsPrivate_
|
||||
{
|
||||
// NB: need to be in sync with last value of ImGuiSelectableFlags_
|
||||
ImGuiSelectableFlags_NoHoldingActiveID = 1 << 20,
|
||||
ImGuiSelectableFlags_SelectOnNav = 1 << 21, // (WIP) Auto-select when moved into. This is not exposed in public API as to handle multi-select and modifiers we will need user to explicitly control focus scope. May be replaced with a BeginSelection() API.
|
||||
ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release)
|
||||
ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release)
|
||||
ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus)
|
||||
@@ -1229,11 +1244,15 @@ struct IMGUI_API ImGuiInputTextState
|
||||
ImVector<char> CallbackTextBackup; // temporary storage for callback to support automatic reconcile of undo-stack
|
||||
int BufCapacity; // end-user buffer capacity (include zero terminator)
|
||||
ImVec2 Scroll; // horizontal offset (managed manually) + vertical scrolling (pulled from child window's own Scroll.y)
|
||||
int LineCount; // last line count (solely for debugging)
|
||||
float WrapWidth; // word-wrapping width
|
||||
float CursorAnim; // timer for cursor blink, reset on every user action so the cursor reappears immediately
|
||||
bool CursorFollow; // set when we want scrolling to follow the current cursor position (not always!)
|
||||
bool CursorCenterY; // set when we want scrolling to be centered over the cursor position (while resizing a word-wrapping field)
|
||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||
bool Edited; // edited this frame
|
||||
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
ImS8 LastMoveDirectionLR; // ImGuiDir_Left or ImGuiDir_Right. track last movement direction so when cursor cross over a word-wrapping boundaries we can display it on either line depending on last move.s
|
||||
int ReloadSelectionStart;
|
||||
int ReloadSelectionEnd;
|
||||
|
||||
@@ -1243,6 +1262,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
void ClearFreeMemory() { TextA.clear(); TextToRevertTo.clear(); }
|
||||
void OnKeyPressed(int key); // Cannot be inline because we call in code in stb_textedit.h implementation
|
||||
void OnCharPressed(unsigned int c);
|
||||
float GetPreferredOffsetX() const;
|
||||
|
||||
// Cursor & Selection
|
||||
void CursorAnimReset();
|
||||
@@ -1507,7 +1527,7 @@ enum ImGuiInputEventType
|
||||
ImGuiInputEventType_COUNT
|
||||
};
|
||||
|
||||
enum ImGuiInputSource
|
||||
enum ImGuiInputSource : int
|
||||
{
|
||||
ImGuiInputSource_None = 0,
|
||||
ImGuiInputSource_Mouse, // Note: may be Mouse or TouchScreen or Pen. See io.MouseSource to distinguish them.
|
||||
@@ -1558,12 +1578,12 @@ struct ImGuiKeyRoutingData
|
||||
{
|
||||
ImGuiKeyRoutingIndex NextEntryIndex;
|
||||
ImU16 Mods; // Technically we'd only need 4-bits but for simplify we store ImGuiMod_ values which need 16-bits.
|
||||
ImU8 RoutingCurrScore; // [DEBUG] For debug display
|
||||
ImU8 RoutingNextScore; // Lower is better (0: perfect score)
|
||||
ImU16 RoutingCurrScore; // [DEBUG] For debug display
|
||||
ImU16 RoutingNextScore; // Lower is better (0: perfect score)
|
||||
ImGuiID RoutingCurr;
|
||||
ImGuiID RoutingNext;
|
||||
|
||||
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 255; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
|
||||
ImGuiKeyRoutingData() { NextEntryIndex = -1; Mods = 0; RoutingCurrScore = RoutingNextScore = 0; RoutingCurr = RoutingNext = ImGuiKeyOwner_NoOwner; }
|
||||
};
|
||||
|
||||
// Routing table: maintain a desired owner for each possible key-chord (key + mods), and setup owner in NewFrame() when mods are matching.
|
||||
@@ -1672,8 +1692,9 @@ enum ImGuiActivateFlags_
|
||||
ImGuiActivateFlags_PreferInput = 1 << 0, // Favor activation that requires keyboard text input (e.g. for Slider/Drag). Default for Enter key.
|
||||
ImGuiActivateFlags_PreferTweak = 1 << 1, // Favor activation for tweaking with arrows or gamepad (e.g. for Slider/Drag). Default for Space key and if keyboard is not used.
|
||||
ImGuiActivateFlags_TryToPreserveState = 1 << 2, // Request widget to preserve state if it can (e.g. InputText will try to preserve cursor/selection)
|
||||
ImGuiActivateFlags_FromTabbing = 1 << 3, // Activation requested by a tabbing request
|
||||
ImGuiActivateFlags_FromTabbing = 1 << 3, // Activation requested by a tabbing request (ImGuiNavMoveFlags_IsTabbing)
|
||||
ImGuiActivateFlags_FromShortcut = 1 << 4, // Activation requested by an item shortcut via SetNextItemShortcut() function.
|
||||
ImGuiActivateFlags_FromFocusApi = 1 << 5, // Activation requested by an api request (ImGuiNavMoveFlags_FocusApi)
|
||||
};
|
||||
|
||||
// Early work-in-progress API for ScrollToItem()
|
||||
@@ -2287,10 +2308,10 @@ struct ImGuiStackLevelInfo
|
||||
ImGuiID ID;
|
||||
ImS8 QueryFrameCount; // >= 1: Query in progress
|
||||
bool QuerySuccess; // Obtained result from DebugHookIdInfo()
|
||||
ImGuiDataType DataType : 8;
|
||||
char Desc[57]; // Arbitrarily sized buffer to hold a result (FIXME: could replace Results[] with a chunk stream?) FIXME: Now that we added CTRL+C this should be fixed.
|
||||
ImS8 DataType; // ImGuiDataType
|
||||
int DescOffset; // -1 or offset into parent's ResultPathsBuf
|
||||
|
||||
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); }
|
||||
ImGuiStackLevelInfo() { memset(this, 0, sizeof(*this)); DescOffset = -1; }
|
||||
};
|
||||
|
||||
// State for ID Stack tool queries
|
||||
@@ -2298,13 +2319,16 @@ struct ImGuiIDStackTool
|
||||
{
|
||||
int LastActiveFrame;
|
||||
int StackLevel; // -1: query stack and resize Results, >= 0: individual stack level
|
||||
ImGuiID QueryId; // ID to query details for
|
||||
ImGuiID QueryMainId; // ID to query details for
|
||||
ImVector<ImGuiStackLevelInfo> Results;
|
||||
bool CopyToClipboardOnCtrlC;
|
||||
bool QueryHookActive; // Used to disambiguate the case where DebugHookIdInfoId == 0 which is valid.
|
||||
bool OptHexEncodeNonAsciiChars;
|
||||
bool OptCopyToClipboardOnCtrlC;
|
||||
float CopyToClipboardLastTime;
|
||||
ImGuiTextBuffer ResultPathBuf;
|
||||
ImGuiTextBuffer ResultPathsBuf;
|
||||
ImGuiTextBuffer ResultTempBuf;
|
||||
|
||||
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); CopyToClipboardLastTime = -FLT_MAX; }
|
||||
ImGuiIDStackTool() { memset(this, 0, sizeof(*this)); LastActiveFrame = -1; OptHexEncodeNonAsciiChars = true; CopyToClipboardLastTime = -FLT_MAX; }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2389,7 +2413,7 @@ struct ImGuiContext
|
||||
|
||||
// Item/widgets state and tracking information
|
||||
ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier
|
||||
ImGuiID DebugHookIdInfo; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
||||
ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
||||
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
||||
ImGuiID HoveredIdPreviousFrame;
|
||||
int HoveredIdPreviousFrameItemCount; // Count numbers of items using the same ID as last frame's hovered id
|
||||
@@ -2408,6 +2432,7 @@ struct ImGuiContext
|
||||
bool ActiveIdHasBeenEditedBefore; // Was the value associated to the widget Edited over the course of the Active state.
|
||||
bool ActiveIdHasBeenEditedThisFrame;
|
||||
bool ActiveIdFromShortcut;
|
||||
ImGuiID ActiveIdDisabledId; // When clicking a disabled item we set ActiveId=window->MoveId to avoid interference with widget code. Actual item ID is stored here.
|
||||
int ActiveIdMouseButton : 8;
|
||||
ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior)
|
||||
ImGuiWindow* ActiveIdWindow;
|
||||
@@ -2486,7 +2511,7 @@ struct ImGuiContext
|
||||
float NavHighlightActivatedTimer;
|
||||
ImGuiID NavNextActivateId; // Set by ActivateItemByID(), queued until next frame.
|
||||
ImGuiActivateFlags NavNextActivateFlags;
|
||||
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse
|
||||
ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Gamepad
|
||||
ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data.
|
||||
ImS8 NavCursorHideFrames;
|
||||
//ImGuiID NavActivateInputId; // Removed in 1.89.4 (July 2023). This is now part of g.NavActivateId and sets g.NavActivateFlags |= ImGuiActivateFlags_PreferInput. See commit c9a53aa74, issue #5606.
|
||||
@@ -2533,8 +2558,8 @@ struct ImGuiContext
|
||||
float NavWindowingTimer;
|
||||
float NavWindowingHighlightAlpha;
|
||||
ImGuiInputSource NavWindowingInputSource;
|
||||
bool NavWindowingToggleLayer;
|
||||
ImGuiKey NavWindowingToggleKey;
|
||||
bool NavWindowingToggleLayer; // Set while Alt or GamepadMenu is held, may be cleared by other operations, and processed when releasing the key.
|
||||
ImGuiKey NavWindowingToggleKey; // Keyboard/gamepad key used when toggling to menu layer.
|
||||
ImVec2 NavWindowingAccumDeltaPos;
|
||||
ImVec2 NavWindowingAccumDeltaSize;
|
||||
|
||||
@@ -2552,6 +2577,7 @@ struct ImGuiContext
|
||||
ImRect DragDropTargetRect; // Store rectangle of current target candidate (we favor small targets when overlapping)
|
||||
ImRect DragDropTargetClipRect; // Store ClipRect at the time of item's drawing
|
||||
ImGuiID DragDropTargetId;
|
||||
ImGuiID DragDropTargetFullViewport;
|
||||
ImGuiDragDropFlags DragDropAcceptFlags;
|
||||
float DragDropAcceptIdCurrRectSurface; // Target item surface (we resolve overlapping targets by prioritizing the smaller surface)
|
||||
ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload)
|
||||
@@ -2602,6 +2628,7 @@ struct ImGuiContext
|
||||
|
||||
// Widget state
|
||||
ImGuiInputTextState InputTextState;
|
||||
ImGuiTextIndex InputTextLineIndex; // Temporary storage
|
||||
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
|
||||
ImFontBaked InputTextPasswordFontBackupBaked;
|
||||
ImFontFlags InputTextPasswordFontBackupFlags;
|
||||
@@ -2664,7 +2691,7 @@ struct ImGuiContext
|
||||
ImGuiWindow* LogWindow;
|
||||
ImFileHandle LogFile; // If != NULL log to stdout/ file
|
||||
ImGuiTextBuffer LogBuffer; // Accumulation buffer when log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators.
|
||||
const char* LogNextPrefix;
|
||||
const char* LogNextPrefix; // See comment in LogSetNextTextDecoration(): doesn't copy underlying data, use carefully!
|
||||
const char* LogNextSuffix;
|
||||
float LogLinePosY;
|
||||
bool LogLineFirstItem;
|
||||
@@ -2968,7 +2995,7 @@ struct ImGuiTabItem
|
||||
int LastFrameSelected; // This allows us to infer an ordered list of the last activated tabs with little maintenance
|
||||
float Offset; // Position relative to beginning of tab
|
||||
float Width; // Width currently displayed
|
||||
float ContentWidth; // Width of label, stored during BeginTabItem() call
|
||||
float ContentWidth; // Width of label + padding, stored during BeginTabItem() call (misnamed as "Content" would normally imply width of label only)
|
||||
float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
|
||||
ImS32 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
|
||||
ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable
|
||||
@@ -2991,6 +3018,7 @@ struct IMGUI_API ImGuiTabBar
|
||||
int CurrFrameVisible;
|
||||
int PrevFrameVisible;
|
||||
ImRect BarRect;
|
||||
float BarRectPrevWidth; // Backup of previous width. When width change we enforce keep horizontal scroll on focused tab.
|
||||
float CurrTabsContentsHeight;
|
||||
float PrevTabsContentsHeight; // Record the height of contents submitted below the tab bar
|
||||
float WidthAllTabs; // Actual width of all tabs (locked during layout)
|
||||
@@ -3009,6 +3037,7 @@ struct IMGUI_API ImGuiTabBar
|
||||
bool WantLayout;
|
||||
bool VisibleTabWasSubmitted;
|
||||
bool TabsAddedNew; // Set to true when a new tab item or button has been added to the tab bar during last frame
|
||||
bool ScrollButtonEnabled;
|
||||
ImS16 TabsActiveCount; // Number of tabs submitted this frame.
|
||||
ImS16 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem()
|
||||
float ItemSpacingY;
|
||||
@@ -3357,7 +3386,7 @@ namespace ImGui
|
||||
IMGUI_API void SetNextWindowRefreshPolicy(ImGuiWindowRefreshFlags flags);
|
||||
|
||||
// Fonts, drawing
|
||||
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture
|
||||
IMGUI_API void RegisterUserTexture(ImTextureData* tex); // Register external texture. EXPERIMENTAL: DO NOT USE YET.
|
||||
IMGUI_API void UnregisterUserTexture(ImTextureData* tex);
|
||||
IMGUI_API void RegisterFontAtlas(ImFontAtlas* atlas);
|
||||
IMGUI_API void UnregisterFontAtlas(ImFontAtlas* atlas);
|
||||
@@ -3382,6 +3411,7 @@ namespace ImGui
|
||||
IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window);
|
||||
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
|
||||
IMGUI_API void StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* node, bool undock);
|
||||
IMGUI_API void StopMouseMovingWindow();
|
||||
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||
|
||||
@@ -3458,7 +3488,8 @@ namespace ImGui
|
||||
IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h);
|
||||
IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x);
|
||||
IMGUI_API void PushMultiItemsWidths(int components, float width_full);
|
||||
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
|
||||
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess, float width_min);
|
||||
IMGUI_API void CalcClipRectVisibleItemsY(const ImRect& clip_rect, const ImVec2& pos, float items_height, int* out_visible_start, int* out_visible_end);
|
||||
|
||||
// Parameter stacks (shared)
|
||||
IMGUI_API const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx);
|
||||
@@ -3683,9 +3714,11 @@ namespace ImGui
|
||||
// Drag and Drop
|
||||
IMGUI_API bool IsDragDropActive();
|
||||
IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id);
|
||||
IMGUI_API bool BeginDragDropTargetViewport(ImGuiViewport* viewport, const ImRect* p_bb = NULL);
|
||||
IMGUI_API void ClearDragDrop();
|
||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||
IMGUI_API void RenderDragDropTargetRect(const ImRect& bb, const ImRect& item_clip_rect);
|
||||
IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);
|
||||
IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb);
|
||||
|
||||
// Typing-Select API
|
||||
// (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature)
|
||||
@@ -3779,6 +3812,8 @@ namespace ImGui
|
||||
|
||||
// Tab Bars
|
||||
inline ImGuiTabBar* GetCurrentTabBar() { ImGuiContext& g = *GImGui; return g.CurrentTabBar; }
|
||||
IMGUI_API ImGuiTabBar* TabBarFindByID(ImGuiID id);
|
||||
IMGUI_API void TabBarRemove(ImGuiTabBar* tab_bar);
|
||||
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);
|
||||
IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||
IMGUI_API ImGuiTabItem* TabBarFindTabByOrder(ImGuiTabBar* tab_bar, int order);
|
||||
@@ -3969,7 +4004,6 @@ namespace ImGui
|
||||
//inline bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0) { return TreeNodeUpdateNextOpen(id, flags); } // Renamed in 1.89
|
||||
//inline bool IsKeyPressedMap(ImGuiKey key, bool repeat = true) { IM_ASSERT(IsNamedKey(key)); return IsKeyPressed(key, repeat); } // Removed in 1.87: Mapping from named key is always identity!
|
||||
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister():
|
||||
// Refactored focus/nav/tabbing system in 1.82 and 1.84. If you have old/custom copy-and-pasted widgets which used FocusableItemRegister():
|
||||
// (Old) IMGUI_VERSION_NUM < 18209: using 'ItemAdd(....)' and 'bool tab_focused = FocusableItemRegister(...)'
|
||||
// (Old) IMGUI_VERSION_NUM >= 18209: using 'ItemAdd(..., ImGuiItemAddFlags_Focusable)' and 'bool tab_focused = (g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Focused) != 0'
|
||||
@@ -4027,12 +4061,12 @@ inline bool operator==(const ImTextureRef& lhs, const ImTextureRef& rhs) { re
|
||||
inline bool operator!=(const ImTextureRef& lhs, const ImTextureRef& rhs) { return lhs._TexID != rhs._TexID || lhs._TexData != rhs._TexData; }
|
||||
|
||||
// Refer to ImFontAtlasPackGetRect() to better understand how this works.
|
||||
#define ImFontAtlasRectId_IndexMask_ (0x000FFFFF) // 20-bits: index to access builder->RectsIndex[].
|
||||
#define ImFontAtlasRectId_IndexMask_ (0x0007FFFF) // 20-bits signed: index to access builder->RectsIndex[].
|
||||
#define ImFontAtlasRectId_GenerationMask_ (0x3FF00000) // 10-bits: entry generation, so each ID is unique and get can safely detected old identifiers.
|
||||
#define ImFontAtlasRectId_GenerationShift_ (20)
|
||||
inline int ImFontAtlasRectId_GetIndex(ImFontAtlasRectId id) { return id & ImFontAtlasRectId_IndexMask_; }
|
||||
inline int ImFontAtlasRectId_GetGeneration(ImFontAtlasRectId id) { return (id & ImFontAtlasRectId_GenerationMask_) >> ImFontAtlasRectId_GenerationShift_; }
|
||||
inline ImFontAtlasRectId ImFontAtlasRectId_Make(int index_idx, int gen_idx) { IM_ASSERT(index_idx < ImFontAtlasRectId_IndexMask_ && gen_idx < (ImFontAtlasRectId_GenerationMask_ >> ImFontAtlasRectId_GenerationShift_)); return (ImFontAtlasRectId)(index_idx | (gen_idx << ImFontAtlasRectId_GenerationShift_)); }
|
||||
inline int ImFontAtlasRectId_GetIndex(ImFontAtlasRectId id) { return (id & ImFontAtlasRectId_IndexMask_); }
|
||||
inline unsigned int ImFontAtlasRectId_GetGeneration(ImFontAtlasRectId id) { return (unsigned int)(id & ImFontAtlasRectId_GenerationMask_) >> ImFontAtlasRectId_GenerationShift_; }
|
||||
inline ImFontAtlasRectId ImFontAtlasRectId_Make(int index_idx, int gen_idx) { IM_ASSERT(index_idx >= 0 && index_idx <= ImFontAtlasRectId_IndexMask_ && gen_idx <= (ImFontAtlasRectId_GenerationMask_ >> ImFontAtlasRectId_GenerationShift_)); return (ImFontAtlasRectId)(index_idx | (gen_idx << ImFontAtlasRectId_GenerationShift_)); }
|
||||
|
||||
// Packed rectangle lookup entry (we need an indirection to allow removing/reordering rectangles)
|
||||
// User are returned ImFontAtlasRectId values which are meant to be persistent.
|
||||
@@ -4042,7 +4076,7 @@ inline ImFontAtlasRectId ImFontAtlasRectId_Make(int index_idx, int gen_idx)
|
||||
struct ImFontAtlasRectEntry
|
||||
{
|
||||
int TargetIndex : 20; // When Used: ImFontAtlasRectId -> into Rects[]. When unused: index to next unused RectsIndex[] slot to consume free-list.
|
||||
int Generation : 10; // Increased each time the entry is reused for a new rectangle.
|
||||
unsigned int Generation : 10; // Increased each time the entry is reused for a new rectangle.
|
||||
unsigned int IsUsed : 1;
|
||||
};
|
||||
|
||||
@@ -4185,7 +4219,7 @@ extern const char* ImGuiTestEngine_FindItemDebugLabel(ImGuiContext* ctx, ImGuiI
|
||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) if (g.TestEngineHookItems) ImGuiTestEngineHook_ItemInfo(&g, _ID, _LABEL, _FLAGS) // Register item label and status flags (optional)
|
||||
#define IMGUI_TEST_ENGINE_LOG(_FMT,...) ImGuiTestEngineHook_Log(&g, _FMT, __VA_ARGS__) // Custom log entry from user land into test log
|
||||
#else
|
||||
#define IMGUI_TEST_ENGINE_ITEM_ADD(_BB,_ID) ((void)0)
|
||||
#define IMGUI_TEST_ENGINE_ITEM_ADD(_ID,_BB,_ITEM_DATA) ((void)0)
|
||||
#define IMGUI_TEST_ENGINE_ITEM_INFO(_ID,_LABEL,_FLAGS) ((void)g)
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// dear imgui, v1.92.1
|
||||
// dear imgui, v1.92.4
|
||||
// (tables and columns code)
|
||||
|
||||
/*
|
||||
@@ -437,7 +437,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
if (table->InnerWindow->SkipItems && outer_window_is_measuring_size)
|
||||
table->InnerWindow->SkipItems = false;
|
||||
|
||||
// When using multiple instances, ensure they have the same amount of horizontal decorations (aka vertical scrollbar) so stretched columns can be aligned)
|
||||
// When using multiple instances, ensure they have the same amount of horizontal decorations (aka vertical scrollbar) so stretched columns can be aligned
|
||||
if (instance_no == 0)
|
||||
{
|
||||
table->HasScrollbarYPrev = table->HasScrollbarYCurr;
|
||||
@@ -542,7 +542,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
|
||||
// Make table current
|
||||
g.CurrentTable = table;
|
||||
outer_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
||||
inner_window->DC.NavIsScrollPushableX = false; // Shortcut for NavUpdateCurrentWindowIsScrollPushableX();
|
||||
outer_window->DC.CurrentTableIdx = table_idx;
|
||||
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
|
||||
inner_window->DC.CurrentTableIdx = table_idx;
|
||||
@@ -1825,6 +1825,11 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(target != ImGuiTableBgTarget_None);
|
||||
if (table == NULL)
|
||||
{
|
||||
IM_ASSERT_USER_ERROR(table != NULL, "Call should only be done while in BeginTable() scope!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (color == IM_COL32_DISABLE)
|
||||
color = 0;
|
||||
@@ -2049,10 +2054,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle)
|
||||
// We need to do that in TableEndRow() instead of TableBeginRow() so the list clipper can mark end of row and
|
||||
// get the new cursor position.
|
||||
// - We need to do that in TableEndRow() instead of TableBeginRow() so the list clipper can mark
|
||||
// end of row and get the new cursor position.
|
||||
if (unfreeze_rows_request)
|
||||
{
|
||||
IM_ASSERT(table->FreezeRowsRequest > 0);
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
table->Columns[column_n].NavLayerCurrent = table->NavLayer;
|
||||
const float y0 = ImMax(table->RowPosY2 + 1, table->InnerClipRect.Min.y);
|
||||
@@ -2812,8 +2818,13 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
continue;
|
||||
|
||||
// Draw in outer window so right-most column won't be clipped
|
||||
// Always draw full height border when being resized/hovered, or on the delimitation of frozen column scrolling.
|
||||
float draw_y2 = (is_hovered || is_resized || is_frozen_separator || (table->Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) == 0) ? draw_y2_body : draw_y2_head;
|
||||
float draw_y2 = draw_y2_head;
|
||||
if (is_frozen_separator)
|
||||
draw_y2 = draw_y2_body;
|
||||
else if ((table->Flags & ImGuiTableFlags_NoBordersInBodyUntilResize) != 0 && (is_hovered || is_resized))
|
||||
draw_y2 = draw_y2_body;
|
||||
else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0)
|
||||
draw_y2 = draw_y2_body;
|
||||
if (draw_y2 > draw_y1)
|
||||
inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size);
|
||||
}
|
||||
@@ -2876,9 +2887,7 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL);
|
||||
|
||||
if (!(table->Flags & ImGuiTableFlags_Sortable))
|
||||
if (table == NULL || !(table->Flags & ImGuiTableFlags_Sortable))
|
||||
return NULL;
|
||||
|
||||
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
|
||||
@@ -3939,7 +3948,7 @@ void ImGui::TableSettingsAddSettingsHandler()
|
||||
// - TableGcCompactSettings() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Remove Table (currently only used by TestEngine)
|
||||
// Remove Table data (currently only used by TestEngine)
|
||||
void ImGui::TableRemove(ImGuiTable* table)
|
||||
{
|
||||
//IMGUI_DEBUG_PRINT("TableRemove() id=0x%08X\n", table->ID);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -181,10 +181,10 @@
|
||||
//
|
||||
// To support UTF-8:
|
||||
//
|
||||
// STB_TEXTEDIT_GETPREVCHARINDEX returns index of previous character
|
||||
// STB_TEXTEDIT_GETNEXTCHARINDEX returns index of next character
|
||||
// STB_TEXTEDIT_GETPREVCHARINDEX returns index of previous character
|
||||
// STB_TEXTEDIT_GETNEXTCHARINDEX returns index of next character
|
||||
// Do NOT define STB_TEXTEDIT_KEYTOTEXT.
|
||||
// Instead, call stb_textedit_text() directly for text contents.
|
||||
// Instead, call stb_textedit_text() directly for text contents.
|
||||
//
|
||||
// Keyboard input must be encoded as a single integer value; e.g. a character code
|
||||
// and some bitflags that represent shift states. to simplify the interface, SHIFT must
|
||||
@@ -260,7 +260,7 @@
|
||||
//
|
||||
// text: (added 2025)
|
||||
// call this to directly send text input the textfield, which is required
|
||||
// for UTF-8 support, because stb_textedit_key() + STB_TEXTEDIT_KEYTOTEXT()
|
||||
// for UTF-8 support, because stb_textedit_key() + STB_TEXTEDIT_KEYTOTEXT()
|
||||
// cannot infer text length.
|
||||
//
|
||||
//
|
||||
@@ -427,7 +427,7 @@ typedef struct
|
||||
//
|
||||
|
||||
// traverse the layout to locate the nearest character to a display position
|
||||
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y, int* out_side_on_line)
|
||||
{
|
||||
StbTexteditRow r;
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
@@ -437,6 +437,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
r.x0 = r.x1 = 0;
|
||||
r.ymin = r.ymax = 0;
|
||||
r.num_chars = 0;
|
||||
*out_side_on_line = 0;
|
||||
|
||||
// search rows to find one that straddles 'y'
|
||||
while (i < n) {
|
||||
@@ -456,7 +457,10 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
|
||||
// below all text, return 'after' last character
|
||||
if (i >= n)
|
||||
{
|
||||
*out_side_on_line = 1;
|
||||
return n;
|
||||
}
|
||||
|
||||
// check if it's before the beginning of the line
|
||||
if (x < r.x0)
|
||||
@@ -469,6 +473,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
for (k=0; k < r.num_chars; k = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, i + k) - i) {
|
||||
float w = STB_TEXTEDIT_GETWIDTH(str, i, k);
|
||||
if (x < prev_x+w) {
|
||||
*out_side_on_line = (k == 0) ? 0 : 1;
|
||||
if (x < prev_x+w/2)
|
||||
return k+i;
|
||||
else
|
||||
@@ -480,6 +485,7 @@ static int stb_text_locate_coord(IMSTB_TEXTEDIT_STRING *str, float x, float y)
|
||||
}
|
||||
|
||||
// if the last character is a newline, return that. otherwise return 'after' the last character
|
||||
*out_side_on_line = 1;
|
||||
if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE)
|
||||
return i+r.num_chars-1;
|
||||
else
|
||||
@@ -491,6 +497,7 @@ static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
|
||||
{
|
||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||
// goes off the top or bottom of the text
|
||||
int side_on_line;
|
||||
if( state->single_line )
|
||||
{
|
||||
StbTexteditRow r;
|
||||
@@ -498,16 +505,18 @@ static void stb_textedit_click(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *st
|
||||
y = r.ymin;
|
||||
}
|
||||
|
||||
state->cursor = stb_text_locate_coord(str, x, y);
|
||||
state->cursor = stb_text_locate_coord(str, x, y, &side_on_line);
|
||||
state->select_start = state->cursor;
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
str->LastMoveDirectionLR = (ImS8)(side_on_line ? ImGuiDir_Right : ImGuiDir_Left);
|
||||
}
|
||||
|
||||
// API drag: on mouse drag, move the cursor and selection endpoint to the clicked location
|
||||
static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
|
||||
{
|
||||
int p = 0;
|
||||
int side_on_line;
|
||||
|
||||
// In single-line mode, just always make y = 0. This lets the drag keep working if the mouse
|
||||
// goes off the top or bottom of the text
|
||||
@@ -521,8 +530,9 @@ static void stb_textedit_drag(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *sta
|
||||
if (state->select_start == state->select_end)
|
||||
state->select_start = state->cursor;
|
||||
|
||||
p = stb_text_locate_coord(str, x, y);
|
||||
p = stb_text_locate_coord(str, x, y, &side_on_line);
|
||||
state->cursor = state->select_end = p;
|
||||
str->LastMoveDirectionLR = (ImS8)(side_on_line ? ImGuiDir_Right : ImGuiDir_Left);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -572,6 +582,8 @@ static void stb_textedit_find_charpos(StbFindState *find, IMSTB_TEXTEDIT_STRING
|
||||
STB_TEXTEDIT_LAYOUTROW(&r, str, i);
|
||||
if (n < i + r.num_chars)
|
||||
break;
|
||||
if (str->LastMoveDirectionLR == ImGuiDir_Right && str->Stb->cursor > 0 && str->Stb->cursor == i + r.num_chars && STB_TEXTEDIT_GETCHAR(str, i + r.num_chars - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] Wrapping point handling
|
||||
break;
|
||||
if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line
|
||||
break; // [DEAR IMGUI]
|
||||
prev_start = i;
|
||||
@@ -668,6 +680,35 @@ static void stb_textedit_move_to_last(IMSTB_TEXTEDIT_STRING *str, STB_TexteditSt
|
||||
}
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Extracted this function so we can more easily add support for word-wrapping.
|
||||
#ifndef STB_TEXTEDIT_MOVELINESTART
|
||||
static int stb_textedit_move_line_start(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int cursor)
|
||||
{
|
||||
if (state->single_line)
|
||||
return 0;
|
||||
while (cursor > 0) {
|
||||
int prev = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, cursor);
|
||||
if (STB_TEXTEDIT_GETCHAR(str, prev) == STB_TEXTEDIT_NEWLINE)
|
||||
break;
|
||||
cursor = prev;
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
#define STB_TEXTEDIT_MOVELINESTART stb_textedit_move_line_start
|
||||
#endif
|
||||
#ifndef STB_TEXTEDIT_MOVELINEEND
|
||||
static int stb_textedit_move_line_end(IMSTB_TEXTEDIT_STRING *str, STB_TexteditState *state, int cursor)
|
||||
{
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
if (state->single_line)
|
||||
return n;
|
||||
while (cursor < n && STB_TEXTEDIT_GETCHAR(str, cursor) != STB_TEXTEDIT_NEWLINE)
|
||||
cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, cursor);
|
||||
return cursor;
|
||||
}
|
||||
#define STB_TEXTEDIT_MOVELINEEND stb_textedit_move_line_end
|
||||
#endif
|
||||
|
||||
#ifdef STB_TEXTEDIT_IS_SPACE
|
||||
static int is_word_boundary( IMSTB_TEXTEDIT_STRING *str, int idx )
|
||||
{
|
||||
@@ -921,8 +962,8 @@ retry:
|
||||
|
||||
// [DEAR IMGUI]
|
||||
// going down while being on the last line shouldn't bring us to that line end
|
||||
if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
break;
|
||||
//if (STB_TEXTEDIT_GETCHAR(str, find.first_char + find.length - 1) != STB_TEXTEDIT_NEWLINE)
|
||||
// break;
|
||||
|
||||
// now find character position down a row
|
||||
state->cursor = start;
|
||||
@@ -943,6 +984,8 @@ retry:
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
if (state->cursor == find.first_char + find.length)
|
||||
str->LastMoveDirectionLR = ImGuiDir_Left;
|
||||
state->has_preferred_x = 1;
|
||||
state->preferred_x = goal_x;
|
||||
|
||||
@@ -1007,6 +1050,10 @@ retry:
|
||||
}
|
||||
stb_textedit_clamp(str, state);
|
||||
|
||||
if (state->cursor == find.first_char)
|
||||
str->LastMoveDirectionLR = ImGuiDir_Right;
|
||||
else if (state->cursor == find.prev_first)
|
||||
str->LastMoveDirectionLR = ImGuiDir_Left;
|
||||
state->has_preferred_x = 1;
|
||||
state->preferred_x = goal_x;
|
||||
|
||||
@@ -1024,7 +1071,7 @@ retry:
|
||||
prev_scan = prev;
|
||||
}
|
||||
find.first_char = find.prev_first;
|
||||
find.prev_first = prev_scan;
|
||||
find.prev_first = STB_TEXTEDIT_MOVELINESTART(str, state, prev_scan);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1098,10 +1145,7 @@ retry:
|
||||
case STB_TEXTEDIT_K_LINESTART:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_move_to_first(state);
|
||||
if (state->single_line)
|
||||
state->cursor = 0;
|
||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||
state->cursor = STB_TEXTEDIT_MOVELINESTART(str, state, state->cursor);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
@@ -1109,13 +1153,9 @@ retry:
|
||||
case STB_TEXTEDIT_K_LINEEND2:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINEEND: {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_move_to_first(state);
|
||||
if (state->single_line)
|
||||
state->cursor = n;
|
||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||
stb_textedit_move_to_last(str, state);
|
||||
state->cursor = STB_TEXTEDIT_MOVELINEEND(str, state, state->cursor);
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
}
|
||||
@@ -1126,10 +1166,7 @@ retry:
|
||||
case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT:
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
if (state->single_line)
|
||||
state->cursor = 0;
|
||||
else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE)
|
||||
state->cursor = IMSTB_TEXTEDIT_GETPREVCHARINDEX(str, state->cursor);
|
||||
state->cursor = STB_TEXTEDIT_MOVELINESTART(str, state, state->cursor);
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
@@ -1138,13 +1175,9 @@ retry:
|
||||
case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
|
||||
#endif
|
||||
case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
|
||||
int n = STB_TEXTEDIT_STRINGLEN(str);
|
||||
stb_textedit_clamp(str, state);
|
||||
stb_textedit_prep_selection_at_cursor(state);
|
||||
if (state->single_line)
|
||||
state->cursor = n;
|
||||
else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE)
|
||||
state->cursor = IMSTB_TEXTEDIT_GETNEXTCHARINDEX(str, state->cursor);
|
||||
state->cursor = STB_TEXTEDIT_MOVELINEEND(str, state, state->cursor);
|
||||
state->select_end = state->cursor;
|
||||
state->has_preferred_x = 0;
|
||||
break;
|
||||
|
||||
@@ -4,8 +4,8 @@ misc/cpp/
|
||||
This is also an example of how you may wrap your own similar types.
|
||||
|
||||
misc/debuggers/
|
||||
Helper files for popular debuggers.
|
||||
With the .natvis file, types like ImVector<> will be displayed nicely in Visual Studio debugger.
|
||||
Helper files for popular debuggers (Visual Studio, GDB, LLDB).
|
||||
e.g. With the .natvis file, types like ImVector<> will be displayed nicely in Visual Studio debugger.
|
||||
|
||||
misc/fonts/
|
||||
Fonts loading/merging instructions (e.g. How to handle glyph ranges, how to merge icons fonts).
|
||||
|
||||
@@ -14,3 +14,8 @@ imgui.natvis
|
||||
With this, types like ImVector<> will be displayed nicely in the debugger.
|
||||
(read comments inside file for details)
|
||||
|
||||
imgui_lldb.py
|
||||
LLDB-based debuggers (*): synthetic children provider and summaries for Dear ImGui types.
|
||||
With this, types like ImVector<> will be displayed nicely in the debugger.
|
||||
(read comments inside file for details)
|
||||
(*) Xcode, Android Studio, may be used from VS Code, C++Builder, CLion, Eclipse etc.
|
||||
|
||||
189
misc/debuggers/imgui_lldb.py
Normal file
189
misc/debuggers/imgui_lldb.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# This file implements synthetic children providers and summaries for various Dear ImGui types for LLDB.
|
||||
# LLDB is used by Xcode, Android Studio, and may be used from VS Code, C++Builder, CLion, Eclipse etc.
|
||||
|
||||
#
|
||||
# Useful links/documentation related to the feature:
|
||||
# - https://lldb.llvm.org/use/variable.html#summary-strings
|
||||
# - https://lldb.llvm.org/use/variable.html#synthetic-children
|
||||
# - https://lldb.llvm.org/python_reference/lldb-module.html
|
||||
#
|
||||
# To use it in a debug session:
|
||||
# > (lldb) command script import <path-to-this-file>
|
||||
#
|
||||
# Alternatively you may include the above command in your ~/.lldbinit file to have the formatters
|
||||
# available in all future sessions
|
||||
|
||||
import lldb
|
||||
|
||||
class ArraySynthBase(object):
|
||||
"""
|
||||
Helper baseclass aimed to reduce the boilerplate needed for "array-like" containers
|
||||
"""
|
||||
|
||||
def __init__(self, valobj, internal_dict):
|
||||
self.valobj = valobj
|
||||
|
||||
def bind_to(self, pointer, size):
|
||||
array_p = pointer.GetType().GetPointeeType().GetArrayType(size).GetPointerType()
|
||||
self.array = pointer.Cast(array_p).Dereference()
|
||||
|
||||
def update(self):
|
||||
self.array = self.valobj
|
||||
|
||||
def num_children(self, max_children):
|
||||
return self.array.GetNumChildren(max_children)
|
||||
|
||||
def get_child_index(self, name):
|
||||
return self.array.GetIndexOfChildWithName(name)
|
||||
|
||||
def get_child_at_index(self, index):
|
||||
return self.array.GetChildAtIndex(index)
|
||||
|
||||
def has_children(self):
|
||||
return self.array.MightHaveChildren()
|
||||
|
||||
def get_value(self):
|
||||
return self.array
|
||||
|
||||
class ImVectorSynth(ArraySynthBase):
|
||||
def update(self):
|
||||
self.size = self.valobj.GetChildMemberWithName("Size").GetValueAsUnsigned()
|
||||
self.capacity = self.valobj.GetChildMemberWithName("Capacity").GetValueAsUnsigned()
|
||||
|
||||
data = self.valobj.GetChildMemberWithName("Data")
|
||||
|
||||
self.bind_to(data, self.size)
|
||||
|
||||
def get_summary(self):
|
||||
return f"Size={self.size} Capacity={self.capacity}"
|
||||
|
||||
class ImSpanSynth(ArraySynthBase):
|
||||
def update(self):
|
||||
data = self.valobj.GetChildMemberWithName("Data")
|
||||
end = self.valobj.GetChildMemberWithName("DataEnd")
|
||||
|
||||
element_size = data.GetType().GetPointeeType().GetByteSize()
|
||||
array_size = end.GetValueAsUnsigned() - data.GetValueAsUnsigned()
|
||||
|
||||
self.size = int(array_size / element_size)
|
||||
|
||||
self.bind_to(data, self.size)
|
||||
|
||||
def get_summary(self):
|
||||
return f"Size={self.size}"
|
||||
|
||||
class ImRectSummary(object):
|
||||
def __init__(self, valobj, internal_dict):
|
||||
self.valobj = valobj
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def get_summary(self):
|
||||
min = self.valobj.GetChildMemberWithName("Min")
|
||||
max = self.valobj.GetChildMemberWithName("Max")
|
||||
|
||||
minX = float(min.GetChildMemberWithName("x").GetValue())
|
||||
minY = float(min.GetChildMemberWithName("y").GetValue())
|
||||
|
||||
maxX = float(max.GetChildMemberWithName("x").GetValue())
|
||||
maxY = float(max.GetChildMemberWithName("y").GetValue())
|
||||
|
||||
return f"Min=({minX}, {minY}) Max=({maxX}, {maxY}) Size=({maxX - minX}, {maxY - minY})"
|
||||
|
||||
def get_active_enum_flags(valobj):
|
||||
flag_set = set()
|
||||
|
||||
enum_name = valobj.GetType().GetName() + "_"
|
||||
enum_type = valobj.GetTarget().FindFirstType(enum_name)
|
||||
|
||||
if not enum_type.IsValid():
|
||||
return flag_set
|
||||
|
||||
enum_members = enum_type.GetEnumMembers()
|
||||
value = valobj.GetValueAsUnsigned()
|
||||
|
||||
for i in range(0, enum_members.GetSize()):
|
||||
member = enum_members.GetTypeEnumMemberAtIndex(i)
|
||||
|
||||
if value & member.GetValueAsUnsigned():
|
||||
flag_set.add(member.GetName().removeprefix(enum_name))
|
||||
|
||||
return flag_set
|
||||
|
||||
class ImGuiWindowSummary(object):
|
||||
def __init__(self, valobj, internal_dict):
|
||||
self.valobj = valobj
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
def get_summary(self):
|
||||
name = self.valobj.GetChildMemberWithName("Name").GetSummary()
|
||||
|
||||
active = self.valobj.GetChildMemberWithName("Active").GetValueAsUnsigned() != 0
|
||||
was_active = self.valobj.GetChildMemberWithName("WasActive").GetValueAsUnsigned() != 0
|
||||
hidden = self.valobj.GetChildMemberWithName("Hidden") != 0
|
||||
|
||||
flags = get_active_enum_flags(self.valobj.GetChildMemberWithName("Flags"))
|
||||
|
||||
active = 1 if active or was_active else 0
|
||||
child = 1 if "ChildWindow" in flags else 0
|
||||
popup = 1 if "Popup" in flags else 0
|
||||
hidden = 1 if hidden else 0
|
||||
|
||||
return f"Name {name} Active {active} Child {child} Popup {popup} Hidden {hidden}"
|
||||
|
||||
|
||||
def __lldb_init_module(debugger, internal_dict):
|
||||
"""
|
||||
This function will be automatically called by LLDB when the module is loaded, here
|
||||
we register the various synthetics/summaries we have build before
|
||||
"""
|
||||
|
||||
category_name = "imgui"
|
||||
category = debugger.GetCategory(category_name)
|
||||
|
||||
# Make sure we don't accidentally keep accumulating languages or override the user's
|
||||
# category enablement in Xcode, where lldb-rpc-server loads this file once for eac
|
||||
# debugging session
|
||||
if not category.IsValid():
|
||||
category = debugger.CreateCategory(category_name)
|
||||
category.AddLanguage(lldb.eLanguageTypeC_plus_plus)
|
||||
category.SetEnabled(True)
|
||||
|
||||
def add_summary(typename, impl):
|
||||
summary = None
|
||||
|
||||
if isinstance(impl, str):
|
||||
summary = lldb.SBTypeSummary.CreateWithSummaryString(impl)
|
||||
summary.SetOptions(lldb.eTypeOptionCascade)
|
||||
else:
|
||||
# Unfortunately programmatic summary string generation is an entirely different codepath
|
||||
# in LLDB. Register a convenient trampoline function which makes it look like it's part
|
||||
# of the SyntheticChildrenProvider contract
|
||||
summary = lldb.SBTypeSummary.CreateWithScriptCode(f'''
|
||||
synth = {impl.__module__}.{impl.__qualname__}(valobj.GetNonSyntheticValue(), internal_dict)
|
||||
synth.update()
|
||||
|
||||
return synth.get_summary()
|
||||
''')
|
||||
summary.SetOptions(lldb.eTypeOptionCascade | lldb.eTypeOptionFrontEndWantsDereference)
|
||||
|
||||
category.AddTypeSummary(lldb.SBTypeNameSpecifier(typename, True), summary)
|
||||
|
||||
def add_synthetic(typename, impl):
|
||||
add_summary(typename, impl)
|
||||
|
||||
synthetic = lldb.SBTypeSynthetic.CreateWithClassName(f"{impl.__module__}.{impl.__qualname__}")
|
||||
synthetic.SetOptions(lldb.eTypeOptionCascade | lldb.eTypeOptionFrontEndWantsDereference)
|
||||
|
||||
category.AddTypeSynthetic(lldb.SBTypeNameSpecifier(typename, True), synthetic)
|
||||
|
||||
add_synthetic("^ImVector<.+>$", ImVectorSynth)
|
||||
add_synthetic("^ImSpan<.+>$", ImSpanSynth)
|
||||
|
||||
add_summary("^ImVec2$", "x=${var.x} y=${var.y}")
|
||||
add_summary("^ImVec4$", "x=${var.x} y=${var.y} z=${var.z} w=${var.w}")
|
||||
add_summary("^ImRect$", ImRectSummary)
|
||||
add_summary("^ImGuiWindow$", ImGuiWindowSummary)
|
||||
@@ -7,7 +7,7 @@ Build font atlases using FreeType instead of stb_truetype (which is the default
|
||||
|
||||
1. Get latest FreeType binaries or build yourself (under Windows you may use vcpkg with `vcpkg install freetype --triplet=x64-windows`, `vcpkg integrate install`).
|
||||
2. Add imgui_freetype.h/cpp alongside your project files.
|
||||
3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file
|
||||
3. Add `#define IMGUI_ENABLE_FREETYPE` in your [imconfig.h](https://github.com/ocornut/imgui/blob/master/imconfig.h) file to make Dear ImGui automatically use the imgui_freetype loader. If your copy Dear ImGui is precompiled, you can always enable imgui_freetype by calling ImFontAtlas::SetFontLoader().
|
||||
|
||||
### About Gamma Correct Blending
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ static void* FreeType_Realloc(FT_Memory /*memory*/, long cur_size, long new_size
|
||||
return block;
|
||||
}
|
||||
|
||||
bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas)
|
||||
static bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas)
|
||||
{
|
||||
IM_ASSERT(atlas->FontLoaderData == nullptr);
|
||||
ImGui_ImplFreeType_Data* bd = IM_NEW(ImGui_ImplFreeType_Data)();
|
||||
@@ -384,7 +384,7 @@ bool ImGui_ImplFreeType_LoaderInit(ImFontAtlas* atlas)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplFreeType_LoaderShutdown(ImFontAtlas* atlas)
|
||||
static void ImGui_ImplFreeType_LoaderShutdown(ImFontAtlas* atlas)
|
||||
{
|
||||
ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData;
|
||||
IM_ASSERT(bd != nullptr);
|
||||
@@ -393,7 +393,7 @@ void ImGui_ImplFreeType_LoaderShutdown(ImFontAtlas* atlas)
|
||||
atlas->FontLoaderData = nullptr;
|
||||
}
|
||||
|
||||
bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
static bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
{
|
||||
ImGui_ImplFreeType_Data* bd = (ImGui_ImplFreeType_Data*)atlas->FontLoaderData;
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = IM_NEW(ImGui_ImplFreeType_FontSrcData);
|
||||
@@ -410,7 +410,7 @@ bool ImGui_ImplFreeType_FontSrcInit(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
static void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
{
|
||||
IM_UNUSED(atlas);
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
|
||||
@@ -418,7 +418,7 @@ void ImGui_ImplFreeType_FontSrcDestroy(ImFontAtlas* atlas, ImFontConfig* src)
|
||||
src->FontLoaderData = nullptr;
|
||||
}
|
||||
|
||||
bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
|
||||
static bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
|
||||
{
|
||||
IM_UNUSED(atlas);
|
||||
float size = baked->Size;
|
||||
@@ -464,7 +464,7 @@ bool ImGui_ImplFreeType_FontBakedInit(ImFontAtlas* atlas, ImFontConfig* src, ImF
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
|
||||
static void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src)
|
||||
{
|
||||
IM_UNUSED(atlas);
|
||||
IM_UNUSED(baked);
|
||||
@@ -475,7 +475,7 @@ void ImGui_ImplFreeType_FontBakedDestroy(ImFontAtlas* atlas, ImFontConfig* src,
|
||||
bd_baked_data->~ImGui_ImplFreeType_FontSrcBakedData(); // ~IM_PLACEMENT_DELETE()
|
||||
}
|
||||
|
||||
bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint, ImFontGlyph* out_glyph, float* out_advance_x)
|
||||
static bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImFontBaked* baked, void* loader_data_for_baked_src, ImWchar codepoint, ImFontGlyph* out_glyph, float* out_advance_x)
|
||||
{
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
|
||||
uint32_t glyph_index = FT_Get_Char_Index(bd_font_data->FtFace, codepoint);
|
||||
@@ -566,7 +566,7 @@ bool ImGui_ImplFreeType_FontBakedLoadGlyph(ImFontAtlas* atlas, ImFontConfig* src
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ImGui_ImplFreetype_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint)
|
||||
static bool ImGui_ImplFreetype_FontSrcContainsGlyph(ImFontAtlas* atlas, ImFontConfig* src, ImWchar codepoint)
|
||||
{
|
||||
IM_UNUSED(atlas);
|
||||
ImGui_ImplFreeType_FontSrcData* bd_font_data = (ImGui_ImplFreeType_FontSrcData*)src->FontLoaderData;
|
||||
|
||||
Reference in New Issue
Block a user