mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-06 06:25:54 +01:00
Compare commits
289 Commits
v1.92.9b-d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbb30112c6 | ||
|
|
253aa51aba | ||
|
|
a1af3c1a59 | ||
|
|
8c8b8fc266 | ||
|
|
b2298afa71 | ||
|
|
9d0b72573a | ||
|
|
67f442d5de | ||
|
|
c5131aff7e | ||
|
|
852269e25f | ||
|
|
c6affd1145 | ||
|
|
7ee4dbac89 | ||
|
|
391f714c37 | ||
|
|
1023d3ddaa | ||
|
|
a13badd73e | ||
|
|
f88ec043af | ||
|
|
89845f9db6 | ||
|
|
c1581882a4 | ||
|
|
0d0cd87dd2 | ||
|
|
c39a91bfbe | ||
|
|
d2ba763635 | ||
|
|
b87728bd2b | ||
|
|
2fb554b1c8 | ||
|
|
80d572ce35 | ||
|
|
1069a952e0 | ||
|
|
50ae760fce | ||
|
|
86b853ae8a | ||
|
|
2f1552d4d5 | ||
|
|
048d7e10b5 | ||
|
|
726399ff76 | ||
|
|
4326411672 | ||
|
|
717f68fefe | ||
|
|
4e99c0ab1a | ||
|
|
09fe7b19d7 | ||
|
|
20ba6c4a28 | ||
|
|
6dd654f27a | ||
|
|
2b7a9dcca4 | ||
|
|
7bd38119c7 | ||
|
|
4be0b47ecc | ||
|
|
9d9a621f33 | ||
|
|
49a1450360 | ||
|
|
c7d17f01cd | ||
|
|
f5d2b7dd01 | ||
|
|
145a2fbab6 | ||
|
|
4c9c888fc5 | ||
|
|
1ff218165d | ||
|
|
93a14c8fda | ||
|
|
cbe3d5fb88 | ||
|
|
f996126249 | ||
|
|
6d32174508 | ||
|
|
c1aaac65e8 | ||
|
|
a6fad9bbda | ||
|
|
a536894821 | ||
|
|
098c71133c | ||
|
|
09cd4416e8 | ||
|
|
42a22377a4 | ||
|
|
6aa6626f29 | ||
|
|
dc09bbee1e | ||
|
|
906c6838ad | ||
|
|
2859f6723c | ||
|
|
b2ade5f3ad | ||
|
|
75ac1ab2c3 | ||
|
|
cbf4f05419 | ||
|
|
9e5e0bf9b2 | ||
|
|
d23a638613 | ||
|
|
f84d77c424 | ||
|
|
cb66fcdaac | ||
|
|
7bccc3bc1e | ||
|
|
475b793baa | ||
|
|
0e756a649d | ||
|
|
c52f84c719 | ||
|
|
7415edbad1 | ||
|
|
dee0e34504 | ||
|
|
451e107b3f | ||
|
|
230cd6feb0 | ||
|
|
3dbb849acf | ||
|
|
c6c352f77d | ||
|
|
91dc4f456a | ||
|
|
475660f53c | ||
|
|
640e931284 | ||
|
|
a547deed9b | ||
|
|
059017188d | ||
|
|
deb9c70ace | ||
|
|
20f17eeb6f | ||
|
|
a597beaf95 | ||
|
|
ba918bc45c | ||
|
|
7a510274ce | ||
|
|
ee66cfcdf3 | ||
|
|
b220bffdbb | ||
|
|
eb02a7f24c | ||
|
|
46e4c26095 | ||
|
|
5181e95a46 | ||
|
|
67bcd9d545 | ||
|
|
f511ce18f9 | ||
|
|
bd0f638d8b | ||
|
|
2fdcf895c8 | ||
|
|
f2cd901be6 | ||
|
|
7e87cb984d | ||
|
|
008e0990b3 | ||
|
|
7ccc8348bc | ||
|
|
02adb46a9f | ||
|
|
cf85b48e55 | ||
|
|
eb75c8056e | ||
|
|
9b608ba079 | ||
|
|
10aa5d92e6 | ||
|
|
145b838818 | ||
|
|
c5c76dcda5 | ||
|
|
d9378b71c5 | ||
|
|
230249ad58 | ||
|
|
efb5c0e1da | ||
|
|
b181739cea | ||
|
|
d24d23fb40 | ||
|
|
f272141a4d | ||
|
|
9be9c998d7 | ||
|
|
478813c359 | ||
|
|
a5d8450a0f | ||
|
|
2edac09d9f | ||
|
|
002e2a5f00 | ||
|
|
ed50e4790b | ||
|
|
ec510539c7 | ||
|
|
f2055fe160 | ||
|
|
c6e5d8c85f | ||
|
|
16860367b3 | ||
|
|
ea638a4a11 | ||
|
|
a5a4bed3ca | ||
|
|
fc8f5e66d4 | ||
|
|
130be3be42 | ||
|
|
6856b3e06b | ||
|
|
b484a90846 | ||
|
|
7ec1bc17fd | ||
|
|
e8c8a10a2d | ||
|
|
c59367efcb | ||
|
|
e9246e6ad3 | ||
|
|
3fca7ef414 | ||
|
|
5410a04db4 | ||
|
|
20110d751d | ||
|
|
68b5bf4466 | ||
|
|
d453a59b9c | ||
|
|
ed8ed8bb71 | ||
|
|
90e45bdde0 | ||
|
|
9f5bfdf83b | ||
|
|
6f00e0b39f | ||
|
|
91e769fbba | ||
|
|
3f7da1e184 | ||
|
|
81f316a3bf | ||
|
|
4d5fcdd4ba | ||
|
|
e3fb7657ba | ||
|
|
0e219e6c4d | ||
|
|
d879e9781b | ||
|
|
ce3d970fc7 | ||
|
|
170a374f59 | ||
|
|
c1f781d7af | ||
|
|
5d9b691248 | ||
|
|
5782f4e0ee | ||
|
|
c2e029fb98 | ||
|
|
d1d2f5aead | ||
|
|
ea2e5c79c0 | ||
|
|
858b2b2952 | ||
|
|
049f1a799a | ||
|
|
6c7b083e0e | ||
|
|
a5b8a920c3 | ||
|
|
c98d220e6f | ||
|
|
60a934afd9 | ||
|
|
442834a428 | ||
|
|
5a5a16da4d | ||
|
|
2361f61526 | ||
|
|
d6fee823b4 | ||
|
|
789f0d7140 | ||
|
|
9199934a7f | ||
|
|
80096045d9 | ||
|
|
b9707d72ab | ||
|
|
237a498c2d | ||
|
|
2665220409 | ||
|
|
ae06573c9a | ||
|
|
37f16412d5 | ||
|
|
43d829885e | ||
|
|
f73d8f4029 | ||
|
|
6335dfb19c | ||
|
|
f502f9c980 | ||
|
|
71fc553bc4 | ||
|
|
4989b4c754 | ||
|
|
68bd43b2b4 | ||
|
|
ed73ef4e84 | ||
|
|
a3f3e4944a | ||
|
|
fe33b77f64 | ||
|
|
3f00c0d0f4 | ||
|
|
a9fd325ca5 | ||
|
|
7263a23f1b | ||
|
|
dfa3c0c0bb | ||
|
|
09d740ba32 | ||
|
|
46ff5a7aab | ||
|
|
580c00c316 | ||
|
|
db436a15bc | ||
|
|
09f7a0f062 | ||
|
|
aa0181478b | ||
|
|
5c6a86a9d2 | ||
|
|
e728936797 | ||
|
|
623ba46120 | ||
|
|
cc072ca90e | ||
|
|
a6784c378f | ||
|
|
7bfc192814 | ||
|
|
d12321803d | ||
|
|
58d7570b8b | ||
|
|
6cf8332f93 | ||
|
|
e19fea020f | ||
|
|
d5c68c301a | ||
|
|
420f179341 | ||
|
|
249e5a939d | ||
|
|
565564bb5c | ||
|
|
c0041b7d3c | ||
|
|
c74e7e93a3 | ||
|
|
54f86be71e | ||
|
|
fc98dc4a72 | ||
|
|
a14bebd948 | ||
|
|
f7ada78e32 | ||
|
|
c8fc1829d0 | ||
|
|
f09485d7be | ||
|
|
6d07f6eb09 | ||
|
|
5a0ac1678c | ||
|
|
eabff0fd08 | ||
|
|
25e16fd8b6 | ||
|
|
333f5186e3 | ||
|
|
b5135f270f | ||
|
|
09b7ff9385 | ||
|
|
8d3e37eb53 | ||
|
|
7cb5ded5d2 | ||
|
|
a5b5f2d85a | ||
|
|
8e174685ae | ||
|
|
b00dd14a34 | ||
|
|
c8b9f0d6be | ||
|
|
ea60e7b748 | ||
|
|
e0a2f6dea9 | ||
|
|
e8602501bb | ||
|
|
ea6d21687b | ||
|
|
db5b735a5d | ||
|
|
32c3f6095a | ||
|
|
148d128f6e | ||
|
|
334f484892 | ||
|
|
dd32dace81 | ||
|
|
04b37d6d23 | ||
|
|
9090ba71e5 | ||
|
|
53d421955f | ||
|
|
687f7fb8ac | ||
|
|
4ebb04333b | ||
|
|
4898533613 | ||
|
|
080319c4ce | ||
|
|
96b6eb7728 | ||
|
|
f150bf09f9 | ||
|
|
51c3c0c992 | ||
|
|
5316e70614 | ||
|
|
7edd2b1f12 | ||
|
|
1807b25b9a | ||
|
|
4dbb921b22 | ||
|
|
e2e9533991 | ||
|
|
a15761f11c | ||
|
|
f562ab8e32 | ||
|
|
e0537bf72b | ||
|
|
ebc7307db5 | ||
|
|
fd74775a0d | ||
|
|
19ead810d2 | ||
|
|
7e0de0e411 | ||
|
|
35a13e9948 | ||
|
|
e44b1129bd | ||
|
|
6d1f88fe4a | ||
|
|
760dff3244 | ||
|
|
d3c5ff395c | ||
|
|
1e51b6ffdc | ||
|
|
0af8f475d1 | ||
|
|
1d7b37dc9b | ||
|
|
3e9d0f7e82 | ||
|
|
46d39d56fe | ||
|
|
551a0a6bc0 | ||
|
|
5de45fb1d9 | ||
|
|
49fa47fc19 | ||
|
|
5b6e19bb50 | ||
|
|
70e60a3c4c | ||
|
|
2ddb5fc095 | ||
|
|
98f3efcf07 | ||
|
|
730f099239 | ||
|
|
724c69b182 | ||
|
|
6a6d7bc3ca | ||
|
|
a5a3e1bd04 | ||
|
|
2de0a07cd4 | ||
|
|
7c9f0c148c | ||
|
|
40ec568762 | ||
|
|
5108603789 | ||
|
|
fdc1152281 | ||
|
|
b647af2100 | ||
|
|
ebd752a0ec | ||
|
|
9b7699f325 |
1
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
1
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@ -14,6 +14,7 @@ body:
|
|||||||
attributes:
|
attributes:
|
||||||
value: |
|
value: |
|
||||||
**Prerequisites:**
|
**Prerequisites:**
|
||||||
|
- I am not using a LLM to think or write for me. Please distill information to what's necessary and meaningful.
|
||||||
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
|
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
|
||||||
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
|
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
|
||||||
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
|
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
|
||||||
|
|||||||
4
.github/pull_request_template.md
vendored
4
.github/pull_request_template.md
vendored
@ -1,12 +1,12 @@
|
|||||||
(Click "Preview" to turn any http URL into a clickable link)
|
(Click "Preview" to turn any http URL into a clickable link)
|
||||||
|
|
||||||
1. PLEASE CAREFULLY READ: [Contributing Guidelines](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md)
|
1. PLEASE CAREFULLY READ: [Contributing Guidelines](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md). By submitting a PR you are agreeing with the [CLA](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#copyright--contributor-license-agreement).
|
||||||
|
|
||||||
2. **Make sure you're using a special branch just for this pull request**. (In git, 1 PR = 1 branch. If you update the branch the PR will be updated.)
|
2. **Make sure you're using a special branch just for this pull request**. (In git, 1 PR = 1 branch. If you update the branch the PR will be updated.)
|
||||||
|
|
||||||
3. Consider running the [imgui_test_suite](https://github.com/ocornut/imgui_test_engine) or adding new tests to test for expected behaviors.
|
3. Consider running the [imgui_test_suite](https://github.com/ocornut/imgui_test_engine) or adding new tests to test for expected behaviors.
|
||||||
|
|
||||||
4. PLEASE DO NOT SUBMIT AI SLOP OR AUTOMATED REPORTS. Submissions that are lacking proper human review/judgement before being passed to us are not welcome.
|
4. PLEASE DO NOT SUBMIT AI-GENERATED PROSE. ONLY SUBMIT CODE THAT YOU REVIEWED AND UNDERSTAND. Submissions that are lacking proper human review/judgement before being passed to us are not welcome.
|
||||||
|
|
||||||
5. Clear this template before submitting your PR.
|
5. Clear this template before submitting your PR.
|
||||||
|
|
||||||
|
|||||||
41
.github/workflows/build.yml
vendored
41
.github/workflows/build.yml
vendored
@ -77,7 +77,7 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
cd examples\example_null
|
cd examples\example_null
|
||||||
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
|
call "%VS_PATH%\VC\Auxiliary\Build\vcvars64.bat"
|
||||||
.\build_win32.bat /W4
|
.\build_win.bat /W4
|
||||||
|
|
||||||
- name: Build example_null (single file build)
|
- name: Build example_null (single file build)
|
||||||
shell: bash
|
shell: bash
|
||||||
@ -268,6 +268,39 @@ jobs:
|
|||||||
shell: cmd
|
shell: cmd
|
||||||
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
run: '"%MSBUILD_PATH%\MSBuild.exe" examples/example_win32_directx12/example_win32_directx12.vcxproj /p:Platform=x64 /p:Configuration=Release'
|
||||||
|
|
||||||
|
Build-Windows-ARM64:
|
||||||
|
runs-on: windows-11-arm
|
||||||
|
name: Build - Windows ARM64
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
working-directory: ${{ github.workspace }}/imgui
|
||||||
|
|
||||||
|
env:
|
||||||
|
VS_PATH: C:\Program Files\Microsoft Visual Studio\18\Enterprise
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v6
|
||||||
|
with:
|
||||||
|
path: ${{ github.workspace }}/imgui
|
||||||
|
|
||||||
|
- name: Build example_null (extra warnings, msvc arm64)
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
cd examples\example_null
|
||||||
|
call "%VS_PATH%\VC\Auxiliary\Build\vcvarsarm64.bat"
|
||||||
|
.\build_win.bat /W4
|
||||||
|
|
||||||
|
- name: Run example_null (msvc arm64)
|
||||||
|
shell: cmd
|
||||||
|
run: examples\example_null\Debug\example_null.exe
|
||||||
|
|
||||||
|
- name: Build example_win32_directx11 (msvc arm64)
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
cd examples\example_win32_directx11
|
||||||
|
call "%VS_PATH%\VC\Auxiliary\Build\vcvarsarm64.bat"
|
||||||
|
.\build_win.bat
|
||||||
|
|
||||||
Build-Linux:
|
Build-Linux:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Build - Linux
|
name: Build - Linux
|
||||||
@ -523,7 +556,7 @@ jobs:
|
|||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: |
|
run: |
|
||||||
brew install glfw3 sdl2 sdl3
|
brew install glfw sdl2 sdl3
|
||||||
|
|
||||||
- name: Build example_null (extra warnings, clang 64-bit)
|
- name: Build example_null (extra warnings, clang 64-bit)
|
||||||
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
run: make -C examples/example_null WITH_EXTRA_WARNINGS=1
|
||||||
@ -601,6 +634,10 @@ jobs:
|
|||||||
run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
|
run: xcodebuild -project examples/example_apple_opengl2/example_apple_opengl2.xcodeproj -target example_osx_opengl2
|
||||||
if: github.event_name == 'workflow_run'
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
|
- name: Build macOS example_apple_opengl3
|
||||||
|
run: xcodebuild -project examples/example_apple_opengl3/example_apple_opengl3.xcodeproj -target example_osx_opengl3
|
||||||
|
if: github.event_name == 'workflow_run'
|
||||||
|
|
||||||
Build-iOS:
|
Build-iOS:
|
||||||
runs-on: macos-14
|
runs-on: macos-14
|
||||||
name: Build - iOS
|
name: Build - iOS
|
||||||
|
|||||||
9
.gitignore
vendored
9
.gitignore
vendored
@ -9,6 +9,8 @@ imgui*.ini
|
|||||||
|
|
||||||
## General build artifacts
|
## General build artifacts
|
||||||
*.o
|
*.o
|
||||||
|
*.so*
|
||||||
|
*.a
|
||||||
*.obj
|
*.obj
|
||||||
*.exe
|
*.exe
|
||||||
examples/*/Debug/*
|
examples/*/Debug/*
|
||||||
@ -57,9 +59,16 @@ examples/example_sdl3_wgpu/web/*
|
|||||||
.idea
|
.idea
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
|
|
||||||
|
## QNX artifacts
|
||||||
|
*.pinfo
|
||||||
|
*.dep
|
||||||
|
*.gcno
|
||||||
|
|
||||||
## Unix executables from our example Makefiles
|
## Unix executables from our example Makefiles
|
||||||
examples/example_apple_metal/example_apple_metal
|
examples/example_apple_metal/example_apple_metal
|
||||||
|
examples/example_apple_metal4/example_apple_metal4
|
||||||
examples/example_apple_opengl2/example_apple_opengl2
|
examples/example_apple_opengl2/example_apple_opengl2
|
||||||
|
examples/example_apple_opengl3/example_apple_opengl3
|
||||||
examples/example_glfw_metal/example_glfw_metal
|
examples/example_glfw_metal/example_glfw_metal
|
||||||
examples/example_glfw_opengl2/example_glfw_opengl2
|
examples/example_glfw_opengl2/example_glfw_opengl2
|
||||||
examples/example_glfw_opengl3/example_glfw_opengl3
|
examples/example_glfw_opengl3/example_glfw_opengl3
|
||||||
|
|||||||
@ -11,7 +11,6 @@
|
|||||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||||
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: Allegro5 cannot enable/disable LINEAR bitmap flags after creation.
|
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: Allegro5 cannot enable/disable LINEAR bitmap flags after creation.
|
||||||
// [ ] Platform: Missing gamepad support.
|
// [ ] Platform: Missing gamepad support.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -269,8 +268,7 @@ void ImGui_ImplAllegro5_UpdateTexture(ImTextureData* tex)
|
|||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
// Create texture
|
// Create texture (bilinear sampling is required)
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
const int new_bitmap_flags = al_get_new_bitmap_flags();
|
const int new_bitmap_flags = al_get_new_bitmap_flags();
|
||||||
int new_bitmap_format = al_get_new_bitmap_format();
|
int new_bitmap_format = al_get_new_bitmap_format();
|
||||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP | ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||||
|
|||||||
@ -11,7 +11,6 @@
|
|||||||
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
// [ ] Renderer: The renderer is suboptimal as we need to unindex our buffers and convert vertices manually.
|
||||||
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: Allegro5 cannot enable/disable LINEAR bitmap flags after creation.
|
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: Allegro5 cannot enable/disable LINEAR bitmap flags after creation.
|
||||||
// [ ] Platform: Missing gamepad support.
|
// [ ] Platform: Missing gamepad support.
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
// [ ] Platform: Clipboard support.
|
// [ ] Platform: Clipboard support.
|
||||||
// [ ] Platform: Gamepad support.
|
// [ ] Platform: Gamepad support.
|
||||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
|
||||||
// Important:
|
// Important:
|
||||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||||
|
|||||||
@ -8,7 +8,6 @@
|
|||||||
// [ ] Platform: Clipboard support.
|
// [ ] Platform: Clipboard support.
|
||||||
// [ ] Platform: Gamepad support.
|
// [ ] Platform: Gamepad support.
|
||||||
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. FIXME: Check if this is even possible with Android.
|
||||||
// [ ] Platform: Multi-viewport support (multiple windows). Not meaningful on Android.
|
|
||||||
// Important:
|
// Important:
|
||||||
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
// - Consider using SDL or GLFW backend on Android, which will be more full-featured than this.
|
||||||
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
// - FIXME: On-screen keyboard currently needs to be enabled by the application (see examples/ and issue #3446)
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX10_GetRenderState().
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-04-23: DirectX10: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplDX10_RenderState. (#9378)
|
// 2026-04-23: DirectX10: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplDX10_RenderState. (#9378)
|
||||||
// 2026-01-19: DirectX10: Added 'SamplerNearest' in ImGui_ImplDX10_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
// 2026-01-19: DirectX10: Added 'SamplerNearest' in ImGui_ImplDX10_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
||||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||||
@ -101,9 +101,10 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState()
|
||||||
static void ImGui_ImplDX10_InitMultiViewportSupport();
|
{
|
||||||
static void ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
return (ImGui_ImplDX10_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
|
static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device* device)
|
||||||
@ -112,8 +113,8 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
|||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D10_VIEWPORT vp = {};
|
D3D10_VIEWPORT vp = {};
|
||||||
vp.Width = (UINT)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
vp.Width = (UINT)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
vp.Height = (UINT)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
vp.Height = (UINT)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
vp.MinDepth = 0.0f;
|
vp.MinDepth = 0.0f;
|
||||||
vp.MaxDepth = 1.0f;
|
vp.MaxDepth = 1.0f;
|
||||||
vp.TopLeftX = vp.TopLeftY = 0;
|
vp.TopLeftX = vp.TopLeftY = 0;
|
||||||
@ -563,8 +564,7 @@ bool ImGui_ImplDX10_CreateDeviceObjects()
|
|||||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create texture sampler
|
// Create texture sampler (bilinear sampling is required)
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
{
|
{
|
||||||
D3D10_SAMPLER_DESC desc;
|
D3D10_SAMPLER_DESC desc;
|
||||||
ZeroMemory(&desc, sizeof(desc));
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
@ -619,7 +619,6 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
|||||||
io.BackendRendererName = "imgui_impl_dx10";
|
io.BackendRendererName = "imgui_impl_dx10";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
@ -642,8 +641,6 @@ bool ImGui_ImplDX10_Init(ID3D10Device* device)
|
|||||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||||
bd->pd3dDevice->AddRef();
|
bd->pd3dDevice->AddRef();
|
||||||
|
|
||||||
ImGui_ImplDX10_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -654,14 +651,13 @@ void ImGui_ImplDX10_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplDX10_InvalidateDeviceObjects();
|
ImGui_ImplDX10_InvalidateDeviceObjects();
|
||||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -676,131 +672,6 @@ void ImGui_ImplDX10_NewFrame()
|
|||||||
IM_ASSERT(0 && "ImGui_ImplDX10_CreateDeviceObjects() failed!");
|
IM_ASSERT(0 && "ImGui_ImplDX10_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplDX10_ViewportData
|
|
||||||
{
|
|
||||||
IDXGISwapChain* SwapChain;
|
|
||||||
ID3D10RenderTargetView* RTView;
|
|
||||||
|
|
||||||
ImGui_ImplDX10_ViewportData() { SwapChain = nullptr; RTView = nullptr; }
|
|
||||||
~ImGui_ImplDX10_ViewportData() { IM_ASSERT(SwapChain == nullptr && RTView == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
|
||||||
ImGui_ImplDX10_ViewportData* vd = IM_NEW(ImGui_ImplDX10_ViewportData)();
|
|
||||||
viewport->RendererUserData = vd;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL's WindowID).
|
|
||||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
|
||||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(hwnd != 0);
|
|
||||||
|
|
||||||
// Create swap chain
|
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
|
||||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
|
||||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
|
||||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
sd.SampleDesc.Count = 1;
|
|
||||||
sd.SampleDesc.Quality = 0;
|
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
sd.BufferCount = 1;
|
|
||||||
sd.OutputWindow = hwnd;
|
|
||||||
sd.Windowed = TRUE;
|
|
||||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
|
||||||
sd.Flags = 0;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
ID3D10Texture2D* pBackBuffer;
|
|
||||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
|
||||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
|
||||||
pBackBuffer->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX10_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 here since we didn't create the data for it.
|
|
||||||
if (ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
if (vd->SwapChain)
|
|
||||||
vd->SwapChain->Release();
|
|
||||||
vd->SwapChain = nullptr;
|
|
||||||
if (vd->RTView)
|
|
||||||
vd->RTView->Release();
|
|
||||||
vd->RTView = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX10_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
|
||||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd->RTView)
|
|
||||||
{
|
|
||||||
vd->RTView->Release();
|
|
||||||
vd->RTView = nullptr;
|
|
||||||
}
|
|
||||||
if (vd->SwapChain)
|
|
||||||
{
|
|
||||||
ID3D10Texture2D* pBackBuffer = nullptr;
|
|
||||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
|
||||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
|
||||||
if (pBackBuffer == nullptr) { fprintf(stderr, "ImGui_ImplDX10_SetWindowSize() failed creating buffers.\n"); return; }
|
|
||||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
|
||||||
pBackBuffer->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
|
||||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
bd->pd3dDevice->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
bd->pd3dDevice->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
|
||||||
ImGui_ImplDX10_RenderDrawData(viewport->DrawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX10_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd->SwapChain)
|
|
||||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX10_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX10_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX10_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderViewport;
|
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX10_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX10_GetRenderState().
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -46,5 +46,6 @@ struct ImGui_ImplDX10_RenderState
|
|||||||
//ID3D10SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
//ID3D10SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
||||||
//ID3D10SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
//ID3D10SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState();
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX11_GetRenderState().
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// 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,13 +17,11 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2026-04-23: DirectX11: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplDX11_RenderState. (#9378)
|
// 2026-04-23: DirectX11: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplDX11_RenderState. (#9378)
|
||||||
// 2026-01-19: DirectX11: Added 'SamplerNearest' in ImGui_ImplDX11_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
// 2026-01-19: DirectX11: Added 'SamplerNearest' in ImGui_ImplDX11_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
||||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||||
// 2025-06-11: DirectX11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
// 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-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.
|
|
||||||
// 2025-01-06: DirectX11: Expose VertexConstantBuffer in ImGui_ImplDX11_RenderState. Reset projection matrix in ImDrawCallback_ResetRenderState handler.
|
// 2025-01-06: DirectX11: Expose VertexConstantBuffer in ImGui_ImplDX11_RenderState. Reset projection matrix in ImDrawCallback_ResetRenderState handler.
|
||||||
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
@ -90,7 +87,6 @@ struct ImGui_ImplDX11_Data
|
|||||||
int VertexBufferSize;
|
int VertexBufferSize;
|
||||||
int IndexBufferSize;
|
int IndexBufferSize;
|
||||||
ImGui_ImplDX11_RenderState* RenderState; // == (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState during rendering.
|
ImGui_ImplDX11_RenderState* RenderState; // == (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState during rendering.
|
||||||
ImVector<DXGI_SWAP_CHAIN_DESC> SwapChainDescsForViewports;
|
|
||||||
|
|
||||||
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
};
|
};
|
||||||
@ -107,9 +103,10 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState()
|
||||||
static void ImGui_ImplDX11_InitMultiViewportSupport();
|
{
|
||||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
return (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||||
@ -118,8 +115,8 @@ static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11D
|
|||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D11_VIEWPORT vp = {};
|
D3D11_VIEWPORT vp = {};
|
||||||
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
vp.Width = (float)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
vp.Height = (float)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
vp.MinDepth = 0.0f;
|
vp.MinDepth = 0.0f;
|
||||||
vp.MaxDepth = 1.0f;
|
vp.MaxDepth = 1.0f;
|
||||||
vp.TopLeftX = vp.TopLeftY = 0;
|
vp.TopLeftX = vp.TopLeftY = 0;
|
||||||
@ -637,7 +634,6 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
io.BackendRendererName = "imgui_impl_dx11";
|
io.BackendRendererName = "imgui_impl_dx11";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
@ -663,8 +659,6 @@ bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_co
|
|||||||
bd->pd3dDevice->AddRef();
|
bd->pd3dDevice->AddRef();
|
||||||
bd->pd3dDeviceContext->AddRef();
|
bd->pd3dDeviceContext->AddRef();
|
||||||
|
|
||||||
ImGui_ImplDX11_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -675,7 +669,6 @@ void ImGui_ImplDX11_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
@ -683,7 +676,7 @@ void ImGui_ImplDX11_Shutdown()
|
|||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -698,152 +691,6 @@ void ImGui_ImplDX11_NewFrame()
|
|||||||
IM_ASSERT(0 && "ImGui_ImplDX11_CreateDeviceObjects() failed!");
|
IM_ASSERT(0 && "ImGui_ImplDX11_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplDX11_ViewportData
|
|
||||||
{
|
|
||||||
IDXGISwapChain* SwapChain;
|
|
||||||
ID3D11RenderTargetView* RTView;
|
|
||||||
|
|
||||||
ImGui_ImplDX11_ViewportData() { SwapChain = nullptr; RTView = nullptr; }
|
|
||||||
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == nullptr && RTView == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Multi-Viewports: configure templates used when creating swapchains for secondary viewports. Will try them in order.
|
|
||||||
// This is intentionally not declared in the .h file yet, so you will need to copy this declaration:
|
|
||||||
void ImGui_ImplDX11_SetSwapChainDescs(const DXGI_SWAP_CHAIN_DESC* desc_templates, int desc_templates_count);
|
|
||||||
void ImGui_ImplDX11_SetSwapChainDescs(const DXGI_SWAP_CHAIN_DESC* desc_templates, int desc_templates_count)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
|
||||||
bd->SwapChainDescsForViewports.resize(desc_templates_count);
|
|
||||||
memcpy(bd->SwapChainDescsForViewports.Data, desc_templates, sizeof(DXGI_SWAP_CHAIN_DESC));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
|
||||||
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
|
||||||
viewport->RendererUserData = vd;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL's WindowID).
|
|
||||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
|
||||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(hwnd != 0);
|
|
||||||
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
|
||||||
|
|
||||||
// Create swap chain
|
|
||||||
HRESULT hr = DXGI_ERROR_UNSUPPORTED;
|
|
||||||
for (const DXGI_SWAP_CHAIN_DESC& sd_template : bd->SwapChainDescsForViewports)
|
|
||||||
{
|
|
||||||
IM_ASSERT(sd_template.BufferDesc.Width == 0 && sd_template.BufferDesc.Height == 0 && sd_template.OutputWindow == nullptr);
|
|
||||||
DXGI_SWAP_CHAIN_DESC sd = sd_template;
|
|
||||||
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
|
||||||
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
|
||||||
sd.OutputWindow = hwnd;
|
|
||||||
hr = bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
|
||||||
if (SUCCEEDED(hr))
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* pBackBuffer;
|
|
||||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
|
||||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
|
||||||
pBackBuffer->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == nullptr since we didn't create the data for it.
|
|
||||||
if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
if (vd->SwapChain)
|
|
||||||
vd->SwapChain->Release();
|
|
||||||
vd->SwapChain = nullptr;
|
|
||||||
if (vd->RTView)
|
|
||||||
vd->RTView->Release();
|
|
||||||
vd->RTView = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
|
||||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd->RTView)
|
|
||||||
{
|
|
||||||
vd->RTView->Release();
|
|
||||||
vd->RTView = nullptr;
|
|
||||||
}
|
|
||||||
if (vd->SwapChain)
|
|
||||||
{
|
|
||||||
ID3D11Texture2D* pBackBuffer = nullptr;
|
|
||||||
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
|
||||||
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
|
||||||
if (pBackBuffer == nullptr) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; }
|
|
||||||
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
|
||||||
pBackBuffer->Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
|
||||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
|
||||||
ImGui_ImplDX11_RenderDrawData(viewport->DrawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd->SwapChain)
|
|
||||||
vd->SwapChain->Present(0, 0); // Present without vsync
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
|
||||||
|
|
||||||
// Default swapchain format
|
|
||||||
DXGI_SWAP_CHAIN_DESC sd;
|
|
||||||
ZeroMemory(&sd, sizeof(sd));
|
|
||||||
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
|
||||||
sd.SampleDesc.Count = 1;
|
|
||||||
sd.SampleDesc.Quality = 0;
|
|
||||||
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
sd.BufferCount = 1;
|
|
||||||
sd.Windowed = TRUE;
|
|
||||||
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
|
||||||
sd.Flags = 0;
|
|
||||||
ImGui_ImplDX11_SetSwapChainDescs(&sd, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX11_GetRenderState().
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -49,5 +48,6 @@ struct ImGui_ImplDX11_RenderState
|
|||||||
//ID3D11SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
//ID3D11SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
||||||
//ID3D11SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
//ID3D11SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState();
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,9 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX12_GetRenderState().
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
|
||||||
|
|
||||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -22,9 +20,9 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
|
// 2026-08-05: DirectX12: *BREAKING CHANGE* Removed support for legacy `ImGui_ImplDX12_Init()` signature obsoleted in 1.91.6 (2024-11-15) because it needed to forcefully disable support for ImGuiBackendFlags_RendererHasTextures. (#9487)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2025-10-23: [Docking] DirectX12: Fixed an issue in synchronization logic improving rendering throughput for secondary viewports. (#8961, #9025)
|
|
||||||
// 2025-10-11: DirectX12: Reuse texture upload buffer and grow it only when necessary. (#9002)
|
// 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: Rework synchronization logic. (#8961)
|
||||||
// 2025-09-29: DirectX12: Enable swapchain tearing to eliminate viewports framerate throttling. (#8965)
|
// 2025-09-29: DirectX12: Enable swapchain tearing to eliminate viewports framerate throttling. (#8965)
|
||||||
@ -122,6 +120,9 @@ struct ImGui_ImplDX12_Data
|
|||||||
UINT pTexUploadBufferSize;
|
UINT pTexUploadBufferSize;
|
||||||
void* pTexUploadBufferMapped;
|
void* pTexUploadBufferMapped;
|
||||||
|
|
||||||
|
ImGui_ImplDX12_RenderBuffers* pFrameResources;
|
||||||
|
UINT frameIndex;
|
||||||
|
|
||||||
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplDX12_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -132,6 +133,11 @@ static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplDX12_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// Buffers used during the rendering of a frame
|
// Buffers used during the rendering of a frame
|
||||||
struct ImGui_ImplDX12_RenderBuffers
|
struct ImGui_ImplDX12_RenderBuffers
|
||||||
{
|
{
|
||||||
@ -141,85 +147,11 @@ struct ImGui_ImplDX12_RenderBuffers
|
|||||||
int VertexBufferSize;
|
int VertexBufferSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
// Main viewport created by application will only use the Resources field.
|
|
||||||
// Secondary viewports created by this backend will use all the fields (including Window fields),
|
|
||||||
struct ImGui_ImplDX12_ViewportData
|
|
||||||
{
|
|
||||||
// Window
|
|
||||||
ID3D12CommandQueue* CommandQueue;
|
|
||||||
ID3D12GraphicsCommandList* CommandList;
|
|
||||||
ID3D12DescriptorHeap* RtvDescHeap;
|
|
||||||
IDXGISwapChain3* SwapChain;
|
|
||||||
HANDLE SwapChainWaitableObject;
|
|
||||||
UINT NumFramesInFlight;
|
|
||||||
ImGui_ImplDX12_FrameContext* FrameCtx;
|
|
||||||
|
|
||||||
// Render buffers
|
|
||||||
UINT FrameIndex;
|
|
||||||
ImGui_ImplDX12_RenderBuffers* FrameRenderBuffers;
|
|
||||||
|
|
||||||
ImGui_ImplDX12_ViewportData(UINT num_frames_in_flight)
|
|
||||||
{
|
|
||||||
CommandQueue = nullptr;
|
|
||||||
CommandList = nullptr;
|
|
||||||
RtvDescHeap = nullptr;
|
|
||||||
SwapChain = nullptr;
|
|
||||||
SwapChainWaitableObject = nullptr;
|
|
||||||
NumFramesInFlight = num_frames_in_flight;
|
|
||||||
FrameCtx = new ImGui_ImplDX12_FrameContext[NumFramesInFlight];
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Create buffers with a default size (they will later be grown as needed)
|
|
||||||
FrameRenderBuffers[i].IndexBuffer = nullptr;
|
|
||||||
FrameRenderBuffers[i].VertexBuffer = nullptr;
|
|
||||||
FrameRenderBuffers[i].VertexBufferSize = 5000;
|
|
||||||
FrameRenderBuffers[i].IndexBufferSize = 10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~ImGui_ImplDX12_ViewportData()
|
|
||||||
{
|
|
||||||
IM_ASSERT(CommandQueue == nullptr && CommandList == nullptr);
|
|
||||||
IM_ASSERT(RtvDescHeap == nullptr);
|
|
||||||
IM_ASSERT(SwapChain == nullptr);
|
|
||||||
IM_ASSERT(SwapChainWaitableObject == nullptr);
|
|
||||||
|
|
||||||
for (UINT i = 0; i < NumFramesInFlight; ++i)
|
|
||||||
{
|
|
||||||
IM_ASSERT(FrameCtx[i].CommandAllocator == nullptr && FrameCtx[i].RenderTarget == nullptr);
|
|
||||||
IM_ASSERT(FrameRenderBuffers[i].IndexBuffer == nullptr && FrameRenderBuffers[i].VertexBuffer == nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete[] FrameCtx; FrameCtx = nullptr;
|
|
||||||
delete[] FrameRenderBuffers; FrameRenderBuffers = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VERTEX_CONSTANT_BUFFER_DX12
|
struct VERTEX_CONSTANT_BUFFER_DX12
|
||||||
{
|
{
|
||||||
float mvp[4][4];
|
float mvp[4][4];
|
||||||
};
|
};
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplDX12_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplDX12_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX12_SetupSamplerLinear(ID3D12GraphicsCommandList* command_list)
|
static void ImGui_ImplDX12_SetupSamplerLinear(ID3D12GraphicsCommandList* command_list)
|
||||||
{
|
{
|
||||||
@ -257,8 +189,8 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
|||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
D3D12_VIEWPORT vp = {};
|
D3D12_VIEWPORT vp = {};
|
||||||
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
vp.Width = (float)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
vp.Height = (float)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
vp.MinDepth = 0.0f;
|
vp.MinDepth = 0.0f;
|
||||||
vp.MaxDepth = 1.0f;
|
vp.MaxDepth = 1.0f;
|
||||||
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
||||||
@ -315,9 +247,8 @@ void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandL
|
|||||||
|
|
||||||
// FIXME: We are assuming that this only gets called once per frame!
|
// FIXME: We are assuming that this only gets called once per frame!
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
bd->frameIndex = bd->frameIndex + 1;
|
||||||
ImGui_ImplDX12_RenderBuffers* fr = &vd->FrameRenderBuffers[vd->FrameIndex % bd->numFramesInFlight];
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[bd->frameIndex % bd->numFramesInFlight];
|
||||||
vd->FrameIndex++;
|
|
||||||
|
|
||||||
// Create and grow vertex/index buffers if needed
|
// Create and grow vertex/index buffers if needed
|
||||||
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
if (fr->VertexBuffer == nullptr || fr->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
@ -684,7 +615,7 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
param[1].DescriptorTable.pDescriptorRanges = &descRange;
|
param[1].DescriptorTable.pDescriptorRanges = &descRange;
|
||||||
param[1].ShaderVisibility = D3D12_SHADER_VISIBILITY_PIXEL;
|
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.
|
// Bilinear sampling is required
|
||||||
D3D12_STATIC_SAMPLER_DESC staticSampler[1] = {};
|
D3D12_STATIC_SAMPLER_DESC staticSampler[1] = {};
|
||||||
staticSampler[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
staticSampler[0].Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
staticSampler[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
staticSampler[0].AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
|
||||||
@ -918,13 +849,6 @@ bool ImGui_ImplDX12_CreateDeviceObjects()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplDX12_DestroyRenderBuffers(ImGui_ImplDX12_RenderBuffers* render_buffers)
|
|
||||||
{
|
|
||||||
SafeRelease(render_buffers->IndexBuffer);
|
|
||||||
SafeRelease(render_buffers->VertexBuffer);
|
|
||||||
render_buffers->IndexBufferSize = render_buffers->VertexBufferSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
void ImGui_ImplDX12_InvalidateDeviceObjects()
|
||||||
{
|
{
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
@ -957,6 +881,13 @@ void ImGui_ImplDX12_InvalidateDeviceObjects()
|
|||||||
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
if (tex->RefCount == 1)
|
if (tex->RefCount == 1)
|
||||||
ImGui_ImplDX12_DestroyTexture(tex);
|
ImGui_ImplDX12_DestroyTexture(tex);
|
||||||
|
|
||||||
|
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||||
|
SafeRelease(fr->IndexBuffer);
|
||||||
|
SafeRelease(fr->VertexBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
@ -1005,15 +936,6 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
|||||||
io.BackendRendererName = "imgui_impl_dx12";
|
io.BackendRendererName = "imgui_impl_dx12";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
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.
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplDX12_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplDX12_DrawCallback_ResetRenderState;
|
||||||
@ -1026,40 +948,21 @@ bool ImGui_ImplDX12_Init(ImGui_ImplDX12_InitInfo* init_info)
|
|||||||
#endif
|
#endif
|
||||||
IM_ASSERT(init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr);
|
IM_ASSERT(init_info->SrvDescriptorAllocFn != nullptr && init_info->SrvDescriptorFreeFn != nullptr);
|
||||||
|
|
||||||
|
// Create buffers with a default size (they will later be grown as needed)
|
||||||
|
bd->frameIndex = UINT_MAX;
|
||||||
|
bd->pFrameResources = new ImGui_ImplDX12_RenderBuffers[bd->numFramesInFlight];
|
||||||
|
for (int i = 0; i < (int)bd->numFramesInFlight; i++)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX12_RenderBuffers* fr = &bd->pFrameResources[i];
|
||||||
|
fr->IndexBuffer = nullptr;
|
||||||
|
fr->VertexBuffer = nullptr;
|
||||||
|
fr->IndexBufferSize = 10000;
|
||||||
|
fr->VertexBufferSize = 5000;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
||||||
// Legacy initialization API Obsoleted in 1.91.5
|
|
||||||
// font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
|
||||||
bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX12_InitInfo init_info;
|
|
||||||
init_info.Device = device;
|
|
||||||
init_info.NumFramesInFlight = num_frames_in_flight;
|
|
||||||
init_info.RTVFormat = rtv_format;
|
|
||||||
init_info.SrvDescriptorHeap = srv_descriptor_heap;
|
|
||||||
init_info.LegacySingleSrvCpuDescriptor = font_srv_cpu_desc_handle;
|
|
||||||
init_info.LegacySingleSrvGpuDescriptor = font_srv_gpu_desc_handle;
|
|
||||||
|
|
||||||
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
|
|
||||||
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
|
|
||||||
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
|
|
||||||
queueDesc.NodeMask = 1;
|
|
||||||
HRESULT hr = device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&init_info.CommandQueue));
|
|
||||||
IM_ASSERT(SUCCEEDED(hr));
|
|
||||||
|
|
||||||
bool ret = ImGui_ImplDX12_Init(&init_info);
|
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
|
||||||
bd->commandQueueOwned = true;
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasTextures; // Using legacy ImGui_ImplDX12_Init() call with 1 SRV descriptor we cannot support multiple textures.
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ImGui_ImplDX12_Shutdown()
|
void ImGui_ImplDX12_Shutdown()
|
||||||
{
|
{
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||||
@ -1067,23 +970,12 @@ void ImGui_ImplDX12_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
// Manually delete main viewport render resources in-case we haven't initialized for viewports
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)main_viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
// We could just call ImGui_ImplDX12_DestroyWindow(main_viewport) as a convenience but that would be misleading since we only use data->Resources[]
|
|
||||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
|
||||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
|
||||||
IM_DELETE(vd);
|
|
||||||
main_viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplDX12_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplDX12_InvalidateDeviceObjects();
|
ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
|
delete[] bd->pFrameResources;
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -1098,254 +990,6 @@ void ImGui_ImplDX12_NewFrame()
|
|||||||
IM_ASSERT(0 && "ImGui_ImplDX12_CreateDeviceObjects() failed!");
|
IM_ASSERT(0 && "ImGui_ImplDX12_CreateDeviceObjects() failed!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
|
||||||
ImGui_ImplDX12_ViewportData* vd = IM_NEW(ImGui_ImplDX12_ViewportData)(bd->numFramesInFlight);
|
|
||||||
viewport->RendererUserData = vd;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL's WindowID).
|
|
||||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
|
||||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(hwnd != 0);
|
|
||||||
|
|
||||||
// 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));
|
|
||||||
IM_ASSERT(res == S_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create command list.
|
|
||||||
res = bd->pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, vd->FrameCtx[0].CommandAllocator, nullptr, IID_PPV_ARGS(&vd->CommandList));
|
|
||||||
IM_ASSERT(res == S_OK);
|
|
||||||
vd->CommandList->Close();
|
|
||||||
|
|
||||||
// Create swap chain
|
|
||||||
// FIXME-VIEWPORT: May want to copy/inherit swap chain settings from the user/application.
|
|
||||||
DXGI_SWAP_CHAIN_DESC1 sd1;
|
|
||||||
ZeroMemory(&sd1, sizeof(sd1));
|
|
||||||
sd1.BufferCount = bd->numFramesInFlight;
|
|
||||||
sd1.Width = (UINT)viewport->Size.x;
|
|
||||||
sd1.Height = (UINT)viewport->Size.y;
|
|
||||||
sd1.Format = bd->RTVFormat;
|
|
||||||
sd1.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
|
||||||
sd1.SampleDesc.Count = 1;
|
|
||||||
sd1.SampleDesc.Quality = 0;
|
|
||||||
sd1.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
|
|
||||||
sd1.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;
|
|
||||||
sd1.Scaling = DXGI_SCALING_NONE;
|
|
||||||
sd1.Stereo = FALSE;
|
|
||||||
sd1.Flags = DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
|
|
||||||
|
|
||||||
if (bd->tearingSupport)
|
|
||||||
sd1.Flags |= DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
|
|
||||||
|
|
||||||
IDXGISwapChain1* swap_chain = nullptr;
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Or swapChain.As(&mSwapChain)
|
|
||||||
IM_ASSERT(vd->SwapChain == nullptr);
|
|
||||||
swap_chain->QueryInterface(IID_PPV_ARGS(&vd->SwapChain));
|
|
||||||
swap_chain->Release();
|
|
||||||
|
|
||||||
// Create the render targets and waitable object
|
|
||||||
if (vd->SwapChain)
|
|
||||||
{
|
|
||||||
D3D12_DESCRIPTOR_HEAP_DESC desc = {};
|
|
||||||
desc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
|
|
||||||
desc.NumDescriptors = bd->numFramesInFlight;
|
|
||||||
desc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
|
|
||||||
desc.NodeMask = 1;
|
|
||||||
|
|
||||||
HRESULT hr = bd->pd3dDevice->CreateDescriptorHeap(&desc, IID_PPV_ARGS(&vd->RtvDescHeap));
|
|
||||||
IM_ASSERT(hr == S_OK);
|
|
||||||
|
|
||||||
SIZE_T rtv_descriptor_size = bd->pd3dDevice->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
|
|
||||||
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle = vd->RtvDescHeap->GetCPUDescriptorHandleForHeapStart();
|
|
||||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
|
||||||
{
|
|
||||||
vd->FrameCtx[i].RenderTargetCpuDescriptors = rtv_handle;
|
|
||||||
rtv_handle.ptr += rtv_descriptor_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D12Resource* back_buffer;
|
|
||||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
|
||||||
{
|
|
||||||
IM_ASSERT(vd->FrameCtx[i].RenderTarget == nullptr);
|
|
||||||
vd->SwapChain->GetBuffer(i, IID_PPV_ARGS(&back_buffer));
|
|
||||||
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++)
|
|
||||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_WaitForPendingOperations(ImGui_ImplDX12_ViewportData* vd)
|
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
HRESULT hr = bd->Fence->SetEventOnCompletion(frame_context->FenceValue, bd->FenceEvent);
|
|
||||||
IM_ASSERT(hr == S_OK);
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
|
||||||
if (ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
ImGui_WaitForPendingOperations(vd);
|
|
||||||
|
|
||||||
vd->CommandQueue = nullptr;
|
|
||||||
::CloseHandle(vd->SwapChainWaitableObject);
|
|
||||||
vd->SwapChainWaitableObject = nullptr;
|
|
||||||
SafeRelease(vd->CommandList);
|
|
||||||
SafeRelease(vd->SwapChain);
|
|
||||||
SafeRelease(vd->RtvDescHeap);
|
|
||||||
|
|
||||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
|
||||||
{
|
|
||||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
|
||||||
SafeRelease(vd->FrameCtx[i].CommandAllocator);
|
|
||||||
ImGui_ImplDX12_DestroyRenderBuffers(&vd->FrameRenderBuffers[i]);
|
|
||||||
}
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX12_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
|
||||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
|
||||||
|
|
||||||
ImGui_WaitForPendingOperations(vd);
|
|
||||||
|
|
||||||
for (UINT i = 0; i < bd->numFramesInFlight; i++)
|
|
||||||
SafeRelease(vd->FrameCtx[i].RenderTarget);
|
|
||||||
|
|
||||||
if (vd->SwapChain)
|
|
||||||
{
|
|
||||||
ID3D12Resource* back_buffer = nullptr;
|
|
||||||
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));
|
|
||||||
bd->pd3dDevice->CreateRenderTargetView(back_buffer, nullptr, vd->FrameCtx[i].RenderTargetCpuDescriptors);
|
|
||||||
vd->FrameCtx[i].RenderTarget = back_buffer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = ImGui_WaitForNextFrameContext(vd);
|
|
||||||
UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex();
|
|
||||||
|
|
||||||
const ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
D3D12_RESOURCE_BARRIER barrier = {};
|
|
||||||
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
|
|
||||||
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
|
|
||||||
barrier.Transition.pResource = vd->FrameCtx[back_buffer_idx].RenderTarget;
|
|
||||||
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
|
|
||||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
|
|
||||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
||||||
|
|
||||||
// Draw
|
|
||||||
ID3D12GraphicsCommandList* cmd_list = vd->CommandList;
|
|
||||||
|
|
||||||
frame_context->CommandAllocator->Reset();
|
|
||||||
cmd_list->Reset(frame_context->CommandAllocator, nullptr);
|
|
||||||
cmd_list->ResourceBarrier(1, &barrier);
|
|
||||||
cmd_list->OMSetRenderTargets(1, &vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, FALSE, nullptr);
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
cmd_list->ClearRenderTargetView(vd->FrameCtx[back_buffer_idx].RenderTargetCpuDescriptors, (const float*)&clear_color, 0, nullptr);
|
|
||||||
cmd_list->SetDescriptorHeaps(1, &bd->pd3dSrvDescHeap);
|
|
||||||
|
|
||||||
ImGui_ImplDX12_RenderDrawData(viewport->DrawData, cmd_list);
|
|
||||||
|
|
||||||
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
|
|
||||||
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
|
|
||||||
cmd_list->ResourceBarrier(1, &barrier);
|
|
||||||
cmd_list->Close();
|
|
||||||
|
|
||||||
vd->CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&cmd_list);
|
|
||||||
|
|
||||||
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, bd->tearingSupport ? DXGI_PRESENT_ALLOW_TEARING : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX12_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX12_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX12_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX12_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX12_RenderWindow;
|
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX12_SwapBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplDX12_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX12_GetRenderState().
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -60,13 +59,6 @@ IMGUI_IMPL_API void ImGui_ImplDX12_Shutdown();
|
|||||||
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
|
IMGUI_IMPL_API void ImGui_ImplDX12_NewFrame();
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
|
IMGUI_IMPL_API void ImGui_ImplDX12_RenderDrawData(ImDrawData* draw_data, ID3D12GraphicsCommandList* graphics_command_list);
|
||||||
|
|
||||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
|
||||||
// Legacy initialization API Obsoleted in 1.91.5
|
|
||||||
// - font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
|
||||||
// - When we introduced the ImGui_ImplDX12_InitInfo struct we also added a 'ID3D12CommandQueue* CommandQueue' field.
|
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects();
|
||||||
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects();
|
||||||
@ -82,6 +74,15 @@ struct ImGui_ImplDX12_RenderState
|
|||||||
ID3D12Device* Device;
|
ID3D12Device* Device;
|
||||||
ID3D12GraphicsCommandList* CommandList;
|
ID3D12GraphicsCommandList* CommandList;
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState();
|
||||||
|
|
||||||
|
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
// Legacy initialization API Obsoleted in 1.91.5
|
||||||
|
// - font_srv_cpu_desc_handle and font_srv_gpu_desc_handle are handles to a single SRV descriptor to use for the internal font texture, they must be in 'srv_descriptor_heap'
|
||||||
|
// - When we introduced the ImGui_ImplDX12_InitInfo struct we also added a 'ID3D12CommandQueue* CommandQueue' field.
|
||||||
|
// - DOES NOT SUPPORT ImGuiBackendFlags_RendererHasTextures.
|
||||||
|
//IMGUI_IMPL_API bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FORMAT rtv_format, ID3D12DescriptorHeap* srv_descriptor_heap, D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#pragma clang diagnostic pop
|
#pragma clang diagnostic pop
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// 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,7 +17,6 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2026-03-19: Fixed issue in ImGui_ImplDX9_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295, #9310)
|
// 2026-03-19: Fixed issue in ImGui_ImplDX9_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295, #9310)
|
||||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||||
@ -91,12 +89,6 @@ static ImGui_ImplDX9_Data* ImGui_ImplDX9_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX9_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplDX9_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
|
||||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
static void ImGui_ImplDX9_SetupRenderState(ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
@ -310,11 +302,6 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data)
|
|||||||
global_vtx_offset += draw_list->VtxBuffer.Size;
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// When using multi-viewports, it appears that there's an odd logic in DirectX9 which prevent subsequent windows
|
|
||||||
// from rendering until the first window submits at least one draw call, even once. That's our workaround. (see #2560)
|
|
||||||
if (global_vtx_offset == 0)
|
|
||||||
bd->pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 0, 0, 0);
|
|
||||||
|
|
||||||
// Restore the DX9 transform
|
// Restore the DX9 transform
|
||||||
device->SetTransform(D3DTS_WORLD, &last_world);
|
device->SetTransform(D3DTS_WORLD, &last_world);
|
||||||
device->SetTransform(D3DTS_VIEW, &last_view);
|
device->SetTransform(D3DTS_VIEW, &last_view);
|
||||||
@ -428,7 +415,6 @@ bool ImGui_ImplDX9_CreateDeviceObjects()
|
|||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
||||||
if (!bd || !bd->pd3dDevice)
|
if (!bd || !bd->pd3dDevice)
|
||||||
return false;
|
return false;
|
||||||
ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -447,7 +433,6 @@ void ImGui_ImplDX9_InvalidateDeviceObjects()
|
|||||||
}
|
}
|
||||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplDX9_NewFrame()
|
void ImGui_ImplDX9_NewFrame()
|
||||||
@ -457,6 +442,7 @@ void ImGui_ImplDX9_NewFrame()
|
|||||||
IM_UNUSED(bd);
|
IM_UNUSED(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
@ -469,7 +455,6 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
|||||||
io.BackendRendererName = "imgui_impl_dx9";
|
io.BackendRendererName = "imgui_impl_dx9";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = 4096;
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = 4096;
|
||||||
@ -481,8 +466,6 @@ bool ImGui_ImplDX9_Init(IDirect3DDevice9* device)
|
|||||||
bd->pd3dDevice->AddRef();
|
bd->pd3dDevice->AddRef();
|
||||||
bd->HasRgbaSupport = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
bd->HasRgbaSupport = ImGui_ImplDX9_CheckFormatSupport(bd->pd3dDevice, D3DFMT_A8B8G8R8);
|
||||||
|
|
||||||
ImGui_ImplDX9_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,159 +476,16 @@ void ImGui_ImplDX9_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplDX9_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplDX9_InvalidateDeviceObjects();
|
ImGui_ImplDX9_InvalidateDeviceObjects();
|
||||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplDX9_ViewportData
|
|
||||||
{
|
|
||||||
IDirect3DSwapChain9* SwapChain;
|
|
||||||
D3DPRESENT_PARAMETERS d3dpp;
|
|
||||||
|
|
||||||
ImGui_ImplDX9_ViewportData() { SwapChain = nullptr; ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS)); }
|
|
||||||
~ImGui_ImplDX9_ViewportData() { IM_ASSERT(SwapChain == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
|
||||||
ImGui_ImplDX9_ViewportData* vd = IM_NEW(ImGui_ImplDX9_ViewportData)();
|
|
||||||
viewport->RendererUserData = vd;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL's WindowID).
|
|
||||||
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
|
||||||
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(hwnd != 0);
|
|
||||||
|
|
||||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
|
||||||
vd->d3dpp.Windowed = TRUE;
|
|
||||||
vd->d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
|
|
||||||
vd->d3dpp.BackBufferWidth = (UINT)viewport->Size.x;
|
|
||||||
vd->d3dpp.BackBufferHeight = (UINT)viewport->Size.y;
|
|
||||||
vd->d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
|
|
||||||
vd->d3dpp.hDeviceWindow = hwnd;
|
|
||||||
vd->d3dpp.EnableAutoDepthStencil = FALSE;
|
|
||||||
vd->d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
|
|
||||||
vd->d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; // Present without vsync
|
|
||||||
|
|
||||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
|
||||||
IM_ASSERT(hr == D3D_OK);
|
|
||||||
IM_ASSERT(vd->SwapChain != nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
|
||||||
if (ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
if (vd->SwapChain)
|
|
||||||
vd->SwapChain->Release();
|
|
||||||
vd->SwapChain = nullptr;
|
|
||||||
ZeroMemory(&vd->d3dpp, sizeof(D3DPRESENT_PARAMETERS));
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
|
||||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd->SwapChain)
|
|
||||||
{
|
|
||||||
vd->SwapChain->Release();
|
|
||||||
vd->SwapChain = nullptr;
|
|
||||||
vd->d3dpp.BackBufferWidth = (UINT)size.x;
|
|
||||||
vd->d3dpp.BackBufferHeight = (UINT)size.y;
|
|
||||||
HRESULT hr = bd->pd3dDevice->CreateAdditionalSwapChain(&vd->d3dpp, &vd->SwapChain); IM_UNUSED(hr);
|
|
||||||
IM_ASSERT(hr == D3D_OK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX9_Data* bd = ImGui_ImplDX9_GetBackendData();
|
|
||||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 render_target = nullptr;
|
|
||||||
LPDIRECT3DSURFACE9 last_render_target = nullptr;
|
|
||||||
LPDIRECT3DSURFACE9 last_depth_stencil = nullptr;
|
|
||||||
vd->SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &render_target);
|
|
||||||
bd->pd3dDevice->GetRenderTarget(0, &last_render_target);
|
|
||||||
bd->pd3dDevice->GetDepthStencilSurface(&last_depth_stencil);
|
|
||||||
bd->pd3dDevice->SetRenderTarget(0, render_target);
|
|
||||||
bd->pd3dDevice->SetDepthStencilSurface(nullptr);
|
|
||||||
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
{
|
|
||||||
D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x*255.0f), (int)(clear_color.y*255.0f), (int)(clear_color.z*255.0f), (int)(clear_color.w*255.0f));
|
|
||||||
bd->pd3dDevice->Clear(0, nullptr, D3DCLEAR_TARGET, clear_col_dx, 1.0f, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplDX9_RenderDrawData(viewport->DrawData);
|
|
||||||
|
|
||||||
// Restore render target
|
|
||||||
bd->pd3dDevice->SetRenderTarget(0, last_render_target);
|
|
||||||
bd->pd3dDevice->SetDepthStencilSurface(last_depth_stencil);
|
|
||||||
render_target->Release();
|
|
||||||
last_render_target->Release();
|
|
||||||
if (last_depth_stencil) last_depth_stencil->Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplDX9_ViewportData* vd = (ImGui_ImplDX9_ViewportData*)viewport->RendererUserData;
|
|
||||||
HRESULT hr = vd->SwapChain->Present(nullptr, nullptr, vd->d3dpp.hDeviceWindow, nullptr, 0);
|
|
||||||
// Let main application handle D3DERR_DEVICELOST by resetting the device.
|
|
||||||
IM_ASSERT(SUCCEEDED(hr) || hr == D3DERR_DEVICELOST);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX9_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX9_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX9_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX9_RenderWindow;
|
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX9_SwapBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_CreateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (!platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplDX9_CreateWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplDX9_InvalidateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplDX9_DestroyWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
// [X] Renderer: IMGUI_USE_BGRA_PACKED_COLOR support, as this is the optimal color encoding for DirectX9.
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -9,12 +9,10 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors) with GLFW 3.1+. Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors) with GLFW 3.1+. Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// [X] Multiple Dear ImGui contexts support.
|
// [X] Multiple Dear ImGui contexts support.
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] 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: 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: 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -31,27 +29,19 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2026-04-21: Added a Win32-specific implementation of ImGui_ImplGlfw_GetContentScaleXXXX functions for legacy GLFW 3.2.
|
// 2026-04-21: Added a Win32-specific implementation of ImGui_ImplGlfw_GetContentScaleXXXX functions for legacy GLFW 3.2.
|
||||||
// 2026-03-25: Mouse cursor is properly restored if changed by user app/code while using glfwSetInputMode(..., GLFW_CURSOR_DISABLED) or ImGuiConfigFlags_NoMouseCursorChange. Amend change from 2025-12-10.
|
// 2026-03-25: Mouse cursor is properly restored if changed by user app/code while using glfwSetInputMode(..., GLFW_CURSOR_DISABLED) or ImGuiConfigFlags_NoMouseCursorChange. Amend change from 2025-12-10.
|
||||||
// 2026-02-10: Try to set IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND automatically if corresponding headers are not accessible. (#9225)
|
// 2026-02-10: Try to set IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND automatically if corresponding headers are not accessible. (#9225)
|
||||||
// 2026-01-25: [Docking] Improve workarounds for cases where GLFW is unable to provide any reliable monitor info. Preserve existing monitor list when none of the new one is valid. (#9195, #7902, #5683)
|
|
||||||
// 2026-01-18: [Docking] Dynamically load X11 functions to avoid -lx11 linking requirement introduced on 2025-09-10.
|
|
||||||
// 2025-12-12: Added IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND to forcefully disable either.
|
// 2025-12-12: Added IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND to forcefully disable either.
|
||||||
// 2025-12-10: Avoid repeated glfwSetCursor()/glfwSetInputMode() calls when unnecessary. Lowers overhead for very high framerates (e.g. 10k+ FPS).
|
// 2025-12-10: Avoid repeated glfwSetCursor()/glfwSetInputMode() calls when unnecessary. Lowers overhead for very high framerates (e.g. 10k+ FPS).
|
||||||
// 2025-11-06: Lower minimum requirement to GLFW 3.0. Though a recent version e.g GLFW 3.4 is highly recommended.
|
// 2025-11-06: Lower minimum requirement to GLFW 3.0. Though a recent version e.g GLFW 3.4 is highly recommended.
|
||||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
// 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-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-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-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.
|
// 2025-06-11: Added ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window) and ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor) helper to facilitate making DPI-aware apps.
|
||||||
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
|
||||||
// 2025-04-26: [Docking] Disable multi-viewports under Wayland. (#8587)
|
|
||||||
// 2025-03-10: Map GLFW_KEY_WORLD_1 and GLFW_KEY_WORLD_2 into ImGuiKey_Oem102.
|
// 2025-03-10: Map GLFW_KEY_WORLD_1 and GLFW_KEY_WORLD_2 into ImGuiKey_Oem102.
|
||||||
// 2025-03-03: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled with asserts enabled.
|
// 2025-03-03: Fixed clipboard handler assertion when using GLFW <= 3.2.1 compiled with asserts enabled.
|
||||||
// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415)
|
|
||||||
// 2024-11-05: [Docking] Added Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922)
|
|
||||||
// 2024-08-22: Moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
// 2024-08-22: Moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||||
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
// - io.SetClipboardTextFn -> platform_io.Platform_SetClipboardTextFn
|
||||||
@ -68,7 +58,6 @@
|
|||||||
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
// 2023-03-16: Inputs: Fixed key modifiers handling on secondary viewports (docking branch). Broken on 2023/01/04. (#6248, #6034)
|
||||||
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
// 2023-03-14: Emscripten: Avoid using glfwGetError() and glfwGetGamepadState() which are not correctly implemented in Emscripten emulation. (#6240)
|
||||||
// 2023-02-03: Emscripten: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096)
|
// 2023-02-03: Emscripten: Registering custom low-level mouse wheel handler to get more accurate scrolling impulses on Emscripten. (#4019, #6096)
|
||||||
// 2023-01-18: Handle unsupported glfwGetVideoMode() call on e.g. Emscripten.
|
|
||||||
// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty.
|
// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty.
|
||||||
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
|
// 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908)
|
||||||
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
// 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785)
|
||||||
@ -121,8 +110,6 @@
|
|||||||
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
|
||||||
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__has_include)
|
#if defined(__has_include)
|
||||||
@ -160,13 +147,10 @@
|
|||||||
#elif GLFW_HAS_X11
|
#elif GLFW_HAS_X11
|
||||||
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
|
#ifndef GLFW_EXPOSE_NATIVE_X11 // for glfwGetX11Display(), glfwGetX11Window() on Freedesktop (Linux, BSD, etc.)
|
||||||
#define GLFW_EXPOSE_NATIVE_X11
|
#define GLFW_EXPOSE_NATIVE_X11
|
||||||
#include <X11/Xatom.h>
|
|
||||||
#include <dlfcn.h> // for dlopen()
|
|
||||||
#endif
|
#endif
|
||||||
#include <GLFW/glfw3native.h>
|
#include <GLFW/glfw3native.h>
|
||||||
#undef Status // X11 headers are leaking this.
|
|
||||||
#endif
|
#endif
|
||||||
|
#undef Status // X11 headers are leaking this.
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <unistd.h> // for usleep()
|
#include <unistd.h> // for usleep()
|
||||||
#endif
|
#endif
|
||||||
@ -185,29 +169,12 @@
|
|||||||
// We gather version tests as define in order to easily see which features are version-dependent.
|
// We gather version tests as define in order to easily see which features are version-dependent.
|
||||||
#define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
|
#define GLFW_VERSION_COMBINED (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 + GLFW_VERSION_REVISION)
|
||||||
#define GLFW_HAS_CREATECURSOR (GLFW_VERSION_COMBINED >= 3100) // 3.1+ glfwCreateCursor()
|
#define GLFW_HAS_CREATECURSOR (GLFW_VERSION_COMBINED >= 3100) // 3.1+ glfwCreateCursor()
|
||||||
#define GLFW_HAS_WINDOW_TOPMOST (GLFW_VERSION_COMBINED >= 3200) // 3.2+ GLFW_FLOATING
|
|
||||||
#define GLFW_HAS_WINDOW_HOVERED (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_HOVERED
|
|
||||||
#define GLFW_HAS_WINDOW_ALPHA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwSetWindowOpacity
|
|
||||||
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
#define GLFW_HAS_PER_MONITOR_DPI (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorContentScale
|
||||||
#if defined(__EMSCRIPTEN__) || defined(__SWITCH__) // no Vulkan support in GLFW for Emscripten or homebrew Nintendo Switch
|
|
||||||
#define GLFW_HAS_VULKAN (0)
|
|
||||||
#else
|
|
||||||
#define GLFW_HAS_VULKAN (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwCreateWindowSurface
|
|
||||||
#endif
|
|
||||||
#define GLFW_HAS_FOCUS_WINDOW (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwFocusWindow
|
|
||||||
#define GLFW_HAS_FOCUS_ON_SHOW (GLFW_VERSION_COMBINED >= 3300) // 3.3+ GLFW_FOCUS_ON_SHOW
|
|
||||||
#define GLFW_HAS_MONITOR_WORK_AREA (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetMonitorWorkarea
|
|
||||||
#define GLFW_HAS_OSX_WINDOW_POS_FIX (GLFW_VERSION_COMBINED >= 3301) // 3.3.1+ Fixed: Resizing window repositions it on MacOS #1553
|
|
||||||
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
#ifdef GLFW_RESIZE_NESW_CURSOR // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2019-11-29 (cursors defines) // FIXME: Remove when GLFW 3.4 is released?
|
||||||
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
#define GLFW_HAS_NEW_CURSORS (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_RESIZE_ALL_CURSOR, GLFW_RESIZE_NESW_CURSOR, GLFW_RESIZE_NWSE_CURSOR, GLFW_NOT_ALLOWED_CURSOR
|
||||||
#else
|
#else
|
||||||
#define GLFW_HAS_NEW_CURSORS (0)
|
#define GLFW_HAS_NEW_CURSORS (0)
|
||||||
#endif
|
#endif
|
||||||
#ifdef GLFW_MOUSE_PASSTHROUGH // Let's be nice to people who pulled GLFW between 2019-04-16 (3.4 define) and 2020-07-17 (passthrough)
|
|
||||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (GLFW_VERSION_COMBINED >= 3400) // 3.4+ GLFW_MOUSE_PASSTHROUGH
|
|
||||||
#else
|
|
||||||
#define GLFW_HAS_MOUSE_PASSTHROUGH (0)
|
|
||||||
#endif
|
|
||||||
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
|
#define GLFW_HAS_GAMEPAD_API (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetGamepadState() new api
|
||||||
#define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
|
#define GLFW_HAS_GETKEYNAME (GLFW_VERSION_COMBINED >= 3200) // 3.2+ glfwGetKeyName()
|
||||||
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
#define GLFW_HAS_GETERROR (GLFW_VERSION_COMBINED >= 3300) // 3.3+ glfwGetError()
|
||||||
@ -230,13 +197,6 @@ enum GlfwClientApi
|
|||||||
GlfwClientApi_Unknown, // Anything else fits here.
|
GlfwClientApi_Unknown, // Anything else fits here.
|
||||||
};
|
};
|
||||||
|
|
||||||
#if GLFW_HAS_X11
|
|
||||||
typedef Atom (*PFN_XInternAtom)(Display*, const char* ,Bool);
|
|
||||||
typedef int (*PFN_XChangeProperty)(Display*, Window, Atom, Atom, int, int, const unsigned char*, int);
|
|
||||||
typedef int (*PFN_XChangeWindowAttributes)(Display*, Window, unsigned long, XSetWindowAttributes*);
|
|
||||||
typedef int (*PFN_XFlush)(Display*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GLFW data
|
// GLFW data
|
||||||
struct ImGui_ImplGlfw_Data
|
struct ImGui_ImplGlfw_Data
|
||||||
{
|
{
|
||||||
@ -249,10 +209,7 @@ struct ImGui_ImplGlfw_Data
|
|||||||
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
GLFWcursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
||||||
GLFWcursor* LastMouseCursor;
|
GLFWcursor* LastMouseCursor;
|
||||||
#endif
|
#endif
|
||||||
bool MouseIgnoreButtonUpWaitForFocusLoss;
|
|
||||||
bool MouseIgnoreButtonUp;
|
|
||||||
ImVec2 LastValidMousePos;
|
ImVec2 LastValidMousePos;
|
||||||
GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST];
|
|
||||||
bool IsWayland;
|
bool IsWayland;
|
||||||
bool InstalledCallbacks;
|
bool InstalledCallbacks;
|
||||||
bool CallbacksChainForAllWindows;
|
bool CallbacksChainForAllWindows;
|
||||||
@ -274,15 +231,6 @@ struct ImGui_ImplGlfw_Data
|
|||||||
WNDPROC PrevWndProc;
|
WNDPROC PrevWndProc;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GLFW_HAS_X11
|
|
||||||
// Module and function pointers loaded at initialization to avoid linking statically with X11.
|
|
||||||
void* X11Module;
|
|
||||||
PFN_XInternAtom XInternAtom;
|
|
||||||
PFN_XChangeProperty XChangeProperty;
|
|
||||||
PFN_XChangeWindowAttributes XChangeWindowAttributes;
|
|
||||||
PFN_XFlush XFlush;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -306,11 +254,6 @@ static ImGui_ImplGlfw_Data* ImGui_ImplGlfw_GetBackendData(GLFWwindow* window)
|
|||||||
return (ImGui_ImplGlfw_Data*)ImGui::GetIO(ctx).BackendPlatformUserData;
|
return (ImGui_ImplGlfw_Data*)ImGui::GetIO(ctx).BackendPlatformUserData;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplGlfw_UpdateMonitors();
|
|
||||||
static void ImGui_ImplGlfw_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static bool ImGui_ImplGlfw_IsWayland()
|
static bool ImGui_ImplGlfw_IsWayland()
|
||||||
{
|
{
|
||||||
@ -481,10 +424,6 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti
|
|||||||
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
if (bd->PrevUserCallbackMousebutton != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
bd->PrevUserCallbackMousebutton(window, button, action, mods);
|
||||||
|
|
||||||
// Workaround for Linux: ignore mouse up events which are following an focus loss following a viewport creation
|
|
||||||
if (bd->MouseIgnoreButtonUp && action == GLFW_RELEASE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
||||||
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
if (button >= 0 && button < ImGuiMouseButton_COUNT)
|
||||||
@ -552,9 +491,6 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i
|
|||||||
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
ImGui_ImplGlfw_UpdateKeyModifiers(io, window);
|
||||||
|
|
||||||
if (keycode >= 0 && keycode < IM_COUNTOF(bd->KeyOwnerWindows))
|
|
||||||
bd->KeyOwnerWindows[keycode] = (action == GLFW_PRESS) ? window : nullptr;
|
|
||||||
|
|
||||||
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode);
|
||||||
|
|
||||||
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
ImGuiKey imgui_key = ImGui_ImplGlfw_KeyToImGuiKey(keycode, scancode);
|
||||||
@ -568,10 +504,6 @@ void ImGui_ImplGlfw_WindowFocusCallback(GLFWwindow* window, int focused)
|
|||||||
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
if (bd->PrevUserCallbackWindowFocus != nullptr && ImGui_ImplGlfw_ShouldChainCallback(bd, window))
|
||||||
bd->PrevUserCallbackWindowFocus(window, focused);
|
bd->PrevUserCallbackWindowFocus(window, focused);
|
||||||
|
|
||||||
// Workaround for Linux: when losing focus with MouseIgnoreButtonUpWaitForFocusLoss set, we will temporarily ignore subsequent Mouse Up events
|
|
||||||
bd->MouseIgnoreButtonUp = (bd->MouseIgnoreButtonUpWaitForFocusLoss && focused == 0);
|
|
||||||
bd->MouseIgnoreButtonUpWaitForFocusLoss = false;
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
io.AddFocusEvent(focused != 0);
|
io.AddFocusEvent(focused != 0);
|
||||||
}
|
}
|
||||||
@ -583,13 +515,6 @@ void ImGui_ImplGlfw_CursorPosCallback(GLFWwindow* window, double x, double y)
|
|||||||
bd->PrevUserCallbackCursorPos(window, x, y);
|
bd->PrevUserCallbackCursorPos(window, x, y);
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
int window_x, window_y;
|
|
||||||
glfwGetWindowPos(window, &window_x, &window_y);
|
|
||||||
x += window_x;
|
|
||||||
y += window_y;
|
|
||||||
}
|
|
||||||
io.AddMousePosEvent((float)x, (float)y);
|
io.AddMousePosEvent((float)x, (float)y);
|
||||||
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
bd->LastValidMousePos = ImVec2((float)x, (float)y);
|
||||||
}
|
}
|
||||||
@ -628,7 +553,7 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c)
|
|||||||
|
|
||||||
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int)
|
||||||
{
|
{
|
||||||
// This function is technically part of the API even if we stopped using the callback, so leaving it around.
|
// Unused in 'master' branch but 'docking' branch will use this, so we declare it ahead of it so if you have to install callbacks you can install this one too.
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
@ -651,7 +576,35 @@ static EM_BOOL ImGui_ImplEmscripten_WheelCallback(int, const EmscriptenWheelEven
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
||||||
|
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
||||||
|
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
||||||
|
{
|
||||||
|
LPARAM extra_info = ::GetMessageExtraInfo();
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
||||||
|
return ImGuiMouseSource_Pen;
|
||||||
|
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
||||||
|
return ImGuiMouseSource_TouchScreen;
|
||||||
|
return ImGuiMouseSource_Mouse;
|
||||||
|
}
|
||||||
|
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)::GetPropA(hWnd, "IMGUI_BACKEND_DATA");
|
||||||
|
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
||||||
|
|
||||||
|
switch (msg)
|
||||||
|
{
|
||||||
|
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
||||||
|
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
||||||
|
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
||||||
|
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
||||||
|
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
||||||
|
io.AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
return ::CallWindowProcW(bd->PrevWndProc, hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window)
|
||||||
@ -737,20 +690,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
#endif
|
#endif
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||||
|
|
||||||
bool has_viewports = false;
|
|
||||||
#ifndef __EMSCRIPTEN__
|
|
||||||
has_viewports = true;
|
|
||||||
#if GLFW_HAS_GETPLATFORM
|
|
||||||
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
|
|
||||||
has_viewports = false;
|
|
||||||
#endif
|
|
||||||
if (has_viewports)
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
|
||||||
#endif
|
|
||||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport; // We can call io.AddMouseViewportEvent() with correct data (optional)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
#if GLFW_VERSION_COMBINED < 3300
|
#if GLFW_VERSION_COMBINED < 3300
|
||||||
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window, text); };
|
platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(ImGui_ImplGlfw_GetBackendData()->Window, text); };
|
||||||
@ -796,11 +735,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
if (install_callbacks)
|
if (install_callbacks)
|
||||||
ImGui_ImplGlfw_InstallCallbacks(window);
|
ImGui_ImplGlfw_InstallCallbacks(window);
|
||||||
|
|
||||||
// Update monitor a first time during init
|
|
||||||
// (note: monitor callback are broken in GLFW 3.2 and earlier, see github.com/glfw/glfw/issues/784)
|
|
||||||
ImGui_ImplGlfw_UpdateMonitors();
|
|
||||||
glfwSetMonitorCallback(ImGui_ImplGlfw_MonitorCallback);
|
|
||||||
|
|
||||||
// Set platform dependent data in viewport
|
// Set platform dependent data in viewport
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
main_viewport->PlatformHandle = (void*)bd->Window;
|
||||||
@ -811,8 +745,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
#else
|
#else
|
||||||
IM_UNUSED(main_viewport);
|
IM_UNUSED(main_viewport);
|
||||||
#endif
|
#endif
|
||||||
if (has_viewports)
|
|
||||||
ImGui_ImplGlfw_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
// Windows: register a WndProc hook so we can intercept some messages.
|
// Windows: register a WndProc hook so we can intercept some messages.
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -823,26 +755,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
|
|||||||
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GLFW_HAS_X11
|
|
||||||
if (!bd->IsWayland)
|
|
||||||
{
|
|
||||||
// Load X11 module dynamically. Copied from the way that GLFW does it in x11_init.c
|
|
||||||
#if defined(__CYGWIN__)
|
|
||||||
const char* x11_module_path = "libX11-6.so";
|
|
||||||
#elif defined(__OpenBSD__) || defined(__NetBSD__)
|
|
||||||
const char* x11_module_path = "libX11.so";
|
|
||||||
#else
|
|
||||||
const char* x11_module_path = "libX11.so.6";
|
|
||||||
#endif
|
|
||||||
bd->X11Module = dlopen(x11_module_path, RTLD_LAZY | RTLD_LOCAL);
|
|
||||||
bd->XInternAtom = (PFN_XInternAtom)dlsym(bd->X11Module, "XInternAtom");
|
|
||||||
bd->XChangeProperty = (PFN_XChangeProperty)dlsym(bd->X11Module, "XChangeProperty");
|
|
||||||
bd->XChangeWindowAttributes = (PFN_XChangeWindowAttributes)dlsym(bd->X11Module, "XChangeWindowAttributes");
|
|
||||||
bd->XFlush = (PFN_XFlush)dlsym(bd->X11Module, "XFlush");
|
|
||||||
IM_ASSERT(bd->XInternAtom != nullptr && bd->XChangeProperty != nullptr && bd->XChangeWindowAttributes != nullptr && bd->XFlush != nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
|
// Emscripten: the same application can run on various platforms, so we detect the Apple platform at runtime
|
||||||
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
|
// to override io.ConfigMacOSXBehaviors from its default (which is always false in Emscripten).
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
@ -887,7 +799,6 @@ void ImGui_ImplGlfw_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplGlfw_ShutdownMultiViewportSupport();
|
|
||||||
if (bd->InstalledCallbacks)
|
if (bd->InstalledCallbacks)
|
||||||
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
ImGui_ImplGlfw_RestoreCallbacks(bd->Window);
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
@ -906,14 +817,9 @@ void ImGui_ImplGlfw_Shutdown()
|
|||||||
bd->PrevWndProc = nullptr;
|
bd->PrevWndProc = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if GLFW_HAS_X11
|
|
||||||
if (bd->X11Module != nullptr)
|
|
||||||
dlclose(bd->X11Module);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
platform_io.ClearPlatformHandlers();
|
platform_io.ClearPlatformHandlers();
|
||||||
ImGui_ImplGlfw_ContextMap_Remove(bd->Window);
|
ImGui_ImplGlfw_ContextMap_Remove(bd->Window);
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
@ -923,15 +829,10 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
|||||||
{
|
{
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
|
|
||||||
ImGuiID mouse_viewport_id = 0;
|
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
|
||||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
|
||||||
{
|
{
|
||||||
ImGuiViewport* viewport = platform_io.Viewports[n];
|
GLFWwindow* window = bd->Window;
|
||||||
GLFWwindow* window = (GLFWwindow*)viewport->PlatformHandle;
|
|
||||||
|
|
||||||
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
#ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3
|
||||||
const bool is_window_focused = true;
|
const bool is_window_focused = true;
|
||||||
#else
|
#else
|
||||||
@ -940,54 +841,19 @@ static void ImGui_ImplGlfw_UpdateMouseData()
|
|||||||
if (is_window_focused)
|
if (is_window_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
glfwSetCursorPos(window, (double)(mouse_pos_prev.x - viewport->Pos.x), (double)(mouse_pos_prev.y - viewport->Pos.y));
|
glfwSetCursorPos(window, (double)io.MousePos.x, (double)io.MousePos.y);
|
||||||
|
|
||||||
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
|
// (Optional) Fallback to provide mouse position when focused (ImGui_ImplGlfw_CursorPosCallback already provides this when hovered or captured)
|
||||||
if (bd->MouseWindow == nullptr)
|
if (bd->MouseWindow == nullptr)
|
||||||
{
|
{
|
||||||
double mouse_x, mouse_y;
|
double mouse_x, mouse_y;
|
||||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
// 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 window_x, window_y;
|
|
||||||
glfwGetWindowPos(window, &window_x, &window_y);
|
|
||||||
mouse_x += window_x;
|
|
||||||
mouse_y += window_y;
|
|
||||||
}
|
|
||||||
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
bd->LastValidMousePos = ImVec2((float)mouse_x, (float)mouse_y);
|
||||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
|
||||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
|
||||||
// - [X] GLFW >= 3.3 backend ON WINDOWS ONLY does correctly ignore viewports with the _NoInputs flag (since we implement hit via our WndProc hook)
|
|
||||||
// On other platforms we rely on the library fallbacking to its own search when reporting a viewport with _NoInputs flag.
|
|
||||||
// - [!] GLFW <= 3.2 backend CANNOT correctly ignore viewports with the _NoInputs flag, and CANNOT reported Hovered Viewport because of mouse capture.
|
|
||||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
|
||||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
|
||||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
|
||||||
// - [X] GLFW backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
|
||||||
// FIXME: This is currently only correct on Win32. See what we do below with the WM_NCHITTEST, missing an equivalent for other systems.
|
|
||||||
// See https://github.com/glfw/glfw/issues/1236 if you want to help in making this a GLFW feature.
|
|
||||||
#if GLFW_HAS_MOUSE_PASSTHROUGH
|
|
||||||
const bool window_no_input = (viewport->Flags & ImGuiViewportFlags_NoInputs) != 0;
|
|
||||||
glfwSetWindowAttrib(window, GLFW_MOUSE_PASSTHROUGH, window_no_input);
|
|
||||||
#endif
|
|
||||||
#if GLFW_HAS_MOUSE_PASSTHROUGH || GLFW_HAS_WINDOW_HOVERED
|
|
||||||
if (glfwGetWindowAttrib(window, GLFW_HOVERED))
|
|
||||||
mouse_viewport_id = viewport->ID;
|
|
||||||
#else
|
|
||||||
// We cannot use bd->MouseWindow maintained from CursorEnter/Leave callbacks, because it is locked to the window capturing mouse.
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
|
||||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_UpdateMouseCursor()
|
static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||||
@ -1001,10 +867,9 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
// (those braces are here to reduce diff with multi-viewports support in 'docking' branch)
|
||||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
|
||||||
{
|
{
|
||||||
GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle;
|
GLFWwindow* window = bd->Window;
|
||||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||||
{
|
{
|
||||||
if (bd->LastMouseCursor != nullptr)
|
if (bd->LastMouseCursor != nullptr)
|
||||||
@ -1084,49 +949,6 @@ static void ImGui_ImplGlfw_UpdateGamepads()
|
|||||||
#undef MAP_ANALOG
|
#undef MAP_ANALOG
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_UpdateMonitors()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
int monitors_count = 0;
|
|
||||||
GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count);
|
|
||||||
|
|
||||||
bool updated_monitors = false;
|
|
||||||
for (int n = 0; n < monitors_count; n++)
|
|
||||||
{
|
|
||||||
ImGuiPlatformMonitor monitor;
|
|
||||||
int x, y;
|
|
||||||
glfwGetMonitorPos(glfw_monitors[n], &x, &y);
|
|
||||||
const GLFWvidmode* vid_mode = glfwGetVideoMode(glfw_monitors[n]);
|
|
||||||
if (vid_mode == nullptr)
|
|
||||||
continue; // Failed to get Video mode (e.g. Emscripten does not support this function)
|
|
||||||
if (vid_mode->width <= 0 || vid_mode->height <= 0)
|
|
||||||
continue; // Failed to query suitable monitor info (#9195)
|
|
||||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)x, (float)y);
|
|
||||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)vid_mode->width, (float)vid_mode->height);
|
|
||||||
#if GLFW_HAS_MONITOR_WORK_AREA
|
|
||||||
int w, h;
|
|
||||||
glfwGetMonitorWorkarea(glfw_monitors[n], &x, &y, &w, &h);
|
|
||||||
if (w > 0 && h > 0) // Workaround a small GLFW issue reporting zero on monitor changes: https://github.com/glfw/glfw/pull/1761
|
|
||||||
{
|
|
||||||
monitor.WorkPos = ImVec2((float)x, (float)y);
|
|
||||||
monitor.WorkSize = ImVec2((float)w, (float)h);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
float scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfw_monitors[n]);
|
|
||||||
if (scale == 0.0f)
|
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0 (#7902)
|
|
||||||
monitor.DpiScale = scale;
|
|
||||||
monitor.PlatformHandle = (void*)glfw_monitors[n]; // [...] GLFW doc states: "guaranteed to be valid only until the monitor configuration changes"
|
|
||||||
|
|
||||||
// Preserve existing monitor list until a valid one is added.
|
|
||||||
// Happens on macOS sleeping (#5683) and seemingly occasionally on Windows (#9195)
|
|
||||||
if (!updated_monitors)
|
|
||||||
platform_io.Monitors.resize(0);
|
|
||||||
updated_monitors = true;
|
|
||||||
platform_io.Monitors.push_back(monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For GFLW 3.2 + Windows: include a simplified non-monitor aware version of ImGui_ImplWin32_GetDpiScaleForMonitor().
|
// For GFLW 3.2 + Windows: include a simplified non-monitor aware version of ImGui_ImplWin32_GetDpiScaleForMonitor().
|
||||||
// This is merely a band-aid to make using GLFW 3.2 a little bit nicer, but prefer to use GLFW 3.3+ or the full correct functions from the Win32 backend.
|
// This is merely a band-aid to make using GLFW 3.2 a little bit nicer, but prefer to use GLFW 3.3+ or the full correct functions from the Win32 backend.
|
||||||
#if !GLFW_HAS_PER_MONITOR_DPI && defined(_WIN32) && !defined(NOGDI)
|
#if !GLFW_HAS_PER_MONITOR_DPI && defined(_WIN32) && !defined(NOGDI)
|
||||||
@ -1200,7 +1022,6 @@ void ImGui_ImplGlfw_NewFrame()
|
|||||||
|
|
||||||
// Setup main viewport size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
ImGui_ImplGlfw_UpdateMonitors();
|
|
||||||
|
|
||||||
// Setup time step
|
// Setup time step
|
||||||
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
// (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644)
|
||||||
@ -1210,7 +1031,6 @@ void ImGui_ImplGlfw_NewFrame()
|
|||||||
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
io.DeltaTime = bd->Time > 0.0 ? (float)(current_time - bd->Time) : (float)(1.0f / 60.0f);
|
||||||
bd->Time = current_time;
|
bd->Time = current_time;
|
||||||
|
|
||||||
bd->MouseIgnoreButtonUp = false;
|
|
||||||
ImGui_ImplGlfw_UpdateMouseData();
|
ImGui_ImplGlfw_UpdateMouseData();
|
||||||
ImGui_ImplGlfw_UpdateMouseCursor();
|
ImGui_ImplGlfw_UpdateMouseCursor();
|
||||||
|
|
||||||
@ -1280,444 +1100,6 @@ void ImGui_ImplGlfw_InstallEmscriptenCallbacks(GLFWwindow* window, const char* c
|
|||||||
}
|
}
|
||||||
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
#endif // #ifdef EMSCRIPTEN_USE_PORT_CONTRIB_GLFW3
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplGlfw_ViewportData
|
|
||||||
{
|
|
||||||
GLFWwindow* Window; // Stored in ImGuiViewport::PlatformHandle
|
|
||||||
bool WindowOwned;
|
|
||||||
int IgnoreWindowPosEventFrame;
|
|
||||||
int IgnoreWindowSizeEventFrame;
|
|
||||||
#ifdef _WIN32
|
|
||||||
WNDPROC PrevWndProc;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGui_ImplGlfw_ViewportData() { memset((void*)this, 0, sizeof(*this)); IgnoreWindowSizeEventFrame = IgnoreWindowPosEventFrame = -1; }
|
|
||||||
~ImGui_ImplGlfw_ViewportData() { IM_ASSERT(Window == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_WindowCloseCallback(GLFWwindow* window)
|
|
||||||
{
|
|
||||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
||||||
viewport->PlatformRequestClose = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// GLFW may dispatch window pos/size events after calling glfwSetWindowPos()/glfwSetWindowSize().
|
|
||||||
// However: depending on the platform the callback may be invoked at different time:
|
|
||||||
// - on Windows it appears to be called within the glfwSetWindowPos()/glfwSetWindowSize() call
|
|
||||||
// - on Linux it is queued and invoked during glfwPollEvents()
|
|
||||||
// Because the event doesn't always fire on glfwSetWindowXXX() we use a frame counter tag to only
|
|
||||||
// ignore recent glfwSetWindowXXX() calls.
|
|
||||||
static void ImGui_ImplGlfw_WindowPosCallback(GLFWwindow* window, int, int)
|
|
||||||
{
|
|
||||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
||||||
{
|
|
||||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowPosEventFrame + 1);
|
|
||||||
//data->IgnoreWindowPosEventFrame = -1;
|
|
||||||
if (ignore_event)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
viewport->PlatformRequestMove = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_WindowSizeCallback(GLFWwindow* window, int, int)
|
|
||||||
{
|
|
||||||
if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle(window))
|
|
||||||
{
|
|
||||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
bool ignore_event = (ImGui::GetFrameCount() <= vd->IgnoreWindowSizeEventFrame + 1);
|
|
||||||
//data->IgnoreWindowSizeEventFrame = -1;
|
|
||||||
if (ignore_event)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
viewport->PlatformRequestResize = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(__APPLE__) && !defined(_WIN32) && !defined(__EMSCRIPTEN__) && GLFW_HAS_GETPLATFORM
|
|
||||||
#define IMGUI_GLFW_HAS_SETWINDOWFLOATING
|
|
||||||
static void ImGui_ImplGlfw_SetWindowFloating(ImGui_ImplGlfw_Data* bd, GLFWwindow* window)
|
|
||||||
{
|
|
||||||
#ifdef GLFW_EXPOSE_NATIVE_X11
|
|
||||||
if (glfwGetPlatform() == GLFW_PLATFORM_X11)
|
|
||||||
{
|
|
||||||
Display* display = glfwGetX11Display();
|
|
||||||
Window xwindow = glfwGetX11Window(window);
|
|
||||||
Atom wm_type = bd->XInternAtom(display, "_NET_WM_WINDOW_TYPE", False);
|
|
||||||
Atom wm_type_dialog = bd->XInternAtom(display, "_NET_WM_WINDOW_TYPE_DIALOG", False);
|
|
||||||
bd->XChangeProperty(display, xwindow, wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&wm_type_dialog, 1);
|
|
||||||
XSetWindowAttributes attrs;
|
|
||||||
attrs.override_redirect = False;
|
|
||||||
bd->XChangeWindowAttributes(display, xwindow, CWOverrideRedirect, &attrs);
|
|
||||||
bd->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();
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
|
||||||
viewport->PlatformUserData = vd;
|
|
||||||
|
|
||||||
// Workaround for Linux: ignore mouse up events corresponding to losing focus of the previously focused window (#7733, #3158, #7922)
|
|
||||||
#ifdef __linux__
|
|
||||||
bd->MouseIgnoreButtonUpWaitForFocusLoss = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// GLFW 3.2 unfortunately always set focus on glfwCreateWindow() if GLFW_VISIBLE is set, regardless of GLFW_FOCUSED
|
|
||||||
// With GLFW 3.3, the hint GLFW_FOCUS_ON_SHOW fixes this problem
|
|
||||||
glfwWindowHint(GLFW_VISIBLE, false);
|
|
||||||
glfwWindowHint(GLFW_FOCUSED, false);
|
|
||||||
#if GLFW_HAS_FOCUS_ON_SHOW
|
|
||||||
glfwWindowHint(GLFW_FOCUS_ON_SHOW, false);
|
|
||||||
#endif
|
|
||||||
glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true);
|
|
||||||
#if GLFW_HAS_WINDOW_TOPMOST
|
|
||||||
glfwWindowHint(GLFW_FLOATING, (viewport->Flags & ImGuiViewportFlags_TopMost) ? true : false);
|
|
||||||
#endif
|
|
||||||
GLFWwindow* share_window = (bd->ClientApi == GlfwClientApi_OpenGL) ? bd->Window : nullptr;
|
|
||||||
vd->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", nullptr, share_window);
|
|
||||||
vd->WindowOwned = true;
|
|
||||||
ImGui_ImplGlfw_ContextMap_Add(vd->Window, bd->Context);
|
|
||||||
viewport->PlatformHandle = (void*)vd->Window;
|
|
||||||
#ifdef IMGUI_GLFW_HAS_SETWINDOWFLOATING
|
|
||||||
ImGui_ImplGlfw_SetWindowFloating(bd, vd->Window);
|
|
||||||
#endif
|
|
||||||
#ifdef _WIN32
|
|
||||||
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
|
|
||||||
::SetPropA((HWND)viewport->PlatformHandleRaw, "IMGUI_BACKEND_DATA", bd);
|
|
||||||
#elif defined(__APPLE__)
|
|
||||||
viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
|
|
||||||
#endif
|
|
||||||
glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
|
||||||
|
|
||||||
// Install GLFW callbacks for secondary viewports
|
|
||||||
glfwSetWindowFocusCallback(vd->Window, ImGui_ImplGlfw_WindowFocusCallback);
|
|
||||||
glfwSetCursorEnterCallback(vd->Window, ImGui_ImplGlfw_CursorEnterCallback);
|
|
||||||
glfwSetCursorPosCallback(vd->Window, ImGui_ImplGlfw_CursorPosCallback);
|
|
||||||
glfwSetMouseButtonCallback(vd->Window, ImGui_ImplGlfw_MouseButtonCallback);
|
|
||||||
glfwSetScrollCallback(vd->Window, ImGui_ImplGlfw_ScrollCallback);
|
|
||||||
glfwSetKeyCallback(vd->Window, ImGui_ImplGlfw_KeyCallback);
|
|
||||||
glfwSetCharCallback(vd->Window, ImGui_ImplGlfw_CharCallback);
|
|
||||||
glfwSetWindowCloseCallback(vd->Window, ImGui_ImplGlfw_WindowCloseCallback);
|
|
||||||
glfwSetWindowPosCallback(vd->Window, ImGui_ImplGlfw_WindowPosCallback);
|
|
||||||
glfwSetWindowSizeCallback(vd->Window, ImGui_ImplGlfw_WindowSizeCallback);
|
|
||||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
|
||||||
{
|
|
||||||
glfwMakeContextCurrent(vd->Window);
|
|
||||||
glfwSwapInterval(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
if (vd->WindowOwned)
|
|
||||||
{
|
|
||||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED && defined(_WIN32)
|
|
||||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
||||||
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Release any keys that were pressed in the window being destroyed and are still held down,
|
|
||||||
// because we will not receive any release events after window is destroyed.
|
|
||||||
for (int i = 0; i < IM_COUNTOF(bd->KeyOwnerWindows); i++)
|
|
||||||
if (bd->KeyOwnerWindows[i] == vd->Window)
|
|
||||||
ImGui_ImplGlfw_KeyCallback(vd->Window, i, 0, GLFW_RELEASE, 0); // Later params are only used for main viewport, on which this function is never called.
|
|
||||||
|
|
||||||
ImGui_ImplGlfw_ContextMap_Remove(vd->Window);
|
|
||||||
glfwDestroyWindow(vd->Window);
|
|
||||||
}
|
|
||||||
vd->Window = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_ShowWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
// GLFW hack: Hide icon from task bar
|
|
||||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
|
||||||
{
|
|
||||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
||||||
ex_style &= ~WS_EX_APPWINDOW;
|
|
||||||
ex_style |= WS_EX_TOOLWINDOW;
|
|
||||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
|
||||||
}
|
|
||||||
|
|
||||||
// GLFW hack: install WndProc for mouse source event and WM_NCHITTEST message handler.
|
|
||||||
::SetPropA(hwnd, "IMGUI_VIEWPORT", viewport);
|
|
||||||
vd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW(hwnd, GWLP_WNDPROC);
|
|
||||||
::SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc);
|
|
||||||
|
|
||||||
#if !GLFW_HAS_FOCUS_ON_SHOW
|
|
||||||
// GLFW hack: GLFW 3.2 has a bug where glfwShowWindow() also activates/focus the window.
|
|
||||||
// The fix was pushed to GLFW repository on 2018/01/09 and should be included in GLFW 3.3 via a GLFW_FOCUS_ON_SHOW window attribute.
|
|
||||||
// See https://github.com/glfw/glfw/issues/1189
|
|
||||||
// FIXME-VIEWPORT: Implement same work-around for Linux/OSX in the meanwhile.
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
|
||||||
{
|
|
||||||
::ShowWindow(hwnd, SW_SHOWNA);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
glfwShowWindow(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplGlfw_GetWindowPos(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int x = 0, y = 0;
|
|
||||||
glfwGetWindowPos(vd->Window, &x, &y);
|
|
||||||
return ImVec2((float)x, (float)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
vd->IgnoreWindowPosEventFrame = ImGui::GetFrameCount();
|
|
||||||
glfwSetWindowPos(vd->Window, (int)pos.x, (int)pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplGlfw_GetWindowSize(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int w = 0, h = 0;
|
|
||||||
glfwGetWindowSize(vd->Window, &w, &h);
|
|
||||||
return ImVec2((float)w, (float)h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
#if defined(__APPLE__) && !GLFW_HAS_OSX_WINDOW_POS_FIX
|
|
||||||
// Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
|
|
||||||
// positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
|
|
||||||
// doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
|
|
||||||
// on the upper-left corner.
|
|
||||||
int x, y, width, height;
|
|
||||||
glfwGetWindowPos(vd->Window, &x, &y);
|
|
||||||
glfwGetWindowSize(vd->Window, &width, &height);
|
|
||||||
glfwSetWindowPos(vd->Window, x, y - height + size.y);
|
|
||||||
#endif
|
|
||||||
vd->IgnoreWindowSizeEventFrame = ImGui::GetFrameCount();
|
|
||||||
glfwSetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplGlfw_GetWindowFramebufferScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
ImVec2 framebuffer_scale;
|
|
||||||
ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale);
|
|
||||||
return framebuffer_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
glfwSetWindowTitle(vd->Window, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_SetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
#if GLFW_HAS_FOCUS_WINDOW
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
glfwFocusWindow(vd->Window);
|
|
||||||
#else
|
|
||||||
// FIXME: What are the effect of not having this function? At the moment imgui doesn't actually call SetWindowFocus - we set that up ahead, will answer that question later.
|
|
||||||
(void)viewport;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return glfwGetWindowAttrib(vd->Window, GLFW_FOCUSED) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return glfwGetWindowAttrib(vd->Window, GLFW_ICONIFIED) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if GLFW_HAS_WINDOW_ALPHA
|
|
||||||
static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
glfwSetWindowOpacity(vd->Window, alpha);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
|
||||||
glfwMakeContextCurrent(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (bd->ClientApi == GlfwClientApi_OpenGL)
|
|
||||||
{
|
|
||||||
glfwMakeContextCurrent(vd->Window);
|
|
||||||
glfwSwapBuffers(vd->Window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Avoid including <vulkan.h> so we can build without it
|
|
||||||
#if GLFW_HAS_VULKAN
|
|
||||||
#ifndef VULKAN_H_
|
|
||||||
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
|
|
||||||
#if defined(__LP64__) || defined(_WIN64) || defined(__x86_64__) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
|
|
||||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef struct object##_T *object;
|
|
||||||
#else
|
|
||||||
#define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object;
|
|
||||||
#endif
|
|
||||||
VK_DEFINE_HANDLE(VkInstance)
|
|
||||||
VK_DEFINE_NON_DISPATCHABLE_HANDLE(VkSurfaceKHR)
|
|
||||||
struct VkAllocationCallbacks;
|
|
||||||
enum VkResult { VK_RESULT_MAX_ENUM = 0x7FFFFFFF };
|
|
||||||
#endif // VULKAN_H_
|
|
||||||
extern "C" { extern GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance, GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface); }
|
|
||||||
static int ImGui_ImplGlfw_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_UNUSED(bd);
|
|
||||||
IM_ASSERT(bd->ClientApi == GlfwClientApi_Vulkan);
|
|
||||||
VkResult err = glfwCreateWindowSurface((VkInstance)vk_instance, vd->Window, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
|
||||||
return (int)err;
|
|
||||||
}
|
|
||||||
#endif // GLFW_HAS_VULKAN
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
|
||||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Platform_CreateWindow = ImGui_ImplGlfw_CreateWindow;
|
|
||||||
platform_io.Platform_DestroyWindow = ImGui_ImplGlfw_DestroyWindow;
|
|
||||||
platform_io.Platform_ShowWindow = ImGui_ImplGlfw_ShowWindow;
|
|
||||||
platform_io.Platform_SetWindowPos = ImGui_ImplGlfw_SetWindowPos;
|
|
||||||
platform_io.Platform_GetWindowPos = ImGui_ImplGlfw_GetWindowPos;
|
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplGlfw_SetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplGlfw_GetWindowFramebufferScale;
|
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized;
|
|
||||||
platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle;
|
|
||||||
platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow;
|
|
||||||
platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers;
|
|
||||||
#if GLFW_HAS_WINDOW_ALPHA
|
|
||||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplGlfw_SetWindowAlpha;
|
|
||||||
#endif
|
|
||||||
#if GLFW_HAS_VULKAN
|
|
||||||
platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
|
||||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplGlfw_ViewportData* vd = IM_NEW(ImGui_ImplGlfw_ViewportData)();
|
|
||||||
vd->Window = bd->Window;
|
|
||||||
vd->WindowOwned = false;
|
|
||||||
main_viewport->PlatformUserData = vd;
|
|
||||||
main_viewport->PlatformHandle = (void*)bd->Window;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplGlfw_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// WndProc hook (declared here because we will need access to ImGui_ImplGlfw_ViewportData)
|
|
||||||
#ifdef _WIN32
|
|
||||||
static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo()
|
|
||||||
{
|
|
||||||
LPARAM extra_info = ::GetMessageExtraInfo();
|
|
||||||
if ((extra_info & 0xFFFFFF80) == 0xFF515700)
|
|
||||||
return ImGuiMouseSource_Pen;
|
|
||||||
if ((extra_info & 0xFFFFFF80) == 0xFF515780)
|
|
||||||
return ImGuiMouseSource_TouchScreen;
|
|
||||||
return ImGuiMouseSource_Mouse;
|
|
||||||
}
|
|
||||||
static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
ImGui_ImplGlfw_Data* bd = (ImGui_ImplGlfw_Data*)::GetPropA(hWnd, "IMGUI_BACKEND_DATA");
|
|
||||||
ImGuiIO& io = ImGui::GetIO(bd->Context);
|
|
||||||
|
|
||||||
WNDPROC prev_wndproc = bd->PrevWndProc;
|
|
||||||
ImGuiViewport* viewport = (ImGuiViewport*)::GetPropA(hWnd, "IMGUI_VIEWPORT");
|
|
||||||
if (viewport != NULL)
|
|
||||||
if (ImGui_ImplGlfw_ViewportData* vd = (ImGui_ImplGlfw_ViewportData*)viewport->PlatformUserData)
|
|
||||||
prev_wndproc = vd->PrevWndProc;
|
|
||||||
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
// GLFW doesn't allow to distinguish Mouse vs TouchScreen vs Pen.
|
|
||||||
// Add support for Win32 (based on imgui_impl_win32), because we rely on _TouchScreen info to trickle inputs differently.
|
|
||||||
case WM_MOUSEMOVE: case WM_NCMOUSEMOVE:
|
|
||||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_LBUTTONUP:
|
|
||||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: case WM_RBUTTONUP:
|
|
||||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK: case WM_MBUTTONUP:
|
|
||||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK: case WM_XBUTTONUP:
|
|
||||||
io.AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo());
|
|
||||||
break;
|
|
||||||
|
|
||||||
// We have submitted https://github.com/glfw/glfw/pull/1568 to allow GLFW to support "transparent inputs".
|
|
||||||
// In the meanwhile we implement custom per-platform workarounds here (FIXME-VIEWPORT: Implement same work-around for Linux/OSX!)
|
|
||||||
#if !GLFW_HAS_MOUSE_PASSTHROUGH && GLFW_HAS_WINDOW_HOVERED
|
|
||||||
case WM_NCHITTEST:
|
|
||||||
{
|
|
||||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() properly (which is OPTIONAL).
|
|
||||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
|
||||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
|
||||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
|
||||||
if (viewport && (viewport->Flags & ImGuiViewportFlags_NoInputs))
|
|
||||||
return HTTRANSPARENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return ::CallWindowProcW(prev_wndproc, hWnd, msg, wParam, lParam);
|
|
||||||
}
|
|
||||||
#endif // #ifdef _WIN32
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|||||||
@ -9,12 +9,10 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy GLFW_KEY_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
// [X] Platform: Gamepad support. Enable with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors) with GLFW 3.1+. Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors) with GLFW 3.1+. Resizing cursors requires GLFW 3.4+! Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// [X] Multiple Dear ImGui contexts support.
|
// [X] Multiple Dear ImGui contexts support.
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] 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: 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: 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||||
// [ ] Platform: Missing gamepad support.
|
// [ ] Platform: Missing gamepad support.
|
||||||
// [ ] Platform: Missing multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -13,7 +13,6 @@
|
|||||||
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
// [ ] Platform: Missing mouse cursor shape/visibility support.
|
||||||
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
// [ ] Platform: Missing clipboard support (not supported by Glut).
|
||||||
// [ ] Platform: Missing gamepad support.
|
// [ ] Platform: Missing gamepad support.
|
||||||
// [ ] Platform: Missing multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -5,7 +5,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -17,7 +16,8 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-10-06: Added support for render passes with multiple color attachments: we render to the first one and leave the others untouched. (#9574)
|
||||||
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
|
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378)
|
||||||
// 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367)
|
// 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367)
|
||||||
@ -50,12 +50,6 @@
|
|||||||
#import <time.h>
|
#import <time.h>
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplMetal_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
|
||||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
|
|
||||||
#pragma mark - Support classes
|
#pragma mark - Support classes
|
||||||
|
|
||||||
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
// A wrapper around a MTLBuffer object that knows the last time it was reused
|
||||||
@ -65,14 +59,16 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|||||||
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#define IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS 8 // Metal's limit (see Metal Feature Set Tables). Not configurable.
|
||||||
|
|
||||||
// An object that encapsulates the data necessary to uniquely identify a
|
// An object that encapsulates the data necessary to uniquely identify a
|
||||||
// render pipeline state. These are used as cache keys.
|
// render pipeline state. These are used as cache keys.
|
||||||
@interface FramebufferDescriptor : NSObject<NSCopying>
|
@interface FramebufferDescriptor : NSObject<NSCopying>
|
||||||
@property (nonatomic, assign) unsigned long sampleCount;
|
@property (nonatomic, assign) unsigned long sampleCount;
|
||||||
@property (nonatomic, assign) MTLPixelFormat colorPixelFormat;
|
|
||||||
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
||||||
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
||||||
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor;
|
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor;
|
||||||
|
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MetalTexture : NSObject
|
@interface MetalTexture : NSObject
|
||||||
@ -171,8 +167,8 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, id<MTLComman
|
|||||||
{
|
{
|
||||||
.originX = 0.0,
|
.originX = 0.0,
|
||||||
.originY = 0.0,
|
.originY = 0.0,
|
||||||
.width = (double)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x),
|
.width = (double)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f),
|
||||||
.height = (double)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y),
|
.height = (double)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f),
|
||||||
.znear = 0.0,
|
.znear = 0.0,
|
||||||
.zfar = 1.0
|
.zfar = 1.0
|
||||||
};
|
};
|
||||||
@ -211,8 +207,8 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
|||||||
MetalContext* ctx = bd->SharedMetalContext;
|
MetalContext* ctx = bd->SharedMetalContext;
|
||||||
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -405,8 +401,6 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest;
|
samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest;
|
||||||
samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest;
|
samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest;
|
||||||
bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor];
|
bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor];
|
||||||
|
|
||||||
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
#ifdef IMGUI_IMPL_METAL_CPP
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
[samplerDescriptor release];
|
[samplerDescriptor release];
|
||||||
[depthStencilDescriptor release];
|
[depthStencilDescriptor release];
|
||||||
@ -424,7 +418,6 @@ void ImGui_ImplMetal_DestroyDeviceObjects()
|
|||||||
if (tex->RefCount == 1)
|
if (tex->RefCount == 1)
|
||||||
ImGui_ImplMetal_DestroyTexture(tex);
|
ImGui_ImplMetal_DestroyTexture(tex);
|
||||||
|
|
||||||
ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
||||||
bd->SharedMetalContext.samplerStateLinear = nil;
|
bd->SharedMetalContext.samplerStateLinear = nil;
|
||||||
bd->SharedMetalContext.samplerStateNearest = nil;
|
bd->SharedMetalContext.samplerStateNearest = nil;
|
||||||
@ -441,7 +434,6 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
io.BackendRendererName = "imgui_impl_metal";
|
io.BackendRendererName = "imgui_impl_metal";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState;
|
||||||
@ -451,8 +443,6 @@ bool ImGui_ImplMetal_Init(id<MTLDevice> device)
|
|||||||
bd->SharedMetalContext = [[MetalContext alloc] init];
|
bd->SharedMetalContext = [[MetalContext alloc] init];
|
||||||
bd->SharedMetalContext.device = device;
|
bd->SharedMetalContext.device = device;
|
||||||
|
|
||||||
ImGui_ImplMetal_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,160 +454,15 @@ void ImGui_ImplMetal_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplMetal_DestroyDeviceObjects();
|
ImGui_ImplMetal_DestroyDeviceObjects();
|
||||||
ImGui_ImplMetal_DestroyBackendData();
|
ImGui_ImplMetal_DestroyBackendData();
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Multi-viewport support
|
|
||||||
|
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct ImGuiViewportDataMetal
|
|
||||||
{
|
|
||||||
CAMetalLayer* MetalLayer;
|
|
||||||
id<MTLCommandQueue> CommandQueue;
|
|
||||||
MTLRenderPassDescriptor* RenderPassDescriptor;
|
|
||||||
void* Handle = nullptr;
|
|
||||||
bool FirstFrame = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
|
|
||||||
ImGuiViewportDataMetal* data = IM_NEW(ImGuiViewportDataMetal)();
|
|
||||||
viewport->RendererUserData = data;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a NSWindow*, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
|
||||||
// Some back-ends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the NSWindow*.
|
|
||||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(handle != nullptr);
|
|
||||||
|
|
||||||
id<MTLDevice> device = bd->SharedMetalContext.device;
|
|
||||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
|
||||||
layer.device = device;
|
|
||||||
layer.framebufferOnly = YES;
|
|
||||||
layer.pixelFormat = bd->SharedMetalContext.framebufferDescriptor.colorPixelFormat;
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
NSWindow* window = (__bridge NSWindow*)handle;
|
|
||||||
NSView* view = window.contentView;
|
|
||||||
view.layer = layer;
|
|
||||||
view.wantsLayer = YES;
|
|
||||||
#endif
|
|
||||||
data->MetalLayer = layer;
|
|
||||||
data->CommandQueue = [device newCommandQueue];
|
|
||||||
data->RenderPassDescriptor = [[MTLRenderPassDescriptor alloc] init];
|
|
||||||
data->Handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
|
||||||
if (ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData)
|
|
||||||
IM_DELETE(data);
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static CGSize MakeScaledSize(CGSize size, CGFloat scale)
|
|
||||||
{
|
|
||||||
return CGSizeMake(size.width * scale, size.height * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
|
||||||
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), viewport->DpiScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
|
||||||
NSWindow* window = (__bridge NSWindow*)handle;
|
|
||||||
|
|
||||||
// Always render the first frame, regardless of occlusionState, to avoid an initial flicker
|
|
||||||
if ((window.occlusionState & NSWindowOcclusionStateVisible) == 0 && !data->FirstFrame)
|
|
||||||
{
|
|
||||||
// Do not render windows which are completely occluded. Calling -[CAMetalLayer nextDrawable] will hang for
|
|
||||||
// approximately 1 second if the Metal layer is completely occluded.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data->FirstFrame = false;
|
|
||||||
|
|
||||||
float fb_scale = (float)window.backingScaleFactor;
|
|
||||||
if (data->MetalLayer.contentsScale != fb_scale)
|
|
||||||
{
|
|
||||||
data->MetalLayer.contentsScale = fb_scale;
|
|
||||||
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, fb_scale);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];
|
|
||||||
if (drawable == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MTLRenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor;
|
|
||||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
|
||||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0);
|
|
||||||
if ((viewport->Flags & ImGuiViewportFlags_NoRendererClear) == 0)
|
|
||||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
|
||||||
|
|
||||||
id <MTLCommandBuffer> commandBuffer = [data->CommandQueue commandBuffer];
|
|
||||||
id <MTLRenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
|
||||||
ImGui_ImplMetal_RenderDrawData(viewport->DrawData, commandBuffer, renderEncoder);
|
|
||||||
[renderEncoder endEncoding];
|
|
||||||
|
|
||||||
[commandBuffer presentDrawable:drawable];
|
|
||||||
[commandBuffer commit];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplMetal_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplMetal_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (!platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplMetal_CreateWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplMetal_DestroyWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - MetalBuffer implementation
|
#pragma mark - MetalBuffer implementation
|
||||||
|
|
||||||
@implementation MetalBuffer
|
@implementation MetalBuffer
|
||||||
@ -635,23 +480,33 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
#pragma mark - FramebufferDescriptor implementation
|
#pragma mark - FramebufferDescriptor implementation
|
||||||
|
|
||||||
@implementation FramebufferDescriptor
|
@implementation FramebufferDescriptor
|
||||||
|
{
|
||||||
|
MTLPixelFormat _colorPixelFormats[IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor
|
- (instancetype)initWithRenderPassDescriptor:(MTLRenderPassDescriptor*)renderPassDescriptor
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
||||||
_colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat;
|
for (NSUInteger n = 0; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||||
|
_colorPixelFormats[n] = renderPassDescriptor.colorAttachments[n].texture.pixelFormat;
|
||||||
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
||||||
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
return _colorPixelFormats[index];
|
||||||
|
}
|
||||||
|
|
||||||
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
||||||
{
|
{
|
||||||
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
||||||
copy.sampleCount = self.sampleCount;
|
copy.sampleCount = self.sampleCount;
|
||||||
copy.colorPixelFormat = self.colorPixelFormat;
|
memcpy(copy->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats));
|
||||||
copy.depthPixelFormat = self.depthPixelFormat;
|
copy.depthPixelFormat = self.depthPixelFormat;
|
||||||
copy.stencilPixelFormat = self.stencilPixelFormat;
|
copy.stencilPixelFormat = self.stencilPixelFormat;
|
||||||
return copy;
|
return copy;
|
||||||
@ -660,10 +515,12 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
- (NSUInteger)hash
|
- (NSUInteger)hash
|
||||||
{
|
{
|
||||||
NSUInteger sc = _sampleCount & 0x3;
|
NSUInteger sc = _sampleCount & 0x3;
|
||||||
NSUInteger cf = _colorPixelFormat & 0x3FF;
|
NSUInteger cf = _colorPixelFormats[0] & 0x3FF;
|
||||||
NSUInteger df = _depthPixelFormat & 0x3FF;
|
NSUInteger df = _depthPixelFormat & 0x3FF;
|
||||||
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
||||||
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
||||||
|
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||||
|
hash = hash * 31 + _colorPixelFormats[n];
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -673,7 +530,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
||||||
return NO;
|
return NO;
|
||||||
return other.sampleCount == self.sampleCount &&
|
return other.sampleCount == self.sampleCount &&
|
||||||
other.colorPixelFormat == self.colorPixelFormat &&
|
memcmp(other->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats)) == 0 &&
|
||||||
other.depthPixelFormat == self.depthPixelFormat &&
|
other.depthPixelFormat == self.depthPixelFormat &&
|
||||||
other.stencilPixelFormat == self.stencilPixelFormat;
|
other.stencilPixelFormat == self.stencilPixelFormat;
|
||||||
}
|
}
|
||||||
@ -743,7 +600,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
return [[MetalBuffer alloc] initWithBuffer:backing];
|
return [[MetalBuffer alloc] initWithBuffer:backing];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
// Bilinear sampling is required.
|
||||||
- (id<MTLRenderPipelineState>)renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor*)descriptor device:(id<MTLDevice>)device
|
- (id<MTLRenderPipelineState>)renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor*)descriptor device:(id<MTLDevice>)device
|
||||||
{
|
{
|
||||||
NSError* error = nil;
|
NSError* error = nil;
|
||||||
@ -819,7 +676,7 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||||
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
||||||
pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat;
|
pipelineDescriptor.colorAttachments[0].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:0];
|
||||||
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
||||||
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
||||||
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
@ -827,6 +684,11 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|||||||
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
||||||
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
||||||
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++) // Don't write to other color attachments, if any.
|
||||||
|
{
|
||||||
|
pipelineDescriptor.colorAttachments[n].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:n];
|
||||||
|
pipelineDescriptor.colorAttachments[n].writeMask = MTLColorWriteMaskNone;
|
||||||
|
}
|
||||||
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
||||||
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture.gpuResourceID' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'MTLTexture.gpuResourceID' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Texture view pool support? Reevaluate which type to use for ImtextureID.
|
// [ ] Texture view pool support? Reevaluate which type to use for ImtextureID.
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,6 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'MTLTexture' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Texture view pool support? Reevaluate which type to use for ImtextureID.
|
// [ ] Texture view pool support? Reevaluate which type to use for ImtextureID.
|
||||||
|
|
||||||
@ -21,6 +19,8 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-10-06: Added support for render passes with multiple color attachments: we render to the first one and leave the others untouched. (#9574)
|
||||||
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-07-07: Metal 4: Added metal-cpp support. (#9461)
|
// 2026-07-07: Metal 4: Added metal-cpp support. (#9461)
|
||||||
// 2026-07-02: Metal 4: Added new Metal 4 backend implementation. (#9458)
|
// 2026-07-02: Metal 4: Added new Metal 4 backend implementation. (#9458)
|
||||||
|
|
||||||
@ -34,21 +34,11 @@
|
|||||||
#include <Metal/Metal.hpp>
|
#include <Metal/Metal.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplMetal_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
|
||||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
|
|
||||||
#pragma mark - Support classes and structs
|
#pragma mark - Support classes and structs
|
||||||
|
|
||||||
#define METAL_IMGUI_VIEWPORTS_PER_CHUNK 64
|
|
||||||
|
|
||||||
struct ImGui_Metal4_ConstantData
|
struct ImGui_Metal4_ConstantData
|
||||||
{
|
{
|
||||||
// 1 projection matrix is encoded as 4x4 float.
|
float ModelViewProjectionMatrix[4][4];
|
||||||
// Store up to 64 of them in same constant buffer, so multiple viewports can use same constant buffer.
|
|
||||||
float ModelViewProjectionMatrix[METAL_IMGUI_VIEWPORTS_PER_CHUNK][4][4];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@interface MetalBuffer : NSObject
|
@interface MetalBuffer : NSObject
|
||||||
@ -57,14 +47,16 @@ struct ImGui_Metal4_ConstantData
|
|||||||
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
- (instancetype)initWithBuffer:(id<MTLBuffer>)buffer;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
#define IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS 8 // Metal's limit (see Metal Feature Set Tables). Not configurable.
|
||||||
|
|
||||||
// An object that encapsulates the data necessary to uniquely identify a
|
// An object that encapsulates the data necessary to uniquely identify a
|
||||||
// render pipeline state. These are used as cache keys.
|
// render pipeline state. These are used as cache keys.
|
||||||
@interface FramebufferDescriptor : NSObject<NSCopying>
|
@interface FramebufferDescriptor : NSObject<NSCopying>
|
||||||
@property (nonatomic, assign) unsigned long sampleCount;
|
@property (nonatomic, assign) unsigned long sampleCount;
|
||||||
@property (nonatomic, assign) MTLPixelFormat colorPixelFormat;
|
|
||||||
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
@property (nonatomic, assign) MTLPixelFormat depthPixelFormat;
|
||||||
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
@property (nonatomic, assign) MTLPixelFormat stencilPixelFormat;
|
||||||
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor;
|
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor;
|
||||||
|
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface MetalTexture : NSObject
|
@interface MetalTexture : NSObject
|
||||||
@ -87,15 +79,13 @@ struct ImGui_Metal4_ConstantData
|
|||||||
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache;
|
@property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache;
|
||||||
@property (nonatomic, assign) NSUInteger framesInFlight;
|
@property (nonatomic, assign) NSUInteger framesInFlight;
|
||||||
@property (nonatomic, assign) NSUInteger currentFrameSlot;
|
@property (nonatomic, assign) NSUInteger currentFrameSlot;
|
||||||
|
@property (nonatomic, strong) NSArray<id<MTLBuffer>>* constantBuffers;
|
||||||
|
@property (nonatomic, assign) ImGui_Metal4_ConstantData** constantBufferContentsArray;
|
||||||
@property (nonatomic, strong) NSMutableArray<NSMutableArray<MetalBuffer*>*>* bufferCaches;
|
@property (nonatomic, strong) NSMutableArray<NSMutableArray<MetalBuffer*>*>* bufferCaches;
|
||||||
@property (nonatomic, strong) NSObject* bufferCacheLock;
|
@property (nonatomic, strong) NSObject* bufferCacheLock;
|
||||||
@property (nonatomic, assign) double lastBufferCachePurge;
|
@property (nonatomic, assign) double lastBufferCachePurge;
|
||||||
@property (nonatomic, strong) NSArray<id<MTLSharedEvent>>* events; // for tracking when a commands are complete to reset allocator
|
- (id<MTLBuffer>)currentConstantBuffer;
|
||||||
@property (nonatomic) uint64_t eventValue;
|
- (ImGui_Metal4_ConstantData*)currentConstantBufferContents;
|
||||||
@property (nonatomic, strong) NSArray<id<MTL4CommandAllocator>>* commandAllocators;
|
|
||||||
@property (nonatomic, strong) NSMutableArray<NSMutableArray<id<MTLBuffer>>*>* constantBuffers;
|
|
||||||
@property (nonatomic) uint64_t constantBufferChunkCount;
|
|
||||||
@property (nonatomic) uint64_t currentConstantBufferIndex;
|
|
||||||
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device;
|
||||||
- (id<MTLRenderPipelineState>)renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor*)descriptor device:(id<MTLDevice>)device;
|
- (id<MTLRenderPipelineState>)renderPipelineStateForFramebufferDescriptor:(FramebufferDescriptor*)descriptor device:(id<MTLDevice>)device;
|
||||||
@end
|
@end
|
||||||
@ -149,7 +139,7 @@ void ImGui_ImplMetal4_NewFrame(MTL4RenderPassDescriptor* renderPassDescriptor, i
|
|||||||
{
|
{
|
||||||
ImGui_ImplMetal4_Data* bd = ImGui_ImplMetal4_GetBackendData();
|
ImGui_ImplMetal4_Data* bd = ImGui_ImplMetal4_GetBackendData();
|
||||||
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal4_Init()?");
|
IM_ASSERT(bd != nil && "Context or backend not initialized! Did you call ImGui_ImplMetal4_Init()?");
|
||||||
IM_ASSERT(frameInFlightIndex < bd->SharedMetalContext.framesInFlight && "frameInFlightIndex out of range! See framesInFlight passed to ImGui_ImplMetal4_Init().");
|
IM_ASSERT(frameInFlightIndex < (int)bd->SharedMetalContext.framesInFlight && "frameInFlightIndex out of range! See framesInFlight passed to ImGui_ImplMetal4_Init().");
|
||||||
#ifdef IMGUI_IMPL_METAL_CPP
|
#ifdef IMGUI_IMPL_METAL_CPP
|
||||||
bd->SharedMetalContext.framebufferDescriptor = [[[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]autorelease];
|
bd->SharedMetalContext.framebufferDescriptor = [[[FramebufferDescriptor alloc] initWithRenderPassDescriptor:renderPassDescriptor]autorelease];
|
||||||
#else
|
#else
|
||||||
@ -158,10 +148,6 @@ void ImGui_ImplMetal4_NewFrame(MTL4RenderPassDescriptor* renderPassDescriptor, i
|
|||||||
bd->SharedMetalContext.currentFrameSlot = (NSUInteger)frameInFlightIndex;
|
bd->SharedMetalContext.currentFrameSlot = (NSUInteger)frameInFlightIndex;
|
||||||
if (bd->SharedMetalContext.depthStencilState == nil)
|
if (bd->SharedMetalContext.depthStencilState == nil)
|
||||||
ImGui_ImplMetal4_CreateDeviceObjects(bd->SharedMetalContext.device);
|
ImGui_ImplMetal4_CreateDeviceObjects(bd->SharedMetalContext.device);
|
||||||
|
|
||||||
bd->SharedMetalContext.currentConstantBufferIndex = 0;
|
|
||||||
[bd->SharedMetalContext.events[frameInFlightIndex] waitUntilSignaledValue:bd->SharedMetalContext.eventValue timeoutMS:UINT64_MAX];
|
|
||||||
[bd->SharedMetalContext.commandAllocators[frameInFlightIndex] reset];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplMetal4_SetupRenderState(ImDrawData* draw_data, id<MTL4CommandBuffer> commandBuffer,
|
static void ImGui_ImplMetal4_SetupRenderState(ImDrawData* draw_data, id<MTL4CommandBuffer> commandBuffer,
|
||||||
@ -180,8 +166,8 @@ static void ImGui_ImplMetal4_SetupRenderState(ImDrawData* draw_data, id<MTL4Comm
|
|||||||
{
|
{
|
||||||
.originX = 0.0,
|
.originX = 0.0,
|
||||||
.originY = 0.0,
|
.originY = 0.0,
|
||||||
.width = (double)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x),
|
.width = (double)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f),
|
||||||
.height = (double)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y),
|
.height = (double)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f),
|
||||||
.znear = 0.0,
|
.znear = 0.0,
|
||||||
.zfar = 1.0
|
.zfar = 1.0
|
||||||
};
|
};
|
||||||
@ -200,18 +186,11 @@ static void ImGui_ImplMetal4_SetupRenderState(ImDrawData* draw_data, id<MTL4Comm
|
|||||||
{ 0.0f, 0.0f, 1/(F-N), 0.0f },
|
{ 0.0f, 0.0f, 1/(F-N), 0.0f },
|
||||||
{ (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f },
|
{ (R+L)/(L-R), (T+B)/(B-T), N/(F-N), 1.0f },
|
||||||
};
|
};
|
||||||
|
ImGui_Metal4_ConstantData* constantBufferContents = [bd->SharedMetalContext currentConstantBufferContents];
|
||||||
int currentChunk = (int)((float)bd->SharedMetalContext.currentConstantBufferIndex / (float)METAL_IMGUI_VIEWPORTS_PER_CHUNK);
|
memcpy(constantBufferContents->ModelViewProjectionMatrix, ortho_projection, sizeof(ortho_projection));
|
||||||
int currentIndex = bd->SharedMetalContext.currentConstantBufferIndex % METAL_IMGUI_VIEWPORTS_PER_CHUNK;
|
|
||||||
|
|
||||||
int currentFrameIndex = (int)bd->SharedMetalContext.currentFrameSlot;
|
|
||||||
id<MTLBuffer> constantBuffer = bd->SharedMetalContext.constantBuffers[currentFrameIndex][currentChunk];
|
|
||||||
ImGui_Metal4_ConstantData* constantBufferContents = (ImGui_Metal4_ConstantData*)constantBuffer.contents;
|
|
||||||
|
|
||||||
memcpy(&constantBufferContents->ModelViewProjectionMatrix[currentIndex], ortho_projection, sizeof(ortho_projection));
|
|
||||||
|
|
||||||
id<MTL4ArgumentTable> argumentTable = bd->SharedMetalContext.argumentTable;
|
id<MTL4ArgumentTable> argumentTable = bd->SharedMetalContext.argumentTable;
|
||||||
[argumentTable setAddress:constantBuffer.gpuAddress+(uint64_t)currentIndex * sizeof(constantBufferContents->ModelViewProjectionMatrix[0]) atIndex:1];
|
[argumentTable setAddress:[bd->SharedMetalContext currentConstantBuffer].gpuAddress atIndex:1];
|
||||||
[argumentTable setAddress:(vertexBuffer.buffer.gpuAddress + vertexBufferOffset) attributeStride:sizeof(ImDrawVert) atIndex:0];
|
[argumentTable setAddress:(vertexBuffer.buffer.gpuAddress + vertexBufferOffset) attributeStride:sizeof(ImDrawVert) atIndex:0];
|
||||||
[argumentTable setSamplerState:bd->SharedMetalContext.samplerStateLinear.gpuResourceID atIndex:0];
|
[argumentTable setSamplerState:bd->SharedMetalContext.samplerStateLinear.gpuResourceID atIndex:0];
|
||||||
[commandEncoder setArgumentTable:argumentTable atStages:MTLRenderStageVertex | MTLRenderStageFragment];
|
[commandEncoder setArgumentTable:argumentTable atStages:MTLRenderStageVertex | MTLRenderStageFragment];
|
||||||
@ -228,8 +207,8 @@ void ImGui_ImplMetal4_RenderDrawData(ImDrawData* draw_data, id<MTL4CommandBuffer
|
|||||||
MetalContext* ctx = bd->SharedMetalContext;
|
MetalContext* ctx = bd->SharedMetalContext;
|
||||||
|
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -258,23 +237,8 @@ void ImGui_ImplMetal4_RenderDrawData(ImDrawData* draw_data, id<MTL4CommandBuffer
|
|||||||
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device];
|
||||||
|
|
||||||
bd->RenderCommandEncoder = commandEncoder;
|
bd->RenderCommandEncoder = commandEncoder;
|
||||||
|
|
||||||
// check if more chunks are required
|
|
||||||
const int chunksRequired = 1 + (int)((float)bd->SharedMetalContext.currentConstantBufferIndex / (float)METAL_IMGUI_VIEWPORTS_PER_CHUNK);
|
|
||||||
if (chunksRequired > bd->SharedMetalContext.constantBufferChunkCount)
|
|
||||||
{
|
|
||||||
for (NSUInteger i = 0; i < bd->SharedMetalContext.framesInFlight; i++)
|
|
||||||
{
|
|
||||||
id<MTLBuffer> buffer = [bd->SharedMetalContext.device newBufferWithLength:sizeof(ImGui_Metal4_ConstantData) options:MTLResourceStorageModeShared];
|
|
||||||
[bd->SharedMetalContext.constantBuffers[i] addObject:buffer];
|
|
||||||
[bd->SharedMetalContext.residencySet addAllocation:buffer];
|
|
||||||
}
|
|
||||||
bd->SharedMetalContext.constantBufferChunkCount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplMetal4_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
ImGui_ImplMetal4_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0);
|
||||||
bd->SharedMetalContext.currentConstantBufferIndex++;
|
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
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)
|
ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2)
|
||||||
@ -454,33 +418,27 @@ bool ImGui_ImplMetal4_CreateDeviceObjects(id<MTLDevice> device)
|
|||||||
samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest;
|
samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest;
|
||||||
bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor];
|
bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor];
|
||||||
|
|
||||||
NSMutableArray<id<MTL4CommandAllocator>>* commandAllocators = [NSMutableArray array];
|
NSMutableArray<id<MTLBuffer>>* constantBuffers = [NSMutableArray array];
|
||||||
NSMutableArray<id<MTLSharedEvent>>* events = [NSMutableArray array];
|
ImGui_Metal4_ConstantData** constantBufferContentsArray = (ImGui_Metal4_ConstantData**)malloc(sizeof(ImGui_Metal4_ConstantData*) * bd->SharedMetalContext.framesInFlight);
|
||||||
bd->SharedMetalContext.constantBuffers = [NSMutableArray array];
|
|
||||||
for (NSUInteger i = 0; i < bd->SharedMetalContext.framesInFlight; i++)
|
for (NSUInteger i = 0; i < bd->SharedMetalContext.framesInFlight; i++)
|
||||||
{
|
{
|
||||||
events[i] = [device newSharedEvent];
|
id<MTLBuffer> constantBuffer = [device newBufferWithLength:sizeof(ImGui_Metal4_ConstantData) options:MTLResourceStorageModeShared];
|
||||||
commandAllocators[i] = [device newCommandAllocator];
|
[constantBuffers addObject:constantBuffer];
|
||||||
bd->SharedMetalContext.constantBuffers[i] = [NSMutableArray array];
|
constantBufferContentsArray[i] = (ImGui_Metal4_ConstantData*)constantBuffer.contents;
|
||||||
id<MTLBuffer> buffer = [device newBufferWithLength:sizeof(ImGui_Metal4_ConstantData) options:MTLResourceStorageModeShared];
|
[bd->SharedMetalContext.residencySet addAllocation:constantBuffer];
|
||||||
[bd->SharedMetalContext.constantBuffers[i] addObject:buffer];
|
|
||||||
[bd->SharedMetalContext.residencySet addAllocation:buffer];
|
|
||||||
}
|
}
|
||||||
bd->SharedMetalContext.constantBufferChunkCount = 1;
|
bd->SharedMetalContext.constantBuffers = constantBuffers;
|
||||||
bd->SharedMetalContext.events = events;
|
bd->SharedMetalContext.constantBufferContentsArray = constantBufferContentsArray;
|
||||||
|
|
||||||
MTL4ArgumentTableDescriptor* argumentTableDescriptor = [[MTL4ArgumentTableDescriptor alloc] init];
|
MTL4ArgumentTableDescriptor* argumentTableDescriptor = [[MTL4ArgumentTableDescriptor alloc] init];
|
||||||
argumentTableDescriptor.maxBufferBindCount = 2; // vertex buffer + constant buffer
|
argumentTableDescriptor.maxBufferBindCount = 8;
|
||||||
argumentTableDescriptor.maxTextureBindCount = 1; // font atlas or user texture
|
argumentTableDescriptor.maxTextureBindCount = 8;
|
||||||
argumentTableDescriptor.maxSamplerStateBindCount = 2;
|
argumentTableDescriptor.maxSamplerStateBindCount = 8;
|
||||||
argumentTableDescriptor.supportAttributeStrides = YES; // required: vertex buffer is bound via setAddress:stride:atIndex: for stage_in fetch
|
argumentTableDescriptor.supportAttributeStrides = YES; // required: vertex buffer is bound via setAddress:stride:atIndex: for stage_in fetch
|
||||||
|
|
||||||
bd->SharedMetalContext.commandAllocators = commandAllocators;
|
|
||||||
|
|
||||||
bd->SharedMetalContext.argumentTable = [device newArgumentTableWithDescriptor:argumentTableDescriptor error:&error];
|
bd->SharedMetalContext.argumentTable = [device newArgumentTableWithDescriptor:argumentTableDescriptor error:&error];
|
||||||
IM_ASSERT(bd->SharedMetalContext.argumentTable != nil && error == nil);
|
IM_ASSERT(bd->SharedMetalContext.argumentTable != nil && error == nil);
|
||||||
|
|
||||||
ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,8 +454,6 @@ void ImGui_ImplMetal4_DestroyDeviceObjects()
|
|||||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
||||||
bd->SharedMetalContext.samplerStateLinear = nil;
|
bd->SharedMetalContext.samplerStateLinear = nil;
|
||||||
bd->SharedMetalContext.samplerStateNearest = nil;
|
bd->SharedMetalContext.samplerStateNearest = nil;
|
||||||
ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
|
|
||||||
[bd->SharedMetalContext.renderPipelineStateCache removeAllObjects];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplMetal4_Init(id<MTLDevice> device, id<MTL4CommandQueue> commandQueue, int framesInFlight)
|
bool ImGui_ImplMetal4_Init(id<MTLDevice> device, id<MTL4CommandQueue> commandQueue, int framesInFlight)
|
||||||
@ -512,7 +468,6 @@ bool ImGui_ImplMetal4_Init(id<MTLDevice> device, id<MTL4CommandQueue> commandQue
|
|||||||
io.BackendRendererName = "imgui_impl_metal4";
|
io.BackendRendererName = "imgui_impl_metal4";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal4_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal4_DrawCallback_ResetRenderState;
|
||||||
@ -524,11 +479,9 @@ bool ImGui_ImplMetal4_Init(id<MTLDevice> device, id<MTL4CommandQueue> commandQue
|
|||||||
bd->SharedMetalContext.commandQueue = commandQueue;
|
bd->SharedMetalContext.commandQueue = commandQueue;
|
||||||
bd->SharedMetalContext.framesInFlight = (NSUInteger)framesInFlight;
|
bd->SharedMetalContext.framesInFlight = (NSUInteger)framesInFlight;
|
||||||
NSMutableArray<NSMutableArray<MetalBuffer*>*>* bufferCaches = [NSMutableArray array];
|
NSMutableArray<NSMutableArray<MetalBuffer*>*>* bufferCaches = [NSMutableArray array];
|
||||||
for (NSUInteger i = 0; i < framesInFlight; i++)
|
for (NSUInteger i = 0; i < (NSUInteger)framesInFlight; i++)
|
||||||
[bufferCaches addObject:[NSMutableArray array]];
|
[bufferCaches addObject:[NSMutableArray array]];
|
||||||
bd->SharedMetalContext.bufferCaches = bufferCaches;
|
bd->SharedMetalContext.bufferCaches = bufferCaches;
|
||||||
|
|
||||||
ImGui_ImplMetal_InitMultiViewportSupport();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -540,7 +493,6 @@ void ImGui_ImplMetal4_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplMetal_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplMetal4_DestroyDeviceObjects();
|
ImGui_ImplMetal4_DestroyDeviceObjects();
|
||||||
ImGui_ImplMetal4_DestroyBackendData();
|
ImGui_ImplMetal4_DestroyBackendData();
|
||||||
|
|
||||||
@ -565,23 +517,33 @@ void ImGui_ImplMetal4_Shutdown()
|
|||||||
#pragma mark - FramebufferDescriptor implementation
|
#pragma mark - FramebufferDescriptor implementation
|
||||||
|
|
||||||
@implementation FramebufferDescriptor
|
@implementation FramebufferDescriptor
|
||||||
|
{
|
||||||
|
MTLPixelFormat _colorPixelFormats[IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor
|
- (instancetype)initWithRenderPassDescriptor:(MTL4RenderPassDescriptor*)renderPassDescriptor
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
_sampleCount = renderPassDescriptor.colorAttachments[0].texture.sampleCount;
|
||||||
_colorPixelFormat = renderPassDescriptor.colorAttachments[0].texture.pixelFormat;
|
for (NSUInteger n = 0; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||||
|
_colorPixelFormats[n] = renderPassDescriptor.colorAttachments[n].texture.pixelFormat;
|
||||||
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
_depthPixelFormat = renderPassDescriptor.depthAttachment.texture.pixelFormat;
|
||||||
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
_stencilPixelFormat = renderPassDescriptor.stencilAttachment.texture.pixelFormat;
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (MTLPixelFormat)colorPixelFormatAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
return _colorPixelFormats[index];
|
||||||
|
}
|
||||||
|
|
||||||
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
- (nonnull id)copyWithZone:(nullable NSZone*)zone
|
||||||
{
|
{
|
||||||
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
FramebufferDescriptor* copy = [[FramebufferDescriptor allocWithZone:zone] init];
|
||||||
copy.sampleCount = self.sampleCount;
|
copy.sampleCount = self.sampleCount;
|
||||||
copy.colorPixelFormat = self.colorPixelFormat;
|
memcpy(copy->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats));
|
||||||
copy.depthPixelFormat = self.depthPixelFormat;
|
copy.depthPixelFormat = self.depthPixelFormat;
|
||||||
copy.stencilPixelFormat = self.stencilPixelFormat;
|
copy.stencilPixelFormat = self.stencilPixelFormat;
|
||||||
return copy;
|
return copy;
|
||||||
@ -590,10 +552,12 @@ void ImGui_ImplMetal4_Shutdown()
|
|||||||
- (NSUInteger)hash
|
- (NSUInteger)hash
|
||||||
{
|
{
|
||||||
NSUInteger sc = _sampleCount & 0x3;
|
NSUInteger sc = _sampleCount & 0x3;
|
||||||
NSUInteger cf = _colorPixelFormat & 0x3FF;
|
NSUInteger cf = _colorPixelFormats[0] & 0x3FF;
|
||||||
NSUInteger df = _depthPixelFormat & 0x3FF;
|
NSUInteger df = _depthPixelFormat & 0x3FF;
|
||||||
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
NSUInteger sf = _stencilPixelFormat & 0x3FF;
|
||||||
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
NSUInteger hash = (sf << 22) | (df << 12) | (cf << 2) | sc;
|
||||||
|
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++)
|
||||||
|
hash = hash * 31 + _colorPixelFormats[n];
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,7 +567,7 @@ void ImGui_ImplMetal4_Shutdown()
|
|||||||
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
if (![other isKindOfClass:[FramebufferDescriptor class]])
|
||||||
return NO;
|
return NO;
|
||||||
return other.sampleCount == self.sampleCount &&
|
return other.sampleCount == self.sampleCount &&
|
||||||
other.colorPixelFormat == self.colorPixelFormat &&
|
memcmp(other->_colorPixelFormats, _colorPixelFormats, sizeof(_colorPixelFormats)) == 0 &&
|
||||||
other.depthPixelFormat == self.depthPixelFormat &&
|
other.depthPixelFormat == self.depthPixelFormat &&
|
||||||
other.stencilPixelFormat == self.stencilPixelFormat;
|
other.stencilPixelFormat == self.stencilPixelFormat;
|
||||||
}
|
}
|
||||||
@ -638,6 +602,17 @@ void ImGui_ImplMetal4_Shutdown()
|
|||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
|
free(_constantBufferContentsArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id<MTLBuffer>)currentConstantBuffer
|
||||||
|
{
|
||||||
|
return self.constantBuffers[self.currentFrameSlot];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (ImGui_Metal4_ConstantData*)currentConstantBufferContents
|
||||||
|
{
|
||||||
|
return self.constantBufferContentsArray[self.currentFrameSlot];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device
|
- (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLDevice>)device
|
||||||
@ -759,7 +734,7 @@ fragment half4 fragment_main(VertexOut in [[stage_in]],
|
|||||||
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
pipelineDescriptor.fragmentFunction = fragmentFunction;
|
||||||
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
pipelineDescriptor.vertexDescriptor = vertexDescriptor;
|
||||||
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
pipelineDescriptor.rasterSampleCount = self.framebufferDescriptor.sampleCount;
|
||||||
pipelineDescriptor.colorAttachments[0].pixelFormat = self.framebufferDescriptor.colorPixelFormat;
|
pipelineDescriptor.colorAttachments[0].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:0];
|
||||||
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
pipelineDescriptor.colorAttachments[0].blendingEnabled = YES;
|
||||||
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
pipelineDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd;
|
||||||
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
pipelineDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha;
|
||||||
@ -767,6 +742,11 @@ fragment half4 fragment_main(VertexOut in [[stage_in]],
|
|||||||
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
pipelineDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd;
|
||||||
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
pipelineDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne;
|
||||||
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
pipelineDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;
|
||||||
|
for (NSUInteger n = 1; n < IMGUI_IMPL_METAL_MAX_COLOR_ATTACHMENTS; n++) // Don't write to other color attachments, if any.
|
||||||
|
{
|
||||||
|
pipelineDescriptor.colorAttachments[n].pixelFormat = [self.framebufferDescriptor colorPixelFormatAtIndex:n];
|
||||||
|
pipelineDescriptor.colorAttachments[n].writeMask = MTLColorWriteMaskNone;
|
||||||
|
}
|
||||||
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
pipelineDescriptor.depthAttachmentPixelFormat = self.framebufferDescriptor.depthPixelFormat;
|
||||||
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
pipelineDescriptor.stencilAttachmentPixelFormat = self.framebufferDescriptor.stencilPixelFormat;
|
||||||
|
|
||||||
@ -779,159 +759,6 @@ fragment half4 fragment_main(VertexOut in [[stage_in]],
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
#pragma mark - Multi-viewport support
|
|
||||||
|
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
#import <Cocoa/Cocoa.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct ImGuiViewportDataMetal
|
|
||||||
{
|
|
||||||
CAMetalLayer* MetalLayer;
|
|
||||||
id<MTLCommandQueue> CommandQueue;
|
|
||||||
MTL4RenderPassDescriptor* RenderPassDescriptor;
|
|
||||||
void* Handle = nullptr;
|
|
||||||
bool FirstFrame = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplMetal4_Data* bd = ImGui_ImplMetal4_GetBackendData();
|
|
||||||
ImGuiViewportDataMetal* data = IM_NEW(ImGuiViewportDataMetal)();
|
|
||||||
viewport->RendererUserData = data;
|
|
||||||
|
|
||||||
// PlatformHandleRaw should always be a NSWindow*, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL_Window*).
|
|
||||||
// Some back-ends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the NSWindow*.
|
|
||||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
|
||||||
IM_ASSERT(handle != nullptr);
|
|
||||||
|
|
||||||
id<MTLDevice> device = bd->SharedMetalContext.device;
|
|
||||||
CAMetalLayer* layer = [CAMetalLayer layer];
|
|
||||||
layer.device = device;
|
|
||||||
layer.framebufferOnly = YES;
|
|
||||||
layer.pixelFormat = bd->SharedMetalContext.framebufferDescriptor.colorPixelFormat;
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
NSWindow* window = (__bridge NSWindow*)handle;
|
|
||||||
NSView* view = window.contentView;
|
|
||||||
view.layer = layer;
|
|
||||||
view.wantsLayer = YES;
|
|
||||||
#endif
|
|
||||||
data->MetalLayer = layer;
|
|
||||||
data->CommandQueue = [device newCommandQueue];
|
|
||||||
data->RenderPassDescriptor = [[MTL4RenderPassDescriptor alloc] init];
|
|
||||||
data->Handle = handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
|
||||||
if (ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData)
|
|
||||||
IM_DELETE(data);
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static CGSize MakeScaledSize(CGSize size, CGFloat scale)
|
|
||||||
{
|
|
||||||
return CGSizeMake(size.width * scale, size.height * scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
|
||||||
data->MetalLayer.drawableSize = MakeScaledSize(CGSizeMake(size.x, size.y), viewport->DpiScale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGuiViewportDataMetal* data = (ImGuiViewportDataMetal*)viewport->RendererUserData;
|
|
||||||
|
|
||||||
#if TARGET_OS_OSX
|
|
||||||
void* handle = viewport->PlatformHandleRaw ? viewport->PlatformHandleRaw : viewport->PlatformHandle;
|
|
||||||
NSWindow* window = (__bridge NSWindow*)handle;
|
|
||||||
|
|
||||||
// Always render the first frame, regardless of occlusionState, to avoid an initial flicker
|
|
||||||
if ((window.occlusionState & NSWindowOcclusionStateVisible) == 0 && !data->FirstFrame)
|
|
||||||
{
|
|
||||||
// Do not render windows which are completely occluded. Calling -[CAMetalLayer nextDrawable] will hang for
|
|
||||||
// approximately 1 second if the Metal layer is completely occluded.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
data->FirstFrame = false;
|
|
||||||
|
|
||||||
float fb_scale = (float)window.backingScaleFactor;
|
|
||||||
if (data->MetalLayer.contentsScale != fb_scale)
|
|
||||||
{
|
|
||||||
data->MetalLayer.contentsScale = fb_scale;
|
|
||||||
data->MetalLayer.drawableSize = MakeScaledSize(window.frame.size, fb_scale);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
id <CAMetalDrawable> drawable = [data->MetalLayer nextDrawable];
|
|
||||||
if (drawable == nil)
|
|
||||||
return;
|
|
||||||
|
|
||||||
MTL4RenderPassDescriptor* renderPassDescriptor = data->RenderPassDescriptor;
|
|
||||||
renderPassDescriptor.colorAttachments[0].texture = drawable.texture;
|
|
||||||
renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0);
|
|
||||||
if ((viewport->Flags & ImGuiViewportFlags_NoRendererClear) == 0)
|
|
||||||
renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear;
|
|
||||||
|
|
||||||
ImGui_ImplMetal4_Data* bd = ImGui_ImplMetal4_GetBackendData();
|
|
||||||
id <MTL4CommandBuffer> commandBuffer = [bd->SharedMetalContext.device newCommandBuffer];
|
|
||||||
[commandBuffer beginCommandBufferWithAllocator:bd->SharedMetalContext.commandAllocators[bd->SharedMetalContext.currentFrameSlot]];
|
|
||||||
|
|
||||||
id <MTL4RenderCommandEncoder> renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor];
|
|
||||||
ImGui_ImplMetal4_RenderDrawData(viewport->DrawData, commandBuffer, renderEncoder);
|
|
||||||
[renderEncoder endEncoding];
|
|
||||||
[commandBuffer endCommandBuffer];
|
|
||||||
|
|
||||||
[bd->SharedMetalContext.commandQueue waitForDrawable:drawable];
|
|
||||||
[bd->SharedMetalContext.commandQueue commit:&commandBuffer count:1];
|
|
||||||
[bd->SharedMetalContext.commandQueue signalDrawable:drawable];
|
|
||||||
[drawable present];
|
|
||||||
[bd->SharedMetalContext.commandQueue signalEvent:bd->SharedMetalContext.events[bd->SharedMetalContext.currentFrameSlot] value:++(bd->SharedMetalContext.eventValue)];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplMetal_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplMetal_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplMetal_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplMetal_RenderWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_CreateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (!platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplMetal_CreateWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int i = 1; i < platform_io.Viewports.Size; i++)
|
|
||||||
if (platform_io.Viewports[i]->RendererUserData)
|
|
||||||
ImGui_ImplMetal_DestroyWindow(platform_io.Viewports[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [ ] Renderer: Use of DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest is emulated by poking to glTexParameter(), as legacy OpenGL doesn't have glBindSampler().
|
// [ ] Renderer: Use of DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest is emulated by poking to glTexParameter(), as legacy OpenGL doesn't have glBindSampler().
|
||||||
@ -27,7 +26,8 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-09-17: OpenGL: Added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378)
|
||||||
|
// 2026-09-07: OpenGL: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
||||||
// 2026-04-23: OpenGL: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: OpenGL: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2026-03-12: OpenGL: Fixed invalid assert in ImGui_ImplOpenGL3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
// 2026-03-12: OpenGL: Fixed invalid assert in ImGui_ImplOpenGL3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
||||||
@ -104,10 +104,6 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
void ImGui_ImplOpenGL2_NewFrame()
|
void ImGui_ImplOpenGL2_NewFrame()
|
||||||
{
|
{
|
||||||
@ -137,6 +133,8 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
|||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
glShadeModel(GL_SMOOTH);
|
glShadeModel(GL_SMOOTH);
|
||||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
bd->UseTexParameterToSetSampler = false;
|
||||||
bd->NextSampler = GL_LINEAR;
|
bd->NextSampler = GL_LINEAR;
|
||||||
|
|
||||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||||
@ -163,9 +161,13 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Draw callbacks
|
// Draw callbacks
|
||||||
static void ImGui_ImplOpenGL2_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
// - IMPORTANT: Using DrawCallback_SetSamplerLinear/DrawCallback_SetSamplerNearest will trash glTexParameteri() values for the texture!!
|
||||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; }
|
// We cannot decently backup/restore that state because glGetTexParameteriv() is slow on many setups.
|
||||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; }
|
// - Using DrawCallback_SetSamplerFromTex will basically instruct the backend to use existing glTexParameteri() values without modifying anything, which is the initial state.
|
||||||
|
static void ImGui_ImplOpenGL2_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||||
|
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; }
|
||||||
|
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; }
|
||||||
|
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = false; }
|
||||||
|
|
||||||
// OpenGL2 Render function.
|
// OpenGL2 Render function.
|
||||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||||
@ -174,8 +176,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
|||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width == 0 || fb_height == 0)
|
if (fb_width == 0 || fb_height == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -282,8 +284,7 @@ void ImGui_ImplOpenGL2_UpdateTexture(ImTextureData* tex)
|
|||||||
const void* pixels = tex->GetPixels();
|
const void* pixels = tex->GetPixels();
|
||||||
GLuint gl_texture_id = 0;
|
GLuint gl_texture_id = 0;
|
||||||
|
|
||||||
// Upload texture to graphics system
|
// Upload texture to graphics system (bilinear sampling is required).
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
GLint last_texture;
|
||||||
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
GL_CALL(glGenTextures(1, &gl_texture_id));
|
GL_CALL(glGenTextures(1, &gl_texture_id));
|
||||||
@ -361,14 +362,12 @@ bool ImGui_ImplOpenGL2_Init()
|
|||||||
io.BackendRendererUserData = (void*)bd;
|
io.BackendRendererUserData = (void*)bd;
|
||||||
io.BackendRendererName = "imgui_impl_opengl2";
|
io.BackendRendererName = "imgui_impl_opengl2";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL2_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL2_DrawCallback_ResetRenderState;
|
||||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear;
|
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear;
|
||||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest;
|
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest;
|
||||||
|
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplOpenGL2_DrawCallback_SetSamplerFromTex;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -380,44 +379,15 @@ void ImGui_ImplOpenGL2_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
ImGui_ImplOpenGL2_DestroyDeviceObjects();
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
{
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
ImGui_ImplOpenGL2_RenderDrawData(viewport->DrawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL2_RenderWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL2_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [ ] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [ ] Renderer: Use of DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest is emulated by poking to glTexParameter(), as legacy OpenGL doesn't have glBindSampler().
|
// [ ] Renderer: Use of DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest is emulated by poking to glTexParameter(), as legacy OpenGL doesn't have glBindSampler().
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplOpenGL3_GetRenderState().
|
||||||
|
|
||||||
// About WebGL/ES:
|
// About WebGL/ES:
|
||||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||||
@ -24,7 +24,11 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-10-01: OpenGL: Added ImGui_ImplOpenGL3_SetClipOrigin() to specify clip origins (GL_LOWER_LEFT/GL_UPPER_LEFT, or use 0 to autodetect). (#2186, #3998, #3146, #3143, #8640)
|
||||||
|
// (Breaking): we now default to GL_LOWER_LEFT instead of 0=autodetect. Because 1) detection is not reliable and 2) is slow.
|
||||||
|
// 2026-10-01: OpenGL: Avoid querying glGetIntegerv(GL_CLIP_ORIGIN) multiple times when using DrawCallback_ResetRenderState. (#2186, #3998, #3146, #3143, #8640)
|
||||||
|
// 2026-09-17: OpenGL: Added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378)
|
||||||
|
// 2026-09-07: OpenGL: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
||||||
// 2026-06-17: OpenGL: Expose selected render state in ImGui_ImplOpenGL3_RenderState, Allowing to dynamically select between use of glBindSampler() and glTexParameter(). You can access in 'void* platform_io.Renderer_RenderState' during rendering.
|
// 2026-06-17: OpenGL: Expose selected render state in ImGui_ImplOpenGL3_RenderState, Allowing to dynamically select between use of glBindSampler() and glTexParameter(). You can access in 'void* platform_io.Renderer_RenderState' during rendering.
|
||||||
// 2026-06-03: OpenGL: GLSL version detection assume GLSL 410 when GL context is 4.1. Fixes an issue running on macOS with Wine. (#9427, #6577)
|
// 2026-06-03: OpenGL: GLSL version detection assume GLSL 410 when GL context is 4.1. Fixes an issue running on macOS with Wine. (#9427, #6577)
|
||||||
@ -188,6 +192,10 @@
|
|||||||
#define IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
#define IMGUI_IMPL_OPENGL_LOADER_IMGL3W
|
||||||
#include "imgui_impl_opengl3_loader.h"
|
#include "imgui_impl_opengl3_loader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef GL_LOWER_LEFT
|
||||||
|
#define GL_LOWER_LEFT 0x8CA1
|
||||||
|
#define GL_UPPER_LEFT 0x8CA2
|
||||||
|
#endif
|
||||||
|
|
||||||
// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension
|
// Vertex arrays are not supported on ES2/WebGL1 unless Emscripten which uses an extension
|
||||||
#ifndef IMGUI_IMPL_OPENGL_ES2
|
#ifndef IMGUI_IMPL_OPENGL_ES2
|
||||||
@ -258,6 +266,8 @@ struct ImGui_ImplOpenGL3_Data
|
|||||||
bool HasPolygonMode;
|
bool HasPolygonMode;
|
||||||
bool HasBindSampler;
|
bool HasBindSampler;
|
||||||
bool HasClipOrigin;
|
bool HasClipOrigin;
|
||||||
|
GLenum ClipOriginRequest; // Default = GL_LOWER_LEFT. Change using ImGui_ImplOpenGL3_SetClipOrigin().
|
||||||
|
GLenum ClipOriginCurrent;
|
||||||
bool UseBufferSubData;
|
bool UseBufferSubData;
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||||
GLuint TexSamplers[2]; // Used if HasBindSimpler. (0=linear, 1=nearest)
|
GLuint TexSamplers[2]; // Used if HasBindSimpler. (0=linear, 1=nearest)
|
||||||
@ -275,9 +285,10 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState()
|
||||||
static void ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
{
|
||||||
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
|
// OpenGL vertex attribute state (for ES 1.0 and ES 2.0 only)
|
||||||
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
#ifndef IMGUI_IMPL_OPENGL_USE_VERTEX_ARRAY
|
||||||
@ -359,17 +370,6 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
|||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
|
||||||
#if defined(GL_CLIP_ORIGIN)
|
|
||||||
bool clip_origin_lower_left = true;
|
|
||||||
if (bd->HasClipOrigin)
|
|
||||||
{
|
|
||||||
GLenum current_clip_origin = 0; glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)¤t_clip_origin);
|
|
||||||
if (current_clip_origin == GL_UPPER_LEFT)
|
|
||||||
clip_origin_lower_left = false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Setup viewport, orthographic projection matrix
|
// Setup viewport, orthographic projection matrix
|
||||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||||
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
GL_CALL(glViewport(0, 0, (GLsizei)fb_width, (GLsizei)fb_height));
|
||||||
@ -377,9 +377,7 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
|||||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
float T = draw_data->DisplayPos.y;
|
float T = draw_data->DisplayPos.y;
|
||||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
#if defined(GL_CLIP_ORIGIN)
|
if (bd->ClipOriginCurrent == GL_UPPER_LEFT) { float tmp = T; T = B; B = tmp; } // Swap top and bottom
|
||||||
if (!clip_origin_lower_left) { float tmp = T; T = B; B = tmp; } // Swap top and bottom if origin is upper left
|
|
||||||
#endif
|
|
||||||
const float ortho_projection[4][4] =
|
const float ortho_projection[4][4] =
|
||||||
{
|
{
|
||||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
@ -391,8 +389,12 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
|||||||
glUniform1i(bd->AttribLocationTex, 0);
|
glUniform1i(bd->AttribLocationTex, 0);
|
||||||
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||||
|
|
||||||
|
render_state->UseBindSampler = bd->HasBindSampler;
|
||||||
|
render_state->UseTexParameterFilter = false;
|
||||||
|
render_state->CurrentSampler = 0;
|
||||||
|
render_state->CurrentTexParameterFilter = 0;
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||||
if (render_state->UseBindSampler)
|
if (bd->HasBindSampler && render_state->UseBindSampler)
|
||||||
{
|
{
|
||||||
render_state->CurrentSampler = bd->TexSamplers[0];
|
render_state->CurrentSampler = bd->TexSamplers[0];
|
||||||
glBindSampler(0, render_state->CurrentSampler); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
|
glBindSampler(0, render_state->CurrentSampler); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
|
||||||
@ -415,16 +417,15 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
|||||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
|
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw callbacks
|
static void ImGui_ImplOpenGL3_DrawCallback_SetSampler(unsigned int sampler_idx, unsigned int tex_parameter_filter)
|
||||||
static void ImGui_ImplOpenGL3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
|
||||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*)
|
|
||||||
{
|
{
|
||||||
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
||||||
|
IM_UNUSED(sampler_idx);
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
if (bd->HasBindSampler)
|
if (bd->HasBindSampler && render_state->UseBindSampler)
|
||||||
{
|
{
|
||||||
render_state->CurrentSampler = bd->TexSamplers[0];
|
render_state->CurrentSampler = bd->TexSamplers[sampler_idx];
|
||||||
render_state->UseTexParameterFilter = false;
|
render_state->UseTexParameterFilter = false;
|
||||||
glBindSampler(0, render_state->CurrentSampler);
|
glBindSampler(0, render_state->CurrentSampler);
|
||||||
}
|
}
|
||||||
@ -432,26 +433,38 @@ static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, c
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
render_state->UseTexParameterFilter = true;
|
render_state->UseTexParameterFilter = true;
|
||||||
render_state->CurrentTexParameterFilter = GL_LINEAR;
|
render_state->CurrentTexParameterFilter = tex_parameter_filter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*)
|
|
||||||
|
// Draw callbacks
|
||||||
|
// - IMPORTANT: Using DrawCallback_SetSamplerLinear/DrawCallback_SetSamplerNearest will trash glTexParameteri() values for the texture if used on a GL context not supporting glBindSampler()!!
|
||||||
|
// We cannot decently backup/restore that state because glGetTexParameteriv() is slow on many setups.
|
||||||
|
// - Using DrawCallback_SetSamplerFromTex will basically instruct the backend to use existing glTexParameteri() values without modifying anything.
|
||||||
|
static void ImGui_ImplOpenGL3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||||
|
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_DrawCallback_SetSampler(0, GL_LINEAR); }
|
||||||
|
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_DrawCallback_SetSampler(1, GL_NEAREST); }
|
||||||
|
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*)
|
||||||
{
|
{
|
||||||
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
||||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
if (bd->HasBindSampler)
|
if (bd->HasBindSampler)
|
||||||
{
|
{
|
||||||
render_state->CurrentSampler = bd->TexSamplers[1];
|
render_state->CurrentSampler = 0;
|
||||||
render_state->UseTexParameterFilter = false;
|
glBindSampler(0, 0);
|
||||||
glBindSampler(0, render_state->CurrentSampler);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
#endif
|
||||||
{
|
render_state->UseBindSampler = false;
|
||||||
render_state->UseTexParameterFilter = true;
|
render_state->UseTexParameterFilter = false;
|
||||||
render_state->CurrentTexParameterFilter = GL_NEAREST;
|
}
|
||||||
}
|
|
||||||
|
// Default is GL_LOWER_LEFT since 2026/10/01. Used to be auto.
|
||||||
|
void ImGui_ImplOpenGL3_SetClipOrigin(unsigned int clip_origin)
|
||||||
|
{
|
||||||
|
IM_ASSERT(clip_origin == 0 || clip_origin == GL_UPPER_LEFT || clip_origin == GL_LOWER_LEFT);
|
||||||
|
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||||
|
bd->ClipOriginRequest = clip_origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenGL3 Render function.
|
// OpenGL3 Render function.
|
||||||
@ -460,8 +473,8 @@ static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*,
|
|||||||
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0)
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -515,6 +528,17 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
GLboolean last_enable_primitive_restart = (!bd->GlProfileIsES3 && bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
|
GLboolean last_enable_primitive_restart = (!bd->GlProfileIsES3 && bd->GlVersion >= 310) ? glIsEnabled(GL_PRIMITIVE_RESTART) : GL_FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Support for GL 4.5 rarely used glClipControl(GL_UPPER_LEFT)
|
||||||
|
bd->ClipOriginCurrent = bd->ClipOriginRequest;
|
||||||
|
if (bd->ClipOriginCurrent == 0)
|
||||||
|
{
|
||||||
|
bd->ClipOriginCurrent = GL_LOWER_LEFT;
|
||||||
|
#ifdef GL_CLIP_ORIGIN
|
||||||
|
if (bd->HasClipOrigin)
|
||||||
|
glGetIntegerv(GL_CLIP_ORIGIN, (GLint*)&bd->ClipOriginCurrent);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Setup desired GL state
|
// Setup desired GL state
|
||||||
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
|
// Recreate the VAO every time (this is to easily allow multiple GL contexts to be rendered to. VAO are not shared among GL contexts)
|
||||||
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
|
// The renderer would actually work without any VAO bound, but then our VertexAttrib calls would overwrite the default one currently bound.
|
||||||
@ -525,11 +549,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
|||||||
|
|
||||||
// Setup render state structure (for callbacks and custom texture bindings)
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
ImGui_ImplOpenGL3_RenderState render_state;
|
ImGui_ImplOpenGL3_RenderState render_state = {};
|
||||||
render_state.UseBindSampler = bd->HasBindSampler;
|
|
||||||
render_state.UseTexParameterFilter = false;
|
|
||||||
render_state.CurrentSampler = 0;
|
|
||||||
render_state.CurrentTexParameterFilter = 0;
|
|
||||||
platform_io.Renderer_RenderState = &render_state;
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, &render_state, fb_width, fb_height, vertex_array_object);
|
ImGui_ImplOpenGL3_SetupRenderState(draw_data, &render_state, fb_width, fb_height, vertex_array_object);
|
||||||
@ -695,8 +715,7 @@ void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex)
|
|||||||
const void* pixels = tex->GetPixels();
|
const void* pixels = tex->GetPixels();
|
||||||
GLuint gl_texture_id = 0;
|
GLuint gl_texture_id = 0;
|
||||||
|
|
||||||
// Upload texture to graphics system
|
// Upload texture to graphics system (bilinear sampling is required).
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
GLint last_texture;
|
GLint last_texture;
|
||||||
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
GL_CALL(glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture));
|
||||||
GL_CALL(glGenTextures(1, &gl_texture_id));
|
GL_CALL(glGenTextures(1, &gl_texture_id));
|
||||||
@ -1094,13 +1113,13 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
#endif
|
#endif
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = (int)bd->MaxTextureSize;
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = (int)bd->MaxTextureSize;
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL3_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL3_DrawCallback_ResetRenderState;
|
||||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear;
|
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear;
|
||||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest;
|
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest;
|
||||||
|
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplOpenGL3_DrawCallback_SetSamplerFromTex;
|
||||||
|
|
||||||
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
||||||
// Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
|
// Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
|
||||||
@ -1146,8 +1165,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
|||||||
bd->HasClipOrigin = true;
|
bd->HasClipOrigin = true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
bd->ClipOriginCurrent = bd->ClipOriginRequest = GL_LOWER_LEFT;
|
||||||
ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1159,46 +1177,17 @@ void ImGui_ImplOpenGL3_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
|
|
||||||
ImGui_ImplOpenGL3_ShutdownLoader();
|
ImGui_ImplOpenGL3_ShutdownLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
|
||||||
{
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
}
|
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(viewport->DrawData);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplOpenGL3_RenderWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplOpenGL3_GetRenderState().
|
||||||
|
|
||||||
// About WebGL/ES:
|
// About WebGL/ES:
|
||||||
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||||
@ -44,6 +44,9 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_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 = nullptr to handle this manually.
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = nullptr to handle this manually.
|
||||||
IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// (Advanced) Specify clip origin, same value as glClipControl() or 0 for auto-detection.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_SetClipOrigin(unsigned int gl_clip_origin);
|
||||||
|
|
||||||
// Configuration flags to add in your imconfig file:
|
// Configuration flags to add in your imconfig file:
|
||||||
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
|
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
|
||||||
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
|
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
|
||||||
@ -73,10 +76,9 @@ struct ImGui_ImplOpenGL3_RenderState
|
|||||||
{
|
{
|
||||||
bool UseBindSampler;
|
bool UseBindSampler;
|
||||||
bool UseTexParameterFilter;
|
bool UseTexParameterFilter;
|
||||||
unsigned int CurrentSampler; // (GLuint) Used if UseBindSampler == true, otherwise always 0
|
unsigned int CurrentSampler; // (GLuint) Used if UseBindSampler == true (and are available), otherwise always 0
|
||||||
unsigned int CurrentTexParameterFilter; // (GLuint) Used if UseTexParameterToSetSampler == true
|
unsigned int CurrentTexParameterFilter; // (GLuint) Used if UseTexParameterFilter == true
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState();
|
||||||
static inline ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState() { return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -114,7 +114,7 @@ extern "C" {
|
|||||||
#define GLAPI extern
|
#define GLAPI extern
|
||||||
#endif
|
#endif
|
||||||
/* glcorearb.h is for use with OpenGL core profile implementations.
|
/* glcorearb.h is for use with OpenGL core profile implementations.
|
||||||
** It should should be placed in the same directory as gl.h and
|
** It should be placed in the same directory as gl.h and
|
||||||
** included as <GL/glcorearb.h>.
|
** included as <GL/glcorearb.h>.
|
||||||
**
|
**
|
||||||
** glcorearb.h includes only APIs in the latest OpenGL core profile
|
** glcorearb.h includes only APIs in the latest OpenGL core profile
|
||||||
@ -303,6 +303,7 @@ typedef khronos_uint16_t GLushort;
|
|||||||
#define GL_LINK_STATUS 0x8B82
|
#define GL_LINK_STATUS 0x8B82
|
||||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||||
#define GL_CURRENT_PROGRAM 0x8B8D
|
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||||
|
#define GL_LOWER_LEFT 0x8CA1
|
||||||
#define GL_UPPER_LEFT 0x8CA2
|
#define GL_UPPER_LEFT 0x8CA2
|
||||||
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
|
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
|
||||||
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
||||||
|
|||||||
@ -10,10 +10,6 @@
|
|||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: IME support.
|
// [X] Platform: IME support.
|
||||||
// [x] Platform: Multi-viewport / platform windows.
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -10,10 +10,6 @@
|
|||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: IME support.
|
// [X] Platform: IME support.
|
||||||
// [x] Platform: Multi-viewport / platform windows.
|
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -33,12 +29,9 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
// 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-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)
|
// 2025-06-12: ImGui_ImplOSX_HandleEvent() only process event for window containing our view. (#8644)
|
||||||
// 2025-05-15: [Docking] Add Platform_GetWindowFramebufferScale() handler, to allow varying Retina display density on multiple monitors.
|
|
||||||
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
||||||
// 2025-01-20: Removed notification observer when shutting down. (#8331)
|
// 2025-01-20: Removed notification observer when shutting down. (#8331)
|
||||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||||
@ -108,9 +101,6 @@ static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(
|
|||||||
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
|
static inline CFTimeInterval GetMachAbsoluteTimeInSeconds() { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
|
||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplOSX_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
|
||||||
static void ImGui_ImplOSX_UpdateMonitors();
|
|
||||||
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
|
static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view);
|
||||||
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
||||||
|
|
||||||
@ -158,20 +148,6 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||||||
NSWindow* window = view.window;
|
NSWindow* window = view.window;
|
||||||
if (!window)
|
if (!window)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
NSRect frame = window.frame;
|
|
||||||
NSRect contentRect = window.contentLayoutRect;
|
|
||||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
|
||||||
contentRect = frame;
|
|
||||||
|
|
||||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
|
||||||
_imeRect = NSMakeRect(_posX, _posY, 0, 0);
|
|
||||||
_imeRect.origin.y = firstScreenFrame.size.height - _imeRect.size.height - _imeRect.origin.y; // Opposite of ConvertNSRect()
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
NSRect contentRect = [window contentRectForFrameRect:window.frame];
|
||||||
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
NSRect rect = NSMakeRect(_posX, contentRect.size.height - _posY, 0, 0);
|
||||||
@ -271,7 +247,6 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||||||
|
|
||||||
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
- (void)onApplicationBecomeActive:(NSNotification*)aNotification;
|
||||||
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
|
- (void)onApplicationBecomeInactive:(NSNotification*)aNotification;
|
||||||
- (void)displaysDidChange:(NSNotification*)aNotification;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -289,11 +264,6 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view);
|
|||||||
io.AddFocusEvent(false);
|
io.AddFocusEvent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)displaysDidChange:(NSNotification*)aNotification
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_UpdateMonitors();
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
@ -448,15 +418,11 @@ bool ImGui_ImplOSX_Init(NSView* view)
|
|||||||
io.BackendPlatformName = "imgui_impl_osx";
|
io.BackendPlatformName = "imgui_impl_osx";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
//io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
//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)
|
|
||||||
|
|
||||||
bd->Observer = [ImGuiObserver new];
|
bd->Observer = [ImGuiObserver new];
|
||||||
bd->Window = view.window ?: NSApp.orderedWindows.firstObject;
|
bd->Window = view.window ?: NSApp.orderedWindows.firstObject;
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
|
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window;
|
||||||
ImGui_ImplOSX_UpdateMonitors();
|
|
||||||
ImGui_ImplOSX_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
// Load cursors. Some of them are undocumented.
|
// Load cursors. Some of them are undocumented.
|
||||||
bd->MouseCursorHidden = false;
|
bd->MouseCursorHidden = false;
|
||||||
@ -548,14 +514,14 @@ void ImGui_ImplOSX_Shutdown()
|
|||||||
bd->Monitor = nullptr;
|
bd->Monitor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui_ImplOSX_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplOSX_DestroyBackendData();
|
ImGui_ImplOSX_DestroyBackendData();
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasGamepad);
|
||||||
platform_io.ClearPlatformHandlers();
|
platform_io.ClearPlatformHandlers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,10 +672,10 @@ static ImGuiMouseSource GetMouseSource(NSEvent* event)
|
|||||||
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
||||||
{
|
{
|
||||||
// Only process events from the window containing ImGui view
|
// Only process events from the window containing ImGui view
|
||||||
if (!ImGui::FindViewportByPlatformHandle((__bridge void*)event.window))
|
if (event.window != view.window)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
|
if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown)
|
||||||
{
|
{
|
||||||
int button = (int)[event buttonNumber];
|
int button = (int)[event buttonNumber];
|
||||||
@ -734,23 +700,14 @@ static bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view)
|
|||||||
|
|
||||||
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged || event.type == NSEventTypeRightMouseDragged || event.type == NSEventTypeOtherMouseDragged)
|
if (event.type == NSEventTypeMouseMoved || event.type == NSEventTypeLeftMouseDragged || event.type == NSEventTypeRightMouseDragged || event.type == NSEventTypeOtherMouseDragged)
|
||||||
{
|
{
|
||||||
NSPoint mousePoint;
|
NSPoint mousePoint = event.locationInWindow;
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
if (event.window == nil)
|
||||||
{
|
mousePoint = [[view window] convertPointFromScreen:mousePoint];
|
||||||
mousePoint = NSEvent.mouseLocation;
|
mousePoint = [view convertPoint:mousePoint fromView:nil];
|
||||||
mousePoint.y = CGDisplayPixelsHigh(kCGDirectMainDisplay) - mousePoint.y; // Normalize y coordinate to top-left of main display.
|
if ([view isFlipped])
|
||||||
}
|
mousePoint = NSMakePoint(mousePoint.x, mousePoint.y);
|
||||||
else
|
else
|
||||||
{
|
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
|
||||||
mousePoint = event.locationInWindow;
|
|
||||||
if (event.window == nil)
|
|
||||||
mousePoint = [[view window] convertPointFromScreen:mousePoint];
|
|
||||||
mousePoint = [view convertPoint:mousePoint fromView:nil]; // Convert to local coordinates of view
|
|
||||||
if ([view isFlipped])
|
|
||||||
mousePoint = NSMakePoint(mousePoint.x, mousePoint.y);
|
|
||||||
else
|
|
||||||
mousePoint = NSMakePoint(mousePoint.x, view.bounds.size.height - mousePoint.y);
|
|
||||||
}
|
|
||||||
io.AddMouseSourceEvent(GetMouseSource(event));
|
io.AddMouseSourceEvent(GetMouseSource(event));
|
||||||
io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
|
io.AddMousePosEvent((float)mousePoint.x, (float)mousePoint.y);
|
||||||
return io.WantCaptureMouse;
|
return io.WantCaptureMouse;
|
||||||
@ -876,300 +833,6 @@ static void ImGui_ImplOSX_AddTrackingArea(NSView* _Nonnull view)
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the back-end to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
struct ImGui_ImplOSX_ViewportData
|
|
||||||
{
|
|
||||||
NSWindow* Window;
|
|
||||||
bool WindowOwned;
|
|
||||||
|
|
||||||
ImGui_ImplOSX_ViewportData() { WindowOwned = false; }
|
|
||||||
~ImGui_ImplOSX_ViewportData() { IM_ASSERT(Window == nil); }
|
|
||||||
};
|
|
||||||
|
|
||||||
@interface ImGui_ImplOSX_Window: NSWindow
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation ImGui_ImplOSX_Window
|
|
||||||
|
|
||||||
- (BOOL)canBecomeKeyWindow
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
static void ConvertNSRect(NSRect* r)
|
|
||||||
{
|
|
||||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
|
||||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
|
||||||
r->origin.y = firstScreenFrame.size.height - r->origin.y - r->size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = IM_NEW(ImGui_ImplOSX_ViewportData)();
|
|
||||||
viewport->PlatformUserData = vd;
|
|
||||||
|
|
||||||
NSScreen* screen = bd->Window.screen;
|
|
||||||
NSRect rect = NSMakeRect(viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y);
|
|
||||||
ConvertNSRect(&rect);
|
|
||||||
|
|
||||||
NSWindowStyleMask styleMask = 0;
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoDecoration)
|
|
||||||
styleMask |= NSWindowStyleMaskBorderless;
|
|
||||||
else
|
|
||||||
styleMask |= NSWindowStyleMaskTitled | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
|
|
||||||
|
|
||||||
NSWindow* window = [[ImGui_ImplOSX_Window alloc] initWithContentRect:rect
|
|
||||||
styleMask:styleMask
|
|
||||||
backing:NSBackingStoreBuffered
|
|
||||||
defer:YES
|
|
||||||
screen:screen];
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_TopMost)
|
|
||||||
[window setLevel:NSFloatingWindowLevel];
|
|
||||||
|
|
||||||
window.title = @"Untitled";
|
|
||||||
window.opaque = YES;
|
|
||||||
|
|
||||||
KeyEventResponder* view = [[KeyEventResponder alloc] initWithFrame:rect];
|
|
||||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && ceil(NSAppKitVersionNumber) < NSAppKitVersionNumber10_15)
|
|
||||||
[view setWantsBestResolutionOpenGLSurface:YES];
|
|
||||||
|
|
||||||
window.contentView = view;
|
|
||||||
|
|
||||||
vd->Window = window;
|
|
||||||
vd->WindowOwned = true;
|
|
||||||
viewport->PlatformRequestResize = false;
|
|
||||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = (__bridge_retained void*)window;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
if (ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
if (window != nil && vd->WindowOwned)
|
|
||||||
{
|
|
||||||
window.contentView = nil;
|
|
||||||
window.contentViewController = nil;
|
|
||||||
[window orderOut:nil];
|
|
||||||
}
|
|
||||||
vd->Window = nil;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = viewport->PlatformHandleRaw = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_ShowWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
|
||||||
[vd->Window orderFront:nil];
|
|
||||||
else
|
|
||||||
[vd->Window makeKeyAndOrderFront:nil];
|
|
||||||
|
|
||||||
[vd->Window setIsVisible:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplOSX_GetWindowPos(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
NSRect frame = window.frame;
|
|
||||||
NSRect contentRect = window.contentLayoutRect;
|
|
||||||
if (window.styleMask & NSWindowStyleMaskFullSizeContentView) // No title bar windows should be considered.
|
|
||||||
contentRect = frame;
|
|
||||||
|
|
||||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
|
||||||
return ImVec2(frame.origin.x, firstScreenFrame.size.height - frame.origin.y - contentRect.size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
NSSize size = window.frame.size;
|
|
||||||
|
|
||||||
NSRect r = NSMakeRect(pos.x, pos.y, size.width, size.height);
|
|
||||||
ConvertNSRect(&r);
|
|
||||||
[window setFrameOrigin:r.origin];
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplOSX_GetWindowSize(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
NSSize size = window.contentLayoutRect.size;
|
|
||||||
return ImVec2(size.width, size.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
NSRect rect = window.frame;
|
|
||||||
rect.origin.y -= (size.y - rect.size.height);
|
|
||||||
rect.size.width = size.x;
|
|
||||||
rect.size.height = size.y;
|
|
||||||
[window setFrame:rect display:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplOSX_GetWindowFramebufferScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
NSWindow* window = vd->Window;
|
|
||||||
const float fb_scale = (float)[window backingScaleFactor];
|
|
||||||
return ImVec2(fb_scale, fb_scale);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
[vd->Window makeKeyAndOrderFront:bd->Window];
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplOSX_GetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
return vd->Window.isKeyWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplOSX_GetWindowMinimized(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
return vd->Window.isMiniaturized;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
vd->Window.title = [NSString stringWithUTF8String:title];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
|
||||||
|
|
||||||
vd->Window.alphaValue = alpha;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float ImGui_ImplOSX_GetWindowDpiScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Window != 0);
|
|
||||||
|
|
||||||
return vd->Window.backingScaleFactor;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_UpdateMonitors()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Monitors.resize(0);
|
|
||||||
|
|
||||||
NSRect firstScreenFrame = NSScreen.screens[0].frame;
|
|
||||||
IM_ASSERT(firstScreenFrame.origin.x == 0 && firstScreenFrame.origin.y == 0);
|
|
||||||
|
|
||||||
for (NSScreen* screen in NSScreen.screens)
|
|
||||||
{
|
|
||||||
NSRect frame = screen.frame;
|
|
||||||
NSRect visibleFrame = screen.visibleFrame;
|
|
||||||
ConvertNSRect(&frame);
|
|
||||||
ConvertNSRect(&visibleFrame);
|
|
||||||
|
|
||||||
ImGuiPlatformMonitor imgui_monitor;
|
|
||||||
imgui_monitor.MainPos = ImVec2(frame.origin.x, frame.origin.y);
|
|
||||||
imgui_monitor.MainSize = ImVec2(frame.size.width, frame.size.height);
|
|
||||||
imgui_monitor.WorkPos = ImVec2(visibleFrame.origin.x, visibleFrame.origin.y);
|
|
||||||
imgui_monitor.WorkSize = ImVec2(visibleFrame.size.width, visibleFrame.size.height);
|
|
||||||
imgui_monitor.DpiScale = screen.backingScaleFactor;
|
|
||||||
imgui_monitor.PlatformHandle = (__bridge_retained void*)screen;
|
|
||||||
|
|
||||||
platform_io.Monitors.push_back(imgui_monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
|
||||||
|
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Platform_CreateWindow = ImGui_ImplOSX_CreateWindow;
|
|
||||||
platform_io.Platform_DestroyWindow = ImGui_ImplOSX_DestroyWindow;
|
|
||||||
platform_io.Platform_ShowWindow = ImGui_ImplOSX_ShowWindow;
|
|
||||||
platform_io.Platform_SetWindowPos = ImGui_ImplOSX_SetWindowPos;
|
|
||||||
platform_io.Platform_GetWindowPos = ImGui_ImplOSX_GetWindowPos;
|
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplOSX_SetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplOSX_GetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplOSX_GetWindowFramebufferScale;
|
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplOSX_SetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplOSX_GetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplOSX_GetWindowMinimized;
|
|
||||||
platform_io.Platform_SetWindowTitle = ImGui_ImplOSX_SetWindowTitle;
|
|
||||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplOSX_SetWindowAlpha;
|
|
||||||
platform_io.Platform_GetWindowDpiScale = ImGui_ImplOSX_GetWindowDpiScale; // FIXME-DPI
|
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = IM_NEW(ImGui_ImplOSX_ViewportData)();
|
|
||||||
vd->Window = bd->Window;
|
|
||||||
vd->WindowOwned = false;
|
|
||||||
main_viewport->PlatformUserData = vd;
|
|
||||||
main_viewport->PlatformHandle = (__bridge void*)bd->Window;
|
|
||||||
|
|
||||||
[NSNotificationCenter.defaultCenter addObserver:bd->Observer
|
|
||||||
selector:@selector(displaysDidChange:)
|
|
||||||
name:NSApplicationDidChangeScreenParametersNotification
|
|
||||||
object:nil];
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplOSX_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_GetBackendData();
|
|
||||||
[NSNotificationCenter.defaultCenter removeObserver:bd->Observer
|
|
||||||
name:NSApplicationDidChangeScreenParametersNotification
|
|
||||||
object:nil];
|
|
||||||
bd->Observer = nullptr;
|
|
||||||
bd->Window = nullptr;
|
|
||||||
if (bd->Monitor != nullptr)
|
|
||||||
{
|
|
||||||
[NSEvent removeMonitor:bd->Monitor];
|
|
||||||
bd->Monitor = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplOSX_ViewportData* vd = (ImGui_ImplOSX_ViewportData*)main_viewport->PlatformUserData;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
main_viewport->PlatformUserData = nullptr;
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
759
backends/imgui_impl_qnx.cpp
Normal file
759
backends/imgui_impl_qnx.cpp
Normal file
@ -0,0 +1,759 @@
|
|||||||
|
// dear imgui: Platform Backend for QNX Screen
|
||||||
|
// This needs to be used along with a Renderer Backend (e.g. OpenGL3, Vulkan).
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Keyboard support. Uses io.AddKeyEvent() and native QNX key symbols.
|
||||||
|
// [X] Platform: Mouse support. Handles position, three buttons and horizontal/vertical wheels.
|
||||||
|
// [X] Platform: Touch support. Maps the first active touch contact to the primary mouse button.
|
||||||
|
// [X] Platform: Focus and window-size updates.
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] Platform: Clipboard support.
|
||||||
|
// [ ] Platform: Gamepad support.
|
||||||
|
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors).
|
||||||
|
// [ ] Platform: Multi-viewport support.
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-08-04: Initial QNX Screen backend. (#9492)
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_qnx.h"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/keycodes.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static unsigned int ImGui_ImplQNX_KeySymToUnicode(unsigned int keysym);
|
||||||
|
|
||||||
|
struct ImGui_ImplQNX_Data
|
||||||
|
{
|
||||||
|
screen_context_t Context;
|
||||||
|
screen_window_t Window;
|
||||||
|
uint64_t TimeNanoseconds;
|
||||||
|
int MouseButtons;
|
||||||
|
int ActiveTouchId;
|
||||||
|
bool LeftSuper;
|
||||||
|
bool RightSuper;
|
||||||
|
|
||||||
|
ImGui_ImplQNX_Data()
|
||||||
|
{
|
||||||
|
memset(this, 0, sizeof(*this));
|
||||||
|
ActiveTouchId = -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static ImGui_ImplQNX_Data* ImGui_ImplQNX_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() != nullptr ? (ImGui_ImplQNX_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t ImGui_ImplQNX_GetTimeNanoseconds()
|
||||||
|
{
|
||||||
|
struct timespec timestamp = {};
|
||||||
|
if (clock_gettime(CLOCK_MONOTONIC, ×tamp) != 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (uint64_t)timestamp.tv_sec * UINT64_C(1000000000) + (uint64_t)timestamp.tv_nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ImGuiKey ImGui_ImplQNX_KeyCodeToImGuiKey(int key_code)
|
||||||
|
{
|
||||||
|
switch (key_code)
|
||||||
|
{
|
||||||
|
case KEYCODE_TAB: return ImGuiKey_Tab;
|
||||||
|
case KEYCODE_LEFT: return ImGuiKey_LeftArrow;
|
||||||
|
case KEYCODE_RIGHT: return ImGuiKey_RightArrow;
|
||||||
|
case KEYCODE_UP: return ImGuiKey_UpArrow;
|
||||||
|
case KEYCODE_DOWN: return ImGuiKey_DownArrow;
|
||||||
|
case KEYCODE_PG_UP: return ImGuiKey_PageUp;
|
||||||
|
case KEYCODE_PG_DOWN: return ImGuiKey_PageDown;
|
||||||
|
case KEYCODE_HOME: return ImGuiKey_Home;
|
||||||
|
case KEYCODE_END: return ImGuiKey_End;
|
||||||
|
case KEYCODE_INSERT: return ImGuiKey_Insert;
|
||||||
|
case KEYCODE_DELETE: return ImGuiKey_Delete;
|
||||||
|
case KEYCODE_BACKSPACE: return ImGuiKey_Backspace;
|
||||||
|
case KEYCODE_SPACE: return ImGuiKey_Space;
|
||||||
|
case KEYCODE_RETURN: return ImGuiKey_Enter;
|
||||||
|
case KEYCODE_ESCAPE: return ImGuiKey_Escape;
|
||||||
|
case KEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||||
|
case KEYCODE_COMMA: return ImGuiKey_Comma;
|
||||||
|
case KEYCODE_MINUS: return ImGuiKey_Minus;
|
||||||
|
case KEYCODE_PERIOD: return ImGuiKey_Period;
|
||||||
|
case KEYCODE_SLASH: return ImGuiKey_Slash;
|
||||||
|
case KEYCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||||
|
case KEYCODE_EQUAL: return ImGuiKey_Equal;
|
||||||
|
case KEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||||
|
case KEYCODE_BACK_SLASH: return ImGuiKey_Backslash;
|
||||||
|
case KEYCODE_RIGHT_BRACKET: return ImGuiKey_RightBracket;
|
||||||
|
case KEYCODE_GRAVE: return ImGuiKey_GraveAccent;
|
||||||
|
case KEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||||
|
case KEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;
|
||||||
|
case KEYCODE_NUM_LOCK: return ImGuiKey_NumLock;
|
||||||
|
case KEYCODE_PRINT: return ImGuiKey_PrintScreen;
|
||||||
|
case KEYCODE_PAUSE: return ImGuiKey_Pause;
|
||||||
|
case KEYCODE_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||||
|
case KEYCODE_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||||
|
case KEYCODE_KP_MINUS: return ImGuiKey_KeypadSubtract;
|
||||||
|
case KEYCODE_KP_PLUS: return ImGuiKey_KeypadAdd;
|
||||||
|
case KEYCODE_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||||
|
// QNX reports keypad digits by their navigation key-cap names.
|
||||||
|
case KEYCODE_KP_INSERT: return ImGuiKey_Keypad0;
|
||||||
|
case KEYCODE_KP_END: return ImGuiKey_Keypad1;
|
||||||
|
case KEYCODE_KP_DOWN: return ImGuiKey_Keypad2;
|
||||||
|
case KEYCODE_KP_PG_DOWN: return ImGuiKey_Keypad3;
|
||||||
|
case KEYCODE_KP_LEFT: return ImGuiKey_Keypad4;
|
||||||
|
case KEYCODE_KP_FIVE: return ImGuiKey_Keypad5;
|
||||||
|
case KEYCODE_KP_RIGHT: return ImGuiKey_Keypad6;
|
||||||
|
case KEYCODE_KP_HOME: return ImGuiKey_Keypad7;
|
||||||
|
case KEYCODE_KP_UP: return ImGuiKey_Keypad8;
|
||||||
|
case KEYCODE_KP_PG_UP: return ImGuiKey_Keypad9;
|
||||||
|
case KEYCODE_KP_DELETE: return ImGuiKey_KeypadDecimal;
|
||||||
|
case KEYCODE_LEFT_CTRL: return ImGuiKey_LeftCtrl;
|
||||||
|
case KEYCODE_LEFT_SHIFT: return ImGuiKey_LeftShift;
|
||||||
|
case KEYCODE_LEFT_ALT: return ImGuiKey_LeftAlt;
|
||||||
|
case KEYCODE_RIGHT_CTRL: return ImGuiKey_RightCtrl;
|
||||||
|
case KEYCODE_RIGHT_SHIFT: return ImGuiKey_RightShift;
|
||||||
|
case KEYCODE_RIGHT_ALT: return ImGuiKey_RightAlt;
|
||||||
|
case KEYCODE_LEFT_HYPER: return ImGuiKey_LeftSuper;
|
||||||
|
case KEYCODE_RIGHT_HYPER: return ImGuiKey_RightSuper;
|
||||||
|
case KEYCODE_MENU: return ImGuiKey_Menu;
|
||||||
|
case KEYCODE_ZERO: return ImGuiKey_0;
|
||||||
|
case KEYCODE_ONE: return ImGuiKey_1;
|
||||||
|
case KEYCODE_TWO: return ImGuiKey_2;
|
||||||
|
case KEYCODE_THREE: return ImGuiKey_3;
|
||||||
|
case KEYCODE_FOUR: return ImGuiKey_4;
|
||||||
|
case KEYCODE_FIVE: return ImGuiKey_5;
|
||||||
|
case KEYCODE_SIX: return ImGuiKey_6;
|
||||||
|
case KEYCODE_SEVEN: return ImGuiKey_7;
|
||||||
|
case KEYCODE_EIGHT: return ImGuiKey_8;
|
||||||
|
case KEYCODE_NINE: return ImGuiKey_9;
|
||||||
|
case KEYCODE_A: return ImGuiKey_A;
|
||||||
|
case KEYCODE_B: return ImGuiKey_B;
|
||||||
|
case KEYCODE_C: return ImGuiKey_C;
|
||||||
|
case KEYCODE_D: return ImGuiKey_D;
|
||||||
|
case KEYCODE_E: return ImGuiKey_E;
|
||||||
|
case KEYCODE_F: return ImGuiKey_F;
|
||||||
|
case KEYCODE_G: return ImGuiKey_G;
|
||||||
|
case KEYCODE_H: return ImGuiKey_H;
|
||||||
|
case KEYCODE_I: return ImGuiKey_I;
|
||||||
|
case KEYCODE_J: return ImGuiKey_J;
|
||||||
|
case KEYCODE_K: return ImGuiKey_K;
|
||||||
|
case KEYCODE_L: return ImGuiKey_L;
|
||||||
|
case KEYCODE_M: return ImGuiKey_M;
|
||||||
|
case KEYCODE_N: return ImGuiKey_N;
|
||||||
|
case KEYCODE_O: return ImGuiKey_O;
|
||||||
|
case KEYCODE_P: return ImGuiKey_P;
|
||||||
|
case KEYCODE_Q: return ImGuiKey_Q;
|
||||||
|
case KEYCODE_R: return ImGuiKey_R;
|
||||||
|
case KEYCODE_S: return ImGuiKey_S;
|
||||||
|
case KEYCODE_T: return ImGuiKey_T;
|
||||||
|
case KEYCODE_U: return ImGuiKey_U;
|
||||||
|
case KEYCODE_V: return ImGuiKey_V;
|
||||||
|
case KEYCODE_W: return ImGuiKey_W;
|
||||||
|
case KEYCODE_X: return ImGuiKey_X;
|
||||||
|
case KEYCODE_Y: return ImGuiKey_Y;
|
||||||
|
case KEYCODE_Z: return ImGuiKey_Z;
|
||||||
|
case KEYCODE_F1: return ImGuiKey_F1;
|
||||||
|
case KEYCODE_F2: return ImGuiKey_F2;
|
||||||
|
case KEYCODE_F3: return ImGuiKey_F3;
|
||||||
|
case KEYCODE_F4: return ImGuiKey_F4;
|
||||||
|
case KEYCODE_F5: return ImGuiKey_F5;
|
||||||
|
case KEYCODE_F6: return ImGuiKey_F6;
|
||||||
|
case KEYCODE_F7: return ImGuiKey_F7;
|
||||||
|
case KEYCODE_F8: return ImGuiKey_F8;
|
||||||
|
case KEYCODE_F9: return ImGuiKey_F9;
|
||||||
|
case KEYCODE_F10: return ImGuiKey_F10;
|
||||||
|
case KEYCODE_F11: return ImGuiKey_F11;
|
||||||
|
case KEYCODE_F12: return ImGuiKey_F12;
|
||||||
|
default: return ImGuiKey_None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplQNX_UpdateKeyModifiers(ImGuiIO& io, ImGui_ImplQNX_Data* bd, int modifiers, ImGuiKey key, bool down)
|
||||||
|
{
|
||||||
|
// SCREEN_PROPERTY_MODIFIERS is the authoritative state for Shift/Ctrl/Alt.
|
||||||
|
// Tracking those keys locally loses sticky modifiers and can become stale if
|
||||||
|
// a key transition is consumed elsewhere. qterm uses this same Screen state.
|
||||||
|
if (key == ImGuiKey_LeftSuper)
|
||||||
|
{
|
||||||
|
bd->LeftSuper = down;
|
||||||
|
}
|
||||||
|
else if (key == ImGuiKey_RightSuper)
|
||||||
|
{
|
||||||
|
bd->RightSuper = down;
|
||||||
|
}
|
||||||
|
|
||||||
|
io.AddKeyEvent(ImGuiMod_Ctrl, (modifiers & KEYMOD_CTRL) != 0);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Shift, (modifiers & KEYMOD_SHIFT) != 0);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Alt, (modifiers & KEYMOD_ALT) != 0);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Super, bd->LeftSuper || bd->RightSuper);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplQNX_ClearModifierState(ImGuiIO& io, ImGui_ImplQNX_Data* bd)
|
||||||
|
{
|
||||||
|
bd->LeftSuper = false;
|
||||||
|
bd->RightSuper = false;
|
||||||
|
io.AddKeyEvent(ImGuiMod_Ctrl, false);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Shift, false);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Alt, false);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Super, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplQNX_IsTextCodePoint(unsigned int code_point)
|
||||||
|
{
|
||||||
|
// At this point the QNX keysym has already been converted to Unicode.
|
||||||
|
// Do not reject Unicode private-use characters: a user keymap may emit one.
|
||||||
|
const bool surrogate = code_point >= 0xd800u && code_point <= 0xdfffu;
|
||||||
|
const bool control = code_point < 0x20u || (code_point >= 0x7fu && code_point <= 0x9fu);
|
||||||
|
return code_point <= IM_UNICODE_CODEPOINT_MAX && !surrogate && !control;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplQNX_ProcessKeyboardEvent(ImGui_ImplQNX_Data* bd, screen_event_t event)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
int modifiers = 0;
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &flags) != 0 ||
|
||||||
|
screen_get_event_property_iv(event, SCREEN_PROPERTY_MODIFIERS, &modifiers) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// KEY_CAP is the unmodified key identity used for ImGuiKey events. SYM is
|
||||||
|
// the layout/modifier-translated QNX keysym used for text input.
|
||||||
|
int key_cap = 0;
|
||||||
|
int key_sym = 0;
|
||||||
|
int scan_code = 0;
|
||||||
|
const bool cap_valid = (flags & SCREEN_FLAG_CAP_VALID) != 0;
|
||||||
|
const bool sym_valid = (flags & SCREEN_FLAG_SYM_VALID) != 0;
|
||||||
|
const bool scan_valid = (flags & SCREEN_FLAG_SCAN_VALID) != 0;
|
||||||
|
const bool down = (flags & (SCREEN_FLAG_KEY_DOWN | SCREEN_FLAG_KEY_REPEAT)) != 0;
|
||||||
|
|
||||||
|
if (cap_valid && screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_CAP, &key_cap) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (sym_valid && screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &key_sym) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (scan_valid && screen_get_event_property_iv(event, SCREEN_PROPERTY_SCAN, &scan_code) != 0)
|
||||||
|
{
|
||||||
|
scan_code = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImGuiKey key = cap_valid ? ImGui_ImplQNX_KeyCodeToImGuiKey(key_cap) : ImGuiKey_None;
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Modifier events must precede the ordinary key event in Dear ImGui's queue.
|
||||||
|
// Unlike qterm, we still submit the individual modifier key because ImGui
|
||||||
|
// exposes Left/Right Ctrl, Shift, Alt and Super as named keys.
|
||||||
|
ImGui_ImplQNX_UpdateKeyModifiers(io, bd, modifiers, key, down);
|
||||||
|
|
||||||
|
if (key != ImGuiKey_None)
|
||||||
|
{
|
||||||
|
io.AddKeyEvent(key, down);
|
||||||
|
io.SetKeyEventNativeData(key, key_cap, scan_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool text_added = false;
|
||||||
|
if (down && sym_valid && key_sym >= 0)
|
||||||
|
{
|
||||||
|
const unsigned int keysym = (unsigned int)key_sym;
|
||||||
|
// QNX special/function symbols begin at KEYCODE_PC_KEYS. Printable
|
||||||
|
// symbols below that boundary use X11 keysym encoding. Also accept the
|
||||||
|
// standard directly encoded UCS keysym form (0x01000000 | codepoint).
|
||||||
|
if (keysym < (unsigned int)KEYCODE_PC_KEYS || (keysym & 0xff000000u) == 0x01000000u)
|
||||||
|
{
|
||||||
|
const unsigned int code_point = ImGui_ImplQNX_KeySymToUnicode(keysym);
|
||||||
|
if (ImGui_ImplQNX_IsTextCodePoint(code_point))
|
||||||
|
{
|
||||||
|
io.AddInputCharacter(code_point);
|
||||||
|
text_added = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return key != ImGuiKey_None || text_added || cap_valid || sym_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplQNX_ProcessPointerEvent(ImGui_ImplQNX_Data* bd, screen_event_t event)
|
||||||
|
{
|
||||||
|
int position[2] = {};
|
||||||
|
int buttons = 0;
|
||||||
|
int wheel_vertical = 0;
|
||||||
|
int wheel_horizontal = 0;
|
||||||
|
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, position) != 0 &&
|
||||||
|
screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, position) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_BUTTONS, &buttons) != 0)
|
||||||
|
{
|
||||||
|
buttons = bd->MouseButtons;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddMouseSourceEvent(ImGuiMouseSource_Mouse);
|
||||||
|
io.AddMousePosEvent((float)position[0], (float)position[1]);
|
||||||
|
|
||||||
|
const int changed_buttons = buttons ^ bd->MouseButtons;
|
||||||
|
if ((changed_buttons & SCREEN_LEFT_MOUSE_BUTTON) != 0)
|
||||||
|
{
|
||||||
|
io.AddMouseButtonEvent(0, (buttons & SCREEN_LEFT_MOUSE_BUTTON) != 0);
|
||||||
|
}
|
||||||
|
if ((changed_buttons & SCREEN_RIGHT_MOUSE_BUTTON) != 0)
|
||||||
|
{
|
||||||
|
io.AddMouseButtonEvent(1, (buttons & SCREEN_RIGHT_MOUSE_BUTTON) != 0);
|
||||||
|
}
|
||||||
|
if ((changed_buttons & SCREEN_MIDDLE_MOUSE_BUTTON) != 0)
|
||||||
|
{
|
||||||
|
io.AddMouseButtonEvent(2, (buttons & SCREEN_MIDDLE_MOUSE_BUTTON) != 0);
|
||||||
|
}
|
||||||
|
bd->MouseButtons = buttons;
|
||||||
|
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_WHEEL, &wheel_vertical) != 0)
|
||||||
|
{
|
||||||
|
wheel_vertical = 0;
|
||||||
|
}
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_MOUSE_HORIZONTAL_WHEEL, &wheel_horizontal) != 0)
|
||||||
|
{
|
||||||
|
wheel_horizontal = 0;
|
||||||
|
}
|
||||||
|
if (wheel_vertical != 0 || wheel_horizontal != 0)
|
||||||
|
{
|
||||||
|
// Screen: up/left are negative. Dear ImGui: up/left are positive.
|
||||||
|
io.AddMouseWheelEvent((float)-wheel_horizontal, (float)-wheel_vertical);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ImGui_ImplQNX_ProcessTouchEvent(ImGui_ImplQNX_Data* bd, screen_event_t event, int event_type)
|
||||||
|
{
|
||||||
|
int touch_id = -1;
|
||||||
|
int position[2] = {};
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TOUCH_ID, &touch_id) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool is_release = event_type == SCREEN_EVENT_MTOUCH_RELEASE;
|
||||||
|
if (bd->ActiveTouchId != -1 && touch_id != bd->ActiveTouchId)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddMouseSourceEvent(ImGuiMouseSource_TouchScreen);
|
||||||
|
|
||||||
|
if (!is_release)
|
||||||
|
{
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_SOURCE_POSITION, position) != 0 &&
|
||||||
|
screen_get_event_property_iv(event, SCREEN_PROPERTY_POSITION, position) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
io.AddMousePosEvent((float)position[0], (float)position[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event_type == SCREEN_EVENT_MTOUCH_TOUCH)
|
||||||
|
{
|
||||||
|
bd->ActiveTouchId = touch_id;
|
||||||
|
io.AddMouseButtonEvent(0, true);
|
||||||
|
}
|
||||||
|
else if (is_release)
|
||||||
|
{
|
||||||
|
io.AddMouseButtonEvent(0, false);
|
||||||
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
|
bd->ActiveTouchId = -1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplQNX_ProcessEvent(screen_event_t event)
|
||||||
|
{
|
||||||
|
ImGui_ImplQNX_Data* bd = ImGui_ImplQNX_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplQNX_Init()?");
|
||||||
|
if (bd == nullptr || event == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int event_type = SCREEN_EVENT_NONE;
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_TYPE, &event_type) != 0 || event_type == SCREEN_EVENT_NONE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (event_type)
|
||||||
|
{
|
||||||
|
case SCREEN_EVENT_KEYBOARD:
|
||||||
|
return ImGui_ImplQNX_ProcessKeyboardEvent(bd, event);
|
||||||
|
case SCREEN_EVENT_POINTER:
|
||||||
|
return ImGui_ImplQNX_ProcessPointerEvent(bd, event);
|
||||||
|
case SCREEN_EVENT_MTOUCH_TOUCH:
|
||||||
|
case SCREEN_EVENT_MTOUCH_MOVE:
|
||||||
|
case SCREEN_EVENT_MTOUCH_RELEASE:
|
||||||
|
return ImGui_ImplQNX_ProcessTouchEvent(bd, event, event_type);
|
||||||
|
case SCREEN_EVENT_PROPERTY:
|
||||||
|
{
|
||||||
|
int property = 0;
|
||||||
|
if (screen_get_event_property_iv(event, SCREEN_PROPERTY_NAME, &property) != 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (property == SCREEN_PROPERTY_FOCUS)
|
||||||
|
{
|
||||||
|
int focused = 0;
|
||||||
|
if (screen_get_window_property_iv(bd->Window, SCREEN_PROPERTY_FOCUS, &focused) == 0)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddFocusEvent(focused != 0);
|
||||||
|
if (focused == 0)
|
||||||
|
{
|
||||||
|
ImGui_ImplQNX_ClearModifierState(io, bd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (property == SCREEN_PROPERTY_SIZE || property == SCREEN_PROPERTY_BUFFER_SIZE || property == SCREEN_PROPERTY_VISIBLE)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
case SCREEN_EVENT_CLOSE:
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.AddFocusEvent(false);
|
||||||
|
ImGui_ImplQNX_ClearModifierState(io, bd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplQNX_Init(screen_context_t context, screen_window_t window)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!");
|
||||||
|
IM_ASSERT(context != nullptr && window != nullptr);
|
||||||
|
if (context == nullptr || window == nullptr)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui_ImplQNX_Data* bd = IM_NEW(ImGui_ImplQNX_Data)();
|
||||||
|
io.BackendPlatformUserData = (void*)bd;
|
||||||
|
io.BackendPlatformName = "imgui_impl_qnx";
|
||||||
|
|
||||||
|
bd->Context = context;
|
||||||
|
bd->Window = window;
|
||||||
|
bd->TimeNanoseconds = ImGui_ImplQNX_GetTimeNanoseconds();
|
||||||
|
|
||||||
|
int focused = 0;
|
||||||
|
if (screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focused) == 0)
|
||||||
|
{
|
||||||
|
io.AddFocusEvent(focused != 0);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplQNX_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplQNX_Data* bd = ImGui_ImplQNX_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No platform backend to shutdown, or already shutdown?");
|
||||||
|
if (bd == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
io.BackendPlatformName = nullptr;
|
||||||
|
io.BackendPlatformUserData = nullptr;
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplQNX_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplQNX_Data* bd = ImGui_ImplQNX_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Did you call ImGui_ImplQNX_Init()?");
|
||||||
|
if (bd == nullptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
int size[2] = {};
|
||||||
|
if (screen_get_window_property_iv(bd->Window, SCREEN_PROPERTY_BUFFER_SIZE, size) != 0 ||
|
||||||
|
size[0] <= 0 || size[1] <= 0)
|
||||||
|
{
|
||||||
|
size[0] = 0;
|
||||||
|
size[1] = 0;
|
||||||
|
(void)screen_get_window_property_iv(bd->Window, SCREEN_PROPERTY_SIZE, size);
|
||||||
|
}
|
||||||
|
if (size[0] > 0 && size[1] > 0)
|
||||||
|
{
|
||||||
|
io.DisplaySize = ImVec2((float)size[0], (float)size[1]);
|
||||||
|
io.DisplayFramebufferScale = ImVec2(1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t current_time = ImGui_ImplQNX_GetTimeNanoseconds();
|
||||||
|
if (current_time > bd->TimeNanoseconds && bd->TimeNanoseconds != 0)
|
||||||
|
{
|
||||||
|
io.DeltaTime = (float)((double)(current_time - bd->TimeNanoseconds) / 1000000000.0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
io.DeltaTime = 1.0f / 60.0f;
|
||||||
|
}
|
||||||
|
bd->TimeNanoseconds = current_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generated by Markus Kuhn's public-domain unicode/convmap.pl from X11 keysymdef.h and UnicodeData.
|
||||||
|
// Original source: https://www.cl.cam.ac.uk/~mgk25/ucs/keysym2ucs.c
|
||||||
|
// The table must remain sorted by keysym for the binary search below.
|
||||||
|
struct ImGui_ImplQNX_KeySymPair
|
||||||
|
{
|
||||||
|
uint16_t KeySym;
|
||||||
|
uint16_t Unicode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const ImGui_ImplQNX_KeySymPair ImGui_ImplQNX_KeySymTable[] =
|
||||||
|
{
|
||||||
|
{ 0x01a1, 0x0104 }, { 0x01a2, 0x02d8 }, { 0x01a3, 0x0141 }, { 0x01a5, 0x013d },
|
||||||
|
{ 0x01a6, 0x015a }, { 0x01a9, 0x0160 }, { 0x01aa, 0x015e }, { 0x01ab, 0x0164 },
|
||||||
|
{ 0x01ac, 0x0179 }, { 0x01ae, 0x017d }, { 0x01af, 0x017b }, { 0x01b1, 0x0105 },
|
||||||
|
{ 0x01b2, 0x02db }, { 0x01b3, 0x0142 }, { 0x01b5, 0x013e }, { 0x01b6, 0x015b },
|
||||||
|
{ 0x01b7, 0x02c7 }, { 0x01b9, 0x0161 }, { 0x01ba, 0x015f }, { 0x01bb, 0x0165 },
|
||||||
|
{ 0x01bc, 0x017a }, { 0x01bd, 0x02dd }, { 0x01be, 0x017e }, { 0x01bf, 0x017c },
|
||||||
|
{ 0x01c0, 0x0154 }, { 0x01c3, 0x0102 }, { 0x01c5, 0x0139 }, { 0x01c6, 0x0106 },
|
||||||
|
{ 0x01c8, 0x010c }, { 0x01ca, 0x0118 }, { 0x01cc, 0x011a }, { 0x01cf, 0x010e },
|
||||||
|
{ 0x01d0, 0x0110 }, { 0x01d1, 0x0143 }, { 0x01d2, 0x0147 }, { 0x01d5, 0x0150 },
|
||||||
|
{ 0x01d8, 0x0158 }, { 0x01d9, 0x016e }, { 0x01db, 0x0170 }, { 0x01de, 0x0162 },
|
||||||
|
{ 0x01e0, 0x0155 }, { 0x01e3, 0x0103 }, { 0x01e5, 0x013a }, { 0x01e6, 0x0107 },
|
||||||
|
{ 0x01e8, 0x010d }, { 0x01ea, 0x0119 }, { 0x01ec, 0x011b }, { 0x01ef, 0x010f },
|
||||||
|
{ 0x01f0, 0x0111 }, { 0x01f1, 0x0144 }, { 0x01f2, 0x0148 }, { 0x01f5, 0x0151 },
|
||||||
|
{ 0x01f8, 0x0159 }, { 0x01f9, 0x016f }, { 0x01fb, 0x0171 }, { 0x01fe, 0x0163 },
|
||||||
|
{ 0x01ff, 0x02d9 }, { 0x02a1, 0x0126 }, { 0x02a6, 0x0124 }, { 0x02a9, 0x0130 },
|
||||||
|
{ 0x02ab, 0x011e }, { 0x02ac, 0x0134 }, { 0x02b1, 0x0127 }, { 0x02b6, 0x0125 },
|
||||||
|
{ 0x02b9, 0x0131 }, { 0x02bb, 0x011f }, { 0x02bc, 0x0135 }, { 0x02c5, 0x010a },
|
||||||
|
{ 0x02c6, 0x0108 }, { 0x02d5, 0x0120 }, { 0x02d8, 0x011c }, { 0x02dd, 0x016c },
|
||||||
|
{ 0x02de, 0x015c }, { 0x02e5, 0x010b }, { 0x02e6, 0x0109 }, { 0x02f5, 0x0121 },
|
||||||
|
{ 0x02f8, 0x011d }, { 0x02fd, 0x016d }, { 0x02fe, 0x015d }, { 0x03a2, 0x0138 },
|
||||||
|
{ 0x03a3, 0x0156 }, { 0x03a5, 0x0128 }, { 0x03a6, 0x013b }, { 0x03aa, 0x0112 },
|
||||||
|
{ 0x03ab, 0x0122 }, { 0x03ac, 0x0166 }, { 0x03b3, 0x0157 }, { 0x03b5, 0x0129 },
|
||||||
|
{ 0x03b6, 0x013c }, { 0x03ba, 0x0113 }, { 0x03bb, 0x0123 }, { 0x03bc, 0x0167 },
|
||||||
|
{ 0x03bd, 0x014a }, { 0x03bf, 0x014b }, { 0x03c0, 0x0100 }, { 0x03c7, 0x012e },
|
||||||
|
{ 0x03cc, 0x0116 }, { 0x03cf, 0x012a }, { 0x03d1, 0x0145 }, { 0x03d2, 0x014c },
|
||||||
|
{ 0x03d3, 0x0136 }, { 0x03d9, 0x0172 }, { 0x03dd, 0x0168 }, { 0x03de, 0x016a },
|
||||||
|
{ 0x03e0, 0x0101 }, { 0x03e7, 0x012f }, { 0x03ec, 0x0117 }, { 0x03ef, 0x012b },
|
||||||
|
{ 0x03f1, 0x0146 }, { 0x03f2, 0x014d }, { 0x03f3, 0x0137 }, { 0x03f9, 0x0173 },
|
||||||
|
{ 0x03fd, 0x0169 }, { 0x03fe, 0x016b }, { 0x047e, 0x203e }, { 0x04a1, 0x3002 },
|
||||||
|
{ 0x04a2, 0x300c }, { 0x04a3, 0x300d }, { 0x04a4, 0x3001 }, { 0x04a5, 0x30fb },
|
||||||
|
{ 0x04a6, 0x30f2 }, { 0x04a7, 0x30a1 }, { 0x04a8, 0x30a3 }, { 0x04a9, 0x30a5 },
|
||||||
|
{ 0x04aa, 0x30a7 }, { 0x04ab, 0x30a9 }, { 0x04ac, 0x30e3 }, { 0x04ad, 0x30e5 },
|
||||||
|
{ 0x04ae, 0x30e7 }, { 0x04af, 0x30c3 }, { 0x04b0, 0x30fc }, { 0x04b1, 0x30a2 },
|
||||||
|
{ 0x04b2, 0x30a4 }, { 0x04b3, 0x30a6 }, { 0x04b4, 0x30a8 }, { 0x04b5, 0x30aa },
|
||||||
|
{ 0x04b6, 0x30ab }, { 0x04b7, 0x30ad }, { 0x04b8, 0x30af }, { 0x04b9, 0x30b1 },
|
||||||
|
{ 0x04ba, 0x30b3 }, { 0x04bb, 0x30b5 }, { 0x04bc, 0x30b7 }, { 0x04bd, 0x30b9 },
|
||||||
|
{ 0x04be, 0x30bb }, { 0x04bf, 0x30bd }, { 0x04c0, 0x30bf }, { 0x04c1, 0x30c1 },
|
||||||
|
{ 0x04c2, 0x30c4 }, { 0x04c3, 0x30c6 }, { 0x04c4, 0x30c8 }, { 0x04c5, 0x30ca },
|
||||||
|
{ 0x04c6, 0x30cb }, { 0x04c7, 0x30cc }, { 0x04c8, 0x30cd }, { 0x04c9, 0x30ce },
|
||||||
|
{ 0x04ca, 0x30cf }, { 0x04cb, 0x30d2 }, { 0x04cc, 0x30d5 }, { 0x04cd, 0x30d8 },
|
||||||
|
{ 0x04ce, 0x30db }, { 0x04cf, 0x30de }, { 0x04d0, 0x30df }, { 0x04d1, 0x30e0 },
|
||||||
|
{ 0x04d2, 0x30e1 }, { 0x04d3, 0x30e2 }, { 0x04d4, 0x30e4 }, { 0x04d5, 0x30e6 },
|
||||||
|
{ 0x04d6, 0x30e8 }, { 0x04d7, 0x30e9 }, { 0x04d8, 0x30ea }, { 0x04d9, 0x30eb },
|
||||||
|
{ 0x04da, 0x30ec }, { 0x04db, 0x30ed }, { 0x04dc, 0x30ef }, { 0x04dd, 0x30f3 },
|
||||||
|
{ 0x04de, 0x309b }, { 0x04df, 0x309c }, { 0x05ac, 0x060c }, { 0x05bb, 0x061b },
|
||||||
|
{ 0x05bf, 0x061f }, { 0x05c1, 0x0621 }, { 0x05c2, 0x0622 }, { 0x05c3, 0x0623 },
|
||||||
|
{ 0x05c4, 0x0624 }, { 0x05c5, 0x0625 }, { 0x05c6, 0x0626 }, { 0x05c7, 0x0627 },
|
||||||
|
{ 0x05c8, 0x0628 }, { 0x05c9, 0x0629 }, { 0x05ca, 0x062a }, { 0x05cb, 0x062b },
|
||||||
|
{ 0x05cc, 0x062c }, { 0x05cd, 0x062d }, { 0x05ce, 0x062e }, { 0x05cf, 0x062f },
|
||||||
|
{ 0x05d0, 0x0630 }, { 0x05d1, 0x0631 }, { 0x05d2, 0x0632 }, { 0x05d3, 0x0633 },
|
||||||
|
{ 0x05d4, 0x0634 }, { 0x05d5, 0x0635 }, { 0x05d6, 0x0636 }, { 0x05d7, 0x0637 },
|
||||||
|
{ 0x05d8, 0x0638 }, { 0x05d9, 0x0639 }, { 0x05da, 0x063a }, { 0x05e0, 0x0640 },
|
||||||
|
{ 0x05e1, 0x0641 }, { 0x05e2, 0x0642 }, { 0x05e3, 0x0643 }, { 0x05e4, 0x0644 },
|
||||||
|
{ 0x05e5, 0x0645 }, { 0x05e6, 0x0646 }, { 0x05e7, 0x0647 }, { 0x05e8, 0x0648 },
|
||||||
|
{ 0x05e9, 0x0649 }, { 0x05ea, 0x064a }, { 0x05eb, 0x064b }, { 0x05ec, 0x064c },
|
||||||
|
{ 0x05ed, 0x064d }, { 0x05ee, 0x064e }, { 0x05ef, 0x064f }, { 0x05f0, 0x0650 },
|
||||||
|
{ 0x05f1, 0x0651 }, { 0x05f2, 0x0652 }, { 0x06a1, 0x0452 }, { 0x06a2, 0x0453 },
|
||||||
|
{ 0x06a3, 0x0451 }, { 0x06a4, 0x0454 }, { 0x06a5, 0x0455 }, { 0x06a6, 0x0456 },
|
||||||
|
{ 0x06a7, 0x0457 }, { 0x06a8, 0x0458 }, { 0x06a9, 0x0459 }, { 0x06aa, 0x045a },
|
||||||
|
{ 0x06ab, 0x045b }, { 0x06ac, 0x045c }, { 0x06ae, 0x045e }, { 0x06af, 0x045f },
|
||||||
|
{ 0x06b0, 0x2116 }, { 0x06b1, 0x0402 }, { 0x06b2, 0x0403 }, { 0x06b3, 0x0401 },
|
||||||
|
{ 0x06b4, 0x0404 }, { 0x06b5, 0x0405 }, { 0x06b6, 0x0406 }, { 0x06b7, 0x0407 },
|
||||||
|
{ 0x06b8, 0x0408 }, { 0x06b9, 0x0409 }, { 0x06ba, 0x040a }, { 0x06bb, 0x040b },
|
||||||
|
{ 0x06bc, 0x040c }, { 0x06be, 0x040e }, { 0x06bf, 0x040f }, { 0x06c0, 0x044e },
|
||||||
|
{ 0x06c1, 0x0430 }, { 0x06c2, 0x0431 }, { 0x06c3, 0x0446 }, { 0x06c4, 0x0434 },
|
||||||
|
{ 0x06c5, 0x0435 }, { 0x06c6, 0x0444 }, { 0x06c7, 0x0433 }, { 0x06c8, 0x0445 },
|
||||||
|
{ 0x06c9, 0x0438 }, { 0x06ca, 0x0439 }, { 0x06cb, 0x043a }, { 0x06cc, 0x043b },
|
||||||
|
{ 0x06cd, 0x043c }, { 0x06ce, 0x043d }, { 0x06cf, 0x043e }, { 0x06d0, 0x043f },
|
||||||
|
{ 0x06d1, 0x044f }, { 0x06d2, 0x0440 }, { 0x06d3, 0x0441 }, { 0x06d4, 0x0442 },
|
||||||
|
{ 0x06d5, 0x0443 }, { 0x06d6, 0x0436 }, { 0x06d7, 0x0432 }, { 0x06d8, 0x044c },
|
||||||
|
{ 0x06d9, 0x044b }, { 0x06da, 0x0437 }, { 0x06db, 0x0448 }, { 0x06dc, 0x044d },
|
||||||
|
{ 0x06dd, 0x0449 }, { 0x06de, 0x0447 }, { 0x06df, 0x044a }, { 0x06e0, 0x042e },
|
||||||
|
{ 0x06e1, 0x0410 }, { 0x06e2, 0x0411 }, { 0x06e3, 0x0426 }, { 0x06e4, 0x0414 },
|
||||||
|
{ 0x06e5, 0x0415 }, { 0x06e6, 0x0424 }, { 0x06e7, 0x0413 }, { 0x06e8, 0x0425 },
|
||||||
|
{ 0x06e9, 0x0418 }, { 0x06ea, 0x0419 }, { 0x06eb, 0x041a }, { 0x06ec, 0x041b },
|
||||||
|
{ 0x06ed, 0x041c }, { 0x06ee, 0x041d }, { 0x06ef, 0x041e }, { 0x06f0, 0x041f },
|
||||||
|
{ 0x06f1, 0x042f }, { 0x06f2, 0x0420 }, { 0x06f3, 0x0421 }, { 0x06f4, 0x0422 },
|
||||||
|
{ 0x06f5, 0x0423 }, { 0x06f6, 0x0416 }, { 0x06f7, 0x0412 }, { 0x06f8, 0x042c },
|
||||||
|
{ 0x06f9, 0x042b }, { 0x06fa, 0x0417 }, { 0x06fb, 0x0428 }, { 0x06fc, 0x042d },
|
||||||
|
{ 0x06fd, 0x0429 }, { 0x06fe, 0x0427 }, { 0x06ff, 0x042a }, { 0x07a1, 0x0386 },
|
||||||
|
{ 0x07a2, 0x0388 }, { 0x07a3, 0x0389 }, { 0x07a4, 0x038a }, { 0x07a5, 0x03aa },
|
||||||
|
{ 0x07a7, 0x038c }, { 0x07a8, 0x038e }, { 0x07a9, 0x03ab }, { 0x07ab, 0x038f },
|
||||||
|
{ 0x07ae, 0x0385 }, { 0x07af, 0x2015 }, { 0x07b1, 0x03ac }, { 0x07b2, 0x03ad },
|
||||||
|
{ 0x07b3, 0x03ae }, { 0x07b4, 0x03af }, { 0x07b5, 0x03ca }, { 0x07b6, 0x0390 },
|
||||||
|
{ 0x07b7, 0x03cc }, { 0x07b8, 0x03cd }, { 0x07b9, 0x03cb }, { 0x07ba, 0x03b0 },
|
||||||
|
{ 0x07bb, 0x03ce }, { 0x07c1, 0x0391 }, { 0x07c2, 0x0392 }, { 0x07c3, 0x0393 },
|
||||||
|
{ 0x07c4, 0x0394 }, { 0x07c5, 0x0395 }, { 0x07c6, 0x0396 }, { 0x07c7, 0x0397 },
|
||||||
|
{ 0x07c8, 0x0398 }, { 0x07c9, 0x0399 }, { 0x07ca, 0x039a }, { 0x07cb, 0x039b },
|
||||||
|
{ 0x07cc, 0x039c }, { 0x07cd, 0x039d }, { 0x07ce, 0x039e }, { 0x07cf, 0x039f },
|
||||||
|
{ 0x07d0, 0x03a0 }, { 0x07d1, 0x03a1 }, { 0x07d2, 0x03a3 }, { 0x07d4, 0x03a4 },
|
||||||
|
{ 0x07d5, 0x03a5 }, { 0x07d6, 0x03a6 }, { 0x07d7, 0x03a7 }, { 0x07d8, 0x03a8 },
|
||||||
|
{ 0x07d9, 0x03a9 }, { 0x07e1, 0x03b1 }, { 0x07e2, 0x03b2 }, { 0x07e3, 0x03b3 },
|
||||||
|
{ 0x07e4, 0x03b4 }, { 0x07e5, 0x03b5 }, { 0x07e6, 0x03b6 }, { 0x07e7, 0x03b7 },
|
||||||
|
{ 0x07e8, 0x03b8 }, { 0x07e9, 0x03b9 }, { 0x07ea, 0x03ba }, { 0x07eb, 0x03bb },
|
||||||
|
{ 0x07ec, 0x03bc }, { 0x07ed, 0x03bd }, { 0x07ee, 0x03be }, { 0x07ef, 0x03bf },
|
||||||
|
{ 0x07f0, 0x03c0 }, { 0x07f1, 0x03c1 }, { 0x07f2, 0x03c3 }, { 0x07f3, 0x03c2 },
|
||||||
|
{ 0x07f4, 0x03c4 }, { 0x07f5, 0x03c5 }, { 0x07f6, 0x03c6 }, { 0x07f7, 0x03c7 },
|
||||||
|
{ 0x07f8, 0x03c8 }, { 0x07f9, 0x03c9 }, { 0x08a1, 0x23b7 }, { 0x08a2, 0x250c },
|
||||||
|
{ 0x08a3, 0x2500 }, { 0x08a4, 0x2320 }, { 0x08a5, 0x2321 }, { 0x08a6, 0x2502 },
|
||||||
|
{ 0x08a7, 0x23a1 }, { 0x08a8, 0x23a3 }, { 0x08a9, 0x23a4 }, { 0x08aa, 0x23a6 },
|
||||||
|
{ 0x08ab, 0x239b }, { 0x08ac, 0x239d }, { 0x08ad, 0x239e }, { 0x08ae, 0x23a0 },
|
||||||
|
{ 0x08af, 0x23a8 }, { 0x08b0, 0x23ac }, { 0x08bc, 0x2264 }, { 0x08bd, 0x2260 },
|
||||||
|
{ 0x08be, 0x2265 }, { 0x08bf, 0x222b }, { 0x08c0, 0x2234 }, { 0x08c1, 0x221d },
|
||||||
|
{ 0x08c2, 0x221e }, { 0x08c5, 0x2207 }, { 0x08c8, 0x223c }, { 0x08c9, 0x2243 },
|
||||||
|
{ 0x08cd, 0x21d4 }, { 0x08ce, 0x21d2 }, { 0x08cf, 0x2261 }, { 0x08d6, 0x221a },
|
||||||
|
{ 0x08da, 0x2282 }, { 0x08db, 0x2283 }, { 0x08dc, 0x2229 }, { 0x08dd, 0x222a },
|
||||||
|
{ 0x08de, 0x2227 }, { 0x08df, 0x2228 }, { 0x08ef, 0x2202 }, { 0x08f6, 0x0192 },
|
||||||
|
{ 0x08fb, 0x2190 }, { 0x08fc, 0x2191 }, { 0x08fd, 0x2192 }, { 0x08fe, 0x2193 },
|
||||||
|
{ 0x09e0, 0x25c6 }, { 0x09e1, 0x2592 }, { 0x09e2, 0x2409 }, { 0x09e3, 0x240c },
|
||||||
|
{ 0x09e4, 0x240d }, { 0x09e5, 0x240a }, { 0x09e8, 0x2424 }, { 0x09e9, 0x240b },
|
||||||
|
{ 0x09ea, 0x2518 }, { 0x09eb, 0x2510 }, { 0x09ec, 0x250c }, { 0x09ed, 0x2514 },
|
||||||
|
{ 0x09ee, 0x253c }, { 0x09ef, 0x23ba }, { 0x09f0, 0x23bb }, { 0x09f1, 0x2500 },
|
||||||
|
{ 0x09f2, 0x23bc }, { 0x09f3, 0x23bd }, { 0x09f4, 0x251c }, { 0x09f5, 0x2524 },
|
||||||
|
{ 0x09f6, 0x2534 }, { 0x09f7, 0x252c }, { 0x09f8, 0x2502 }, { 0x0aa1, 0x2003 },
|
||||||
|
{ 0x0aa2, 0x2002 }, { 0x0aa3, 0x2004 }, { 0x0aa4, 0x2005 }, { 0x0aa5, 0x2007 },
|
||||||
|
{ 0x0aa6, 0x2008 }, { 0x0aa7, 0x2009 }, { 0x0aa8, 0x200a }, { 0x0aa9, 0x2014 },
|
||||||
|
{ 0x0aaa, 0x2013 }, { 0x0aae, 0x2026 }, { 0x0aaf, 0x2025 }, { 0x0ab0, 0x2153 },
|
||||||
|
{ 0x0ab1, 0x2154 }, { 0x0ab2, 0x2155 }, { 0x0ab3, 0x2156 }, { 0x0ab4, 0x2157 },
|
||||||
|
{ 0x0ab5, 0x2158 }, { 0x0ab6, 0x2159 }, { 0x0ab7, 0x215a }, { 0x0ab8, 0x2105 },
|
||||||
|
{ 0x0abb, 0x2012 }, { 0x0abc, 0x2329 }, { 0x0abe, 0x232a }, { 0x0ac3, 0x215b },
|
||||||
|
{ 0x0ac4, 0x215c }, { 0x0ac5, 0x215d }, { 0x0ac6, 0x215e }, { 0x0ac9, 0x2122 },
|
||||||
|
{ 0x0aca, 0x2613 }, { 0x0acc, 0x25c1 }, { 0x0acd, 0x25b7 }, { 0x0ace, 0x25cb },
|
||||||
|
{ 0x0acf, 0x25af }, { 0x0ad0, 0x2018 }, { 0x0ad1, 0x2019 }, { 0x0ad2, 0x201c },
|
||||||
|
{ 0x0ad3, 0x201d }, { 0x0ad4, 0x211e }, { 0x0ad6, 0x2032 }, { 0x0ad7, 0x2033 },
|
||||||
|
{ 0x0ad9, 0x271d }, { 0x0adb, 0x25ac }, { 0x0adc, 0x25c0 }, { 0x0add, 0x25b6 },
|
||||||
|
{ 0x0ade, 0x25cf }, { 0x0adf, 0x25ae }, { 0x0ae0, 0x25e6 }, { 0x0ae1, 0x25ab },
|
||||||
|
{ 0x0ae2, 0x25ad }, { 0x0ae3, 0x25b3 }, { 0x0ae4, 0x25bd }, { 0x0ae5, 0x2606 },
|
||||||
|
{ 0x0ae6, 0x2022 }, { 0x0ae7, 0x25aa }, { 0x0ae8, 0x25b2 }, { 0x0ae9, 0x25bc },
|
||||||
|
{ 0x0aea, 0x261c }, { 0x0aeb, 0x261e }, { 0x0aec, 0x2663 }, { 0x0aed, 0x2666 },
|
||||||
|
{ 0x0aee, 0x2665 }, { 0x0af0, 0x2720 }, { 0x0af1, 0x2020 }, { 0x0af2, 0x2021 },
|
||||||
|
{ 0x0af3, 0x2713 }, { 0x0af4, 0x2717 }, { 0x0af5, 0x266f }, { 0x0af6, 0x266d },
|
||||||
|
{ 0x0af7, 0x2642 }, { 0x0af8, 0x2640 }, { 0x0af9, 0x260e }, { 0x0afa, 0x2315 },
|
||||||
|
{ 0x0afb, 0x2117 }, { 0x0afc, 0x2038 }, { 0x0afd, 0x201a }, { 0x0afe, 0x201e },
|
||||||
|
{ 0x0ba3, 0x003c }, { 0x0ba6, 0x003e }, { 0x0ba8, 0x2228 }, { 0x0ba9, 0x2227 },
|
||||||
|
{ 0x0bc0, 0x00af }, { 0x0bc2, 0x22a5 }, { 0x0bc3, 0x2229 }, { 0x0bc4, 0x230a },
|
||||||
|
{ 0x0bc6, 0x005f }, { 0x0bca, 0x2218 }, { 0x0bcc, 0x2395 }, { 0x0bce, 0x22a4 },
|
||||||
|
{ 0x0bcf, 0x25cb }, { 0x0bd3, 0x2308 }, { 0x0bd6, 0x222a }, { 0x0bd8, 0x2283 },
|
||||||
|
{ 0x0bda, 0x2282 }, { 0x0bdc, 0x22a2 }, { 0x0bfc, 0x22a3 }, { 0x0cdf, 0x2017 },
|
||||||
|
{ 0x0ce0, 0x05d0 }, { 0x0ce1, 0x05d1 }, { 0x0ce2, 0x05d2 }, { 0x0ce3, 0x05d3 },
|
||||||
|
{ 0x0ce4, 0x05d4 }, { 0x0ce5, 0x05d5 }, { 0x0ce6, 0x05d6 }, { 0x0ce7, 0x05d7 },
|
||||||
|
{ 0x0ce8, 0x05d8 }, { 0x0ce9, 0x05d9 }, { 0x0cea, 0x05da }, { 0x0ceb, 0x05db },
|
||||||
|
{ 0x0cec, 0x05dc }, { 0x0ced, 0x05dd }, { 0x0cee, 0x05de }, { 0x0cef, 0x05df },
|
||||||
|
{ 0x0cf0, 0x05e0 }, { 0x0cf1, 0x05e1 }, { 0x0cf2, 0x05e2 }, { 0x0cf3, 0x05e3 },
|
||||||
|
{ 0x0cf4, 0x05e4 }, { 0x0cf5, 0x05e5 }, { 0x0cf6, 0x05e6 }, { 0x0cf7, 0x05e7 },
|
||||||
|
{ 0x0cf8, 0x05e8 }, { 0x0cf9, 0x05e9 }, { 0x0cfa, 0x05ea }, { 0x0da1, 0x0e01 },
|
||||||
|
{ 0x0da2, 0x0e02 }, { 0x0da3, 0x0e03 }, { 0x0da4, 0x0e04 }, { 0x0da5, 0x0e05 },
|
||||||
|
{ 0x0da6, 0x0e06 }, { 0x0da7, 0x0e07 }, { 0x0da8, 0x0e08 }, { 0x0da9, 0x0e09 },
|
||||||
|
{ 0x0daa, 0x0e0a }, { 0x0dab, 0x0e0b }, { 0x0dac, 0x0e0c }, { 0x0dad, 0x0e0d },
|
||||||
|
{ 0x0dae, 0x0e0e }, { 0x0daf, 0x0e0f }, { 0x0db0, 0x0e10 }, { 0x0db1, 0x0e11 },
|
||||||
|
{ 0x0db2, 0x0e12 }, { 0x0db3, 0x0e13 }, { 0x0db4, 0x0e14 }, { 0x0db5, 0x0e15 },
|
||||||
|
{ 0x0db6, 0x0e16 }, { 0x0db7, 0x0e17 }, { 0x0db8, 0x0e18 }, { 0x0db9, 0x0e19 },
|
||||||
|
{ 0x0dba, 0x0e1a }, { 0x0dbb, 0x0e1b }, { 0x0dbc, 0x0e1c }, { 0x0dbd, 0x0e1d },
|
||||||
|
{ 0x0dbe, 0x0e1e }, { 0x0dbf, 0x0e1f }, { 0x0dc0, 0x0e20 }, { 0x0dc1, 0x0e21 },
|
||||||
|
{ 0x0dc2, 0x0e22 }, { 0x0dc3, 0x0e23 }, { 0x0dc4, 0x0e24 }, { 0x0dc5, 0x0e25 },
|
||||||
|
{ 0x0dc6, 0x0e26 }, { 0x0dc7, 0x0e27 }, { 0x0dc8, 0x0e28 }, { 0x0dc9, 0x0e29 },
|
||||||
|
{ 0x0dca, 0x0e2a }, { 0x0dcb, 0x0e2b }, { 0x0dcc, 0x0e2c }, { 0x0dcd, 0x0e2d },
|
||||||
|
{ 0x0dce, 0x0e2e }, { 0x0dcf, 0x0e2f }, { 0x0dd0, 0x0e30 }, { 0x0dd1, 0x0e31 },
|
||||||
|
{ 0x0dd2, 0x0e32 }, { 0x0dd3, 0x0e33 }, { 0x0dd4, 0x0e34 }, { 0x0dd5, 0x0e35 },
|
||||||
|
{ 0x0dd6, 0x0e36 }, { 0x0dd7, 0x0e37 }, { 0x0dd8, 0x0e38 }, { 0x0dd9, 0x0e39 },
|
||||||
|
{ 0x0dda, 0x0e3a }, { 0x0ddf, 0x0e3f }, { 0x0de0, 0x0e40 }, { 0x0de1, 0x0e41 },
|
||||||
|
{ 0x0de2, 0x0e42 }, { 0x0de3, 0x0e43 }, { 0x0de4, 0x0e44 }, { 0x0de5, 0x0e45 },
|
||||||
|
{ 0x0de6, 0x0e46 }, { 0x0de7, 0x0e47 }, { 0x0de8, 0x0e48 }, { 0x0de9, 0x0e49 },
|
||||||
|
{ 0x0dea, 0x0e4a }, { 0x0deb, 0x0e4b }, { 0x0dec, 0x0e4c }, { 0x0ded, 0x0e4d },
|
||||||
|
{ 0x0df0, 0x0e50 }, { 0x0df1, 0x0e51 }, { 0x0df2, 0x0e52 }, { 0x0df3, 0x0e53 },
|
||||||
|
{ 0x0df4, 0x0e54 }, { 0x0df5, 0x0e55 }, { 0x0df6, 0x0e56 }, { 0x0df7, 0x0e57 },
|
||||||
|
{ 0x0df8, 0x0e58 }, { 0x0df9, 0x0e59 }, { 0x0ea1, 0x3131 }, { 0x0ea2, 0x3132 },
|
||||||
|
{ 0x0ea3, 0x3133 }, { 0x0ea4, 0x3134 }, { 0x0ea5, 0x3135 }, { 0x0ea6, 0x3136 },
|
||||||
|
{ 0x0ea7, 0x3137 }, { 0x0ea8, 0x3138 }, { 0x0ea9, 0x3139 }, { 0x0eaa, 0x313a },
|
||||||
|
{ 0x0eab, 0x313b }, { 0x0eac, 0x313c }, { 0x0ead, 0x313d }, { 0x0eae, 0x313e },
|
||||||
|
{ 0x0eaf, 0x313f }, { 0x0eb0, 0x3140 }, { 0x0eb1, 0x3141 }, { 0x0eb2, 0x3142 },
|
||||||
|
{ 0x0eb3, 0x3143 }, { 0x0eb4, 0x3144 }, { 0x0eb5, 0x3145 }, { 0x0eb6, 0x3146 },
|
||||||
|
{ 0x0eb7, 0x3147 }, { 0x0eb8, 0x3148 }, { 0x0eb9, 0x3149 }, { 0x0eba, 0x314a },
|
||||||
|
{ 0x0ebb, 0x314b }, { 0x0ebc, 0x314c }, { 0x0ebd, 0x314d }, { 0x0ebe, 0x314e },
|
||||||
|
{ 0x0ebf, 0x314f }, { 0x0ec0, 0x3150 }, { 0x0ec1, 0x3151 }, { 0x0ec2, 0x3152 },
|
||||||
|
{ 0x0ec3, 0x3153 }, { 0x0ec4, 0x3154 }, { 0x0ec5, 0x3155 }, { 0x0ec6, 0x3156 },
|
||||||
|
{ 0x0ec7, 0x3157 }, { 0x0ec8, 0x3158 }, { 0x0ec9, 0x3159 }, { 0x0eca, 0x315a },
|
||||||
|
{ 0x0ecb, 0x315b }, { 0x0ecc, 0x315c }, { 0x0ecd, 0x315d }, { 0x0ece, 0x315e },
|
||||||
|
{ 0x0ecf, 0x315f }, { 0x0ed0, 0x3160 }, { 0x0ed1, 0x3161 }, { 0x0ed2, 0x3162 },
|
||||||
|
{ 0x0ed3, 0x3163 }, { 0x0ed4, 0x11a8 }, { 0x0ed5, 0x11a9 }, { 0x0ed6, 0x11aa },
|
||||||
|
{ 0x0ed7, 0x11ab }, { 0x0ed8, 0x11ac }, { 0x0ed9, 0x11ad }, { 0x0eda, 0x11ae },
|
||||||
|
{ 0x0edb, 0x11af }, { 0x0edc, 0x11b0 }, { 0x0edd, 0x11b1 }, { 0x0ede, 0x11b2 },
|
||||||
|
{ 0x0edf, 0x11b3 }, { 0x0ee0, 0x11b4 }, { 0x0ee1, 0x11b5 }, { 0x0ee2, 0x11b6 },
|
||||||
|
{ 0x0ee3, 0x11b7 }, { 0x0ee4, 0x11b8 }, { 0x0ee5, 0x11b9 }, { 0x0ee6, 0x11ba },
|
||||||
|
{ 0x0ee7, 0x11bb }, { 0x0ee8, 0x11bc }, { 0x0ee9, 0x11bd }, { 0x0eea, 0x11be },
|
||||||
|
{ 0x0eeb, 0x11bf }, { 0x0eec, 0x11c0 }, { 0x0eed, 0x11c1 }, { 0x0eee, 0x11c2 },
|
||||||
|
{ 0x0eef, 0x316d }, { 0x0ef0, 0x3171 }, { 0x0ef1, 0x3178 }, { 0x0ef2, 0x317f },
|
||||||
|
{ 0x0ef3, 0x3181 }, { 0x0ef4, 0x3184 }, { 0x0ef5, 0x3186 }, { 0x0ef6, 0x318d },
|
||||||
|
{ 0x0ef7, 0x318e }, { 0x0ef8, 0x11eb }, { 0x0ef9, 0x11f0 }, { 0x0efa, 0x11f9 },
|
||||||
|
{ 0x0eff, 0x20a9 }, { 0x13a4, 0x20ac }, { 0x13bc, 0x0152 }, { 0x13bd, 0x0153 },
|
||||||
|
{ 0x13be, 0x0178 }, { 0x20ac, 0x20ac },
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int ImGui_ImplQNX_KeySymToUnicode(unsigned int keysym)
|
||||||
|
{
|
||||||
|
// Latin-1 keysyms map directly to Unicode.
|
||||||
|
if ((keysym >= 0x0020u && keysym <= 0x007eu) ||
|
||||||
|
(keysym >= 0x00a0u && keysym <= 0x00ffu))
|
||||||
|
{
|
||||||
|
return keysym;
|
||||||
|
}
|
||||||
|
|
||||||
|
// X11-style directly encoded UCS keysyms use 0x01000000 | codepoint.
|
||||||
|
if ((keysym & 0xff000000u) == 0x01000000u)
|
||||||
|
{
|
||||||
|
const unsigned int codepoint = keysym & 0x00ffffffu;
|
||||||
|
return codepoint <= IM_UNICODE_CODEPOINT_MAX ? codepoint : 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
int min = 0;
|
||||||
|
int max = (int)(sizeof(ImGui_ImplQNX_KeySymTable) / sizeof(ImGui_ImplQNX_KeySymTable[0])) - 1;
|
||||||
|
while (max >= min)
|
||||||
|
{
|
||||||
|
const int mid = min + (max - min) / 2;
|
||||||
|
if (ImGui_ImplQNX_KeySymTable[mid].KeySym < keysym)
|
||||||
|
{
|
||||||
|
min = mid + 1;
|
||||||
|
}
|
||||||
|
else if (ImGui_ImplQNX_KeySymTable[mid].KeySym > keysym)
|
||||||
|
{
|
||||||
|
max = mid - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return ImGui_ImplQNX_KeySymTable[mid].Unicode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
35
backends/imgui_impl_qnx.h
Normal file
35
backends/imgui_impl_qnx.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// dear imgui: Platform Backend for QNX Screen
|
||||||
|
// This needs to be used along with a Renderer Backend (e.g. OpenGL3, Vulkan).
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Keyboard support. Uses io.AddKeyEvent() and native QNX key symbols.
|
||||||
|
// [X] Platform: Mouse support. Handles position, three buttons and horizontal/vertical wheels.
|
||||||
|
// [X] Platform: Touch support. Maps the first active touch contact to the primary mouse button.
|
||||||
|
// [X] Platform: Focus and window-size updates.
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] Platform: Clipboard support.
|
||||||
|
// [ ] Platform: Gamepad support.
|
||||||
|
// [ ] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors).
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
#include <screen/screen.h>
|
||||||
|
|
||||||
|
// The application owns the Screen context, window and event object.
|
||||||
|
// Poll events with screen_get_event() and pass each non-NONE event to ProcessEvent().
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplQNX_Init(screen_context_t context, screen_window_t window);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplQNX_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplQNX_NewFrame();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplQNX_ProcessEvent(screen_event_t event);
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
@ -10,10 +10,6 @@
|
|||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||||
// [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: 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -25,10 +21,9 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-08-06: Fixed querying framebuffer scale when using Metal. (#5592)
|
||||||
// 2026-07-15: Inputs: restore SDL_StartTextInput()/SDL_StopTextInput() in IME handler for on-screen keyboard support on Android/mobile. (#7636, #9474)
|
// 2026-07-15: Inputs: restore SDL_StartTextInput()/SDL_StopTextInput() in IME handler for on-screen keyboard support on Android/mobile. (#7636, #9474)
|
||||||
// 2026-04-16: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return a minimum of 1.0f, as some Linux setup seems to report <1.0f value and this breaks scaling border size. (#9369)
|
// 2026-04-16: Made ImGui_ImplSDL2_GetContentScaleForWindow(), ImGui_ImplSDL2_GetContentScaleForDisplay() helpers return a minimum of 1.0f, as some Linux setup seems to report <1.0f value and this breaks scaling border size. (#9369)
|
||||||
// 2026-03-09: [Docking] Fixed an issue dated 2025/04/09 (1.92 WIP) where a refactor+merge caused ImGuiBackendFlags_HasMouseHoveredViewport to never be set, causing foreign windows to be ignored when deciding of hovered viewport. (#9284)
|
|
||||||
// 2026-02-13: Inputs: systems other than X11 are back to starting mouse capture on mouse down (reverts 2025-02-26 change). Only X11 requires waiting for a drag by default (not ideal, but a better default for X11 users). Added ImGui_ImplSDL2_SetMouseCaptureMode() for X11 debugger users. (#3650, #6410, #9235)
|
// 2026-02-13: Inputs: systems other than X11 are back to starting mouse capture on mouse down (reverts 2025-02-26 change). Only X11 requires waiting for a drag by default (not ideal, but a better default for X11 users). Added ImGui_ImplSDL2_SetMouseCaptureMode() for X11 debugger users. (#3650, #6410, #9235)
|
||||||
// 2026-01-15: Changed GetClipboardText() handler to return nullptr on error aka clipboard contents is not text. Consistent with other backends. (#9168)
|
// 2026-01-15: Changed GetClipboardText() handler to return nullptr on error aka clipboard contents is not text. Consistent with other backends. (#9168)
|
||||||
// 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-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)
|
||||||
@ -36,15 +31,11 @@
|
|||||||
// 2025-09-15: Content Scales are always reported as 1.0 on Wayland. (#8921)
|
// 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-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-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.
|
|
||||||
// 2025-04-09: [Docking] Revert update monitors and work areas information every frame. Only do it on Windows. (#8415, #8558)
|
|
||||||
// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
|
// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
|
||||||
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
||||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||||
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g. Linux debuggers not claiming capture back. (#6410, #3650)
|
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g. Linux debuggers not claiming capture back. (#6410, #3650)
|
||||||
// 2025-02-25: [Docking] Revert to use SDL_GetDisplayBounds() for WorkPos/WorkRect if SDL_GetDisplayUsableBounds() failed.
|
|
||||||
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
||||||
// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415)
|
|
||||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
||||||
// 2025-01-20: Made ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode_Manual) accept an empty array.
|
// 2025-01-20: Made ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode_Manual) accept an empty array.
|
||||||
@ -85,7 +76,7 @@
|
|||||||
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
// 2022-01-10: Inputs: calling new io.AddKeyEvent(), io.AddKeyModsEvent() + io.SetKeyEventNativeData() API (1.87+). Support for full ImGuiKey range.
|
||||||
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
|
// 2021-08-17: Calling io.AddFocusEvent() on SDL_WINDOWEVENT_FOCUS_GAINED/SDL_WINDOWEVENT_FOCUS_LOST.
|
||||||
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
|
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using SDL_GetMouseFocus() + SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, requires SDL 2.0.5+)
|
||||||
// 2021-06:29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
// 2021-06-29: *BREAKING CHANGE* Removed 'SDL_Window* window' parameter to ImGui_ImplSDL2_NewFrame() which was unnecessary.
|
||||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
|
// 2021-03-22: Rework global mouse pos availability check listing supported platforms explicitly, effectively fixing mouse access on Raspberry Pi. (#2837, #3950)
|
||||||
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
|
// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends.
|
||||||
@ -127,7 +118,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
// (the multi-viewports feature requires SDL features supported from SDL 2.0.4+. SDL 2.0.5+ is highly recommended)
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_syswm.h>
|
#include <SDL_syswm.h>
|
||||||
#include <stdio.h> // for snprintf()
|
#include <stdio.h> // for snprintf()
|
||||||
@ -144,18 +134,19 @@
|
|||||||
#else
|
#else
|
||||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||||
#endif
|
#endif
|
||||||
#define SDL_HAS_WINDOW_ALPHA SDL_VERSION_ATLEAST(2,0,5)
|
|
||||||
#define SDL_HAS_ALWAYS_ON_TOP SDL_VERSION_ATLEAST(2,0,5)
|
|
||||||
#define SDL_HAS_USABLE_DISPLAY_BOUNDS SDL_VERSION_ATLEAST(2,0,5)
|
|
||||||
#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4)
|
#define SDL_HAS_PER_MONITOR_DPI SDL_VERSION_ATLEAST(2,0,4)
|
||||||
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
#define SDL_HAS_VULKAN SDL_VERSION_ATLEAST(2,0,6)
|
||||||
#define SDL_HAS_DISPLAY_EVENT SDL_VERSION_ATLEAST(2,0,9)
|
#if defined(__APPLE__)
|
||||||
|
#define SDL_HAS_METAL SDL_VERSION_ATLEAST(2,0,14)
|
||||||
|
#else
|
||||||
|
#define SDL_HAS_METAL 0
|
||||||
|
#endif
|
||||||
#define SDL_HAS_OPEN_URL SDL_VERSION_ATLEAST(2,0,14)
|
#define SDL_HAS_OPEN_URL SDL_VERSION_ATLEAST(2,0,14)
|
||||||
#define SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT SDL_VERSION_ATLEAST(2,0,18)
|
|
||||||
#if SDL_HAS_VULKAN
|
#if SDL_HAS_VULKAN
|
||||||
#include <SDL_vulkan.h>
|
#include <SDL_vulkan.h>
|
||||||
#else
|
#endif
|
||||||
static const Uint32 SDL_WINDOW_VULKAN = 0x10000000;
|
#if SDL_HAS_METAL
|
||||||
|
#include <SDL_metal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL Data
|
// SDL Data
|
||||||
@ -168,8 +159,6 @@ struct ImGui_ImplSDL2_Data
|
|||||||
char* ClipboardTextData;
|
char* ClipboardTextData;
|
||||||
char BackendPlatformName[64];
|
char BackendPlatformName[64];
|
||||||
bool IsWayland;
|
bool IsWayland;
|
||||||
bool IsVulkan;
|
|
||||||
bool WantUpdateMonitors;
|
|
||||||
|
|
||||||
// Mouse handling
|
// Mouse handling
|
||||||
Uint32 MouseWindowID;
|
Uint32 MouseWindowID;
|
||||||
@ -178,7 +167,6 @@ struct ImGui_ImplSDL2_Data
|
|||||||
SDL_Cursor* MouseLastCursor;
|
SDL_Cursor* MouseLastCursor;
|
||||||
int MouseLastLeaveFrame;
|
int MouseLastLeaveFrame;
|
||||||
bool MouseCanUseGlobalState;
|
bool MouseCanUseGlobalState;
|
||||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
|
||||||
ImGui_ImplSDL2_MouseCaptureMode MouseCaptureMode;
|
ImGui_ImplSDL2_MouseCaptureMode MouseCaptureMode;
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
@ -198,11 +186,6 @@ static ImGui_ImplSDL2_Data* ImGui_ImplSDL2_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplSDL2_Data*)ImGui::GetIO().BackendPlatformUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplSDL2_UpdateMonitors();
|
|
||||||
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
|
|
||||||
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
|
static const char* ImGui_ImplSDL2_GetClipboardText(ImGuiContext*)
|
||||||
{
|
{
|
||||||
@ -222,13 +205,13 @@ static void ImGui_ImplSDL2_SetClipboardText(ImGuiContext*, const char* text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
|
// Note: native IME will only display if user calls SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1") _before_ SDL_CreateWindow().
|
||||||
static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport* viewport, ImGuiPlatformImeData* data)
|
static void ImGui_ImplSDL2_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||||
{
|
{
|
||||||
if (data->WantVisible)
|
if (data->WantVisible)
|
||||||
{
|
{
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
r.x = (int)(data->InputPos.x - viewport->Pos.x);
|
r.x = (int)data->InputPos.x;
|
||||||
r.y = (int)(data->InputPos.y - viewport->Pos.y);
|
r.y = (int)data->InputPos.y;
|
||||||
r.w = 1;
|
r.w = 1;
|
||||||
r.h = (int)data->InputLineHeight;
|
r.h = (int)data->InputLineHeight;
|
||||||
SDL_SetTextInputRect(&r);
|
SDL_SetTextInputRect(&r);
|
||||||
@ -406,7 +389,8 @@ static void ImGui_ImplSDL2_UpdateKeyModifiers(SDL_Keymod sdl_key_mods)
|
|||||||
|
|
||||||
static ImGuiViewport* ImGui_ImplSDL2_GetViewportForWindowID(Uint32 window_id)
|
static ImGuiViewport* ImGui_ImplSDL2_GetViewportForWindowID(Uint32 window_id)
|
||||||
{
|
{
|
||||||
return ImGui::FindViewportByPlatformHandle((void*)(intptr_t)window_id);
|
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||||
|
return (window_id == bd->WindowID) ? ImGui::GetMainViewport() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
|
||||||
@ -426,13 +410,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
int window_x, window_y;
|
|
||||||
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
|
|
||||||
mouse_pos.x += window_x;
|
|
||||||
mouse_pos.y += window_y;
|
|
||||||
}
|
|
||||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||||
return true;
|
return true;
|
||||||
@ -484,32 +461,20 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
case SDL_KEYUP:
|
case SDL_KEYUP:
|
||||||
{
|
{
|
||||||
ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID);
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->key.windowID) == nullptr)
|
||||||
if (viewport == nullptr)
|
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("SDL_KEY%s : key=0x%08X ('%s'), scancode=%d ('%s'), mod=%X, windowID=%d, viewport=%08X\n",
|
|
||||||
// (event->type == SDL_KEYDOWN) ? "DOWN" : "UP ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod, event->key.windowID, viewport ? viewport->ID : 0);
|
|
||||||
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
|
ImGui_ImplSDL2_UpdateKeyModifiers((SDL_Keymod)event->key.keysym.mod);
|
||||||
|
//IMGUI_DEBUG_LOG("SDL_KEY_%s : key=%d ('%s'), scancode=%d ('%s'), mod=%X\n",
|
||||||
|
// (event->type == SDL_KEYDOWN) ? "DOWN" : "UP ", event->key.keysym.sym, SDL_GetKeyName(event->key.keysym.sym), event->key.keysym.scancode, SDL_GetScancodeName(event->key.keysym.scancode), event->key.keysym.mod);
|
||||||
ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode);
|
ImGuiKey key = ImGui_ImplSDL2_KeyEventToImGuiKey(event->key.keysym.sym, event->key.keysym.scancode);
|
||||||
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
|
io.AddKeyEvent(key, (event->type == SDL_KEYDOWN));
|
||||||
io.SetKeyEventNativeData(key, (int)event->key.keysym.sym, (int)event->key.keysym.scancode, (int)event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
io.SetKeyEventNativeData(key, (int)event->key.keysym.sym, (int)event->key.keysym.scancode, (int)event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#if SDL_HAS_DISPLAY_EVENT
|
|
||||||
case SDL_DISPLAYEVENT:
|
|
||||||
{
|
|
||||||
// 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION,
|
|
||||||
// so change of DPI/Scaling are not reflected in this event. (SDL3 has it)
|
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
{
|
{
|
||||||
ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID);
|
if (ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||||
if (viewport == NULL)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
|
// - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right.
|
||||||
// - However we won't get a correct LEAVE event for a captured window.
|
// - However we won't get a correct LEAVE event for a captured window.
|
||||||
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
|
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
|
||||||
@ -523,18 +488,10 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
|||||||
}
|
}
|
||||||
if (window_event == SDL_WINDOWEVENT_LEAVE)
|
if (window_event == SDL_WINDOWEVENT_LEAVE)
|
||||||
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
|
bd->MouseLastLeaveFrame = ImGui::GetFrameCount() + 1;
|
||||||
//if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_GAINED: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
|
|
||||||
//if (window_event == SDL_WINDOWEVENT_FOCUS_LOST) { IMGUI_DEBUG_LOG("SDL_WINDOWEVENT_FOCUS_LOST: windowId %d, viewport: %08X\n", event->window.windowID, viewport ? viewport->ID : 0); }
|
|
||||||
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
|
||||||
io.AddFocusEvent(true);
|
io.AddFocusEvent(true);
|
||||||
if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
|
||||||
io.AddFocusEvent(false);
|
io.AddFocusEvent(false);
|
||||||
if (window_event == SDL_WINDOWEVENT_CLOSE)
|
|
||||||
viewport->PlatformRequestClose = true;
|
|
||||||
if (window_event == SDL_WINDOWEVENT_MOVED)
|
|
||||||
viewport->PlatformRequestMove = true;
|
|
||||||
if (window_event == SDL_WINDOWEVENT_RESIZED)
|
|
||||||
viewport->PlatformRequestResize = true;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case SDL_CONTROLLERDEVICEADDED:
|
case SDL_CONTROLLERDEVICEADDED:
|
||||||
@ -575,7 +532,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
io.BackendPlatformName = bd->BackendPlatformName;
|
io.BackendPlatformName = bd->BackendPlatformName;
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||||
// (ImGuiBackendFlags_PlatformHasViewports may be set just below)
|
|
||||||
|
|
||||||
bd->Window = window;
|
bd->Window = window;
|
||||||
bd->WindowID = SDL_GetWindowID(window);
|
bd->WindowID = SDL_GetWindowID(window);
|
||||||
@ -595,16 +551,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
bd->MouseCaptureMode = (strcmp(item, "x11") == 0) ? ImGui_ImplSDL2_MouseCaptureMode_EnabledAfterDrag : ImGui_ImplSDL2_MouseCaptureMode_Enabled;
|
bd->MouseCaptureMode = (strcmp(item, "x11") == 0) ? ImGui_ImplSDL2_MouseCaptureMode_EnabledAfterDrag : ImGui_ImplSDL2_MouseCaptureMode_Enabled;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (bd->MouseCanUseGlobalState)
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
|
|
||||||
|
|
||||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
|
||||||
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
|
||||||
#ifndef __APPLE__
|
|
||||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
|
||||||
#else
|
|
||||||
bd->MouseCanReportHoveredViewport = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
|
||||||
@ -617,9 +563,6 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url) == 0; };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Update monitor a first time during init
|
|
||||||
ImGui_ImplSDL2_UpdateMonitors();
|
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
|
bd->GamepadMode = ImGui_ImplSDL2_GamepadMode_AutoFirst;
|
||||||
bd->WantUpdateGamepadsList = true;
|
bd->WantUpdateGamepadsList = true;
|
||||||
@ -674,11 +617,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
(void)sdl_gl_context; // Unused in 'master' branch.
|
||||||
// We left the call to ImGui_ImplSDL2_InitMultiViewportSupport() outside of #ifdef to avoid unused-function warnings.
|
|
||||||
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
|
|
||||||
ImGui_ImplSDL2_InitMultiViewportSupport(window, sdl_gl_context);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,11 +631,7 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
|
|||||||
#if !SDL_HAS_VULKAN
|
#if !SDL_HAS_VULKAN
|
||||||
IM_ASSERT(0 && "Unsupported");
|
IM_ASSERT(0 && "Unsupported");
|
||||||
#endif
|
#endif
|
||||||
if (!ImGui_ImplSDL2_Init(window, nullptr, nullptr))
|
return ImGui_ImplSDL2_Init(window, nullptr, nullptr);
|
||||||
return false;
|
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
|
||||||
bd->IsVulkan = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
|
||||||
@ -731,7 +666,6 @@ void ImGui_ImplSDL2_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplSDL2_ShutdownMultiViewportSupport();
|
|
||||||
if (bd->ClipboardTextData)
|
if (bd->ClipboardTextData)
|
||||||
SDL_free(bd->ClipboardTextData);
|
SDL_free(bd->ClipboardTextData);
|
||||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||||
@ -740,7 +674,7 @@ void ImGui_ImplSDL2_Shutdown()
|
|||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport);
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
platform_io.ClearPlatformHandlers();
|
platform_io.ClearPlatformHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -753,7 +687,6 @@ void ImGui_ImplSDL2_SetMouseCaptureMode(ImGui_ImplSDL2_MouseCaptureMode mode)
|
|||||||
bd->MouseCaptureMode = mode;
|
bd->MouseCaptureMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// This code is rather messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
|
|
||||||
static void ImGui_ImplSDL2_UpdateMouseData()
|
static void ImGui_ImplSDL2_UpdateMouseData()
|
||||||
{
|
{
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
||||||
@ -777,24 +710,16 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||||
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL2_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
|
const bool is_app_focused = (bd->Window == focused_window);
|
||||||
#else
|
#else
|
||||||
SDL_Window* focused_window = bd->Window;
|
SDL_Window* focused_window = bd->Window;
|
||||||
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (is_app_focused)
|
if (is_app_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
{
|
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
SDL_WarpMouseGlobal((int)io.MousePos.x, (int)io.MousePos.y);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Optional) Fallback to provide unclamped mouse position when focused but not hovered (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.
|
// 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.
|
||||||
@ -803,34 +728,15 @@ static void ImGui_ImplSDL2_UpdateMouseData()
|
|||||||
if (hovered_window == nullptr && bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
if (hovered_window == nullptr && 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)
|
// 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;
|
int mouse_x, mouse_y;
|
||||||
int window_x, window_y;
|
int window_x, window_y;
|
||||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||||
{
|
mouse_x -= window_x;
|
||||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
mouse_y -= window_y;
|
||||||
mouse_x -= window_x;
|
|
||||||
mouse_y -= window_y;
|
|
||||||
}
|
|
||||||
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
io.AddMousePosEvent((float)mouse_x, (float)mouse_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
|
||||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
|
||||||
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
|
||||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
|
||||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
|
||||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
|
||||||
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
|
||||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
|
||||||
{
|
|
||||||
ImGuiID mouse_viewport_id = 0;
|
|
||||||
if (ImGuiViewport* mouse_viewport = ImGui_ImplSDL2_GetViewportForWindowID(bd->MouseWindowID))
|
|
||||||
mouse_viewport_id = mouse_viewport->ID;
|
|
||||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_UpdateMouseCursor()
|
static void ImGui_ImplSDL2_UpdateMouseCursor()
|
||||||
@ -990,38 +896,6 @@ static void ImGui_ImplSDL2_UpdateGamepads()
|
|||||||
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
ImGui_ImplSDL2_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_CONTROLLER_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has).
|
|
||||||
static void ImGui_ImplSDL2_UpdateMonitors()
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Monitors.resize(0);
|
|
||||||
bd->WantUpdateMonitors = false;
|
|
||||||
int display_count = SDL_GetNumVideoDisplays();
|
|
||||||
for (int n = 0; n < display_count; n++)
|
|
||||||
{
|
|
||||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
|
||||||
ImGuiPlatformMonitor monitor;
|
|
||||||
SDL_Rect r;
|
|
||||||
SDL_GetDisplayBounds(n, &r);
|
|
||||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
|
||||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
|
||||||
#if SDL_HAS_USABLE_DISPLAY_BOUNDS
|
|
||||||
if (SDL_GetDisplayUsableBounds(n, &r) == 0 && r.w > 0 && r.h > 0)
|
|
||||||
{
|
|
||||||
monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
|
||||||
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
float dpi_scale = ImGui_ImplSDL2_GetContentScaleForDisplay(n);
|
|
||||||
if (dpi_scale <= 0.0f)
|
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
|
||||||
monitor.DpiScale = dpi_scale;
|
|
||||||
monitor.PlatformHandle = (void*)(intptr_t)n;
|
|
||||||
platform_io.Monitors.push_back(monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window, SDL_Renderer* renderer, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window, SDL_Renderer* renderer, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
@ -1034,6 +908,10 @@ static void ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(SDL_Window* window,
|
|||||||
#if SDL_HAS_VULKAN
|
#if SDL_HAS_VULKAN
|
||||||
else if (SDL_GetWindowFlags(window) & SDL_WINDOW_VULKAN)
|
else if (SDL_GetWindowFlags(window) & SDL_WINDOW_VULKAN)
|
||||||
SDL_Vulkan_GetDrawableSize(window, &display_w, &display_h);
|
SDL_Vulkan_GetDrawableSize(window, &display_w, &display_h);
|
||||||
|
#endif
|
||||||
|
#if SDL_HAS_METAL
|
||||||
|
else if (SDL_GetWindowFlags(window) & SDL_WINDOW_METAL)
|
||||||
|
SDL_Metal_GetDrawableSize(window, &display_w, &display_h);
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
|
SDL_GL_GetDrawableSize(window, &display_w, &display_h);
|
||||||
@ -1052,13 +930,6 @@ void ImGui_ImplSDL2_NewFrame()
|
|||||||
// Setup main viewport size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(bd->Window, bd->Renderer, &io.DisplaySize, &io.DisplayFramebufferScale);
|
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(bd->Window, bd->Renderer, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
|
|
||||||
// Update monitors
|
|
||||||
#ifdef WIN32
|
|
||||||
bd->WantUpdateMonitors = true; // Keep polling under Windows to handle changes of work area when resizing task-bar (#8415)
|
|
||||||
#endif
|
|
||||||
if (bd->WantUpdateMonitors)
|
|
||||||
ImGui_ImplSDL2_UpdateMonitors();
|
|
||||||
|
|
||||||
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
// Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution)
|
||||||
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
||||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||||
@ -1075,13 +946,6 @@ void ImGui_ImplSDL2_NewFrame()
|
|||||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
|
|
||||||
// Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rigorous, but testing for payload reduces noise and potential side-effects.
|
|
||||||
if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
|
|
||||||
else
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_UpdateMouseData();
|
ImGui_ImplSDL2_UpdateMouseData();
|
||||||
ImGui_ImplSDL2_UpdateMouseCursor();
|
ImGui_ImplSDL2_UpdateMouseCursor();
|
||||||
|
|
||||||
@ -1089,266 +953,6 @@ void ImGui_ImplSDL2_NewFrame()
|
|||||||
ImGui_ImplSDL2_UpdateGamepads();
|
ImGui_ImplSDL2_UpdateGamepads();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplSDL2_ViewportData
|
|
||||||
{
|
|
||||||
SDL_Window* Window;
|
|
||||||
Uint32 WindowID; // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
|
|
||||||
bool WindowOwned;
|
|
||||||
SDL_GLContext GLContext;
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_ViewportData() { Window = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
|
||||||
~ImGui_ImplSDL2_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData();
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
|
||||||
viewport->PlatformUserData = vd;
|
|
||||||
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplSDL2_ViewportData* main_viewport_data = (ImGui_ImplSDL2_ViewportData*)main_viewport->PlatformUserData;
|
|
||||||
|
|
||||||
// Share GL resources with main context
|
|
||||||
bool use_opengl = (main_viewport_data->GLContext != nullptr);
|
|
||||||
SDL_GLContext backup_context = nullptr;
|
|
||||||
if (use_opengl)
|
|
||||||
{
|
|
||||||
backup_context = SDL_GL_GetCurrentContext();
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
|
||||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint32 sdl_flags = 0;
|
|
||||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->IsVulkan ? SDL_WINDOW_VULKAN : 0);
|
|
||||||
sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_ALLOW_HIGHDPI;
|
|
||||||
sdl_flags |= SDL_WINDOW_HIDDEN;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
// See SDL hack in ImGui_ImplSDL2_ShowWindow().
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_SKIP_TASKBAR : 0;
|
|
||||||
#endif
|
|
||||||
#if SDL_HAS_ALWAYS_ON_TOP
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
|
|
||||||
#endif
|
|
||||||
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Pos.x, (int)viewport->Pos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
|
||||||
vd->WindowOwned = true;
|
|
||||||
if (use_opengl)
|
|
||||||
{
|
|
||||||
vd->GLContext = SDL_GL_CreateContext(vd->Window);
|
|
||||||
SDL_GL_SetSwapInterval(0);
|
|
||||||
}
|
|
||||||
if (use_opengl && backup_context)
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
|
||||||
|
|
||||||
viewport->PlatformHandle = (void*)(intptr_t)SDL_GetWindowID(vd->Window);
|
|
||||||
viewport->PlatformHandleRaw = nullptr;
|
|
||||||
SDL_SysWMinfo info;
|
|
||||||
SDL_VERSION(&info.version);
|
|
||||||
if (SDL_GetWindowWMInfo(vd->Window, &info))
|
|
||||||
{
|
|
||||||
#if defined(SDL_VIDEO_DRIVER_WINDOWS)
|
|
||||||
viewport->PlatformHandleRaw = info.info.win.window;
|
|
||||||
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
|
|
||||||
viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
if (ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
if (vd->GLContext && vd->WindowOwned)
|
|
||||||
SDL_GL_DeleteContext(vd->GLContext);
|
|
||||||
if (vd->Window && vd->WindowOwned)
|
|
||||||
SDL_DestroyWindow(vd->Window);
|
|
||||||
vd->GLContext = nullptr;
|
|
||||||
vd->Window = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_ShowWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)))
|
|
||||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
||||||
|
|
||||||
// SDL hack: Hide icon from task bar
|
|
||||||
// Note: SDL 2.0.6+ has a SDL_WINDOW_SKIP_TASKBAR flag which is supported under Windows but the way it create the window breaks our seamless transition.
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon)
|
|
||||||
{
|
|
||||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
||||||
ex_style &= ~WS_EX_APPWINDOW;
|
|
||||||
ex_style |= WS_EX_TOOLWINDOW;
|
|
||||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SDL_HAS_SHOW_WINDOW_ACTIVATION_HINT
|
|
||||||
SDL_SetHint(SDL_HINT_WINDOW_NO_ACTIVATION_WHEN_SHOWN, (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "1" : "0");
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
// SDL hack: SDL always activate/focus windows :/
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
|
||||||
{
|
|
||||||
::ShowWindow(hwnd, SW_SHOWNA);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
SDL_ShowWindow(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL2_GetWindowPos(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int x = 0, y = 0;
|
|
||||||
SDL_GetWindowPosition(vd->Window, &x, &y);
|
|
||||||
return ImVec2((float)x, (float)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL2_GetWindowSize(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int w = 0, h = 0;
|
|
||||||
SDL_GetWindowSize(vd->Window, &w, &h);
|
|
||||||
return ImVec2((float)w, (float)h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL2_GetWindowFramebufferScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
// FIXME: SDL_Renderer does not support multi-viewport.
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
ImVec2 framebuffer_scale;
|
|
||||||
ImGui_ImplSDL2_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, nullptr, &framebuffer_scale);
|
|
||||||
return framebuffer_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowTitle(vd->Window, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SDL_HAS_WINDOW_ALPHA
|
|
||||||
static void ImGui_ImplSDL2_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowOpacity(vd->Window, alpha);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_SetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_RaiseWindow(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (vd->GLContext)
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (vd->GLContext)
|
|
||||||
{
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
|
||||||
SDL_GL_SwapWindow(vd->Window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
|
||||||
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
|
|
||||||
#if SDL_HAS_VULKAN
|
|
||||||
#include <SDL_vulkan.h>
|
|
||||||
static int ImGui_ImplSDL2_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = (ImGui_ImplSDL2_ViewportData*)viewport->PlatformUserData;
|
|
||||||
(void)vk_allocator;
|
|
||||||
SDL_bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (VkSurfaceKHR*)out_vk_surface);
|
|
||||||
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
|
||||||
}
|
|
||||||
#endif // SDL_HAS_VULKAN
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
|
|
||||||
{
|
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Platform_CreateWindow = ImGui_ImplSDL2_CreateWindow;
|
|
||||||
platform_io.Platform_DestroyWindow = ImGui_ImplSDL2_DestroyWindow;
|
|
||||||
platform_io.Platform_ShowWindow = ImGui_ImplSDL2_ShowWindow;
|
|
||||||
platform_io.Platform_SetWindowPos = ImGui_ImplSDL2_SetWindowPos;
|
|
||||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL2_GetWindowPos;
|
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL2_SetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL2_GetWindowFramebufferScale;
|
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized;
|
|
||||||
platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle;
|
|
||||||
platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow;
|
|
||||||
platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers;
|
|
||||||
#if SDL_HAS_WINDOW_ALPHA
|
|
||||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL2_SetWindowAlpha;
|
|
||||||
#endif
|
|
||||||
#if SDL_HAS_VULKAN
|
|
||||||
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
|
||||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplSDL2_ViewportData* vd = IM_NEW(ImGui_ImplSDL2_ViewportData)();
|
|
||||||
vd->Window = window;
|
|
||||||
vd->WindowID = SDL_GetWindowID(window);
|
|
||||||
vd->WindowOwned = false;
|
|
||||||
vd->GLContext = sdl_gl_context;
|
|
||||||
main_viewport->PlatformUserData = vd;
|
|
||||||
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL2_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|||||||
@ -9,10 +9,6 @@
|
|||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
// [X] Platform: Basic IME support. App needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||||
// [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: 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.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -8,10 +8,7 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
// [X] Platform: IME support.
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
|
||||||
// [x] Platform: IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -23,9 +20,6 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2026-03-25: [Docking] Use SDL_HAS_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED (SDL 3.4.0+) when available to avoid refreshing monitor work area every frame on Windows. (#8415)
|
|
||||||
// 2026-03-09: [Docking] Fixed an issue dated 2025/04/09 (1.92 WIP) where a refactor+merge caused ImGuiBackendFlags_HasMouseHoveredViewport to never be set, causing foreign windows to be ignored when deciding of hovered viewport. (#9284)
|
|
||||||
// 2026-02-13: Inputs: systems other than X11 are back to starting mouse capture on mouse down (reverts 2025-02-26 change). Only X11 requires waiting for a drag by default (not ideal, but a better default for X11 users). Added ImGui_ImplSDL3_SetMouseCaptureMode() for X11 debugger users. (#3650, #6410, #9235)
|
// 2026-02-13: Inputs: systems other than X11 are back to starting mouse capture on mouse down (reverts 2025-02-26 change). Only X11 requires waiting for a drag by default (not ideal, but a better default for X11 users). Added ImGui_ImplSDL3_SetMouseCaptureMode() for X11 debugger users. (#3650, #6410, #9235)
|
||||||
// 2026-01-15: Changed GetClipboardText() handler to return nullptr on error aka clipboard contents is not text. Consistent with other backends. (#9168)
|
// 2026-01-15: Changed GetClipboardText() handler to return nullptr on error aka clipboard contents is not text. Consistent with other backends. (#9168)
|
||||||
// 2025-11-05: Fixed an issue with missing characters events when an already active text field changes viewports. (#9054)
|
// 2025-11-05: Fixed an issue with missing characters events when an already active text field changes viewports. (#9054)
|
||||||
@ -34,23 +28,17 @@
|
|||||||
// 2025-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
// 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-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-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.
|
|
||||||
// 2025-04-09: [Docking] Revert update monitors and work areas information every frame. Only do it on Windows. (#8415, #8558)
|
|
||||||
// 2025-04-22: IME: honor ImGuiPlatformImeData->WantTextInput as an alternative way to call SDL_StartTextInput(), without IME being necessarily visible.
|
// 2025-04-22: IME: honor ImGuiPlatformImeData->WantTextInput as an alternative way to call SDL_StartTextInput(), without IME being necessarily visible.
|
||||||
// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
|
// 2025-04-09: Don't attempt to call SDL_CaptureMouse() on drivers where we don't call SDL_GetGlobalMouseState(). (#8561)
|
||||||
// 2025-03-30: Update for SDL3 api changes: Revert SDL_GetClipboardText() memory ownership change. (#8530, #7801)
|
// 2025-03-30: Update for SDL3 api changes: Revert SDL_GetClipboardText() memory ownership change. (#8530, #7801)
|
||||||
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
// 2025-03-21: Fill gamepad inputs and set ImGuiBackendFlags_HasGamepad regardless of ImGuiConfigFlags_NavEnableGamepad being set.
|
||||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||||
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g. Linux debuggers not claiming capture back. (#6410, #3650)
|
// 2025-02-26: Only start SDL_CaptureMouse() when mouse is being dragged, to mitigate issues with e.g. Linux debuggers not claiming capture back. (#6410, #3650)
|
||||||
// 2025-02-25: [Docking] Revert to use SDL_GetDisplayBounds() for WorkPos/WorkRect if SDL_GetDisplayUsableBounds() failed.
|
|
||||||
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
// 2025-02-24: Avoid calling SDL_GetGlobalMouseState() when mouse is in relative mode.
|
||||||
// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415)
|
|
||||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
// 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler.
|
||||||
// 2025-01-20: Made ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode_Manual) accept an empty array.
|
// 2025-01-20: Made ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode_Manual) accept an empty array.
|
||||||
// 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten.
|
// 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten.
|
||||||
// 2024-09-11: (Docking) Added support for viewport->ParentViewportId field to support parenting at OS level. (#7973)
|
|
||||||
// 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807)
|
// 2024-09-03: Update for SDL3 api changes: SDL_GetGamepads() memory ownership revert. (#7918, #7898, #7807)
|
||||||
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
// 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO:
|
||||||
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
// - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn
|
||||||
@ -106,7 +94,6 @@
|
|||||||
#else
|
#else
|
||||||
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
#define SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE 0
|
||||||
#endif
|
#endif
|
||||||
#define SDL_HAS_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED SDL_VERSION_ATLEAST(3,4,0)
|
|
||||||
|
|
||||||
// FIXME-LEGACY: remove when SDL 3.1.3 preview is released.
|
// FIXME-LEGACY: remove when SDL 3.1.3 preview is released.
|
||||||
#ifndef SDLK_APOSTROPHE
|
#ifndef SDLK_APOSTROPHE
|
||||||
@ -126,8 +113,6 @@ struct ImGui_ImplSDL3_Data
|
|||||||
char* ClipboardTextData;
|
char* ClipboardTextData;
|
||||||
char BackendPlatformName[64];
|
char BackendPlatformName[64];
|
||||||
bool IsWayland;
|
bool IsWayland;
|
||||||
bool IsVulkan;
|
|
||||||
bool WantUpdateMonitors;
|
|
||||||
|
|
||||||
// IME handling
|
// IME handling
|
||||||
SDL_Window* ImeWindow;
|
SDL_Window* ImeWindow;
|
||||||
@ -141,13 +126,12 @@ struct ImGui_ImplSDL3_Data
|
|||||||
SDL_Cursor* MouseLastCursor;
|
SDL_Cursor* MouseLastCursor;
|
||||||
int MousePendingLeaveFrame;
|
int MousePendingLeaveFrame;
|
||||||
bool MouseCanUseGlobalState;
|
bool MouseCanUseGlobalState;
|
||||||
bool MouseCanReportHoveredViewport; // This is hard to use/unreliable on SDL so we'll set ImGuiBackendFlags_HasMouseHoveredViewport dynamically based on state.
|
|
||||||
ImGui_ImplSDL3_MouseCaptureMode MouseCaptureMode;
|
ImGui_ImplSDL3_MouseCaptureMode MouseCaptureMode;
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
ImVector<SDL_Gamepad*> Gamepads;
|
ImVector<SDL_Gamepad*> Gamepads;
|
||||||
ImGui_ImplSDL3_GamepadMode GamepadMode;
|
ImGui_ImplSDL3_GamepadMode GamepadMode;
|
||||||
bool WantUpdateGamepadsList;
|
bool WantUpdateGamepadsList;
|
||||||
|
|
||||||
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplSDL3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@ -163,9 +147,6 @@ static ImGui_ImplSDL3_Data* ImGui_ImplSDL3_GetBackendData()
|
|||||||
|
|
||||||
// Forward Declarations
|
// Forward Declarations
|
||||||
static void ImGui_ImplSDL3_UpdateIme();
|
static void ImGui_ImplSDL3_UpdateIme();
|
||||||
static void ImGui_ImplSDL3_UpdateMonitors();
|
|
||||||
static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context);
|
|
||||||
static void ImGui_ImplSDL3_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
static const char* ImGui_ImplSDL3_GetClipboardText(ImGuiContext*)
|
||||||
@ -187,7 +168,8 @@ static void ImGui_ImplSDL3_SetClipboardText(ImGuiContext*, const char* text)
|
|||||||
|
|
||||||
static ImGuiViewport* ImGui_ImplSDL3_GetViewportForWindowID(SDL_WindowID window_id)
|
static ImGuiViewport* ImGui_ImplSDL3_GetViewportForWindowID(SDL_WindowID window_id)
|
||||||
{
|
{
|
||||||
return ImGui::FindViewportByPlatformHandle((void*)(intptr_t)window_id);
|
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
||||||
|
return (window_id == bd->WindowID) ? ImGui::GetMainViewport() : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data)
|
static void ImGui_ImplSDL3_PlatformSetImeData(ImGuiContext*, ImGuiViewport*, ImGuiPlatformImeData* data)
|
||||||
@ -218,12 +200,9 @@ static void ImGui_ImplSDL3_UpdateIme()
|
|||||||
bd->ImeDirty = false;
|
bd->ImeDirty = false;
|
||||||
if (data->WantVisible)
|
if (data->WantVisible)
|
||||||
{
|
{
|
||||||
ImVec2 viewport_pos;
|
|
||||||
if (ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(window)))
|
|
||||||
viewport_pos = viewport->Pos;
|
|
||||||
SDL_Rect r;
|
SDL_Rect r;
|
||||||
r.x = (int)(data->InputPos.x - viewport_pos.x);
|
r.x = (int)data->InputPos.x;
|
||||||
r.y = (int)(data->InputPos.y - viewport_pos.y);
|
r.y = (int)data->InputPos.y;
|
||||||
r.w = 1;
|
r.w = 1;
|
||||||
r.h = (int)data->InputLineHeight;
|
r.h = (int)data->InputLineHeight;
|
||||||
SDL_SetTextInputArea(window, &r, 0);
|
SDL_SetTextInputArea(window, &r, 0);
|
||||||
@ -412,13 +391,6 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->motion.windowID) == nullptr)
|
||||||
return false;
|
return false;
|
||||||
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
ImVec2 mouse_pos((float)event->motion.x, (float)event->motion.y);
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
int window_x, window_y;
|
|
||||||
SDL_GetWindowPosition(SDL_GetWindowFromID(event->motion.windowID), &window_x, &window_y);
|
|
||||||
mouse_pos.x += window_x;
|
|
||||||
mouse_pos.y += window_y;
|
|
||||||
}
|
|
||||||
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
io.AddMouseSourceEvent(event->motion.which == SDL_TOUCH_MOUSEID ? ImGuiMouseSource_TouchScreen : ImGuiMouseSource_Mouse);
|
||||||
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
io.AddMousePosEvent(mouse_pos.x, mouse_pos.y);
|
||||||
return true;
|
return true;
|
||||||
@ -462,29 +434,16 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_EVENT_KEY_DOWN:
|
case SDL_EVENT_KEY_DOWN:
|
||||||
case SDL_EVENT_KEY_UP:
|
case SDL_EVENT_KEY_UP:
|
||||||
{
|
{
|
||||||
ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(event->key.windowID);
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->key.windowID) == nullptr)
|
||||||
if (viewport == nullptr)
|
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("SDL_EVENT_KEY_%s : key=0x%08X ('%s'), scancode=%d ('%s'), mod=%X, windowID=%d, viewport=%08X\n",
|
|
||||||
// (event->type == SDL_EVENT_KEY_DOWN) ? "DOWN" : "UP ", event->key.key, SDL_GetKeyName(event->key.key), event->key.scancode, SDL_GetScancodeName(event->key.scancode), event->key.mod, event->key.windowID, viewport ? viewport->ID : 0);
|
|
||||||
ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod);
|
ImGui_ImplSDL3_UpdateKeyModifiers((SDL_Keymod)event->key.mod);
|
||||||
|
//IMGUI_DEBUG_LOG("SDL_EVENT_KEY_%s : key=%d ('%s'), scancode=%d ('%s'), mod=%X\n",
|
||||||
|
// (event->type == SDL_EVENT_KEY_DOWN) ? "DOWN" : "UP ", event->key.key, SDL_GetKeyName(event->key.key), event->key.scancode, SDL_GetScancodeName(event->key.scancode), event->key.mod);
|
||||||
ImGuiKey key = ImGui_ImplSDL3_KeyEventToImGuiKey(event->key.key, event->key.scancode);
|
ImGuiKey key = ImGui_ImplSDL3_KeyEventToImGuiKey(event->key.key, event->key.scancode);
|
||||||
io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN));
|
io.AddKeyEvent(key, (event->type == SDL_EVENT_KEY_DOWN));
|
||||||
io.SetKeyEventNativeData(key, (int)event->key.key, (int)event->key.scancode, (int)event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
io.SetKeyEventNativeData(key, (int)event->key.key, (int)event->key.scancode, (int)event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case SDL_EVENT_DISPLAY_ORIENTATION:
|
|
||||||
case SDL_EVENT_DISPLAY_ADDED:
|
|
||||||
case SDL_EVENT_DISPLAY_REMOVED:
|
|
||||||
case SDL_EVENT_DISPLAY_MOVED:
|
|
||||||
case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED:
|
|
||||||
#if SDL_HAS_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED
|
|
||||||
case SDL_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED:
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
case SDL_EVENT_WINDOW_MOUSE_ENTER:
|
||||||
{
|
{
|
||||||
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||||
@ -507,28 +466,11 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event)
|
|||||||
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
case SDL_EVENT_WINDOW_FOCUS_GAINED:
|
||||||
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
case SDL_EVENT_WINDOW_FOCUS_LOST:
|
||||||
{
|
{
|
||||||
ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID);
|
if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr)
|
||||||
if (viewport == nullptr)
|
|
||||||
return false;
|
return false;
|
||||||
//IMGUI_DEBUG_LOG("%s: windowId %d, viewport: %08X\n", (event->type == SDL_EVENT_WINDOW_FOCUS_GAINED) ? "SDL_EVENT_WINDOW_FOCUS_GAINED" : "SDL_WINDOWEVENT_FOCUS_LOST", event->window.windowID, viewport ? viewport->ID : 0);
|
|
||||||
io.AddFocusEvent(event->type == SDL_EVENT_WINDOW_FOCUS_GAINED);
|
io.AddFocusEvent(event->type == SDL_EVENT_WINDOW_FOCUS_GAINED);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
|
||||||
case SDL_EVENT_WINDOW_MOVED:
|
|
||||||
case SDL_EVENT_WINDOW_RESIZED:
|
|
||||||
{
|
|
||||||
ImGuiViewport* viewport = ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID);
|
|
||||||
if (viewport == NULL)
|
|
||||||
return false;
|
|
||||||
if (event->type == SDL_EVENT_WINDOW_CLOSE_REQUESTED)
|
|
||||||
viewport->PlatformRequestClose = true;
|
|
||||||
if (event->type == SDL_EVENT_WINDOW_MOVED)
|
|
||||||
viewport->PlatformRequestMove = true;
|
|
||||||
if (event->type == SDL_EVENT_WINDOW_RESIZED)
|
|
||||||
viewport->PlatformRequestResize = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case SDL_EVENT_GAMEPAD_ADDED:
|
case SDL_EVENT_GAMEPAD_ADDED:
|
||||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||||
{
|
{
|
||||||
@ -572,8 +514,6 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
io.BackendPlatformName = bd->BackendPlatformName;
|
io.BackendPlatformName = bd->BackendPlatformName;
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||||
// (ImGuiBackendFlags_PlatformHasViewports and ImGuiBackendFlags_HasParentViewport may be set just below)
|
|
||||||
// (ImGuiBackendFlags_HasMouseHoveredViewport is set dynamically in our _NewFrame function)
|
|
||||||
|
|
||||||
bd->Window = window;
|
bd->Window = window;
|
||||||
bd->WindowID = SDL_GetWindowID(window);
|
bd->WindowID = SDL_GetWindowID(window);
|
||||||
@ -593,19 +533,6 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
bd->MouseCaptureMode = (strcmp(item, "x11") == 0) ? ImGui_ImplSDL3_MouseCaptureMode_EnabledAfterDrag : ImGui_ImplSDL3_MouseCaptureMode_Enabled;
|
bd->MouseCaptureMode = (strcmp(item, "x11") == 0) ? ImGui_ImplSDL3_MouseCaptureMode_EnabledAfterDrag : ImGui_ImplSDL3_MouseCaptureMode_Enabled;
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
|
||||||
}
|
|
||||||
|
|
||||||
// SDL on Linux/OSX doesn't report events for unfocused windows (see https://github.com/ocornut/imgui/issues/4960)
|
|
||||||
// We will use 'MouseCanReportHoveredViewport' to set 'ImGuiBackendFlags_HasMouseHoveredViewport' dynamically each frame.
|
|
||||||
#ifndef __APPLE__
|
|
||||||
bd->MouseCanReportHoveredViewport = bd->MouseCanUseGlobalState;
|
|
||||||
#else
|
|
||||||
bd->MouseCanReportHoveredViewport = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
platform_io.Platform_SetClipboardTextFn = ImGui_ImplSDL3_SetClipboardText;
|
||||||
@ -613,9 +540,6 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
platform_io.Platform_SetImeDataFn = ImGui_ImplSDL3_PlatformSetImeData;
|
||||||
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url); };
|
platform_io.Platform_OpenInShellFn = [](ImGuiContext*, const char* url) { return SDL_OpenURL(url); };
|
||||||
|
|
||||||
// Update monitor a first time during init
|
|
||||||
ImGui_ImplSDL3_UpdateMonitors();
|
|
||||||
|
|
||||||
// Gamepad handling
|
// Gamepad handling
|
||||||
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
|
bd->GamepadMode = ImGui_ImplSDL3_GamepadMode_AutoFirst;
|
||||||
bd->WantUpdateGamepadsList = true;
|
bd->WantUpdateGamepadsList = true;
|
||||||
@ -648,14 +572,6 @@ static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void
|
|||||||
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
|
// From 2.0.22: Disable auto-capture, this is preventing drag and drop across multiple windows (see #5710)
|
||||||
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0");
|
||||||
|
|
||||||
// SDL 3.x : see https://github.com/libsdl-org/SDL/issues/6659
|
|
||||||
SDL_SetHint("SDL_BORDERLESS_WINDOWED_STYLE", "0");
|
|
||||||
|
|
||||||
// We need SDL_CaptureMouse(), SDL_GetGlobalMouseState() from SDL 2.0.4+ to support multiple viewports.
|
|
||||||
// We left the call to ImGui_ImplSDL3_InitPlatformInterface() outside of #ifdef to avoid unused-function warnings.
|
|
||||||
if (io.BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
|
|
||||||
ImGui_ImplSDL3_InitMultiViewportSupport(window, sdl_gl_context);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,11 +583,7 @@ bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
|
|||||||
|
|
||||||
bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window)
|
bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window)
|
||||||
{
|
{
|
||||||
if (!ImGui_ImplSDL3_Init(window, nullptr, nullptr))
|
return ImGui_ImplSDL3_Init(window, nullptr, nullptr);
|
||||||
return false;
|
|
||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
|
||||||
bd->IsVulkan = true;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window)
|
bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window)
|
||||||
@ -711,7 +623,6 @@ void ImGui_ImplSDL3_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplSDL3_ShutdownMultiViewportSupport();
|
|
||||||
if (bd->ClipboardTextData)
|
if (bd->ClipboardTextData)
|
||||||
SDL_free(bd->ClipboardTextData);
|
SDL_free(bd->ClipboardTextData);
|
||||||
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++)
|
||||||
@ -720,7 +631,7 @@ void ImGui_ImplSDL3_Shutdown()
|
|||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewport);
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
platform_io.ClearPlatformHandlers();
|
platform_io.ClearPlatformHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -756,7 +667,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
SDL_Window* focused_window = SDL_GetKeyboardFocus();
|
||||||
const bool is_app_focused = (focused_window && (bd->Window == focused_window || ImGui_ImplSDL3_GetViewportForWindowID(SDL_GetWindowID(focused_window)) != NULL));
|
const bool is_app_focused = (bd->Window == focused_window);
|
||||||
#else
|
#else
|
||||||
SDL_Window* focused_window = bd->Window;
|
SDL_Window* focused_window = bd->Window;
|
||||||
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
const bool is_app_focused = (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; // SDL 2.0.3 and non-windowed systems: single-viewport only
|
||||||
@ -765,14 +676,7 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
{
|
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
||||||
#if SDL_HAS_CAPTURE_AND_GLOBAL_MOUSE
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
SDL_WarpMouseGlobal(io.MousePos.x, io.MousePos.y);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Optional) Fallback to provide unclamped mouse position when focused but not hovered (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.
|
// 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.
|
||||||
@ -781,34 +685,15 @@ static void ImGui_ImplSDL3_UpdateMouseData()
|
|||||||
if (hovered_window == nullptr && bd->MouseCanUseGlobalState && bd->MouseButtonsDown == 0 && !is_relative_mouse_mode)
|
if (hovered_window == nullptr && 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)
|
// 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)
|
|
||||||
float mouse_x, mouse_y;
|
float mouse_x, mouse_y;
|
||||||
int window_x, window_y;
|
int window_x, window_y;
|
||||||
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
SDL_GetGlobalMouseState(&mouse_x, &mouse_y);
|
||||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
||||||
{
|
mouse_x -= (float)window_x;
|
||||||
SDL_GetWindowPosition(focused_window, &window_x, &window_y);
|
mouse_y -= (float)window_y;
|
||||||
mouse_x -= (float)window_x;
|
|
||||||
mouse_y -= (float)window_y;
|
|
||||||
}
|
|
||||||
io.AddMousePosEvent(mouse_x, mouse_y);
|
io.AddMousePosEvent(mouse_x, mouse_y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
|
||||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
|
||||||
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
|
||||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
|
||||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
|
||||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
|
||||||
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
|
||||||
if (io.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
|
|
||||||
{
|
|
||||||
ImGuiID mouse_viewport_id = 0;
|
|
||||||
if (ImGuiViewport* mouse_viewport = ImGui_ImplSDL3_GetViewportForWindowID(bd->MouseWindowID))
|
|
||||||
mouse_viewport_id = mouse_viewport->ID;
|
|
||||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_UpdateMouseCursor()
|
static void ImGui_ImplSDL3_UpdateMouseCursor()
|
||||||
@ -940,38 +825,6 @@ static void ImGui_ImplSDL3_UpdateGamepads()
|
|||||||
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
ImGui_ImplSDL3_UpdateGamepadAnalog(bd, io, ImGuiKey_GamepadRStickDown, SDL_GAMEPAD_AXIS_RIGHTY, +thumb_dead_zone, +32767);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_UpdateMonitors()
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Monitors.resize(0);
|
|
||||||
bd->WantUpdateMonitors = false;
|
|
||||||
|
|
||||||
int display_count;
|
|
||||||
SDL_DisplayID* displays = SDL_GetDisplays(&display_count);
|
|
||||||
for (int n = 0; n < display_count; n++)
|
|
||||||
{
|
|
||||||
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
|
|
||||||
SDL_DisplayID display_id = displays[n];
|
|
||||||
ImGuiPlatformMonitor monitor;
|
|
||||||
SDL_Rect r;
|
|
||||||
SDL_GetDisplayBounds(display_id, &r);
|
|
||||||
monitor.MainPos = monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
|
||||||
monitor.MainSize = monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
|
||||||
if (SDL_GetDisplayUsableBounds(display_id, &r) && r.w > 0 && r.h > 0)
|
|
||||||
{
|
|
||||||
monitor.WorkPos = ImVec2((float)r.x, (float)r.y);
|
|
||||||
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
|
|
||||||
}
|
|
||||||
monitor.DpiScale = SDL_GetDisplayContentScale(display_id); // See https://wiki.libsdl.org/SDL3/README-highdpi for details.
|
|
||||||
monitor.PlatformHandle = (void*)(intptr_t)n;
|
|
||||||
if (monitor.DpiScale <= 0.0f)
|
|
||||||
continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
|
||||||
platform_io.Monitors.push_back(monitor);
|
|
||||||
}
|
|
||||||
SDL_free(displays);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window, ImVec2* out_size, ImVec2* out_framebuffer_scale)
|
||||||
{
|
{
|
||||||
int w, h;
|
int w, h;
|
||||||
@ -1004,13 +857,6 @@ void ImGui_ImplSDL3_NewFrame()
|
|||||||
// Setup main viewport size (every frame to accommodate for window resizing)
|
// Setup main viewport size (every frame to accommodate for window resizing)
|
||||||
ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(bd->Window, &io.DisplaySize, &io.DisplayFramebufferScale);
|
||||||
|
|
||||||
// Update monitors
|
|
||||||
#if defined(WIN32) && !SDL_HAS_EVENT_DISPLAY_USABLE_BOUNDS_CHANGED
|
|
||||||
bd->WantUpdateMonitors = true; // Keep polling under Windows to handle changes of work area when resizing task-bar (#8415)
|
|
||||||
#endif
|
|
||||||
if (bd->WantUpdateMonitors)
|
|
||||||
ImGui_ImplSDL3_UpdateMonitors();
|
|
||||||
|
|
||||||
// Setup time step (we could also use SDL_GetTicksNS() available since SDL3)
|
// Setup time step (we could also use SDL_GetTicksNS() available since SDL3)
|
||||||
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
// (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644)
|
||||||
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
static Uint64 frequency = SDL_GetPerformanceFrequency();
|
||||||
@ -1027,13 +873,6 @@ void ImGui_ImplSDL3_NewFrame()
|
|||||||
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our io.AddMouseViewportEvent() calls will only be valid when not capturing.
|
|
||||||
// Technically speaking testing for 'bd->MouseButtonsDown == 0' would be more rigorous, but testing for payload reduces noise and potential side-effects.
|
|
||||||
if (bd->MouseCanReportHoveredViewport && ImGui::GetDragDropPayload() == nullptr)
|
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport;
|
|
||||||
else
|
|
||||||
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseHoveredViewport;
|
|
||||||
|
|
||||||
ImGui_ImplSDL3_UpdateMouseData();
|
ImGui_ImplSDL3_UpdateMouseData();
|
||||||
ImGui_ImplSDL3_UpdateMouseCursor();
|
ImGui_ImplSDL3_UpdateMouseCursor();
|
||||||
ImGui_ImplSDL3_UpdateIme();
|
ImGui_ImplSDL3_UpdateIme();
|
||||||
@ -1042,272 +881,6 @@ void ImGui_ImplSDL3_NewFrame()
|
|||||||
ImGui_ImplSDL3_UpdateGamepads();
|
ImGui_ImplSDL3_UpdateGamepads();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplSDL3_ViewportData
|
|
||||||
{
|
|
||||||
SDL_Window* Window;
|
|
||||||
SDL_Window* ParentWindow;
|
|
||||||
Uint32 WindowID; // Stored in ImGuiViewport::PlatformHandle. Use SDL_GetWindowFromID() to get SDL_Window* from Uint32 WindowID.
|
|
||||||
bool WindowOwned;
|
|
||||||
SDL_GLContext GLContext;
|
|
||||||
|
|
||||||
ImGui_ImplSDL3_ViewportData() { Window = ParentWindow = nullptr; WindowID = 0; WindowOwned = false; GLContext = nullptr; }
|
|
||||||
~ImGui_ImplSDL3_ViewportData() { IM_ASSERT(Window == nullptr && GLContext == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static SDL_Window* ImGui_ImplSDL3_GetSDLWindowFromViewport(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
if (viewport != nullptr)
|
|
||||||
{
|
|
||||||
SDL_WindowID window_id = (SDL_WindowID)(intptr_t)viewport->PlatformHandle;
|
|
||||||
return SDL_GetWindowFromID(window_id);
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData();
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = IM_NEW(ImGui_ImplSDL3_ViewportData)();
|
|
||||||
viewport->PlatformUserData = vd;
|
|
||||||
|
|
||||||
vd->ParentWindow = ImGui_ImplSDL3_GetSDLWindowFromViewport(viewport->ParentViewport);
|
|
||||||
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplSDL3_ViewportData* main_viewport_data = (ImGui_ImplSDL3_ViewportData*)main_viewport->PlatformUserData;
|
|
||||||
|
|
||||||
// Share GL resources with main context
|
|
||||||
bool use_opengl = (main_viewport_data->GLContext != nullptr);
|
|
||||||
SDL_GLContext backup_context = nullptr;
|
|
||||||
if (use_opengl)
|
|
||||||
{
|
|
||||||
backup_context = SDL_GL_GetCurrentContext();
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
|
||||||
SDL_GL_MakeCurrent(main_viewport_data->Window, main_viewport_data->GLContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_WindowFlags sdl_flags = 0;
|
|
||||||
sdl_flags |= SDL_WINDOW_HIDDEN;
|
|
||||||
sdl_flags |= use_opengl ? SDL_WINDOW_OPENGL : (bd->IsVulkan ? SDL_WINDOW_VULKAN : 0);
|
|
||||||
sdl_flags |= SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon) ? SDL_WINDOW_UTILITY : 0;
|
|
||||||
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_TopMost) ? SDL_WINDOW_ALWAYS_ON_TOP : 0;
|
|
||||||
vd->Window = SDL_CreateWindow("No Title Yet", (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
|
|
||||||
#ifndef __APPLE__ // On Mac, SDL3 Parenting appears to prevent viewport from appearing in another monitor
|
|
||||||
SDL_SetWindowParent(vd->Window, vd->ParentWindow);
|
|
||||||
#endif
|
|
||||||
SDL_SetWindowPosition(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
|
|
||||||
vd->WindowOwned = true;
|
|
||||||
if (use_opengl)
|
|
||||||
{
|
|
||||||
vd->GLContext = SDL_GL_CreateContext(vd->Window);
|
|
||||||
SDL_GL_SetSwapInterval(0);
|
|
||||||
}
|
|
||||||
if (use_opengl && backup_context)
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, backup_context);
|
|
||||||
|
|
||||||
ImGui_ImplSDL3_SetupPlatformHandles(viewport, vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
if (ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
if (vd->GLContext && vd->WindowOwned)
|
|
||||||
SDL_GL_DestroyContext(vd->GLContext);
|
|
||||||
if (vd->Window && vd->WindowOwned)
|
|
||||||
SDL_DestroyWindow(vd->Window);
|
|
||||||
vd->GLContext = nullptr;
|
|
||||||
vd->Window = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_ShowWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
#if defined(_WIN32) && !(defined(WINAPI_FAMILY) && ((defined(WINAPI_FAMILY_APP) && WINAPI_FAMILY == WINAPI_FAMILY_APP) || (defined(WINAPI_FAMILY_GAMES) && WINAPI_FAMILY == WINAPI_FAMILY_GAMES)))
|
|
||||||
HWND hwnd = (HWND)viewport->PlatformHandleRaw;
|
|
||||||
|
|
||||||
// SDL hack: Show icon in task bar (#7989)
|
|
||||||
// Note: SDL_WINDOW_UTILITY can be used to control task bar visibility, but on Windows, it does not affect child windows.
|
|
||||||
if (!(viewport->Flags & ImGuiViewportFlags_NoTaskBarIcon))
|
|
||||||
{
|
|
||||||
LONG ex_style = ::GetWindowLong(hwnd, GWL_EXSTYLE);
|
|
||||||
ex_style |= WS_EX_APPWINDOW;
|
|
||||||
ex_style &= ~WS_EX_TOOLWINDOW;
|
|
||||||
::ShowWindow(hwnd, SW_HIDE);
|
|
||||||
::SetWindowLong(hwnd, GWL_EXSTYLE, ex_style);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, "1"); // Otherwise new window appear under
|
|
||||||
#else
|
|
||||||
SDL_SetHint(SDL_HINT_WINDOW_ACTIVATE_WHEN_SHOWN, (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing) ? "0" : "1");
|
|
||||||
#endif
|
|
||||||
SDL_ShowWindow(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_UpdateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_UNUSED(vd);
|
|
||||||
|
|
||||||
#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_GetSDLWindowFromViewport(viewport->ParentViewport);
|
|
||||||
if (new_parent != vd->ParentWindow)
|
|
||||||
{
|
|
||||||
vd->ParentWindow = new_parent;
|
|
||||||
SDL_SetWindowParent(vd->Window, vd->ParentWindow);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL3_GetWindowPos(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int x = 0, y = 0;
|
|
||||||
SDL_GetWindowPosition(vd->Window, &x, &y);
|
|
||||||
return ImVec2((float)x, (float)y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowPosition(vd->Window, (int)pos.x, (int)pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL3_GetWindowSize(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
int w = 0, h = 0;
|
|
||||||
SDL_GetWindowSize(vd->Window, &w, &h);
|
|
||||||
return ImVec2((float)w, (float)h);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowSize(vd->Window, (int)size.x, (int)size.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplSDL3_GetWindowFramebufferScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
ImVec2 framebuffer_scale;
|
|
||||||
ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(vd->Window, nullptr, &framebuffer_scale);
|
|
||||||
return framebuffer_scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowTitle(vd->Window, title);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_SetWindowOpacity(vd->Window, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
SDL_RaiseWindow(vd->Window);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplSDL3_GetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_INPUT_FOCUS) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplSDL3_GetWindowMinimized(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
return (SDL_GetWindowFlags(vd->Window) & SDL_WINDOW_MINIMIZED) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (vd->GLContext)
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
if (vd->GLContext)
|
|
||||||
{
|
|
||||||
SDL_GL_MakeCurrent(vd->Window, vd->GLContext);
|
|
||||||
SDL_GL_SwapWindow(vd->Window);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vulkan support (the Vulkan renderer needs to call a platform-side support function to create the surface)
|
|
||||||
// SDL is graceful enough to _not_ need <vulkan/vulkan.h> so we can safely include this.
|
|
||||||
#include <SDL3/SDL_vulkan.h>
|
|
||||||
static int ImGui_ImplSDL3_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = (ImGui_ImplSDL3_ViewportData*)viewport->PlatformUserData;
|
|
||||||
(void)vk_allocator;
|
|
||||||
bool ret = SDL_Vulkan_CreateSurface(vd->Window, (VkInstance)vk_instance, (const VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface);
|
|
||||||
return ret ? 0 : 1; // ret ? VK_SUCCESS : VK_NOT_READY
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_InitMultiViewportSupport(SDL_Window* window, void* sdl_gl_context)
|
|
||||||
{
|
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Platform_CreateWindow = ImGui_ImplSDL3_CreateWindow;
|
|
||||||
platform_io.Platform_DestroyWindow = ImGui_ImplSDL3_DestroyWindow;
|
|
||||||
platform_io.Platform_ShowWindow = ImGui_ImplSDL3_ShowWindow;
|
|
||||||
platform_io.Platform_UpdateWindow = ImGui_ImplSDL3_UpdateWindow;
|
|
||||||
platform_io.Platform_SetWindowPos = ImGui_ImplSDL3_SetWindowPos;
|
|
||||||
platform_io.Platform_GetWindowPos = ImGui_ImplSDL3_GetWindowPos;
|
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplSDL3_SetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplSDL3_GetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowFramebufferScale = ImGui_ImplSDL3_GetWindowFramebufferScale;
|
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplSDL3_SetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplSDL3_GetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL3_GetWindowMinimized;
|
|
||||||
platform_io.Platform_SetWindowTitle = ImGui_ImplSDL3_SetWindowTitle;
|
|
||||||
platform_io.Platform_RenderWindow = ImGui_ImplSDL3_RenderWindow;
|
|
||||||
platform_io.Platform_SwapBuffers = ImGui_ImplSDL3_SwapBuffers;
|
|
||||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplSDL3_SetWindowAlpha;
|
|
||||||
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL3_CreateVkSurface;
|
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
|
||||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplSDL3_ViewportData* vd = IM_NEW(ImGui_ImplSDL3_ViewportData)();
|
|
||||||
vd->Window = window;
|
|
||||||
vd->WindowID = SDL_GetWindowID(window);
|
|
||||||
vd->WindowOwned = false;
|
|
||||||
vd->GLContext = (SDL_GLContext)sdl_gl_context;
|
|
||||||
main_viewport->PlatformUserData = vd;
|
|
||||||
main_viewport->PlatformHandle = (void*)(intptr_t)vd->WindowID;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDL3_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
|||||||
@ -8,10 +8,7 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
// [X] Platform: IME support.
|
||||||
// Missing features or Issues:
|
|
||||||
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
|
||||||
// [x] Platform: IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// [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: 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: 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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLGPU3_GetRenderState().
|
||||||
|
|
||||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -23,7 +23,7 @@
|
|||||||
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
// Calling the function is MANDATORY, otherwise the ImGui will not upload neither the vertex nor the index buffer for the GPU. See imgui_impl_sdlgpu3.cpp for more info.
|
||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplSDLGPU3_RenderState. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplSDLGPU3_RenderState. (#9378)
|
||||||
// 2026-03-19: Fixed issue in ImGui_ImplSDLGPU3_DestroyTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295, #9310)
|
// 2026-03-19: Fixed issue in ImGui_ImplSDLGPU3_DestroyTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295, #9310)
|
||||||
// 2026-02-25: Removed unnecessary call to SDL_WaitForGPUIdle when releasing vertex/index buffers. (#9262)
|
// 2026-02-25: Removed unnecessary call to SDL_WaitForGPUIdle when releasing vertex/index buffers. (#9262)
|
||||||
@ -94,6 +94,11 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplSDLGPU3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
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, 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();
|
||||||
@ -165,8 +170,8 @@ static void CreateOrResizeBuffers(SDL_GPUBuffer** buffer, SDL_GPUTransferBuffer*
|
|||||||
void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -231,8 +236,8 @@ static void ImGui_ImplSDLGPU3_DrawCallback_SetSamplerNearest(const ImDrawList*,
|
|||||||
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0)
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -593,7 +598,7 @@ void ImGui_ImplSDLGPU3_CreateDeviceObjects()
|
|||||||
|
|
||||||
if (bd->TexSamplerLinear == 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.
|
// Bilinear sampling is required.
|
||||||
SDL_GPUSamplerCreateInfo sampler_info = {};
|
SDL_GPUSamplerCreateInfo sampler_info = {};
|
||||||
sampler_info.min_filter = SDL_GPU_FILTER_LINEAR;
|
sampler_info.min_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR;
|
sampler_info.mag_filter = SDL_GPU_FILTER_LINEAR;
|
||||||
@ -654,9 +659,6 @@ void ImGui_ImplSDLGPU3_DestroyDeviceObjects()
|
|||||||
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr; }
|
if (bd->Pipeline) { SDL_ReleaseGPUGraphicsPipeline(v->Device, bd->Pipeline); bd->Pipeline = nullptr; }
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ImGui_ImplSDLGPU3_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
@ -669,7 +671,6 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
|||||||
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
io.BackendRendererName = "imgui_impl_sdlgpu3";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLGPU3_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLGPU3_DrawCallback_ResetRenderState;
|
||||||
@ -681,8 +682,6 @@ bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info)
|
|||||||
|
|
||||||
bd->InitInfo = *info;
|
bd->InitInfo = *info;
|
||||||
|
|
||||||
ImGui_ImplSDLGPU3_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,12 +692,11 @@ void ImGui_ImplSDLGPU3_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport();
|
|
||||||
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
ImGui_ImplSDLGPU3_DestroyDeviceObjects();
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -712,76 +710,4 @@ void ImGui_ImplSDLGPU3_NewFrame()
|
|||||||
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
ImGui_ImplSDLGPU3_CreateDeviceObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDLGPU3_RenderWindow(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
|
|
||||||
SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
|
|
||||||
|
|
||||||
ImDrawData* draw_data = viewport->DrawData;
|
|
||||||
|
|
||||||
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(data->InitInfo.Device);
|
|
||||||
|
|
||||||
SDL_GPUTexture* swapchain_texture;
|
|
||||||
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr);
|
|
||||||
|
|
||||||
if (swapchain_texture != nullptr)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer); // FIXME-OPT: Not optimal, may this be done earlier?
|
|
||||||
SDL_GPUColorTargetInfo target_info = {};
|
|
||||||
target_info.texture = swapchain_texture;
|
|
||||||
target_info.clear_color = SDL_FColor{ 0.0f,0.0f,0.0f,1.0f };
|
|
||||||
target_info.load_op = SDL_GPU_LOADOP_CLEAR;
|
|
||||||
target_info.store_op = SDL_GPU_STOREOP_STORE;
|
|
||||||
target_info.mip_level = 0;
|
|
||||||
target_info.layer_or_depth_plane = 0;
|
|
||||||
target_info.cycle = false;
|
|
||||||
SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr);
|
|
||||||
ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass);
|
|
||||||
SDL_EndGPURenderPass(render_pass);
|
|
||||||
}
|
|
||||||
|
|
||||||
SDL_SubmitGPUCommandBuffer(command_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDLGPU3_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplSDLGPU3_Data* data = ImGui_ImplSDLGPU3_GetBackendData();
|
|
||||||
if (viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
SDL_Window* window = SDL_GetWindowFromID((SDL_WindowID)(intptr_t)viewport->PlatformHandle);
|
|
||||||
SDL_ReleaseWindowFromGPUDevice(data->InitInfo.Device, window);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDLGPU3_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplSDLGPU3_RenderWindow;
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplSDLGPU3_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplSDLGPU3_DestroyWindow;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplSDLGPU3_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,7 +5,7 @@
|
|||||||
// [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: 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: 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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLGPU3_GetRenderState().
|
||||||
|
|
||||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -59,5 +59,6 @@ struct ImGui_ImplSDLGPU3_RenderState
|
|||||||
{
|
{
|
||||||
SDL_GPUDevice* Device;
|
SDL_GPUDevice* Device;
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState();
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: SDLRenderer2 does not support changing SDL_SCALE_MODE while rendering.
|
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: SDLRenderer2 does not support changing SDL_SCALE_MODE while rendering.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
@ -56,7 +55,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
#include <SDL.h>
|
#include <SDL_render.h>
|
||||||
|
#include <SDL_version.h>
|
||||||
#if !SDL_VERSION_ATLEAST(2,0,17)
|
#if !SDL_VERSION_ATLEAST(2,0,17)
|
||||||
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
||||||
#endif
|
#endif
|
||||||
@ -76,6 +76,11 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
@ -214,8 +219,7 @@ void ImGui_ImplSDLRenderer2_UpdateTexture(ImTextureData* tex)
|
|||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
// Create texture
|
// Create texture (bilinear sampling is required)
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
SDL_Texture* sdl_texture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
|
SDL_Texture* sdl_texture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
|
||||||
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
||||||
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
||||||
|
|||||||
@ -15,7 +15,6 @@
|
|||||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
// Missing features or Issues:
|
// Missing features or Issues:
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: SDLRenderer2 does not support changing SDL_SCALE_MODE while rendering.
|
// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks: SDLRenderer2 does not support changing SDL_SCALE_MODE while rendering.
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
@ -52,5 +51,6 @@ struct ImGui_ImplSDLRenderer2_RenderState
|
|||||||
{
|
{
|
||||||
SDL_Renderer* Renderer;
|
SDL_Renderer* Renderer;
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState();
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -13,9 +13,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLRenderer3_GetRenderState().
|
||||||
// Missing features:
|
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -27,6 +25,7 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-09-17: Restore modified texture scale modes at the end of RenderDrawData(). Added DrawCallback_SetSamplerFromTex support. Added CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState (#9543, #9378)
|
||||||
// 2026-07-15: Fixed default sampler state to be linear (broken 2026-04-23). (#9470, #9378)
|
// 2026-07-15: Fixed default sampler state to be linear (broken 2026-04-23). (#9470, #9378)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2026-03-12: Fixed invalid assert in ImGui_ImplSDLRenderer3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
// 2026-03-12: Fixed invalid assert in ImGui_ImplSDLRenderer3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
||||||
@ -53,19 +52,24 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL
|
// SDL
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL_render.h>
|
||||||
|
#include <SDL3/SDL_version.h>
|
||||||
#if !SDL_VERSION_ATLEAST(3,0,0)
|
#if !SDL_VERSION_ATLEAST(3,0,0)
|
||||||
#error This backend requires SDL 3.0.0+
|
#error This backend requires SDL 3.0.0+
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDL_Renderer data
|
// SDL_Renderer data
|
||||||
|
struct ImGui_ImplSDLRenderer3_TexScaleModeEntry
|
||||||
|
{
|
||||||
|
SDL_Texture* Texture;
|
||||||
|
SDL_ScaleMode ScaleModeBackup;
|
||||||
|
};
|
||||||
|
|
||||||
struct ImGui_ImplSDLRenderer3_Data
|
struct ImGui_ImplSDLRenderer3_Data
|
||||||
{
|
{
|
||||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||||
ImVector<SDL_FColor> ColorBuffer;
|
ImVector<SDL_FColor> ColorBuffer;
|
||||||
|
ImVector<ImGui_ImplSDLRenderer3_TexScaleModeEntry> TexScaleModeBackups; // Backup of texture scale modes
|
||||||
// Render State
|
|
||||||
SDL_ScaleMode CurrentScaleMode;
|
|
||||||
|
|
||||||
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
@ -77,17 +81,21 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState();
|
||||||
|
|
||||||
// Clear out any viewports and cliprect set by the user
|
// Clear out any viewports and cliprect set by the user
|
||||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||||
SDL_SetRenderViewport(renderer, nullptr);
|
SDL_SetRenderViewport(renderer, nullptr);
|
||||||
SDL_SetRenderClipRect(renderer, nullptr);
|
SDL_SetRenderClipRect(renderer, nullptr);
|
||||||
|
render_state->CurrentScaleMode = SDL_SCALEMODE_LINEAR;
|
||||||
bd->CurrentScaleMode = SDL_SCALEMODE_LINEAR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_NewFrame()
|
void ImGui_ImplSDLRenderer3_NewFrame()
|
||||||
@ -117,8 +125,61 @@ static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVector<SDL_F
|
|||||||
|
|
||||||
// Draw callbacks
|
// Draw callbacks
|
||||||
static void ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
static void ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); bd->CurrentScaleMode = SDL_SCALEMODE_LINEAR; }
|
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_LINEAR; }
|
||||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); bd->CurrentScaleMode = SDL_SCALEMODE_NEAREST; }
|
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_NEAREST; }
|
||||||
|
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_INVALID; } // SDL_SCALEMODE_INVALID = use/keep value in texture.
|
||||||
|
|
||||||
|
// SDLRenderer has various design issues which makes it hard to do it compared to regular graphics API.
|
||||||
|
// - scale/filtering mode is tied to a texture.
|
||||||
|
// - scale/filtering mode is not queued as part of the SDL_RenderGeometryXXX commands, so a change in one texture requires a flush.
|
||||||
|
static void ImGui_ImplSDLRenderer3_TexScaleModeUpdate(SDL_Renderer* renderer, SDL_Texture* tex, SDL_ScaleMode desired_scale_mode)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||||
|
if (desired_scale_mode != SDL_SCALEMODE_INVALID)
|
||||||
|
{
|
||||||
|
// Enforce a scale mode
|
||||||
|
SDL_ScaleMode tex_scale_mode = desired_scale_mode;
|
||||||
|
if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode)
|
||||||
|
return;
|
||||||
|
SDL_FlushRenderer(renderer);
|
||||||
|
SDL_SetTextureScaleMode(tex, desired_scale_mode);
|
||||||
|
|
||||||
|
// Store backup of old scale mode (FIXME-OPT)
|
||||||
|
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||||
|
if (entry.Texture == tex)
|
||||||
|
{
|
||||||
|
if (entry.ScaleModeBackup == SDL_SCALEMODE_INVALID)
|
||||||
|
entry.ScaleModeBackup = tex_scale_mode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode };
|
||||||
|
bd->TexScaleModeBackups.push_back(entry);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use scale mode that was set in texture by user. If there is an entry, restore it and clear the entry.
|
||||||
|
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||||
|
if (entry.Texture == tex && entry.ScaleModeBackup != SDL_SCALEMODE_INVALID)
|
||||||
|
{
|
||||||
|
SDL_FlushRenderer(renderer);
|
||||||
|
SDL_SetTextureScaleMode(tex, entry.ScaleModeBackup);
|
||||||
|
entry.ScaleModeBackup = SDL_SCALEMODE_INVALID;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplSDLRenderer3_TexScaleModeRestoreBackups(SDL_Renderer* renderer)
|
||||||
|
{
|
||||||
|
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||||
|
if (bd->TexScaleModeBackups.Size == 0)
|
||||||
|
return;
|
||||||
|
SDL_FlushRenderer(renderer);
|
||||||
|
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||||
|
if (entry.ScaleModeBackup != SDL_SCALEMODE_INVALID)
|
||||||
|
SDL_SetTextureScaleMode(entry.Texture, entry.ScaleModeBackup);
|
||||||
|
bd->TexScaleModeBackups.resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||||
{
|
{
|
||||||
@ -161,19 +222,19 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
SDL_GetRenderViewport(renderer, &old.Viewport);
|
SDL_GetRenderViewport(renderer, &old.Viewport);
|
||||||
SDL_GetRenderClipRect(renderer, &old.ClipRect);
|
SDL_GetRenderClipRect(renderer, &old.ClipRect);
|
||||||
|
|
||||||
// Setup desired state
|
|
||||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
|
||||||
|
|
||||||
// Setup render state structure (for callbacks and custom texture bindings)
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
ImGui_ImplSDLRenderer3_RenderState render_state;
|
ImGui_ImplSDLRenderer3_RenderState render_state;
|
||||||
render_state.Renderer = renderer;
|
render_state.Renderer = renderer;
|
||||||
platform_io.Renderer_RenderState = &render_state;
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
|
// Setup desired state
|
||||||
|
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||||
|
IM_ASSERT(bd->TexScaleModeBackups.Size == 0);
|
||||||
|
|
||||||
// Will project scissor/clipping rectangles into framebuffer space
|
// Will project scissor/clipping rectangles into framebuffer space
|
||||||
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports
|
||||||
ImVec2 clip_scale = render_scale;
|
ImVec2 clip_scale = render_scale;
|
||||||
SDL_ScaleMode last_scale_mode = bd->CurrentScaleMode;
|
|
||||||
|
|
||||||
// Render command lists
|
// Render command lists
|
||||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
@ -203,20 +264,17 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
|
if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
|
||||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
||||||
SDL_SetRenderClipRect(renderer, &r);
|
SDL_SetRenderClipRect(renderer, &r);
|
||||||
|
|
||||||
|
// Setup texture scale/filtering mode
|
||||||
|
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||||
|
ImGui_ImplSDLRenderer3_TexScaleModeUpdate(renderer, tex, render_state.CurrentScaleMode);
|
||||||
|
|
||||||
|
// Draw
|
||||||
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
||||||
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
||||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
|
||||||
|
|
||||||
if (last_scale_mode != bd->CurrentScaleMode)
|
|
||||||
SDL_FlushRenderer(renderer);
|
|
||||||
|
|
||||||
// Bind texture, Draw
|
|
||||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
|
||||||
SDL_SetTextureScaleMode(tex, bd->CurrentScaleMode);
|
|
||||||
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
||||||
xy, (int)sizeof(ImDrawVert),
|
xy, (int)sizeof(ImDrawVert),
|
||||||
color, (int)sizeof(ImDrawVert),
|
color, (int)sizeof(ImDrawVert),
|
||||||
@ -231,6 +289,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
|||||||
// Restore modified SDL_Renderer state
|
// Restore modified SDL_Renderer state
|
||||||
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
||||||
SDL_SetRenderClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
SDL_SetRenderClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||||
|
ImGui_ImplSDLRenderer3_TexScaleModeRestoreBackups(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
||||||
@ -244,8 +303,7 @@ void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
|||||||
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
|
||||||
// Create texture
|
// Create texture (bilinear sampling is required)
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
SDL_Texture* sdl_texture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
|
SDL_Texture* sdl_texture = SDL_CreateTexture(bd->Renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STATIC, tex->Width, tex->Height);
|
||||||
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
IM_ASSERT(sdl_texture != nullptr && "Backend failed to create texture!");
|
||||||
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
SDL_UpdateTexture(sdl_texture, nullptr, tex->GetPixels(), tex->GetPitch());
|
||||||
@ -313,6 +371,7 @@ bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
|
|||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState;
|
||||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear;
|
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear;
|
||||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest;
|
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest;
|
||||||
|
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex;
|
||||||
|
|
||||||
bd->Renderer = renderer;
|
bd->Renderer = renderer;
|
||||||
|
|
||||||
|
|||||||
@ -13,9 +13,7 @@
|
|||||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLRenderer3_GetRenderState().
|
||||||
// Missing features:
|
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -29,7 +27,8 @@
|
|||||||
#include "imgui.h" // IMGUI_IMPL_API
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
#ifndef IMGUI_DISABLE
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
struct SDL_Renderer;
|
// For SDL_ScaleMode which cannot be forward declared.
|
||||||
|
#include <SDL3/SDL_render.h>
|
||||||
|
|
||||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
|
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
|
||||||
@ -50,6 +49,8 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
|||||||
struct ImGui_ImplSDLRenderer3_RenderState
|
struct ImGui_ImplSDLRenderer3_RenderState
|
||||||
{
|
{
|
||||||
SDL_Renderer* Renderer;
|
SDL_Renderer* Renderer;
|
||||||
|
SDL_ScaleMode CurrentScaleMode; // Current scale mode during render. Set to SDL_SCALEMODE_INVALID to use "SetSamplerFromTex" mode.
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState();
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplVulkan_GetRenderState().
|
||||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
|
||||||
|
|
||||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -28,8 +27,9 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
// 2026-10-06: Added support for dynamic rendering with multiple color attachments (PipelineRenderingCreateInfo.colorAttachmentCount > 1): we render to the first one and leave the others untouched. (#9574)
|
||||||
// 2026-07-15: [Docking] Vulkan: fixed use-after-free when using multi-viewport with dynamic rendering path: deep-copy SurfaceFormat.format into the persistent buffer instead of storing a pointer to the viewport's wd->SurfaceFormat which dangles after the viewport is destroyed. (#9390, #9468)
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
|
// 2026-09-03: Added for support for multiple Vulkan contexts with custom loaders. (#6616)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2026-04-22: *BREAKING CHANGE* redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. This change allows us to facilitate changing samplers, in line with other backends.
|
// 2026-04-22: *BREAKING CHANGE* redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. This change allows us to facilitate changing samplers, in line with other backends.
|
||||||
// - When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler.
|
// - When registering custom textures: changed ImGui_ImplVulkan_AddTexture() signature to remove Sampler.
|
||||||
@ -44,13 +44,11 @@
|
|||||||
// 2025-09-26: [Helpers] *BREAKING CHANGE*: Vulkan: Helper ImGui_ImplVulkanH_DestroyWindow() does not call vkDestroySurfaceKHR(): as surface is created by caller of ImGui_ImplVulkanH_CreateOrResizeWindow(), it is more consistent that we don't destroy it. (#9163)
|
// 2025-09-26: [Helpers] *BREAKING CHANGE*: Vulkan: Helper ImGui_ImplVulkanH_DestroyWindow() does not call vkDestroySurfaceKHR(): as surface is created by caller of ImGui_ImplVulkanH_CreateOrResizeWindow(), it is more consistent that we don't destroy it. (#9163)
|
||||||
// 2026-01-05: [Helpers] *BREAKING CHANGE*: Vulkan: Helper for creating render pass uses ImGui_ImplVulkanH_Window::AttachmentDesc to create render pass. Removed ClearEnabled. (#9152)
|
// 2026-01-05: [Helpers] *BREAKING CHANGE*: Vulkan: Helper for creating render pass uses ImGui_ImplVulkanH_Window::AttachmentDesc to create render pass. Removed ClearEnabled. (#9152)
|
||||||
// 2025-11-24: [Helpers] Vulkan: Helper for creating a swap-chain (used by examples and multi-viewports) selects VkSwapchainCreateInfoKHR's compositeAlpha based on cap.supportedCompositeAlpha. (#8784)
|
// 2025-11-24: [Helpers] Vulkan: Helper for creating a swap-chain (used by examples and multi-viewports) selects VkSwapchainCreateInfoKHR's compositeAlpha based on cap.supportedCompositeAlpha. (#8784)
|
||||||
// 2025-11-13: [Docking] Handle viewport surface creation failure without crashing. (#9068)
|
|
||||||
// 2025-10-15: Vulkan: Added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to volk.h header. (#9008)
|
// 2025-10-15: Vulkan: Added IMGUI_IMPL_VULKAN_VOLK_FILENAME to configure path to volk.h header. (#9008)
|
||||||
// 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*: 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*: renamed ImGui_ImplVulkan_MainPipelineCreateInfo to ImGui_ImplVulkan_PipelineInfo. Introduced very recently so shouldn't affect many users.
|
||||||
// 2025-09-26: [Helpers] *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: [Helpers] *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-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-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||||
// 2025-09-04: Vulkan: Added ImGui_ImplVulkan_CreateMainPipeline(). (#8110, #8111)
|
// 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-27: Vulkan: Fixed texture update corruption introduced on 2025-06-11. (#8801, #8755, #8840)
|
||||||
@ -149,7 +147,6 @@ void ImGui_ImplVulkan_DestroyFrameRenderBuffers(VkDevice device, ImGui_ImplVulka
|
|||||||
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
void ImGui_ImplVulkan_DestroyWindowRenderBuffers(VkDevice device, ImGui_ImplVulkan_WindowRenderBuffers* buffers, const VkAllocationCallbacks* allocator);
|
||||||
void ImGui_ImplVulkanH_DestroyFrame(VkDevice device, ImGui_ImplVulkanH_Frame* fd, const VkAllocationCallbacks* allocator);
|
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_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, VkImageUsageFlags image_usage);
|
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);
|
void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator);
|
||||||
|
|
||||||
@ -166,18 +163,15 @@ static bool g_FunctionsLoaded = true;
|
|||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateMemory) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkAcquireNextImageKHR) \
|
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBeginCommandBuffer) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindBufferMemory) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkBindImageMemory) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBeginRenderPass) \
|
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindDescriptorSets) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindIndexBuffer) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindIndexBuffer) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindPipeline) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindPipeline) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindVertexBuffers) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdBindVertexBuffers) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdCopyBufferToImage) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdCopyBufferToImage) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdDrawIndexed) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdDrawIndexed) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdEndRenderPass) \
|
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPipelineBarrier) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPipelineBarrier) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPushConstants) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdPushConstants) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetScissor) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkCmdSetScissor) \
|
||||||
@ -229,10 +223,8 @@ static bool g_FunctionsLoaded = true;
|
|||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceCapabilitiesKHR) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceFormatsKHR) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfacePresentModesKHR) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetPhysicalDeviceSurfaceSupportKHR) \
|
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkGetSwapchainImagesKHR) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkMapMemory) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueuePresentKHR) \
|
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueSubmit) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueWaitIdle) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkQueueWaitIdle) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkResetCommandPool) \
|
||||||
@ -241,10 +233,28 @@ static bool g_FunctionsLoaded = true;
|
|||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \
|
||||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences)
|
IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences)
|
||||||
|
|
||||||
|
struct ImGui_ImplVulkan_Functions
|
||||||
|
{
|
||||||
// Define function pointers
|
// Define function pointers
|
||||||
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
|
#define IMGUI_VULKAN_FUNC_DEF(func) PFN_##func pfn_##func;
|
||||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||||
#undef IMGUI_VULKAN_FUNC_DEF
|
#undef IMGUI_VULKAN_FUNC_DEF
|
||||||
|
};
|
||||||
|
|
||||||
|
// Globally available function pointers used for initialization of the backend data
|
||||||
|
static ImGui_ImplVulkan_Functions ImGuiImplVulkanFuncs;
|
||||||
|
|
||||||
|
// Multi Vulkan contexts support: wrap each Vulkan function pointer to properly dispatch it using the current backend data
|
||||||
|
static ImGui_ImplVulkan_Functions& ImGui_ImplVulkan_GetFunctions();
|
||||||
|
#define IMGUI_VULKAN_FUNC_WRAPPER(func) \
|
||||||
|
template<typename... Args> \
|
||||||
|
auto func(Args&&... args) -> decltype(ImGui_ImplVulkan_GetFunctions().pfn_##func(args...)) \
|
||||||
|
{ \
|
||||||
|
return ImGui_ImplVulkan_GetFunctions().pfn_##func(args...); \
|
||||||
|
}
|
||||||
|
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_WRAPPER)
|
||||||
|
#undef IMGUI_VULKAN_FUNC_WRAPPER
|
||||||
|
|
||||||
#endif // IMGUI_IMPL_VULKAN_USE_LOADER
|
#endif // IMGUI_IMPL_VULKAN_USE_LOADER
|
||||||
|
|
||||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
@ -283,20 +293,6 @@ struct ImGui_ImplVulkan_Texture
|
|||||||
ImGui_ImplVulkan_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
ImGui_ImplVulkan_Texture() { memset((void*)this, 0, sizeof(*this)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// For multi-viewport support:
|
|
||||||
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplVulkan_ViewportData
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkanH_Window Window; // Used by secondary viewports only
|
|
||||||
ImGui_ImplVulkan_WindowRenderBuffers RenderBuffers; // Used by all viewports
|
|
||||||
bool WindowOwned;
|
|
||||||
bool SwapChainNeedRebuild; // Flag when viewport swapchain resized in the middle of processing a frame
|
|
||||||
bool SwapChainSuboptimal; // Flag when VK_SUBOPTIMAL_KHR was returned.
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_ViewportData() { WindowOwned = SwapChainNeedRebuild = SwapChainSuboptimal = false; memset((void*)&RenderBuffers, 0, sizeof(RenderBuffers)); }
|
|
||||||
~ImGui_ImplVulkan_ViewportData() { }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Vulkan data
|
// Vulkan data
|
||||||
struct ImGui_ImplVulkan_Data
|
struct ImGui_ImplVulkan_Data
|
||||||
{
|
{
|
||||||
@ -309,7 +305,6 @@ struct ImGui_ImplVulkan_Data
|
|||||||
VkDescriptorSetLayout DescriptorSetLayoutSampler;
|
VkDescriptorSetLayout DescriptorSetLayoutSampler;
|
||||||
VkPipelineLayout PipelineLayout;
|
VkPipelineLayout PipelineLayout;
|
||||||
VkPipeline Pipeline; // pipeline for main render pass (created by app)
|
VkPipeline Pipeline; // pipeline for main render pass (created by app)
|
||||||
VkPipeline PipelineForViewports; // pipeline for secondary viewports (created by backend)
|
|
||||||
VkShaderModule ShaderModuleVert;
|
VkShaderModule ShaderModuleVert;
|
||||||
VkShaderModule ShaderModuleFrag;
|
VkShaderModule ShaderModuleFrag;
|
||||||
VkDescriptorPool DescriptorPool;
|
VkDescriptorPool DescriptorPool;
|
||||||
@ -326,6 +321,11 @@ struct ImGui_ImplVulkan_Data
|
|||||||
// Render buffers for main window
|
// Render buffers for main window
|
||||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||||
|
|
||||||
|
// Vulkan function pointers loaded for this context
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||||
|
ImGui_ImplVulkan_Functions Functions;
|
||||||
|
#endif
|
||||||
|
|
||||||
ImGui_ImplVulkan_Data()
|
ImGui_ImplVulkan_Data()
|
||||||
{
|
{
|
||||||
memset((void*)this, 0, sizeof(*this));
|
memset((void*)this, 0, sizeof(*this));
|
||||||
@ -338,10 +338,6 @@ struct ImGui_ImplVulkan_Data
|
|||||||
// SHADERS
|
// SHADERS
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplVulkan_InitMultiViewportSupport();
|
|
||||||
static void ImGui_ImplVulkan_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// backends/vulkan/glsl_shader.vert, compiled with:
|
// backends/vulkan/glsl_shader.vert, compiled with:
|
||||||
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
// # glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert
|
||||||
/*
|
/*
|
||||||
@ -464,6 +460,21 @@ static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplVulkan_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||||
|
// Get the Vulkan function pointers used by the current backend.
|
||||||
|
// If no backend is available, return the currently loaded global function pointers (ImGuiImplVulkanFuncs).
|
||||||
|
static ImGui_ImplVulkan_Functions& ImGui_ImplVulkan_GetFunctions()
|
||||||
|
{
|
||||||
|
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||||
|
return bd ? bd->Functions : ImGuiImplVulkanFuncs;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
|
static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
|
||||||
{
|
{
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||||
@ -559,7 +570,7 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline
|
|||||||
constants[1] = 2.0f / draw_data->DisplaySize.y;
|
constants[1] = 2.0f / draw_data->DisplaySize.y;
|
||||||
constants[2] = -1.0f - draw_data->DisplayPos.x * constants[0]; // Translate
|
constants[2] = -1.0f - draw_data->DisplayPos.x * constants[0]; // Translate
|
||||||
constants[3] = -1.0f - draw_data->DisplayPos.y * constants[1];
|
constants[3] = -1.0f - draw_data->DisplayPos.y * constants[1];
|
||||||
vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 4, constants);
|
vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, (uint32_t)sizeof(float) * 4, constants);
|
||||||
|
|
||||||
// Setup sampler
|
// Setup sampler
|
||||||
vkCmdBindDescriptorSets(bd->RenderState->CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 1, 1, &bd->SamplerLinearDS, 0, nullptr);
|
vkCmdBindDescriptorSets(bd->RenderState->CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 1, 1, &bd->SamplerLinearDS, 0, nullptr);
|
||||||
@ -583,8 +594,8 @@ void ImGui_ImplVulkan_DrawCallback_SetSamplerCustom(const ImDrawList*, const ImD
|
|||||||
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline)
|
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
// 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_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0)
|
if (fb_width <= 0 || fb_height <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -600,10 +611,8 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm
|
|||||||
if (pipeline == VK_NULL_HANDLE)
|
if (pipeline == VK_NULL_HANDLE)
|
||||||
pipeline = bd->Pipeline;
|
pipeline = bd->Pipeline;
|
||||||
|
|
||||||
// Allocate array to store enough vertex/index buffers. Each unique viewport gets its own storage.
|
// Allocate array to store enough vertex/index buffers
|
||||||
ImGui_ImplVulkan_ViewportData* viewport_renderer_data = (ImGui_ImplVulkan_ViewportData*)draw_data->OwnerViewport->RendererUserData;
|
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers;
|
||||||
IM_ASSERT(viewport_renderer_data != nullptr);
|
|
||||||
ImGui_ImplVulkan_WindowRenderBuffers* wrb = &viewport_renderer_data->RenderBuffers;
|
|
||||||
if (wrb->FrameRenderBuffers.Size == 0)
|
if (wrb->FrameRenderBuffers.Size == 0)
|
||||||
{
|
{
|
||||||
wrb->Index = 0;
|
wrb->Index = 0;
|
||||||
@ -1054,7 +1063,14 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
|
|||||||
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
|
||||||
ms_info.rasterizationSamples = (info->MSAASamples != 0) ? info->MSAASamples : VK_SAMPLE_COUNT_1_BIT;
|
ms_info.rasterizationSamples = (info->MSAASamples != 0) ? info->MSAASamples : VK_SAMPLE_COUNT_1_BIT;
|
||||||
|
|
||||||
VkPipelineColorBlendAttachmentState color_attachment[1] = {};
|
// Blend into the first color attachment. With dynamic rendering, other color attachments of the rendering are left untouched (requires independentBlend feature).
|
||||||
|
int color_attachment_count = 1;
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
|
if (bd->VulkanInitInfo.UseDynamicRendering && info->PipelineRenderingCreateInfo.colorAttachmentCount > 1)
|
||||||
|
color_attachment_count = (int)info->PipelineRenderingCreateInfo.colorAttachmentCount;
|
||||||
|
#endif
|
||||||
|
ImVector<VkPipelineColorBlendAttachmentState> color_attachment;
|
||||||
|
color_attachment.resize(color_attachment_count, VkPipelineColorBlendAttachmentState()); // colorWriteMask = 0
|
||||||
color_attachment[0].blendEnable = VK_TRUE;
|
color_attachment[0].blendEnable = VK_TRUE;
|
||||||
color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
color_attachment[0].srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
|
||||||
color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
color_attachment[0].dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
|
||||||
@ -1069,8 +1085,8 @@ static VkPipeline ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAlloc
|
|||||||
|
|
||||||
VkPipelineColorBlendStateCreateInfo blend_info = {};
|
VkPipelineColorBlendStateCreateInfo blend_info = {};
|
||||||
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
blend_info.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
|
||||||
blend_info.attachmentCount = 1;
|
blend_info.attachmentCount = (uint32_t)color_attachment.Size;
|
||||||
blend_info.pAttachments = color_attachment;
|
blend_info.pAttachments = color_attachment.Data;
|
||||||
|
|
||||||
ImVector<VkDynamicState> dynamic_states = info->ExtraDynamicStates;
|
ImVector<VkDynamicState> dynamic_states = info->ExtraDynamicStates;
|
||||||
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
dynamic_states.push_back(VK_DYNAMIC_STATE_VIEWPORT);
|
||||||
@ -1185,8 +1201,7 @@ bool ImGui_ImplVulkan_CreateDeviceObjects()
|
|||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create samplers
|
// Create samplers (bilinear sampling is required)
|
||||||
// Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling.
|
|
||||||
if (!bd->SamplerLinear || !bd->SamplerNearest)
|
if (!bd->SamplerLinear || !bd->SamplerNearest)
|
||||||
{
|
{
|
||||||
VkSamplerCreateInfo info = {};
|
VkSamplerCreateInfo info = {};
|
||||||
@ -1293,7 +1308,7 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
|||||||
{
|
{
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||||
|
|
||||||
// Destroy all textures
|
// Destroy all textures
|
||||||
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
@ -1310,7 +1325,6 @@ void ImGui_ImplVulkan_DestroyDeviceObjects()
|
|||||||
if (bd->DescriptorSetLayoutSampler) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayoutSampler, v->Allocator); bd->DescriptorSetLayoutSampler = VK_NULL_HANDLE; }
|
if (bd->DescriptorSetLayoutSampler) { vkDestroyDescriptorSetLayout(v->Device, bd->DescriptorSetLayoutSampler, v->Allocator); bd->DescriptorSetLayoutSampler = VK_NULL_HANDLE; }
|
||||||
if (bd->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; }
|
if (bd->PipelineLayout) { vkDestroyPipelineLayout(v->Device, bd->PipelineLayout, v->Allocator); bd->PipelineLayout = VK_NULL_HANDLE; }
|
||||||
if (bd->Pipeline) { vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator); bd->Pipeline = VK_NULL_HANDLE; }
|
if (bd->Pipeline) { vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator); bd->Pipeline = VK_NULL_HANDLE; }
|
||||||
if (bd->PipelineForViewports) { vkDestroyPipeline(v->Device, bd->PipelineForViewports, v->Allocator); bd->PipelineForViewports = VK_NULL_HANDLE; }
|
|
||||||
if (bd->DescriptorPool) { vkDestroyDescriptorPool(v->Device, bd->DescriptorPool, v->Allocator); bd->DescriptorPool = VK_NULL_HANDLE; }
|
if (bd->DescriptorPool) { vkDestroyDescriptorPool(v->Device, bd->DescriptorPool, v->Allocator); bd->DescriptorPool = VK_NULL_HANDLE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1355,8 +1369,8 @@ bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(
|
|||||||
|
|
||||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||||
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
||||||
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
|
ImGuiImplVulkanFuncs.pfn_##func = reinterpret_cast<PFN_##func>(loader_func(#func, user_data)); \
|
||||||
if (func == nullptr) \
|
if (ImGuiImplVulkanFuncs.pfn_##func == nullptr) \
|
||||||
return false;
|
return false;
|
||||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
|
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
|
||||||
#undef IMGUI_VULKAN_FUNC_LOAD
|
#undef IMGUI_VULKAN_FUNC_LOAD
|
||||||
@ -1403,7 +1417,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
|||||||
io.BackendRendererName = "imgui_impl_vulkan";
|
io.BackendRendererName = "imgui_impl_vulkan";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
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)
|
|
||||||
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplVulkan_DrawCallback_ResetRenderState;
|
platform_io.DrawCallback_ResetRenderState = ImGui_ImplVulkan_DrawCallback_ResetRenderState;
|
||||||
@ -1422,9 +1435,12 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
|||||||
else
|
else
|
||||||
IM_ASSERT(info->DescriptorPoolSize > 0);
|
IM_ASSERT(info->DescriptorPoolSize > 0);
|
||||||
if (info->UseDynamicRendering)
|
if (info->UseDynamicRendering)
|
||||||
IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE && info->PipelineInfoForViewports.RenderPass == VK_NULL_HANDLE);
|
IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE);
|
||||||
|
|
||||||
bd->VulkanInitInfo = *info;
|
bd->VulkanInitInfo = *info;
|
||||||
|
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||||
|
bd->Functions = ImGuiImplVulkanFuncs;
|
||||||
|
#endif
|
||||||
|
|
||||||
VkPhysicalDeviceProperties properties;
|
VkPhysicalDeviceProperties properties;
|
||||||
vkGetPhysicalDeviceProperties(info->PhysicalDevice, &properties);
|
vkGetPhysicalDeviceProperties(info->PhysicalDevice, &properties);
|
||||||
@ -1433,12 +1449,6 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
|||||||
if (!ImGui_ImplVulkan_CreateDeviceObjects())
|
if (!ImGui_ImplVulkan_CreateDeviceObjects())
|
||||||
IM_ASSERT(0 && "ImGui_ImplVulkan_CreateDeviceObjects() failed!"); // <- Can't be hit yet.
|
IM_ASSERT(0 && "ImGui_ImplVulkan_CreateDeviceObjects() failed!"); // <- Can't be hit yet.
|
||||||
|
|
||||||
// Our render function expect RendererUserData to be storing the window render buffer we need (for the main viewport we won't use ->Window)
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
main_viewport->RendererUserData = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_InitMultiViewportSupport();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1449,21 +1459,11 @@ void ImGui_ImplVulkan_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
// First destroy objects in all viewports
|
|
||||||
ImGui_ImplVulkan_DestroyDeviceObjects();
|
ImGui_ImplVulkan_DestroyDeviceObjects();
|
||||||
|
|
||||||
// Manually delete main viewport render data in-case we haven't initialized for viewports
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)main_viewport->RendererUserData)
|
|
||||||
IM_DELETE(vd);
|
|
||||||
main_viewport->RendererUserData = nullptr;
|
|
||||||
|
|
||||||
// Clean up windows
|
|
||||||
ImGui_ImplVulkan_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
io.BackendRendererName = nullptr;
|
io.BackendRendererName = nullptr;
|
||||||
io.BackendRendererUserData = nullptr;
|
io.BackendRendererUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures);
|
||||||
platform_io.ClearRendererHandlers();
|
platform_io.ClearRendererHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -1482,12 +1482,10 @@ void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count)
|
|||||||
if (bd->VulkanInitInfo.MinImageCount == min_image_count)
|
if (bd->VulkanInitInfo.MinImageCount == min_image_count)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IM_ASSERT(0); // FIXME-VIEWPORT: Unsupported. Need to recreate all swap chains!
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
||||||
VkResult err = vkDeviceWaitIdle(v->Device);
|
VkResult err = vkDeviceWaitIdle(v->Device);
|
||||||
check_vk_result(err);
|
check_vk_result(err);
|
||||||
ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(v->Device, v->Allocator);
|
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &bd->MainWindowRenderBuffers, v->Allocator);
|
||||||
|
|
||||||
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
bd->VulkanInitInfo.MinImageCount = min_image_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1772,6 +1770,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V
|
|||||||
wd->ImageCount = 0;
|
wd->ImageCount = 0;
|
||||||
if (wd->RenderPass)
|
if (wd->RenderPass)
|
||||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||||
|
if (wd->Pipeline)
|
||||||
|
vkDestroyPipeline(device, wd->Pipeline, allocator);
|
||||||
|
|
||||||
// If min image count was not specified, request different count of images dependent on selected present mode
|
// If min image count was not specified, request different count of images dependent on selected present mode
|
||||||
if (min_image_count == 0)
|
if (min_image_count == 0)
|
||||||
@ -2015,6 +2015,7 @@ void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui
|
|||||||
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
ImGui_ImplVulkanH_DestroyFrameSemaphores(device, &wd->FrameSemaphores[i], allocator);
|
||||||
wd->Frames.clear();
|
wd->Frames.clear();
|
||||||
wd->FrameSemaphores.clear();
|
wd->FrameSemaphores.clear();
|
||||||
|
vkDestroyPipeline(device, wd->Pipeline, allocator);
|
||||||
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
vkDestroyRenderPass(device, wd->RenderPass, allocator);
|
||||||
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
vkDestroySwapchainKHR(device, wd->Swapchain, allocator);
|
||||||
wd->RenderPass = VK_NULL_HANDLE;
|
wd->RenderPass = VK_NULL_HANDLE;
|
||||||
@ -2044,335 +2045,6 @@ void ImGui_ImplVulkanH_DestroyFrameSemaphores(VkDevice device, ImGui_ImplVulkanH
|
|||||||
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
|
fsd->ImageAcquiredSemaphore = fsd->RenderCompleteSemaphore = VK_NULL_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGui_ImplVulkanH_DestroyAllViewportsRenderBuffers(VkDevice device, const VkAllocationCallbacks* allocator)
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
|
||||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)platform_io.Viewports[n]->RendererUserData)
|
|
||||||
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.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
|
||||||
ImGui_ImplVulkan_ViewportData* vd = IM_NEW(ImGui_ImplVulkan_ViewportData)();
|
|
||||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
|
||||||
|
|
||||||
// Create surface
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
VkResult err = (VkResult)platform_io.Platform_CreateVkSurface(viewport, (ImU64)v->Instance, (const void*)v->Allocator, (ImU64*)&wd->Surface);
|
|
||||||
check_vk_result(err);
|
|
||||||
|
|
||||||
// Check if surface creation failed
|
|
||||||
if (err != VK_SUCCESS || wd->Surface == VK_NULL_HANDLE)
|
|
||||||
{
|
|
||||||
IM_DELETE(vd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for WSI support
|
|
||||||
VkBool32 res;
|
|
||||||
vkGetPhysicalDeviceSurfaceSupportKHR(v->PhysicalDevice, v->QueueFamily, wd->Surface, &res);
|
|
||||||
if (res != VK_TRUE)
|
|
||||||
{
|
|
||||||
vkDestroySurfaceKHR(v->Instance, wd->Surface, v->Allocator); // Error: no WSI support on physical device, clean up and return
|
|
||||||
IM_DELETE(vd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = vd;
|
|
||||||
|
|
||||||
// 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 < 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)
|
|
||||||
requestSurfaceImageFormats.push_back(format);
|
|
||||||
|
|
||||||
const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
|
|
||||||
wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(v->PhysicalDevice, wd->Surface, requestSurfaceImageFormats.Data, requestSurfaceImageFormats.Size, requestSurfaceColorSpace);
|
|
||||||
|
|
||||||
// Select Present Mode
|
|
||||||
// FIXME-VULKAN: Even thought mailbox seems to get us maximum framerate with a single window, it halves framerate with a second window etc. (w/ Nvidia and SDK 1.82.1)
|
|
||||||
VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR };
|
|
||||||
wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(v->PhysicalDevice, wd->Surface, &present_modes[0], IM_COUNTOF(present_modes));
|
|
||||||
//printf("[vulkan] Secondary window selected PresentMode = %d\n", wd->PresentMode);
|
|
||||||
|
|
||||||
// Create SwapChain, RenderPass, Framebuffer, etc.
|
|
||||||
wd->UseDynamicRendering = v->UseDynamicRendering;
|
|
||||||
wd->AttachmentDesc.loadOp = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
#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;
|
|
||||||
bd->PipelineRenderingCreateInfoColorAttachmentFormats.resize(1);
|
|
||||||
bd->PipelineRenderingCreateInfoColorAttachmentFormats[0] = wd->SurfaceFormat.format;
|
|
||||||
pipeline_info->PipelineRenderingCreateInfo.pColorAttachmentFormats = bd->PipelineRenderingCreateInfoColorAttachmentFormats.Data;
|
|
||||||
}
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
// The main viewport (owned by the application) will always have RendererUserData == 0 since we didn't create the data for it.
|
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
|
||||||
if (ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
|
||||||
if (vd->WindowOwned)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkanH_DestroyWindow(v->Instance, v->Device, &vd->Window, v->Allocator);
|
|
||||||
vkDestroySurfaceKHR(v->Instance, vd->Window.Surface, v->Allocator);
|
|
||||||
}
|
|
||||||
ImGui_ImplVulkan_DestroyWindowRenderBuffers(v->Device, &vd->RenderBuffers, v->Allocator);
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->RendererUserData = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplVulkan_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
|
||||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd == nullptr) // This is nullptr for the main viewport (which is left to the user/app to handle)
|
|
||||||
return;
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
|
||||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
|
||||||
wd->AttachmentDesc.loadOp = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
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*)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
|
||||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd == nullptr)
|
|
||||||
return;
|
|
||||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
|
||||||
VkResult err;
|
|
||||||
|
|
||||||
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, v->PipelineInfoForViewports.SwapChainImageUsage);
|
|
||||||
vd->SwapChainNeedRebuild = vd->SwapChainSuboptimal = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplVulkanH_Frame* fd = nullptr;
|
|
||||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
|
||||||
{
|
|
||||||
{
|
|
||||||
err = vkAcquireNextImageKHR(v->Device, wd->Swapchain, UINT64_MAX, fsd->ImageAcquiredSemaphore, VK_NULL_HANDLE, &wd->FrameIndex);
|
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
|
||||||
{
|
|
||||||
vd->SwapChainNeedRebuild = true; // Since we are not going to swap this frame anyway, it's ok that recreation happens on next frame.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (err == VK_SUBOPTIMAL_KHR)
|
|
||||||
vd->SwapChainSuboptimal = true;
|
|
||||||
else
|
|
||||||
check_vk_result(err);
|
|
||||||
fd = &wd->Frames[wd->FrameIndex];
|
|
||||||
}
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
err = vkWaitForFences(v->Device, 1, &fd->Fence, VK_TRUE, 100);
|
|
||||||
if (err == VK_SUCCESS) break;
|
|
||||||
if (err == VK_TIMEOUT) continue;
|
|
||||||
check_vk_result(err);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
err = vkResetCommandPool(v->Device, fd->CommandPool, 0);
|
|
||||||
check_vk_result(err);
|
|
||||||
VkCommandBufferBeginInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
|
|
||||||
info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
|
|
||||||
err = vkBeginCommandBuffer(fd->CommandBuffer, &info);
|
|
||||||
check_vk_result(err);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float));
|
|
||||||
}
|
|
||||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
|
||||||
if (v->UseDynamicRendering)
|
|
||||||
{
|
|
||||||
// Transition swapchain image to a layout suitable for drawing.
|
|
||||||
VkImageMemoryBarrier barrier = {};
|
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
||||||
barrier.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
||||||
barrier.oldLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
barrier.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
barrier.image = fd->Backbuffer;
|
|
||||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
barrier.subresourceRange.levelCount = 1;
|
|
||||||
barrier.subresourceRange.layerCount = 1;
|
|
||||||
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_NONE, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
|
||||||
|
|
||||||
VkRenderingAttachmentInfo attachmentInfo = {};
|
|
||||||
attachmentInfo.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR;
|
|
||||||
attachmentInfo.imageView = fd->BackbufferView;
|
|
||||||
attachmentInfo.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
attachmentInfo.resolveMode = VK_RESOLVE_MODE_NONE;
|
|
||||||
attachmentInfo.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
|
||||||
attachmentInfo.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
|
||||||
attachmentInfo.clearValue = wd->ClearValue;
|
|
||||||
|
|
||||||
VkRenderingInfo renderingInfo = {};
|
|
||||||
renderingInfo.sType = VK_STRUCTURE_TYPE_RENDERING_INFO_KHR;
|
|
||||||
renderingInfo.renderArea.extent.width = wd->Width;
|
|
||||||
renderingInfo.renderArea.extent.height = wd->Height;
|
|
||||||
renderingInfo.layerCount = 1;
|
|
||||||
renderingInfo.viewMask = 0;
|
|
||||||
renderingInfo.colorAttachmentCount = 1;
|
|
||||||
renderingInfo.pColorAttachments = &attachmentInfo;
|
|
||||||
|
|
||||||
ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR(fd->CommandBuffer, &renderingInfo);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
VkRenderPassBeginInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
|
|
||||||
info.renderPass = wd->RenderPass;
|
|
||||||
info.framebuffer = fd->Framebuffer;
|
|
||||||
info.renderArea.extent.width = wd->Width;
|
|
||||||
info.renderArea.extent.height = wd->Height;
|
|
||||||
info.clearValueCount = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? 0 : 1;
|
|
||||||
info.pClearValues = (viewport->Flags & ImGuiViewportFlags_NoRendererClear) ? nullptr : &wd->ClearValue;
|
|
||||||
vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplVulkan_RenderDrawData(viewport->DrawData, fd->CommandBuffer, bd->PipelineForViewports);
|
|
||||||
|
|
||||||
{
|
|
||||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
|
||||||
if (v->UseDynamicRendering)
|
|
||||||
{
|
|
||||||
ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR(fd->CommandBuffer);
|
|
||||||
|
|
||||||
// Transition image to a layout suitable for presentation
|
|
||||||
VkImageMemoryBarrier barrier = {};
|
|
||||||
barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
|
|
||||||
barrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
|
|
||||||
barrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
|
|
||||||
barrier.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
|
|
||||||
barrier.image = fd->Backbuffer;
|
|
||||||
barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
|
|
||||||
barrier.subresourceRange.levelCount = 1;
|
|
||||||
barrier.subresourceRange.layerCount = 1;
|
|
||||||
vkCmdPipelineBarrier(fd->CommandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
vkCmdEndRenderPass(fd->CommandBuffer);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
|
|
||||||
VkSubmitInfo info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
|
|
||||||
info.waitSemaphoreCount = 1;
|
|
||||||
info.pWaitSemaphores = &fsd->ImageAcquiredSemaphore;
|
|
||||||
info.pWaitDstStageMask = &wait_stage;
|
|
||||||
info.commandBufferCount = 1;
|
|
||||||
info.pCommandBuffers = &fd->CommandBuffer;
|
|
||||||
info.signalSemaphoreCount = 1;
|
|
||||||
info.pSignalSemaphores = &fsd->RenderCompleteSemaphore;
|
|
||||||
|
|
||||||
err = vkEndCommandBuffer(fd->CommandBuffer);
|
|
||||||
check_vk_result(err);
|
|
||||||
err = vkResetFences(v->Device, 1, &fd->Fence);
|
|
||||||
check_vk_result(err);
|
|
||||||
err = vkQueueSubmit(v->Queue, 1, &info, fd->Fence);
|
|
||||||
check_vk_result(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport, void*)
|
|
||||||
{
|
|
||||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
|
||||||
ImGui_ImplVulkan_ViewportData* vd = (ImGui_ImplVulkan_ViewportData*)viewport->RendererUserData;
|
|
||||||
if (vd == nullptr)
|
|
||||||
return;
|
|
||||||
ImGui_ImplVulkanH_Window* wd = &vd->Window;
|
|
||||||
ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo;
|
|
||||||
|
|
||||||
if (vd->SwapChainNeedRebuild) // Frame data became invalid in the middle of rendering
|
|
||||||
return;
|
|
||||||
|
|
||||||
VkResult err;
|
|
||||||
uint32_t present_index = wd->FrameIndex;
|
|
||||||
|
|
||||||
ImGui_ImplVulkanH_FrameSemaphores* fsd = &wd->FrameSemaphores[wd->SemaphoreIndex];
|
|
||||||
VkPresentInfoKHR info = {};
|
|
||||||
info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR;
|
|
||||||
info.waitSemaphoreCount = 1;
|
|
||||||
info.pWaitSemaphores = &fsd->RenderCompleteSemaphore;
|
|
||||||
info.swapchainCount = 1;
|
|
||||||
info.pSwapchains = &wd->Swapchain;
|
|
||||||
info.pImageIndices = &present_index;
|
|
||||||
err = vkQueuePresentKHR(v->Queue, &info);
|
|
||||||
if (err == VK_ERROR_OUT_OF_DATE_KHR)
|
|
||||||
{
|
|
||||||
vd->SwapChainNeedRebuild = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (err == VK_SUBOPTIMAL_KHR)
|
|
||||||
vd->SwapChainSuboptimal = true;
|
|
||||||
else
|
|
||||||
check_vk_result(err);
|
|
||||||
wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplVulkan_InitMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
if (ImGui::GetIO().BackendFlags & ImGuiBackendFlags_PlatformHasViewports)
|
|
||||||
IM_ASSERT(platform_io.Platform_CreateVkSurface != nullptr && "Platform needs to setup the CreateVkSurface handler.");
|
|
||||||
platform_io.Renderer_CreateWindow = ImGui_ImplVulkan_CreateWindow;
|
|
||||||
platform_io.Renderer_DestroyWindow = ImGui_ImplVulkan_DestroyWindow;
|
|
||||||
platform_io.Renderer_SetWindowSize = ImGui_ImplVulkan_SetWindowSize;
|
|
||||||
platform_io.Renderer_RenderWindow = ImGui_ImplVulkan_RenderWindow;
|
|
||||||
platform_io.Renderer_SwapBuffers = ImGui_ImplVulkan_SwapBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplVulkan_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#endif // #ifndef IMGUI_DISABLE
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [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: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplVulkan_GetRenderState().
|
||||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
|
||||||
|
|
||||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||||
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
// IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/
|
||||||
@ -85,19 +84,13 @@
|
|||||||
// Specify settings to create pipeline and swapchain
|
// Specify settings to create pipeline and swapchain
|
||||||
struct ImGui_ImplVulkan_PipelineInfo
|
struct ImGui_ImplVulkan_PipelineInfo
|
||||||
{
|
{
|
||||||
// For Main viewport only
|
|
||||||
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
VkRenderPass RenderPass; // Ignored if using dynamic rendering
|
||||||
|
|
||||||
// For Main and Secondary viewports
|
|
||||||
uint32_t Subpass; //
|
uint32_t Subpass; //
|
||||||
VkSampleCountFlagBits MSAASamples = {}; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
VkSampleCountFlagBits MSAASamples = {}; // 0 defaults to VK_SAMPLE_COUNT_1_BIT
|
||||||
ImVector<VkDynamicState> ExtraDynamicStates; // Optional, allows to insert more dynamic states into our VkPipeline
|
ImVector<VkDynamicState> ExtraDynamicStates; // Optional, allows to insert more dynamic states into our VkPipeline
|
||||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||||
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
|
VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Optional, valid if .sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR
|
||||||
#endif
|
#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()
|
// Initialization data, for ImGui_ImplVulkan_Init()
|
||||||
@ -108,6 +101,7 @@ struct ImGui_ImplVulkan_PipelineInfo
|
|||||||
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
// - As an convenience, by setting DescriptorPoolSize > 0 the backend will create one for you.
|
||||||
// - About dynamic rendering:
|
// - About dynamic rendering:
|
||||||
// - When using dynamic rendering, set UseDynamicRendering=true + fill PipelineInfoMain.PipelineRenderingCreateInfo structure.
|
// - When using dynamic rendering, set UseDynamicRendering=true + fill PipelineInfoMain.PipelineRenderingCreateInfo structure.
|
||||||
|
// - PipelineRenderingCreateInfo may describe multiple color attachments: we render to the first one and leave the others untouched. This requires the 'independentBlend' device feature.
|
||||||
struct ImGui_ImplVulkan_InitInfo
|
struct ImGui_ImplVulkan_InitInfo
|
||||||
{
|
{
|
||||||
uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3 or your value of VkApplicationInfo::apiVersion. May be lower than header version (VK_HEADER_VERSION_COMPLETE)
|
uint32_t ApiVersion; // Fill with API version of Instance, e.g. VK_API_VERSION_1_3 or your value of VkApplicationInfo::apiVersion. May be lower than header version (VK_HEADER_VERSION_COMPLETE)
|
||||||
@ -124,14 +118,13 @@ struct ImGui_ImplVulkan_InitInfo
|
|||||||
|
|
||||||
// Pipeline
|
// Pipeline
|
||||||
ImGui_ImplVulkan_PipelineInfo PipelineInfoMain; // Infos for Main Viewport (created by app/user)
|
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
|
//VkRenderPass RenderPass; // --> Since 2025/09/26: set 'PipelineInfoMain.RenderPass' instead
|
||||||
//uint32_t Subpass; // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
|
//uint32_t Subpass; // --> Since 2025/09/26: set 'PipelineInfoMain.Subpass' instead
|
||||||
//VkSampleCountFlagBits MSAASamples; // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
|
//VkSampleCountFlagBits MSAASamples; // --> Since 2025/09/26: set 'PipelineInfoMain.MSAASamples' instead
|
||||||
//VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
|
//VkPipelineRenderingCreateInfoKHR PipelineRenderingCreateInfo; // Since 2025/09/26: set 'PipelineInfoMain.PipelineRenderingCreateInfo' instead
|
||||||
|
|
||||||
// (Optional) Dynamic Rendering
|
// (Optional) Dynamic Rendering
|
||||||
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo and PipelineInfoViewports.PipelineRenderingCreateInfo.
|
// Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3 + setup PipelineInfoMain.PipelineRenderingCreateInfo.
|
||||||
bool UseDynamicRendering;
|
bool UseDynamicRendering;
|
||||||
|
|
||||||
// (Optional) Allocation, Debugging
|
// (Optional) Allocation, Debugging
|
||||||
@ -183,6 +176,7 @@ struct ImGui_ImplVulkan_RenderState
|
|||||||
VkPipeline Pipeline;
|
VkPipeline Pipeline;
|
||||||
VkPipelineLayout PipelineLayout;
|
VkPipelineLayout PipelineLayout;
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState();
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Internal / Miscellaneous Vulkan Helpers
|
// Internal / Miscellaneous Vulkan Helpers
|
||||||
@ -216,7 +210,6 @@ IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysic
|
|||||||
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
IMGUI_IMPL_API VkPhysicalDevice ImGui_ImplVulkanH_SelectPhysicalDevice(VkInstance instance);
|
||||||
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
IMGUI_IMPL_API uint32_t ImGui_ImplVulkanH_SelectQueueFamilyIndex(VkPhysicalDevice physical_device);
|
||||||
IMGUI_IMPL_API int ImGui_ImplVulkanH_GetMinImageCountFromPresentMode(VkPresentModeKHR present_mode);
|
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
|
// 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.)
|
// (Used by example's main.cpp. Used by multi-viewport features. Probably NOT used by your own engine/app.)
|
||||||
@ -254,6 +247,7 @@ struct ImGui_ImplVulkanH_Window
|
|||||||
int Height;
|
int Height;
|
||||||
VkSwapchainKHR Swapchain;
|
VkSwapchainKHR Swapchain;
|
||||||
VkRenderPass RenderPass;
|
VkRenderPass RenderPass;
|
||||||
|
VkPipeline Pipeline; // The window pipeline may uses a different VkRenderPass than the one passed in ImGui_ImplVulkan_InitInfo
|
||||||
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
uint32_t FrameIndex; // Current frame being rendered to (0 <= FrameIndex < FrameInFlightCount)
|
||||||
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
uint32_t ImageCount; // Number of simultaneous in-flight frames (returned by vkGetSwapchainImagesKHR, usually derived from min_image_count)
|
||||||
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
uint32_t SemaphoreCount; // Number of simultaneous in-flight frames + 1, to be able to use it in vkAcquireNextImageKHR
|
||||||
|
|||||||
@ -5,10 +5,8 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
|
||||||
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// Missing features or Issues:
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplWGPU_GetRenderState().
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop.
|
|
||||||
|
|
||||||
// Read imgui_impl_wgpu.h about how to use the IMGUI_IMPL_WEBGPU_BACKEND_WGPU or IMGUI_IMPL_WEBGPU_BACKEND_DAWN flags.
|
// Read imgui_impl_wgpu.h about how to use the IMGUI_IMPL_WEBGPU_BACKEND_WGPU or IMGUI_IMPL_WEBGPU_BACKEND_DAWN flags.
|
||||||
|
|
||||||
@ -22,6 +20,9 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||||
|
// 2026-08-31: Update to compile with wgpu-native 29.0. (#9377, #9532, #9530)
|
||||||
|
// 2026-08-18: Fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport() when FramebufferScale is >1.0f. (#9515, #8628)
|
||||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||||
// 2026-03-25: Added support for WGVK native backend via IMGUI_IMPL_WEBGPU_BACKEND_WGVK define, with SPIRV shaders if WGSL is not available. (#9316, #9246, #9257)
|
// 2026-03-25: Added support for WGVK native backend via IMGUI_IMPL_WEBGPU_BACKEND_WGVK define, with SPIRV shaders if WGSL is not available. (#9316, #9246, #9257)
|
||||||
// 2026-03-09: Removed support for Emscripten < 4.0.10. (#9281)
|
// 2026-03-09: Removed support for Emscripten < 4.0.10. (#9281)
|
||||||
@ -67,12 +68,6 @@
|
|||||||
#error Emscripten <4.0.10 with '-sUSE_WEBGPU=1' is not supported anymore.
|
#error Emscripten <4.0.10 with '-sUSE_WEBGPU=1' is not supported anymore.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK
|
|
||||||
// Dawn renamed WGPUProgrammableStageDescriptor to WGPUComputeState (see: https://github.com/webgpu-native/webgpu-headers/pull/413)
|
|
||||||
// Using type alias until WGPU adopts the same naming convention (#8369)
|
|
||||||
using WGPUProgrammableStageDescriptor = WGPUComputeState;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Dear ImGui prototypes from imgui_internal.h
|
// Dear ImGui prototypes from imgui_internal.h
|
||||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed);
|
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed);
|
||||||
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
|
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
|
||||||
@ -134,6 +129,11 @@ static ImGui_ImplWGPU_Data* ImGui_ImplWGPU_GetBackendData()
|
|||||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState()
|
||||||
|
{
|
||||||
|
return (ImGui_ImplWGPU_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// SHADERS
|
// SHADERS
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -318,7 +318,7 @@ static void SafeRelease(FrameResources& res)
|
|||||||
SafeRelease(res.VertexBufferHost);
|
SafeRelease(res.VertexBufferHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source)
|
static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source)
|
||||||
{
|
{
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
IM_UNUSED(bd);
|
IM_UNUSED(bd);
|
||||||
@ -345,7 +345,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
|
|||||||
pop_cb.userdata1 = &validation_error;
|
pop_cb.userdata1 = &validation_error;
|
||||||
wgpuDevicePopErrorScope(bd->wgpuDevice, pop_cb);
|
wgpuDevicePopErrorScope(bd->wgpuDevice, pop_cb);
|
||||||
|
|
||||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
WGPUComputeState stage_desc = {};
|
||||||
if (module && !validation_error)
|
if (module && !validation_error)
|
||||||
{
|
{
|
||||||
stage_desc.module = module;
|
stage_desc.module = module;
|
||||||
@ -358,7 +358,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
|
|||||||
return stage_desc;
|
return stage_desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length)
|
static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length)
|
||||||
{
|
{
|
||||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||||
|
|
||||||
@ -370,7 +370,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(co
|
|||||||
WGPUShaderModuleDescriptor desc = {};
|
WGPUShaderModuleDescriptor desc = {};
|
||||||
desc.nextInChain = (WGPUChainedStruct*)&spirv_desc;
|
desc.nextInChain = (WGPUChainedStruct*)&spirv_desc;
|
||||||
|
|
||||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
WGPUComputeState stage_desc = {};
|
||||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||||
|
|
||||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||||
@ -442,7 +442,9 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup viewport
|
// Setup viewport
|
||||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, draw_data->FramebufferScale.x * draw_data->DisplaySize.x, draw_data->FramebufferScale.y * draw_data->DisplaySize.y, 0, 1);
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
|
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, (float)fb_width, (float)fb_height, 0, 1);
|
||||||
|
|
||||||
// Bind shader and vertex buffers
|
// Bind shader and vertex buffers
|
||||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
|
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
|
||||||
@ -464,8 +466,8 @@ static void ImGui_ImplWGPU_DrawCallback_SetSamplerNearest(const ImDrawList*, con
|
|||||||
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
|
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
|
||||||
{
|
{
|
||||||
// Avoid rendering when minimized
|
// Avoid rendering when minimized
|
||||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -771,7 +773,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc);
|
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc);
|
||||||
|
|
||||||
// Create the vertex shader
|
// Create the vertex shader
|
||||||
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl);
|
WGPUComputeState vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl);
|
||||||
if (!vertex_shader_desc.module) vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_vert_spirv, sizeof(__shader_vert_spirv));
|
if (!vertex_shader_desc.module) vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_vert_spirv, sizeof(__shader_vert_spirv));
|
||||||
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
|
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
|
||||||
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
|
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
|
||||||
@ -779,15 +781,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
// Vertex input configuration
|
// Vertex input configuration
|
||||||
WGPUVertexAttribute attribute_desc[] =
|
WGPUVertexAttribute attribute_desc[] =
|
||||||
{
|
{
|
||||||
#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK
|
|
||||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||||
{ nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
{ nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||||
#else
|
|
||||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
|
||||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
|
||||||
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
WGPUVertexBufferLayout buffer_layouts[1];
|
WGPUVertexBufferLayout buffer_layouts[1];
|
||||||
@ -800,7 +796,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
graphics_pipeline_desc.vertex.buffers = buffer_layouts;
|
graphics_pipeline_desc.vertex.buffers = buffer_layouts;
|
||||||
|
|
||||||
// Create the pixel shader
|
// Create the pixel shader
|
||||||
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl);
|
WGPUComputeState pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl);
|
||||||
if (!pixel_shader_desc.module) pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_frag_spirv, sizeof(__shader_frag_spirv));
|
if (!pixel_shader_desc.module) pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_frag_spirv, sizeof(__shader_frag_spirv));
|
||||||
|
|
||||||
// Create the blending setup
|
// Create the blending setup
|
||||||
@ -846,8 +842,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
|||||||
|
|
||||||
ImGui_ImplWGPU_CreateUniformBuffer();
|
ImGui_ImplWGPU_CreateUniformBuffer();
|
||||||
|
|
||||||
// Create samplers (Linear/Nearest)
|
// Create samplers (Linear/Nearest) (bilinear sampling is required)
|
||||||
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
|
||||||
WGPUSamplerDescriptor sampler_desc = {};
|
WGPUSamplerDescriptor sampler_desc = {};
|
||||||
sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
|
sampler_desc.addressModeU = WGPUAddressMode_ClampToEdge;
|
||||||
sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
|
sampler_desc.addressModeV = WGPUAddressMode_ClampToEdge;
|
||||||
@ -994,11 +989,7 @@ void ImGui_ImplWGPU_NewFrame()
|
|||||||
|
|
||||||
bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status)
|
bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status)
|
||||||
{
|
{
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
|
||||||
return (status == WGPUSurfaceGetCurrentTextureStatus_Error);
|
return (status == WGPUSurfaceGetCurrentTextureStatus_Error);
|
||||||
#else
|
|
||||||
return (status == WGPUSurfaceGetCurrentTextureStatus_OutOfMemory || status == WGPUSurfaceGetCurrentTextureStatus_DeviceLost);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status)
|
bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status)
|
||||||
@ -1011,7 +1002,6 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helpers to obtain a string
|
// Helpers to obtain a string
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
|
||||||
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type)
|
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type)
|
||||||
{
|
{
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -1034,7 +1024,7 @@ const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type)
|
|||||||
default: return "Unknown";
|
default: return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif !defined(__EMSCRIPTEN__)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||||
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level)
|
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level)
|
||||||
{
|
{
|
||||||
switch (level)
|
switch (level)
|
||||||
|
|||||||
@ -17,10 +17,8 @@
|
|||||||
// Implemented features:
|
// Implemented features:
|
||||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
|
||||||
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||||
// Missing features or Issues:
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplWGPU_GetRenderState().
|
||||||
// [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -83,6 +81,7 @@ struct ImGui_ImplWGPU_RenderState
|
|||||||
WGPUDevice Device;
|
WGPUDevice Device;
|
||||||
WGPURenderPassEncoder RenderPassEncoder;
|
WGPURenderPassEncoder RenderPassEncoder;
|
||||||
};
|
};
|
||||||
|
IMGUI_IMPL_API ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState();
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// Internal Helpers
|
// Internal Helpers
|
||||||
@ -97,10 +96,9 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextur
|
|||||||
void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter);
|
void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter);
|
||||||
const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type);
|
const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type);
|
||||||
const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type);
|
const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type);
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
|
||||||
const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type);
|
const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type);
|
||||||
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type);
|
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type);
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||||
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level);
|
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
@ -22,24 +21,15 @@
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
|
||||||
// 2026-05-19: DPI: ImGui_ImplWin32_EnableDpiAwareness() helper uses SetProcessDpiAwarenessContext() instead of SetThreadDpiAwarenessContext(), fixes DPI scaling issues with e.g. OpenGL. (#9403)
|
// 2026-05-19: DPI: ImGui_ImplWin32_EnableDpiAwareness() helper uses SetProcessDpiAwarenessContext() instead of SetThreadDpiAwarenessContext(), fixes DPI scaling issues with e.g. OpenGL. (#9403)
|
||||||
// 2026-03-31: [Viewports] Fixed setting/getting size when viewports have OS decorations (e.g. io.ConfigViewportsNoDecoration = false) and process is running in Per-Monitor V2 DPI mode. (#8897)
|
|
||||||
// 2026-01-28: Inputs: Minor optimization not submitting gamepad input if packet number has not changed (reworked from 2025-09-23 attempt). (#9202, #8556)
|
// 2026-01-28: Inputs: Minor optimization not submitting gamepad input if packet number has not changed (reworked from 2025-09-23 attempt). (#9202, #8556)
|
||||||
// 2026-01-26: [Viewports] Fixed an issue from 1.90.5 where newly appearing windows that are not parented to the main viewport don't have task bar icon appear before the windows was explicited refocused. (#7354, #8669)
|
|
||||||
// 2025-12-03: Inputs: handle WM_IME_CHAR/WM_IME_COMPOSITION messages to support Unicode inputs on MBCS (non-Unicode) Windows. (#9099, #3653, #5961)
|
// 2025-12-03: Inputs: handle WM_IME_CHAR/WM_IME_COMPOSITION messages to support Unicode inputs on MBCS (non-Unicode) Windows. (#9099, #3653, #5961)
|
||||||
// 2025-10-19: Inputs: Revert previous change to allow for io.ClearInputKeys() on focus-out not losing gamepad state.
|
// 2025-10-19: Inputs: Revert previous change to allow for io.ClearInputKeys() on focus-out not losing gamepad state.
|
||||||
// 2025-09-23: Inputs: Minor optimization not submitting gamepad input if packet number has not changed.
|
// 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-09-18: Call platform_io.ClearPlatformHandlers() on shutdown.
|
||||||
// 2025-06-02: [Viewports] 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-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: [Viewports] 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.
|
|
||||||
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
// 2025-03-10: When dealing with OEM keys, use scancodes instead of translated keycodes to choose ImGuiKey values. (#7136, #7201, #7206, #7306, #7670, #7672, #8468)
|
||||||
// 2025-02-21: [Viewports] WM_SETTINGCHANGE's SPI_SETWORKAREA message also triggers a refresh of monitor list. (#8415)
|
|
||||||
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
// 2025-02-18: Added ImGuiMouseCursor_Wait and ImGuiMouseCursor_Progress mouse cursor support.
|
||||||
// 2024-11-21: [Viewports] Fixed a crash when multiple processes are running with multi-viewports, caused by misusage of GetProp(). (#8162, #8069)
|
|
||||||
// 2024-10-28: [Viewports] Rely on property stored inside HWND to retrieve context/viewport, should facilitate attempt to use this for parallel contexts. (#8069)
|
|
||||||
// 2024-09-16: [Viewports] Inputs: fixed an issue where a viewport destroyed while clicking would hog mouse tracking and temporary lead to incorrect update of HoveredWindow. (#7971)
|
|
||||||
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
// 2024-07-08: Inputs: Fixed ImGuiMod_Super being mapped to VK_APPS instead of VK_LWIN||VK_RWIN. (#7768)
|
||||||
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
// 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys.
|
||||||
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
// 2023-09-25: Inputs: Synthesize key-down event on key-up for VK_SNAPSHOT / ImGuiKey_PrintScreen as Windows doesn't emit it (same behavior as GLFW/SDL).
|
||||||
@ -110,7 +100,6 @@
|
|||||||
typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||||
typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||||
#endif
|
#endif
|
||||||
typedef BOOL(WINAPI* PFN_AdjustWindowRectExForDpi)(LPRECT, DWORD, BOOL, DWORD, UINT);
|
|
||||||
|
|
||||||
// Clang/GCC warnings with -Weverything
|
// Clang/GCC warnings with -Weverything
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
@ -123,12 +112,6 @@ typedef BOOL(WINAPI* PFN_AdjustWindowRectExForDpi)(LPRECT, DWORD, BOOL, DWORD, U
|
|||||||
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Forward Declarations
|
|
||||||
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc);
|
|
||||||
static void ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
|
||||||
static void ImGui_ImplWin32_UpdateMonitors();
|
|
||||||
static bool ImGui_ImplWin32_IsDpiAwarenessPerMonitorAwareV2();
|
|
||||||
|
|
||||||
struct ImGui_ImplWin32_Data
|
struct ImGui_ImplWin32_Data
|
||||||
{
|
{
|
||||||
HWND hWnd;
|
HWND hWnd;
|
||||||
@ -139,9 +122,6 @@ struct ImGui_ImplWin32_Data
|
|||||||
INT64 TicksPerSecond;
|
INT64 TicksPerSecond;
|
||||||
ImGuiMouseCursor LastMouseCursor;
|
ImGuiMouseCursor LastMouseCursor;
|
||||||
UINT32 KeyboardCodePage;
|
UINT32 KeyboardCodePage;
|
||||||
bool WantUpdateMonitors;
|
|
||||||
bool IsPerMonitorDpiAwareV2;
|
|
||||||
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi;
|
|
||||||
|
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
bool HasGamepad;
|
bool HasGamepad;
|
||||||
@ -197,9 +177,6 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
|||||||
io.BackendPlatformName = "imgui_impl_win32";
|
io.BackendPlatformName = "imgui_impl_win32";
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
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->hWnd = (HWND)hwnd;
|
||||||
bd->TicksPerSecond = perf_frequency;
|
bd->TicksPerSecond = perf_frequency;
|
||||||
@ -207,21 +184,10 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc)
|
|||||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||||
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
ImGui_ImplWin32_UpdateKeyboardCodePage(io);
|
||||||
|
|
||||||
// Update monitor a first time during init
|
|
||||||
ImGui_ImplWin32_UpdateMonitors();
|
|
||||||
|
|
||||||
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
// Our mouse update function expect PlatformHandle to be filled for the main viewport
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
||||||
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd;
|
||||||
|
IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch
|
||||||
// Be aware that GetPropA()/SetPropA() may be accessed from other processes.
|
|
||||||
// So as we store a pointer in IMGUI_CONTEXT we need to make sure we only call GetPropA() on windows owned by our process.
|
|
||||||
::SetPropA(bd->hWnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
|
|
||||||
ImGui_ImplWin32_InitMultiViewportSupport(platform_has_own_dc);
|
|
||||||
|
|
||||||
if (HINSTANCE user32_dll = ::GetModuleHandleA("user32.dll"))
|
|
||||||
bd->AdjustWindowRectExForDpi = (PFN_AdjustWindowRectExForDpi)::GetProcAddress(user32_dll, "AdjustWindowRectExForDpi");
|
|
||||||
bd->IsPerMonitorDpiAwareV2 = ImGui_ImplWin32_IsDpiAwarenessPerMonitorAwareV2();
|
|
||||||
|
|
||||||
// Dynamically load XInput library
|
// Dynamically load XInput library
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
@ -265,9 +231,6 @@ void ImGui_ImplWin32_Shutdown()
|
|||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
::SetPropA(bd->hWnd, "IMGUI_CONTEXT", nullptr);
|
|
||||||
ImGui_ImplWin32_ShutdownMultiViewportSupport();
|
|
||||||
|
|
||||||
// Unload XInput library
|
// Unload XInput library
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
if (bd->XInputDLL)
|
if (bd->XInputDLL)
|
||||||
@ -276,7 +239,7 @@ void ImGui_ImplWin32_Shutdown()
|
|||||||
|
|
||||||
io.BackendPlatformName = nullptr;
|
io.BackendPlatformName = nullptr;
|
||||||
io.BackendPlatformUserData = nullptr;
|
io.BackendPlatformUserData = nullptr;
|
||||||
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad | ImGuiBackendFlags_PlatformHasViewports | ImGuiBackendFlags_HasMouseHoveredViewport | ImGuiBackendFlags_HasParentViewport);
|
io.BackendFlags &= ~(ImGuiBackendFlags_HasMouseCursors | ImGuiBackendFlags_HasSetMousePos | ImGuiBackendFlags_HasGamepad);
|
||||||
platform_io.ClearPlatformHandlers();
|
platform_io.ClearPlatformHandlers();
|
||||||
IM_DELETE(bd);
|
IM_DELETE(bd);
|
||||||
}
|
}
|
||||||
@ -349,69 +312,32 @@ static void ImGui_ImplWin32_UpdateKeyModifiers(ImGuiIO& io)
|
|||||||
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
|
io.AddKeyEvent(ImGuiMod_Super, IsVkDown(VK_LWIN) || IsVkDown(VK_RWIN));
|
||||||
}
|
}
|
||||||
|
|
||||||
static ImGuiViewport* ImGui_ImplWin32_FindViewportByPlatformHandle(ImGuiPlatformIO& platform_io, HWND hwnd)
|
static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io)
|
||||||
{
|
|
||||||
// We cannot use ImGui::FindViewportByPlatformHandle() because it doesn't take a context.
|
|
||||||
// When called from ImGui_ImplWin32_WndProcHandler_PlatformWindow() we don't assume that context is bound.
|
|
||||||
//return ImGui::FindViewportByPlatformHandle((void*)hwnd);
|
|
||||||
for (ImGuiViewport* viewport : platform_io.Viewports)
|
|
||||||
if (viewport->PlatformHandle == hwnd)
|
|
||||||
return viewport;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This code supports multi-viewports (multiple OS Windows mapped into different Dear ImGui viewports)
|
|
||||||
// Because of that, it is a little more complicated than your typical single-viewport binding code!
|
|
||||||
static void ImGui_ImplWin32_UpdateMouseData(ImGuiIO& io, ImGuiPlatformIO& platform_io)
|
|
||||||
{
|
{
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(io);
|
||||||
IM_ASSERT(bd->hWnd != 0);
|
IM_ASSERT(bd->hWnd != 0);
|
||||||
|
|
||||||
POINT mouse_screen_pos;
|
|
||||||
bool has_mouse_screen_pos = ::GetCursorPos(&mouse_screen_pos) != 0;
|
|
||||||
|
|
||||||
HWND focused_window = ::GetForegroundWindow();
|
HWND focused_window = ::GetForegroundWindow();
|
||||||
const bool is_app_focused = (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd) || ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, focused_window)));
|
const bool is_app_focused = (focused_window == bd->hWnd);
|
||||||
if (is_app_focused)
|
if (is_app_focused)
|
||||||
{
|
{
|
||||||
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||||
// When multi-viewports are enabled, all Dear ImGui positions are same as OS positions.
|
|
||||||
if (io.WantSetMousePos)
|
if (io.WantSetMousePos)
|
||||||
{
|
{
|
||||||
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y };
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) == 0)
|
if (::ClientToScreen(bd->hWnd, &pos))
|
||||||
::ClientToScreen(focused_window, &pos);
|
::SetCursorPos(pos.x, pos.y);
|
||||||
::SetCursorPos(pos.x, pos.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
// (Optional) Fallback to provide mouse position when focused (WM_MOUSEMOVE already provides this when hovered or captured)
|
||||||
// This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
|
// This also fills a short gap when clicking non-client area: WM_NCMOUSELEAVE -> modal OS move -> gap -> WM_NCMOUSEMOVE
|
||||||
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0 && has_mouse_screen_pos)
|
if (!io.WantSetMousePos && bd->MouseTrackedArea == 0)
|
||||||
{
|
{
|
||||||
// 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)
|
POINT pos;
|
||||||
// (This is the position you can get with ::GetCursorPos() + ::ScreenToClient() or WM_MOUSEMOVE.)
|
if (::GetCursorPos(&pos) && ::ScreenToClient(bd->hWnd, &pos))
|
||||||
// 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)
|
io.AddMousePosEvent((float)pos.x, (float)pos.y);
|
||||||
// (This is the position you can get with ::GetCursorPos() or WM_MOUSEMOVE + ::ClientToScreen(). In theory adding viewport->Pos to a client position would also be the same.)
|
|
||||||
POINT mouse_pos = mouse_screen_pos;
|
|
||||||
if (!(io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
|
||||||
::ScreenToClient(bd->hWnd, &mouse_pos);
|
|
||||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
|
||||||
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
|
||||||
// - [X] Win32 backend correctly ignore viewports with the _NoInputs flag (here using ::WindowFromPoint with WM_NCHITTEST + HTTRANSPARENT in WndProc does that)
|
|
||||||
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
|
||||||
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
|
||||||
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
|
||||||
// - [X] Win32 backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
|
||||||
ImGuiID mouse_viewport_id = 0;
|
|
||||||
if (has_mouse_screen_pos)
|
|
||||||
if (HWND hovered_hwnd = ::WindowFromPoint(mouse_screen_pos))
|
|
||||||
if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hovered_hwnd))
|
|
||||||
mouse_viewport_id = viewport->ID;
|
|
||||||
io.AddMouseViewportEvent(mouse_viewport_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gamepad navigation mapping
|
// Gamepad navigation mapping
|
||||||
@ -473,50 +399,16 @@ static void ImGui_ImplWin32_UpdateGamepads(ImGuiIO& io)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK ImGui_ImplWin32_UpdateMonitors_EnumFunc(HMONITOR monitor, HDC, LPRECT, LPARAM)
|
|
||||||
{
|
|
||||||
MONITORINFO info = {};
|
|
||||||
info.cbSize = sizeof(MONITORINFO);
|
|
||||||
if (!::GetMonitorInfo(monitor, &info))
|
|
||||||
return TRUE;
|
|
||||||
ImGuiPlatformMonitor imgui_monitor;
|
|
||||||
imgui_monitor.MainPos = ImVec2((float)info.rcMonitor.left, (float)info.rcMonitor.top);
|
|
||||||
imgui_monitor.MainSize = ImVec2((float)(info.rcMonitor.right - info.rcMonitor.left), (float)(info.rcMonitor.bottom - info.rcMonitor.top));
|
|
||||||
imgui_monitor.WorkPos = ImVec2((float)info.rcWork.left, (float)info.rcWork.top);
|
|
||||||
imgui_monitor.WorkSize = ImVec2((float)(info.rcWork.right - info.rcWork.left), (float)(info.rcWork.bottom - info.rcWork.top));
|
|
||||||
imgui_monitor.DpiScale = ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
|
||||||
imgui_monitor.PlatformHandle = (void*)monitor;
|
|
||||||
if (imgui_monitor.DpiScale <= 0.0f)
|
|
||||||
return TRUE; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902.
|
|
||||||
ImGuiPlatformIO& io = ImGui::GetPlatformIO();
|
|
||||||
if (info.dwFlags & MONITORINFOF_PRIMARY)
|
|
||||||
io.Monitors.push_front(imgui_monitor);
|
|
||||||
else
|
|
||||||
io.Monitors.push_back(imgui_monitor);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_UpdateMonitors()
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
||||||
ImGui::GetPlatformIO().Monitors.resize(0);
|
|
||||||
::EnumDisplayMonitors(nullptr, nullptr, ImGui_ImplWin32_UpdateMonitors_EnumFunc, 0);
|
|
||||||
bd->WantUpdateMonitors = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImGui_ImplWin32_NewFrame()
|
void ImGui_ImplWin32_NewFrame()
|
||||||
{
|
{
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||||
IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?");
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized? Did you call ImGui_ImplWin32_Init()?");
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
|
|
||||||
// Setup display size (every frame to accommodate for window resizing)
|
// Setup display size (every frame to accommodate for window resizing)
|
||||||
RECT rect = { 0, 0, 0, 0 };
|
RECT rect = { 0, 0, 0, 0 };
|
||||||
::GetClientRect(bd->hWnd, &rect);
|
::GetClientRect(bd->hWnd, &rect);
|
||||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||||
if (bd->WantUpdateMonitors)
|
|
||||||
ImGui_ImplWin32_UpdateMonitors();
|
|
||||||
|
|
||||||
// Setup time step
|
// Setup time step
|
||||||
INT64 current_time = 0;
|
INT64 current_time = 0;
|
||||||
@ -525,7 +417,7 @@ void ImGui_ImplWin32_NewFrame()
|
|||||||
bd->Time = current_time;
|
bd->Time = current_time;
|
||||||
|
|
||||||
// Update OS mouse position
|
// Update OS mouse position
|
||||||
ImGui_ImplWin32_UpdateMouseData(io, platform_io);
|
ImGui_ImplWin32_UpdateMouseData(io);
|
||||||
|
|
||||||
// Process workarounds for known Windows key handling issues
|
// Process workarounds for known Windows key handling issues
|
||||||
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
|
ImGui_ImplWin32_ProcessKeyEventsWorkarounds(io);
|
||||||
@ -730,10 +622,6 @@ static ImGuiMouseSource ImGui_ImplWin32_GetMouseSourceFromMessageExtraInfo()
|
|||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Use ImGui::GetCurrentContext()
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Use ImGui::GetCurrentContext()
|
||||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io); // Doesn't use ImGui::GetCurrentContext()
|
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, ImGuiIO& io); // Doesn't use ImGui::GetCurrentContext()
|
||||||
|
|
||||||
#ifndef WM_DPICHANGED
|
|
||||||
#define WM_DPICHANGED 0x02E0 // From Windows SDK 8.1+ headers
|
|
||||||
#endif
|
|
||||||
|
|
||||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
|
// Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow().
|
||||||
@ -768,11 +656,8 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPA
|
|||||||
bd->MouseTrackedArea = area;
|
bd->MouseTrackedArea = area;
|
||||||
}
|
}
|
||||||
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) };
|
||||||
bool want_absolute_pos = (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) != 0;
|
if (msg == WM_NCMOUSEMOVE) // WM_NCMOUSEMOVE are absolute coordinates.
|
||||||
if (msg == WM_MOUSEMOVE && want_absolute_pos) // WM_MOUSEMOVE are client-relative coordinates.
|
::ScreenToClient(hwnd, &mouse_pos);
|
||||||
::ClientToScreen(hwnd, &mouse_pos);
|
|
||||||
if (msg == WM_NCMOUSEMOVE && !want_absolute_pos) // WM_NCMOUSEMOVE are absolute coordinates.
|
|
||||||
::ScreenToClient(hwnd, &mouse_pos);
|
|
||||||
io.AddMouseSourceEvent(mouse_source);
|
io.AddMouseSourceEvent(mouse_source);
|
||||||
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y);
|
||||||
return 0;
|
return 0;
|
||||||
@ -942,21 +827,6 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandlerEx(HWND hwnd, UINT msg, WPA
|
|||||||
bd->WantUpdateHasGamepad = true;
|
bd->WantUpdateHasGamepad = true;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
case WM_DISPLAYCHANGE:
|
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
return 0;
|
|
||||||
case WM_SETTINGCHANGE:
|
|
||||||
if (wParam == SPI_SETWORKAREA)
|
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
return 0;
|
|
||||||
case WM_DPICHANGED:
|
|
||||||
{
|
|
||||||
// FIXME-DPI: see SDL3's WM_GETDPISCALEDSIZE handler.
|
|
||||||
const RECT* suggested_rect = (RECT*)lParam;
|
|
||||||
if (io.ConfigDpiScaleViewports)
|
|
||||||
::SetWindowPos(hwnd, nullptr, suggested_rect->left, suggested_rect->top, suggested_rect->right - suggested_rect->left, suggested_rect->bottom - suggested_rect->top, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1014,20 +884,14 @@ DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
|||||||
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
|
||||||
#endif
|
#endif
|
||||||
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
||||||
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
||||||
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
||||||
typedef BOOL (WINAPI* PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1703+ (Creators Update)
|
typedef BOOL(WINAPI* PFN_SetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1703+ (Creators Update)
|
||||||
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_GetThreadDpiAwarenessContext)(); // "
|
|
||||||
typedef BOOL(WINAPI* PFN_AreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT, DPI_AWARENESS_CONTEXT); // "
|
|
||||||
|
|
||||||
// Helper function to enable DPI awareness without setting up a manifest
|
// Helper function to enable DPI awareness without setting up a manifest
|
||||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||||
{
|
{
|
||||||
// Make sure monitors will be updated with latest correct scaling
|
|
||||||
if (ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData())
|
|
||||||
bd->WantUpdateMonitors = true;
|
|
||||||
|
|
||||||
if (_IsWindows10OrGreater())
|
if (_IsWindows10OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||||
@ -1056,18 +920,6 @@ void ImGui_ImplWin32_EnableDpiAwareness()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ImGui_ImplWin32_IsDpiAwarenessPerMonitorAwareV2()
|
|
||||||
{
|
|
||||||
if (!_IsWindows10OrGreater())
|
|
||||||
return false;
|
|
||||||
static HINSTANCE user32_dll = ::GetModuleHandleA("user32.dll");
|
|
||||||
PFN_GetThreadDpiAwarenessContext GetThreadDpiAwarenessContextFn = (PFN_GetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "GetThreadDpiAwarenessContext");
|
|
||||||
PFN_AreDpiAwarenessContextsEqual AreDpiAwarenessContextsEqualFn = (PFN_AreDpiAwarenessContextsEqual)::GetProcAddress(user32_dll, "AreDpiAwarenessContextsEqual");
|
|
||||||
if (GetThreadDpiAwarenessContextFn && AreDpiAwarenessContextsEqualFn)
|
|
||||||
return AreDpiAwarenessContextsEqualFn(GetThreadDpiAwarenessContextFn(), DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) != 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(NOGDI)
|
#if defined(_MSC_VER) && !defined(NOGDI)
|
||||||
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
|
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
|
||||||
#endif
|
#endif
|
||||||
@ -1144,398 +996,6 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
|
||||||
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
|
||||||
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
|
||||||
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
|
||||||
//--------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// Helper structure we store in the void* PlatformUserData field of each ImGuiViewport to easily retrieve our backend data.
|
|
||||||
struct ImGui_ImplWin32_ViewportData
|
|
||||||
{
|
|
||||||
HWND Hwnd; // Stored in ImGuiViewport::PlatformHandle + PlatformHandleRaw
|
|
||||||
HWND HwndParent;
|
|
||||||
bool HwndOwned;
|
|
||||||
DWORD DwStyle;
|
|
||||||
DWORD DwExStyle;
|
|
||||||
|
|
||||||
ImGui_ImplWin32_ViewportData() { Hwnd = HwndParent = nullptr; HwndOwned = false; DwStyle = DwExStyle = 0; }
|
|
||||||
~ImGui_ImplWin32_ViewportData() { IM_ASSERT(Hwnd == nullptr); }
|
|
||||||
};
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_GetWin32StyleFromViewportFlags(ImGuiViewportFlags flags, DWORD* out_style, DWORD* out_ex_style)
|
|
||||||
{
|
|
||||||
if (flags & ImGuiViewportFlags_NoDecoration)
|
|
||||||
*out_style = WS_POPUP;
|
|
||||||
else
|
|
||||||
*out_style = WS_OVERLAPPEDWINDOW;
|
|
||||||
|
|
||||||
if (flags & ImGuiViewportFlags_NoTaskBarIcon)
|
|
||||||
*out_ex_style = WS_EX_TOOLWINDOW;
|
|
||||||
else
|
|
||||||
*out_ex_style = WS_EX_APPWINDOW;
|
|
||||||
|
|
||||||
if (flags & ImGuiViewportFlags_TopMost)
|
|
||||||
*out_ex_style |= WS_EX_TOPMOST;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HWND ImGui_ImplWin32_GetHwndFromViewport(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
if (viewport != nullptr)
|
|
||||||
return (HWND)viewport->PlatformHandle;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_AdjustWindowRect(ImGuiViewport* viewport, RECT* rect, DWORD style, DWORD ex_style)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
||||||
if (bd->AdjustWindowRectExForDpi && bd->IsPerMonitorDpiAwareV2)
|
|
||||||
{
|
|
||||||
UINT dpi = (UINT)(viewport->DpiScale * 96.0f + 0.5f);
|
|
||||||
if (dpi != 0 && bd->AdjustWindowRectExForDpi(rect, style, FALSE, ex_style, dpi))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
::AdjustWindowRectEx(rect, style, FALSE, ex_style);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
|
||||||
viewport->PlatformUserData = vd;
|
|
||||||
|
|
||||||
// Select style and parent window
|
|
||||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &vd->DwStyle, &vd->DwExStyle);
|
|
||||||
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) };
|
|
||||||
ImGui_ImplWin32_AdjustWindowRect(viewport, &rect, vd->DwStyle, vd->DwExStyle);
|
|
||||||
vd->Hwnd = ::CreateWindowExW(
|
|
||||||
vd->DwExStyle, L"ImGui Platform", L"Untitled", vd->DwStyle, // Style, class name, window name
|
|
||||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
|
|
||||||
vd->HwndParent, nullptr, ::GetModuleHandle(nullptr), nullptr); // Owner window, Menu, Instance, Param
|
|
||||||
vd->HwndOwned = true;
|
|
||||||
viewport->PlatformRequestResize = false;
|
|
||||||
viewport->PlatformHandle = viewport->PlatformHandleRaw = vd->Hwnd;
|
|
||||||
|
|
||||||
// Secondary viewports store their imgui context
|
|
||||||
::SetPropA(vd->Hwnd, "IMGUI_CONTEXT", ImGui::GetCurrentContext());
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
||||||
if (ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData)
|
|
||||||
{
|
|
||||||
if (::GetCapture() == vd->Hwnd)
|
|
||||||
{
|
|
||||||
// Transfer capture so if we started dragging from a window that later disappears, we'll still receive the MOUSEUP event.
|
|
||||||
::ReleaseCapture();
|
|
||||||
::SetCapture(bd->hWnd);
|
|
||||||
}
|
|
||||||
if (vd->Hwnd && vd->HwndOwned)
|
|
||||||
::DestroyWindow(vd->Hwnd);
|
|
||||||
vd->Hwnd = nullptr;
|
|
||||||
IM_DELETE(vd);
|
|
||||||
}
|
|
||||||
viewport->PlatformUserData = viewport->PlatformHandle = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_ShowWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
|
|
||||||
// ShowParent() even with SW_SHOWNA also brings parent to front, which is not always desirable,
|
|
||||||
// so we temporarily disable parenting. (#7354, #8669)
|
|
||||||
bool avoid_bringing_parent_to_front = vd->HwndParent != NULL && (viewport->Flags & (ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoTaskBarIcon)) != 0;
|
|
||||||
if (avoid_bringing_parent_to_front)
|
|
||||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)nullptr);
|
|
||||||
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnAppearing)
|
|
||||||
::ShowWindow(vd->Hwnd, SW_SHOWNA);
|
|
||||||
else
|
|
||||||
::ShowWindow(vd->Hwnd, SW_SHOW);
|
|
||||||
|
|
||||||
// Restore
|
|
||||||
if (avoid_bringing_parent_to_front)
|
|
||||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_UpdateWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
|
|
||||||
// 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_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).
|
|
||||||
// Our Dear Imgui-side concept of parenting only mostly care about what Win32 call "Owner".
|
|
||||||
// The parent parameter of CreateWindowEx() sets up Parent OR Owner depending on WS_CHILD flag. In our case an Owner as we never use WS_CHILD.
|
|
||||||
// Calling ::SetParent() here would be incorrect: it will create a full child relation, alter coordinate system and clipping.
|
|
||||||
// Calling ::SetWindowLongPtr() with GWLP_HWNDPARENT seems correct although poorly documented.
|
|
||||||
// https://devblogs.microsoft.com/oldnewthing/20100315-00/?p=14613
|
|
||||||
vd->HwndParent = new_parent;
|
|
||||||
::SetWindowLongPtr(vd->Hwnd, GWLP_HWNDPARENT, (LONG_PTR)vd->HwndParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
// (Optional) Update Win32 style if it changed _after_ creation.
|
|
||||||
// Generally they won't change unless configuration flags are changed, but advanced uses (such as manually rewriting viewport flags) make this useful.
|
|
||||||
DWORD new_style;
|
|
||||||
DWORD new_ex_style;
|
|
||||||
ImGui_ImplWin32_GetWin32StyleFromViewportFlags(viewport->Flags, &new_style, &new_ex_style);
|
|
||||||
|
|
||||||
// Only reapply the flags that have been changed from our point of view (as other flags are being modified by Windows)
|
|
||||||
if (vd->DwStyle != new_style || vd->DwExStyle != new_ex_style)
|
|
||||||
{
|
|
||||||
// (Optional) Update TopMost state if it changed _after_ creation
|
|
||||||
bool top_most_changed = (vd->DwExStyle & WS_EX_TOPMOST) != (new_ex_style & WS_EX_TOPMOST);
|
|
||||||
HWND insert_after = top_most_changed ? ((viewport->Flags & ImGuiViewportFlags_TopMost) ? HWND_TOPMOST : HWND_NOTOPMOST) : 0;
|
|
||||||
UINT swp_flag = top_most_changed ? 0 : SWP_NOZORDER;
|
|
||||||
|
|
||||||
// Apply flags and position (since it is affected by flags)
|
|
||||||
vd->DwStyle = new_style;
|
|
||||||
vd->DwExStyle = new_ex_style;
|
|
||||||
::SetWindowLong(vd->Hwnd, GWL_STYLE, vd->DwStyle);
|
|
||||||
::SetWindowLong(vd->Hwnd, GWL_EXSTYLE, vd->DwExStyle);
|
|
||||||
RECT rect = { (LONG)viewport->Pos.x, (LONG)viewport->Pos.y, (LONG)(viewport->Pos.x + viewport->Size.x), (LONG)(viewport->Pos.y + viewport->Size.y) };
|
|
||||||
ImGui_ImplWin32_AdjustWindowRect(viewport, &rect, vd->DwStyle, vd->DwExStyle); // Client to Screen
|
|
||||||
::SetWindowPos(vd->Hwnd, insert_after, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, swp_flag | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
|
||||||
::ShowWindow(vd->Hwnd, SW_SHOWNA); // This is necessary when we alter the style
|
|
||||||
viewport->PlatformRequestMove = viewport->PlatformRequestResize = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplWin32_GetWindowPos(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
POINT pos = { 0, 0 };
|
|
||||||
::ClientToScreen(vd->Hwnd, &pos);
|
|
||||||
return ImVec2((float)pos.x, (float)pos.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_UpdateWin32StyleFromWindow(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
vd->DwStyle = ::GetWindowLongW(vd->Hwnd, GWL_STYLE);
|
|
||||||
vd->DwExStyle = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_SetWindowPos(ImGuiViewport* viewport, ImVec2 pos)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
RECT rect = { (LONG)pos.x, (LONG)pos.y, (LONG)pos.x, (LONG)pos.y };
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_OwnedByApp)
|
|
||||||
ImGui_ImplWin32_UpdateWin32StyleFromWindow(viewport); // Not our window, poll style before using
|
|
||||||
ImGui_ImplWin32_AdjustWindowRect(viewport, &rect, vd->DwStyle, vd->DwExStyle);
|
|
||||||
::SetWindowPos(vd->Hwnd, nullptr, rect.left, rect.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ImVec2 ImGui_ImplWin32_GetWindowSize(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
RECT rect;
|
|
||||||
::GetClientRect(vd->Hwnd, &rect);
|
|
||||||
return ImVec2(float(rect.right - rect.left), float(rect.bottom - rect.top));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
RECT rect = { 0, 0, (LONG)size.x, (LONG)size.y };
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_OwnedByApp)
|
|
||||||
ImGui_ImplWin32_UpdateWin32StyleFromWindow(viewport); // Not our window, poll style before using
|
|
||||||
ImGui_ImplWin32_AdjustWindowRect(viewport, &rect, vd->DwStyle, vd->DwExStyle); // Client to Screen
|
|
||||||
::SetWindowPos(vd->Hwnd, nullptr, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE | SWP_NOACTIVATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_SetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
::BringWindowToTop(vd->Hwnd);
|
|
||||||
::SetForegroundWindow(vd->Hwnd);
|
|
||||||
::SetFocus(vd->Hwnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
return ::GetForegroundWindow() == vd->Hwnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
return ::IsIconic(vd->Hwnd) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title)
|
|
||||||
{
|
|
||||||
// ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string.
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
int n = ::MultiByteToWideChar(CP_UTF8, 0, title, -1, nullptr, 0);
|
|
||||||
ImVector<wchar_t> title_w;
|
|
||||||
title_w.resize(n);
|
|
||||||
::MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w.Data, n);
|
|
||||||
|
|
||||||
// Calling SetWindowTextW() in a project where UNICODE is not set doesn't work but there's a trick
|
|
||||||
// which is to pass it directly to the DefWindowProcW() handler.
|
|
||||||
// See: https://stackoverflow.com/questions/9410681/setwindowtextw-in-an-ansi-project
|
|
||||||
//::SetWindowTextW(vd->Hwnd, title_w.Data);
|
|
||||||
::DefWindowProcW(vd->Hwnd, WM_SETTEXT, 0, (LPARAM)title_w.Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_SetWindowAlpha(ImGuiViewport* viewport, float alpha)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
|
||||||
if (alpha < 1.0f)
|
|
||||||
{
|
|
||||||
DWORD ex_style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) | WS_EX_LAYERED;
|
|
||||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, ex_style);
|
|
||||||
::SetLayeredWindowAttributes(vd->Hwnd, 0, (BYTE)(255 * alpha), LWA_ALPHA);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DWORD ex_style = ::GetWindowLongW(vd->Hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED;
|
|
||||||
::SetWindowLongW(vd->Hwnd, GWL_EXSTYLE, ex_style);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static float ImGui_ImplWin32_GetWindowDpiScale(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = (ImGui_ImplWin32_ViewportData*)viewport->PlatformUserData;
|
|
||||||
IM_ASSERT(vd->Hwnd != 0);
|
|
||||||
return ImGui_ImplWin32_GetDpiScaleForHwnd(vd->Hwnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME-DPI: Testing DPI related ideas
|
|
||||||
static void ImGui_ImplWin32_OnChangedViewport(ImGuiViewport* viewport)
|
|
||||||
{
|
|
||||||
(void)viewport;
|
|
||||||
#if 0
|
|
||||||
ImGuiStyle default_style;
|
|
||||||
//default_style.WindowPadding = ImVec2(0, 0);
|
|
||||||
//default_style.WindowBorderSize = 0.0f;
|
|
||||||
//default_style.ItemSpacing.y = 3.0f;
|
|
||||||
//default_style.FramePadding = ImVec2(0, 0);
|
|
||||||
default_style.ScaleAllSizes(viewport->DpiScale);
|
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
|
||||||
style = default_style;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace ImGui { extern ImGuiIO& GetIO(ImGuiContext*); extern ImGuiPlatformIO& GetPlatformIO(ImGuiContext*); }
|
|
||||||
|
|
||||||
static LRESULT CALLBACK ImGui_ImplWin32_WndProcHandler_PlatformWindow(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
||||||
{
|
|
||||||
// Allow secondary viewport WndProc to be called regardless of current context
|
|
||||||
ImGuiContext* ctx = (ImGuiContext*)::GetPropA(hWnd, "IMGUI_CONTEXT");
|
|
||||||
if (ctx == NULL)
|
|
||||||
return ::DefWindowProcW(hWnd, msg, wParam, lParam); // unlike ImGui_ImplWin32_WndProcHandler() we are called directly by Windows, we can't just return 0.
|
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO(ctx);
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(ctx);
|
|
||||||
LRESULT result = 0;
|
|
||||||
if (ImGui_ImplWin32_WndProcHandlerEx(hWnd, msg, wParam, lParam, io))
|
|
||||||
result = 1;
|
|
||||||
else if (ImGuiViewport* viewport = ImGui_ImplWin32_FindViewportByPlatformHandle(platform_io, hWnd))
|
|
||||||
{
|
|
||||||
switch (msg)
|
|
||||||
{
|
|
||||||
case WM_CLOSE:
|
|
||||||
viewport->PlatformRequestClose = true;
|
|
||||||
return 0; // 0 = Operating system will ignore the message and not destroy the window. We close ourselves.
|
|
||||||
case WM_MOVE:
|
|
||||||
viewport->PlatformRequestMove = true;
|
|
||||||
break;
|
|
||||||
case WM_SIZE:
|
|
||||||
viewport->PlatformRequestResize = true;
|
|
||||||
break;
|
|
||||||
case WM_MOUSEACTIVATE:
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoFocusOnClick)
|
|
||||||
result = MA_NOACTIVATE;
|
|
||||||
break;
|
|
||||||
case WM_NCHITTEST:
|
|
||||||
// Let mouse pass-through the window. This will allow the backend to call io.AddMouseViewportEvent() correctly. (which is optional).
|
|
||||||
// The ImGuiViewportFlags_NoInputs flag is set while dragging a viewport, as want to detect the window behind the one we are dragging.
|
|
||||||
// If you cannot easily access those viewport flags from your windowing/event code: you may manually synchronize its state e.g. in
|
|
||||||
// your main loop after calling UpdatePlatformWindows(). Iterate all viewports/platform windows and pass the flag to your windowing system.
|
|
||||||
if (viewport->Flags & ImGuiViewportFlags_NoInputs)
|
|
||||||
result = HTTRANSPARENT;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == 0)
|
|
||||||
result = ::DefWindowProcW(hWnd, msg, wParam, lParam);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_InitMultiViewportSupport(bool platform_has_own_dc)
|
|
||||||
{
|
|
||||||
WNDCLASSEXW wcex;
|
|
||||||
wcex.cbSize = sizeof(WNDCLASSEXW);
|
|
||||||
wcex.style = CS_HREDRAW | CS_VREDRAW | (platform_has_own_dc ? CS_OWNDC : 0);
|
|
||||||
wcex.lpfnWndProc = ImGui_ImplWin32_WndProcHandler_PlatformWindow;
|
|
||||||
wcex.cbClsExtra = 0;
|
|
||||||
wcex.cbWndExtra = 0;
|
|
||||||
wcex.hInstance = ::GetModuleHandle(nullptr);
|
|
||||||
wcex.hIcon = nullptr;
|
|
||||||
wcex.hCursor = nullptr;
|
|
||||||
wcex.hbrBackground = (HBRUSH)(COLOR_BACKGROUND + 1);
|
|
||||||
wcex.lpszMenuName = nullptr;
|
|
||||||
wcex.lpszClassName = L"ImGui Platform";
|
|
||||||
wcex.hIconSm = nullptr;
|
|
||||||
::RegisterClassExW(&wcex);
|
|
||||||
|
|
||||||
ImGui_ImplWin32_UpdateMonitors();
|
|
||||||
|
|
||||||
// Register platform interface (will be coupled with a renderer interface)
|
|
||||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
|
||||||
platform_io.Platform_CreateWindow = ImGui_ImplWin32_CreateWindow;
|
|
||||||
platform_io.Platform_DestroyWindow = ImGui_ImplWin32_DestroyWindow;
|
|
||||||
platform_io.Platform_ShowWindow = ImGui_ImplWin32_ShowWindow;
|
|
||||||
platform_io.Platform_SetWindowPos = ImGui_ImplWin32_SetWindowPos;
|
|
||||||
platform_io.Platform_GetWindowPos = ImGui_ImplWin32_GetWindowPos;
|
|
||||||
platform_io.Platform_SetWindowSize = ImGui_ImplWin32_SetWindowSize;
|
|
||||||
platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize;
|
|
||||||
platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus;
|
|
||||||
platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized;
|
|
||||||
platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle;
|
|
||||||
platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha;
|
|
||||||
platform_io.Platform_UpdateWindow = ImGui_ImplWin32_UpdateWindow;
|
|
||||||
platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; // FIXME-DPI
|
|
||||||
platform_io.Platform_OnChangedViewport = ImGui_ImplWin32_OnChangedViewport; // FIXME-DPI
|
|
||||||
|
|
||||||
// Register main window handle (which is owned by the main application, not by us)
|
|
||||||
// This is mostly for simplicity and consistency, so that our code (e.g. mouse handling etc.) can use same logic for main and secondary viewports.
|
|
||||||
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
|
|
||||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
|
||||||
ImGui_ImplWin32_ViewportData* vd = IM_NEW(ImGui_ImplWin32_ViewportData)();
|
|
||||||
vd->Hwnd = bd->hWnd;
|
|
||||||
vd->HwndOwned = false;
|
|
||||||
main_viewport->PlatformUserData = vd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ImGui_ImplWin32_ShutdownMultiViewportSupport()
|
|
||||||
{
|
|
||||||
::UnregisterClassW(L"ImGui Platform", ::GetModuleHandle(nullptr));
|
|
||||||
ImGui::DestroyPlatformWindows();
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
#if defined(__GNUC__)
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy VK_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
// [X] Platform: Gamepad support.
|
// [X] Platform: Gamepad support.
|
||||||
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
// [X] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
|
||||||
|
|
||||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
// 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.
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
|||||||
@ -72,13 +72,14 @@ For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree
|
|||||||
|
|
||||||
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
|
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
|
||||||
|
|
||||||
List of Platforms Backends:
|
List of Platform Backends:
|
||||||
|
|
||||||
imgui_impl_android.cpp ; Android native app API
|
imgui_impl_android.cpp ; Android native app API
|
||||||
imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
|
imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
|
||||||
imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
|
imgui_impl_osx.mm ; macOS native API (not as feature complete as glfw/sdl backends)
|
||||||
imgui_impl_sdl2.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
|
imgui_impl_sdl2.cpp ; SDL2 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
|
||||||
imgui_impl_sdl3.cpp ; SDL3 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
|
imgui_impl_sdl3.cpp ; SDL3 (Windows, macOS, Linux, iOS, Android) https://www.libsdl.org
|
||||||
|
imgui_impl_qnx.cpp ; QNX Screen
|
||||||
imgui_impl_win32.cpp ; Win32 native API (Windows)
|
imgui_impl_win32.cpp ; Win32 native API (Windows)
|
||||||
imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
|
imgui_impl_glut.cpp ; GLUT/FreeGLUT (this is prehistoric software and absolutely not recommended today!)
|
||||||
|
|
||||||
@ -184,7 +185,6 @@ 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_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_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_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:**
|
**In your `ImGui_ImplXXX_NewFrame()` function:**
|
||||||
- Set `io.DeltaTime` to the time elapsed (in seconds) since last frame.
|
- Set `io.DeltaTime` to the time elapsed (in seconds) since last frame.
|
||||||
@ -235,9 +235,7 @@ void MyImGuiBackend_RenderDrawData(ImDrawData* draw_data)
|
|||||||
// - Scissor enabled
|
// - Scissor enabled
|
||||||
MyEngineSetupenderState();
|
MyEngineSetupenderState();
|
||||||
|
|
||||||
// TODO: Setup texture sampling state
|
// TODO: Setup texture sampler to bilinear (NOT point/nearest filtering).
|
||||||
// - Sample with bilinear filtering (NOT point/nearest filtering).
|
|
||||||
// - Use 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines;' to allow point/nearest filtering.
|
|
||||||
|
|
||||||
// TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
|
// TODO: Setup viewport covering draw_data->DisplayPos to draw_data->DisplayPos + draw_data->DisplaySize
|
||||||
|
|
||||||
|
|||||||
1261
docs/CHANGELOG.txt
1261
docs/CHANGELOG.txt
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
## Index
|
## Index
|
||||||
|
|
||||||
- [Getting Started & General Advice](#getting-started--general-advice)
|
- [Getting Started & General Advice](#getting-started--general-advice)
|
||||||
- [Issues vs Discussions](#issues-vs-discussions)
|
- [Using "Issues" for almost everything!](using-issues-for-almost-everything)
|
||||||
- [How to open an Issue](#how-to-open-an-issue)
|
- [How to open an Issue](#how-to-open-an-issue)
|
||||||
- [How to open a Pull Request](#how-to-open-a-pull-request)
|
- [How to open a Pull Request](#how-to-open-a-pull-request)
|
||||||
- [Copyright / Contributor License Agreement](#copyright--contributor-license-agreement)
|
- [Copyright / Contributor License Agreement](#copyright--contributor-license-agreement)
|
||||||
@ -23,18 +23,20 @@
|
|||||||
- If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around.
|
- If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around.
|
||||||
- Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/).
|
- Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/).
|
||||||
|
|
||||||
## 'Issues' vs 'Discussions'
|
## Using "Issues" for almost everything!
|
||||||
|
|
||||||
We are happy to use 'Issues' for many type of open-ended questions. We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents.
|
We are happy to use 'Issues' for many type of open-ended questions.
|
||||||
|
We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents.
|
||||||
|
|
||||||
Only if you:
|
- Need help using the API? Open an Issue!
|
||||||
|
- Want to suggest a feature? Open an Issue!
|
||||||
|
- etc.
|
||||||
|
|
||||||
|
ONLY IN THOSE CASE you can use the [Discussions forums](https://github.com/ocornut/imgui/discussions)
|
||||||
- Cannot BUILD or LINK examples.
|
- Cannot BUILD or LINK examples.
|
||||||
- Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine.
|
- Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine.
|
||||||
- Cannot LOAD a font.
|
|
||||||
|
|
||||||
Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue.
|
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new Issue.
|
||||||
|
|
||||||
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue.
|
|
||||||
|
|
||||||
## How to open an issue
|
## How to open an issue
|
||||||
|
|
||||||
|
|||||||
@ -70,8 +70,10 @@ OSX & iOS + Metal4 example, Mac only. <BR>
|
|||||||
[example_apple_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl2/) <BR>
|
[example_apple_opengl2/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl2/) <BR>
|
||||||
OSX + OpenGL2 example. <BR>
|
OSX + OpenGL2 example. <BR>
|
||||||
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp <BR>
|
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl2.cpp <BR>
|
||||||
(NB: imgui_impl_osx.mm is currently not as feature complete as other platforms backends.
|
|
||||||
You may prefer to use the GLFW Or SDL backends, which will also support Windows and Linux.)
|
[example_apple_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_apple_opengl3/) <BR>
|
||||||
|
OSX + OpenGL3 example. <BR>
|
||||||
|
= main.mm + imgui_impl_osx.mm + imgui_impl_opengl3.cpp <BR>
|
||||||
|
|
||||||
[example_glfw_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_wgpu/) <BR>
|
[example_glfw_wgpu/](https://github.com/ocornut/imgui/blob/master/examples/example_glfw_wgpu/) <BR>
|
||||||
GLFW + WebGPU example. Supports Emscripten (web), Dawn (native), WGPU (native). <BR>
|
GLFW + WebGPU example. Supports Emscripten (web), Dawn (native), WGPU (native). <BR>
|
||||||
@ -117,6 +119,16 @@ Because this application doesn't create a window nor a graphic context, there's
|
|||||||
Please note that imgui_impl_null itself is a rather empty backend. We provide it for consistency but
|
Please note that imgui_impl_null itself is a rather empty backend. We provide it for consistency but
|
||||||
it is similarly easy to create a skeleton application without the null backend.
|
it is similarly easy to create a skeleton application without the null backend.
|
||||||
|
|
||||||
|
[example_qnx_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_qnx_opengl3/) <BR>
|
||||||
|
QNX Screen + OpenGL ES 3 example. <BR>
|
||||||
|
= main.cpp + imgui_impl_qnx.cpp + imgui_impl_opengl3.cpp <BR>
|
||||||
|
Uses the QNX recursive make build system and compiles the OpenGL3 renderer with `IMGUI_IMPL_OPENGL_ES3`.
|
||||||
|
|
||||||
|
[example_qnx_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_qnx_vulkan/) <BR>
|
||||||
|
QNX Screen + Vulkan example using `VK_QNX_screen_surface`. <BR>
|
||||||
|
= main.cpp + imgui_impl_qnx.cpp + imgui_impl_vulkan.cpp <BR>
|
||||||
|
Uses the QNX recursive make build system and the Vulkan backend's example helper structures.
|
||||||
|
|
||||||
[example_sdl2_directx11/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_directx11/) <BR>
|
[example_sdl2_directx11/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_directx11/) <BR>
|
||||||
SDL2 + DirectX11 example, Windows only. <BR>
|
SDL2 + DirectX11 example, Windows only. <BR>
|
||||||
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_dx11.cpp <BR>
|
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_dx11.cpp <BR>
|
||||||
|
|||||||
@ -570,8 +570,8 @@ typedef ImU64 ImTextureID; // Default: store up to 64-bits (any pointer or inte
|
|||||||
// Store a ImTextureID _or_ a ImTextureData*.
|
// Store a ImTextureID _or_ a ImTextureData*.
|
||||||
struct ImTextureRef
|
struct ImTextureRef
|
||||||
{
|
{
|
||||||
ImTextureRef() { _TexData = NULL; _TexID = ImTextureID_Invalid; }
|
ImTextureRef() { _TexData = nullptr; _TexID = ImTextureID_Invalid; }
|
||||||
ImTextureRef(ImTextureID tex_id) { _TexData = NULL; _TexID = tex_id; }
|
ImTextureRef(ImTextureID tex_id) { _TexData = nullptr; _TexID = tex_id; }
|
||||||
inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; }
|
inline ImTextureID GetTexID() const { return _TexData ? _TexData->TexID : _TexID; }
|
||||||
|
|
||||||
// Members (either are set, never both!)
|
// Members (either are set, never both!)
|
||||||
@ -589,7 +589,7 @@ struct ImTextureRef
|
|||||||
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.
|
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.
|
- 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`.
|
- 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; }`
|
- 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 = nullptr, .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.**
|
**Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.**
|
||||||
|
|
||||||
@ -780,7 +780,7 @@ style.FontScaleDpi = 2.0f;
|
|||||||
|
|
||||||
To change font size:
|
To change font size:
|
||||||
```cpp
|
```cpp
|
||||||
ImGui::PushFont(NULL, 42.0f); // This will be multiplied by style.FontScaleDpi
|
ImGui::PushFont(nullptr, 42.0f); // This will be multiplied by style.FontScaleDpi
|
||||||
```
|
```
|
||||||
To change font and font size:
|
To change font and font size:
|
||||||
```cpp
|
```cpp
|
||||||
|
|||||||
@ -96,7 +96,7 @@ atlas->AddFont(...);
|
|||||||
|
|
||||||
v1.92 introduces a newer, dynamic font system. It requires backend to support the `ImGuiBackendFlags_HasTextures` feature:
|
v1.92 introduces a newer, dynamic font system. It requires backend to support the `ImGuiBackendFlags_HasTextures` feature:
|
||||||
- Users of icons, Asian and non-English languages do not need to pre-build all glyphs ahead of time. Saving on loading time, memory, and also reducing issues with missing glyphs. Specifying glyph ranges is not needed anymore.
|
- Users of icons, Asian and non-English languages do not need to pre-build all glyphs ahead of time. Saving on loading time, memory, and also reducing issues with missing glyphs. Specifying glyph ranges is not needed anymore.
|
||||||
- `PushFont(NULL, new_size)` may be used anytime to change font size.
|
- `PushFont(nullptr, new_size)` may be used anytime to change font size.
|
||||||
- Packing custom rectangles is more convenient as pixels may be written to immediately.
|
- Packing custom rectangles is more convenient as pixels may be written to immediately.
|
||||||
- Any update to fonts previously required backend specific calls to re-upload the texture, and said calls were not portable across backends. It is now possible to scale fonts etc. in a way that doesn't require you to make backend-specific calls.
|
- Any update to fonts previously required backend specific calls to re-upload the texture, and said calls were not portable across backends. It is now possible to scale fonts etc. in a way that doesn't require you to make backend-specific calls.
|
||||||
- It is possible to plug a custom loader/backend to any font source.
|
- It is possible to plug a custom loader/backend to any font source.
|
||||||
|
|||||||
@ -113,7 +113,7 @@ Calling the `ImGui::ShowDemoWindow()` function will create a demo window showcas
|
|||||||
- [imgui_explorer](https://pthom.github.io/imgui_explorer): Web version of the demo w/ source code browser, courtesy of [@pthom](https://github.com/pthom).
|
- [imgui_explorer](https://pthom.github.io/imgui_explorer): Web version of the demo w/ source code browser, courtesy of [@pthom](https://github.com/pthom).
|
||||||
|
|
||||||
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:
|
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-20260225.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20260225.zip) (Windows, 1.92.6, built 2026/02/25, master) or [older binaries](https://www.dearimgui.com/binaries).
|
- [imgui-demo-binaries-20261015-win32.zip](https://www.dearimgui.com/binaries/imgui-demo-binaries-20261015-win32.zip) (Win32, 1.93.0, built 2026/10/15, master) or [older binaries](https://www.dearimgui.com/binaries).
|
||||||
|
|
||||||
### Gallery
|
### Gallery
|
||||||
|
|
||||||
|
|||||||
@ -115,35 +115,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- separator: width, thickness, centering (#1643, #2657)
|
- separator: width, thickness, centering (#1643, #2657)
|
||||||
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
|
- splitter: formalize the splitter idiom into an official api (we want to handle n-way split) (#319)
|
||||||
|
|
||||||
- docking: B: ordering currently held in tab bar should be implicitly held by windows themselves (also see #2304)
|
- docking: merge docking branch (#2109)
|
||||||
- docking: B- tab bar: the order/focus restoring code could be part of TabBar and not DockNode? (#8)
|
|
||||||
- docking: B~ rework code to be able to lazily create tab bar instance in a single place. The _Unsorted tab flag could be replacing a trailing-counter in DockNode?
|
|
||||||
- docking: B~ fully track windows/settings reference in dock nodes. perhaps find a representation that allows facilitate use of dock builder functions.
|
|
||||||
- docking: B~ Unreal style document system (requires low-level controls of dockspace serialization fork/copy/delete). this is mostly working but the DockBuilderXXX api are not exposed/finished.
|
|
||||||
- docking: B: when docking outer, perform size locking on neighbors nodes the same way we do it with splitters, so other nodes are not resized.
|
|
||||||
- docking: B~ central node resizing behavior incorrect.
|
|
||||||
- docking: B: changing title font/style per-window is not supported as dock nodes are created in NewFrame.
|
|
||||||
- docking: B- dock node inside its own viewports creates 1 temporary viewport per window on startup before ditching them (doesn't affect the user nor request platform windows to be created, but unnecessary)
|
|
||||||
- docking: B- resize sibling locking behavior may be less desirable if we merged same-axis sibling in a same node level?
|
|
||||||
- docking: B- single visible node part of a hidden split hierarchy (OnlyNodeWithWindows != NULL) should show a normal title bar (not a tab bar)
|
|
||||||
- docking: B~ SetNextWindowDock() calls (with conditional) -> defer everything to DockContextUpdate (repro: Documents->[X]Windows->Dock 1 elsewhere->Click Redock All
|
|
||||||
- docking: B~ tidy up tab list popup buttons features (available with manual tab-bar, see ImGuiTabBarFlags_NoTabListPopupButton code, not used by docking nodes)
|
|
||||||
- docking: B- SetNextWindowDockId(0) with a second Begin() in the frame will asserts
|
|
||||||
- docking: B: resize grip drawn in host window typically appears under scrollbar.
|
|
||||||
- docking: B: resize grip auto-resize on multiple node hierarchy doesn't make much sense or should be improved?
|
|
||||||
- docking: B- SetNextWindowFocus() doesn't seem to apply if the window is hidden this frame, need repro (#4)
|
|
||||||
- docking: B- resizing a dock tree small currently has glitches (overlapping collapse and close button, etc.)
|
|
||||||
- docking: B- dpi: look at interaction with the hi-dpi and multi-dpi stuff.
|
|
||||||
- docking: B- tab bar: appearing on first frame with a dumb layout would do less harm that not appearing? (when behind dynamic branch) or store titles + render in EndTabBar()
|
|
||||||
- docking: B- tab bar: make selected tab always shows its full title?
|
|
||||||
- docking: B- hide close button on single tab bar?
|
|
||||||
- docking: B- nav: design interactions so nav controls can dock/undock
|
|
||||||
- docking: B- dockspace: flag to lock the dock tree and/or sizes (ImGuiDockNodeFlags_Locked?)
|
|
||||||
- docking: B- reintroduce collapsing a floating dock node. also collapsing a docked dock node!
|
|
||||||
- docking: B- allow dragging a non-floating dock node by clicking on the title-bar-looking section (not just the collapse/menu button)
|
|
||||||
- docking: B- option to remember undocked window size? (instead of keeping their docked size) (relate to #2104)
|
|
||||||
- docking: C- nav: CTRL+TAB highlighting tabs shows the mismatch between focus-stack and tab-order (not visible in VS because it doesn't highlight the tabs)
|
|
||||||
- docking: C- after a dock/undock, the Scrollbar Status update in Begin() should use an updated e.g. size_y_for_scrollbars to avoid a 1 frame scrollbar flicker.
|
|
||||||
|
|
||||||
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work (WIP branch)
|
- tabs: "there is currently a problem because TabItem() will try to submit their own tooltip after 0.50 second, and this will have the effect of making your tooltip flicker once." -> tooltip priority work (WIP branch)
|
||||||
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
|
- tabs: make EndTabBar fail if users doesn't respect BeginTabBar return value, for consistency/future-proofing.
|
||||||
@ -300,21 +272,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
|
|||||||
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
|
- nav/windowing: Resizing window will currently fail with certain types of resizing constraints/callback applied
|
||||||
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
|
- focus: preserve ActiveId/focus stack state, e.g. when opening a menu and close it, previously selected InputText() focus gets restored (#622)
|
||||||
|
|
||||||
- viewport: make it possible to have no main/hosting viewport (see #8268)
|
|
||||||
- viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without
|
|
||||||
on a custom e.g. Win32 bindings. It prevents newly dragged-out viewports from taking the focus, which makes ALT+F4 more ambiguous.
|
|
||||||
- viewport: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front.
|
|
||||||
- viewport: with platform decoration enabled, platform may force constraint (e.g. minimum size)
|
|
||||||
- viewport: use getfocus/setfocus api to synchronize imgui<>platform focus better (e.g imgui-side ctrl-tab can focus os window, OS initial setup and alt-tab can focus imgui window etc.)
|
|
||||||
- viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for.
|
|
||||||
- viewport: implicit/fallback Debug window can hog a zombie viewport (harmless, noisy?) > could at least clear out the reference on a per session basis?
|
|
||||||
- viewport: need to clarify how to use GetMousePos() from a user point of view.
|
|
||||||
- viewport: could apply monitor boundaries to cliprect to coarse clip things out of monitor? (#8698)
|
|
||||||
- platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport.
|
|
||||||
- platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set
|
|
||||||
- platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it).
|
|
||||||
- platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32).
|
|
||||||
|
|
||||||
- inputs: support track pad style scrolling & slider edit.
|
- inputs: support track pad style scrolling & slider edit.
|
||||||
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
|
- inputs/io: backspace and arrows in the context of a text input could use system repeat rate.
|
||||||
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
|
- inputs/io: clarify/standardize/expose repeat rate and repeat delays (#1808)
|
||||||
|
|||||||
@ -92,6 +92,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -107,6 +108,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@ -40,24 +40,26 @@ int main(int, char**)
|
|||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplAllegro5_Init(display);
|
ImGui_ImplAllegro5_Init(display);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
|
|||||||
@ -144,8 +144,12 @@ void Init(struct android_app* app)
|
|||||||
io.IniFilename = g_IniFilename.c_str();;
|
io.IniFilename = g_IniFilename.c_str();;
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplAndroid_Init(g_App->window);
|
ImGui_ImplAndroid_Init(g_App->window);
|
||||||
@ -153,20 +157,18 @@ void Init(struct android_app* app)
|
|||||||
|
|
||||||
// Setup scaling
|
// Setup scaling
|
||||||
float main_scale = 2.0f;
|
float main_scale = 2.0f;
|
||||||
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.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.
|
style.FontScaleDpi = main_scale; // Set initial font scale.
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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.
|
// - 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.
|
||||||
//style.FontSizeBase = 20.0f;
|
|
||||||
//io.Fonts->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
|
||||||
050450AD276863B000AB6805 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 050450AC276863B000AB6805 /* QuartzCore.framework */; };
|
|
||||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; };
|
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05318E0E274C397200A8DE2E /* GameController.framework */; };
|
||||||
05A275442773BEA20084EF39 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05A275432773BEA20084EF39 /* QuartzCore.framework */; };
|
|
||||||
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
07A82ED82139413D0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82ED72139413C0078D120 /* imgui_widgets.cpp */; };
|
||||||
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822D257677DB0038A28D /* imgui_tables.cpp */; };
|
||||||
@ -36,11 +33,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
050450AC276863B000AB6805 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
|
|
||||||
05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
05318E0E274C397200A8DE2E /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||||
05A2754027728F5B0084EF39 /* imgui_impl_metal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_metal.h; path = ../../backends/imgui_impl_metal.h; sourceTree = "<group>"; };
|
|
||||||
05A2754127728F5B0084EF39 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../backends/imgui_impl_osx.h; sourceTree = "<group>"; };
|
|
||||||
05A275432773BEA20084EF39 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS15.2.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; };
|
|
||||||
07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
|
07A82ED62139413C0078D120 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
|
||||||
07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
07A82ED72139413C0078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
||||||
5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = "<group>"; };
|
5079822D257677DB0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = "<group>"; };
|
||||||
@ -73,7 +66,6 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
05A275442773BEA20084EF39 /* QuartzCore.framework in Frameworks */,
|
|
||||||
8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */,
|
8309BD8F253CCAAA0045E2A1 /* UIKit.framework in Frameworks */,
|
||||||
83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */,
|
83BBE9E720EB46BD00295997 /* MetalKit.framework in Frameworks */,
|
||||||
83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */,
|
83BBE9E520EB46B900295997 /* Metal.framework in Frameworks */,
|
||||||
@ -84,7 +76,6 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
050450AD276863B000AB6805 /* QuartzCore.framework in Frameworks */,
|
|
||||||
8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */,
|
8309BDC6253CCCFE0045E2A1 /* AppKit.framework in Frameworks */,
|
||||||
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */,
|
83BBE9EC20EB471700295997 /* MetalKit.framework in Frameworks */,
|
||||||
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */,
|
05318E0F274C397200A8DE2E /* GameController.framework in Frameworks */,
|
||||||
@ -145,8 +136,6 @@
|
|||||||
83BBE9E320EB46B800295997 /* Frameworks */ = {
|
83BBE9E320EB46B800295997 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
050450AC276863B000AB6805 /* QuartzCore.framework */,
|
|
||||||
05A275432773BEA20084EF39 /* QuartzCore.framework */,
|
|
||||||
05318E0E274C397200A8DE2E /* GameController.framework */,
|
05318E0E274C397200A8DE2E /* GameController.framework */,
|
||||||
8309BDC5253CCCFE0045E2A1 /* AppKit.framework */,
|
8309BDC5253CCCFE0045E2A1 /* AppKit.framework */,
|
||||||
8309BD8E253CCAAA0045E2A1 /* UIKit.framework */,
|
8309BD8E253CCAAA0045E2A1 /* UIKit.framework */,
|
||||||
@ -164,9 +153,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5079822D257677DB0038A28D /* imgui_tables.cpp */,
|
5079822D257677DB0038A28D /* imgui_tables.cpp */,
|
||||||
05A2754027728F5B0084EF39 /* imgui_impl_metal.h */,
|
|
||||||
8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */,
|
8309BDB5253CCC9D0045E2A1 /* imgui_impl_metal.mm */,
|
||||||
05A2754127728F5B0084EF39 /* imgui_impl_osx.h */,
|
|
||||||
8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */,
|
8309BDB6253CCC9D0045E2A1 /* imgui_impl_osx.mm */,
|
||||||
83BBEA0420EB54E700295997 /* imconfig.h */,
|
83BBEA0420EB54E700295997 /* imconfig.h */,
|
||||||
83BBEA0320EB54E700295997 /* imgui.cpp */,
|
83BBEA0320EB54E700295997 /* imgui.cpp */,
|
||||||
@ -298,7 +285,7 @@
|
|||||||
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
83BBEA0A20EB54E700295997 /* imgui.cpp in Sources */,
|
||||||
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
83BBEA0820EB54E700295997 /* imgui_demo.cpp in Sources */,
|
||||||
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
83BBEA0620EB54E700295997 /* imgui_draw.cpp in Sources */,
|
||||||
050450AB2768052600AB6805 /* imgui_tables.cpp in Sources */,
|
5079822E257677DB0038A28D /* imgui_tables.cpp in Sources */,
|
||||||
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */,
|
07A82ED92139418F0078D120 /* imgui_widgets.cpp in Sources */,
|
||||||
8309BDA8253CCC080045E2A1 /* main.mm in Sources */,
|
8309BDA8253CCC080045E2A1 /* main.mm in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -60,33 +60,26 @@
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
style.FrameRounding = 3.0f;
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
style.GrabRounding = 3.0f;
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
style.WindowRounding = 0.0f;
|
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Renderer backend
|
// Setup Renderer backend
|
||||||
ImGui_ImplMetal_Init(_device);
|
ImGui_ImplMetal_Init(_device);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -118,7 +111,6 @@
|
|||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
ImGui_ImplOSX_Init(self.view);
|
ImGui_ImplOSX_Init(self.view);
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,13 +199,6 @@
|
|||||||
// Present
|
// Present
|
||||||
[commandBuffer presentDrawable:view.currentDrawable];
|
[commandBuffer presentDrawable:view.currentDrawable];
|
||||||
[commandBuffer commit];
|
[commandBuffer commit];
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size
|
-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size
|
||||||
@ -287,6 +272,22 @@
|
|||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
NSMenu* mainMenuBar = [[NSMenu alloc] init];
|
||||||
|
NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+Metal Example"];
|
||||||
|
NSMenuItem* quitMenuItem = [appMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
|
||||||
|
[quitMenuItem setTarget:NSApp];
|
||||||
|
[quitMenuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
|
||||||
|
|
||||||
|
NSMenuItem* appMenuItem = [[NSMenuItem alloc] init];
|
||||||
|
[appMenuItem setSubmenu:appMenu];
|
||||||
|
[mainMenuBar addItem:appMenuItem];
|
||||||
|
[NSApp setMainMenu:mainMenuBar];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
@ -301,6 +302,7 @@
|
|||||||
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
|
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
|
||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
defer:NO];
|
defer:NO];
|
||||||
|
self.window.title = @"Dear ImGui OSX+Metal Example";
|
||||||
self.window.contentViewController = rootViewController;
|
self.window.contentViewController = rootViewController;
|
||||||
[self.window center];
|
[self.window center];
|
||||||
[self.window makeKeyAndOrderFront:self];
|
[self.window makeKeyAndOrderFront:self];
|
||||||
@ -348,7 +350,6 @@ int main(int, const char**)
|
|||||||
AppDelegate *appDelegate = [[AppDelegate alloc] init]; // creates window
|
AppDelegate *appDelegate = [[AppDelegate alloc] init]; // creates window
|
||||||
[NSApp setDelegate:appDelegate];
|
[NSApp setDelegate:appDelegate];
|
||||||
|
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -64,33 +64,28 @@
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
style.WindowRounding = 0.0f;
|
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Renderer backend
|
// Setup Renderer backend
|
||||||
ImGui_ImplMetal4_Init(_device, _commandQueue, FRAMES_IN_FLIGHT);
|
ImGui_ImplMetal4_Init(_device, _commandQueue, FRAMES_IN_FLIGHT);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -122,7 +117,6 @@
|
|||||||
|
|
||||||
#if TARGET_OS_OSX
|
#if TARGET_OS_OSX
|
||||||
ImGui_ImplOSX_Init(self.view);
|
ImGui_ImplOSX_Init(self.view);
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,13 +215,6 @@
|
|||||||
[self.commandQueue commit:&commandBuffer count:1];
|
[self.commandQueue commit:&commandBuffer count:1];
|
||||||
[self.commandQueue signalDrawable:view.currentDrawable];
|
[self.commandQueue signalDrawable:view.currentDrawable];
|
||||||
[view.currentDrawable present];
|
[view.currentDrawable present];
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size
|
-(void)mtkView:(MTKView*)view drawableSizeWillChange:(CGSize)size
|
||||||
@ -301,6 +288,22 @@
|
|||||||
|
|
||||||
@implementation AppDelegate
|
@implementation AppDelegate
|
||||||
|
|
||||||
|
-(void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
NSMenu* mainMenuBar = [[NSMenu alloc] init];
|
||||||
|
NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+Metal4 Example"];
|
||||||
|
NSMenuItem* quitMenuItem = [appMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
|
||||||
|
[quitMenuItem setTarget:NSApp];
|
||||||
|
[quitMenuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
|
||||||
|
|
||||||
|
NSMenuItem* appMenuItem = [[NSMenuItem alloc] init];
|
||||||
|
[appMenuItem setSubmenu:appMenu];
|
||||||
|
[mainMenuBar addItem:appMenuItem];
|
||||||
|
[NSApp setMainMenu:mainMenuBar];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
}
|
||||||
|
|
||||||
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
|
||||||
{
|
{
|
||||||
return YES;
|
return YES;
|
||||||
@ -315,6 +318,7 @@
|
|||||||
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
|
styleMask:NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable | NSWindowStyleMaskMiniaturizable
|
||||||
backing:NSBackingStoreBuffered
|
backing:NSBackingStoreBuffered
|
||||||
defer:NO];
|
defer:NO];
|
||||||
|
self.window.title = @"Dear ImGui OSX+Metal4 Example";
|
||||||
self.window.contentViewController = rootViewController;
|
self.window.contentViewController = rootViewController;
|
||||||
[self.window center];
|
[self.window center];
|
||||||
[self.window makeKeyAndOrderFront:self];
|
[self.window makeKeyAndOrderFront:self];
|
||||||
@ -362,7 +366,6 @@ int main(int, const char**)
|
|||||||
AppDelegate *appDelegate = [[AppDelegate alloc] init]; // creates window
|
AppDelegate *appDelegate = [[AppDelegate alloc] init]; // creates window
|
||||||
[NSApp setDelegate:appDelegate];
|
[NSApp setDelegate:appDelegate];
|
||||||
|
|
||||||
[NSApp activateIgnoringOtherApps:YES];
|
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
// - Introduction, links and more at the top of imgui.cpp
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
// FIXME: Multi-viewports is not yet functional in this example. May need backend rework/coordination.
|
#define GL_SILENCE_DEPRECATION
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
#import <OpenGL/gl.h>
|
#import <OpenGL/gl.h>
|
||||||
#import <OpenGL/glu.h>
|
#import <OpenGL/glu.h>
|
||||||
@ -34,7 +33,7 @@
|
|||||||
|
|
||||||
#ifndef DEBUG
|
#ifndef DEBUG
|
||||||
GLint swapInterval = 1;
|
GLint swapInterval = 1;
|
||||||
[[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
|
[[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
if (swapInterval == 0)
|
if (swapInterval == 0)
|
||||||
NSLog(@"Error: Cannot set swap interval.");
|
NSLog(@"Error: Cannot set swap interval.");
|
||||||
#endif
|
#endif
|
||||||
@ -49,20 +48,14 @@
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
|
style.FrameRounding = 3.0f;
|
||||||
ImGuiStyle& style = ImGui::GetStyle();
|
style.GrabRounding = 3.0f;
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
style.WindowRounding = 0.0f;
|
|
||||||
style.Colors[ImGuiCol_WindowBg].w = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplOSX_Init(self);
|
ImGui_ImplOSX_Init(self);
|
||||||
@ -70,13 +63,12 @@
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -142,21 +134,14 @@
|
|||||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
|
|
||||||
[[self openGLContext] makeCurrentContext];
|
[[self openGLContext] makeCurrentContext];
|
||||||
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
ImGui_ImplOpenGL2_RenderDrawData(draw_data);
|
ImGui_ImplOpenGL2_RenderDrawData(draw_data);
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Present
|
// Present
|
||||||
[[self openGLContext] flushBuffer];
|
[[self openGLContext] flushBuffer];
|
||||||
|
|
||||||
@ -206,19 +191,14 @@
|
|||||||
-(void)setupMenu
|
-(void)setupMenu
|
||||||
{
|
{
|
||||||
NSMenu* mainMenuBar = [[NSMenu alloc] init];
|
NSMenu* mainMenuBar = [[NSMenu alloc] init];
|
||||||
NSMenu* appMenu;
|
NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL2 Example"];
|
||||||
NSMenuItem* menuItem;
|
NSMenuItem* quitMenuItem = [appMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
|
||||||
|
[quitMenuItem setTarget:NSApp];
|
||||||
|
[quitMenuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
|
||||||
|
|
||||||
appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL2 Example"];
|
NSMenuItem* appMenuItem = [[NSMenuItem alloc] init];
|
||||||
menuItem = [appMenu addItemWithTitle:@"Quit Dear ImGui OSX+OpenGL2 Example" action:@selector(terminate:) keyEquivalent:@"q"];
|
[appMenuItem setSubmenu:appMenu];
|
||||||
[menuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
|
[mainMenuBar addItem:appMenuItem];
|
||||||
|
|
||||||
menuItem = [[NSMenuItem alloc] init];
|
|
||||||
[menuItem setSubmenu:appMenu];
|
|
||||||
|
|
||||||
[mainMenuBar addItem:menuItem];
|
|
||||||
|
|
||||||
appMenu = nil;
|
|
||||||
[NSApp setMainMenu:mainMenuBar];
|
[NSApp setMainMenu:mainMenuBar];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,10 +209,6 @@
|
|||||||
|
|
||||||
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
// Make the application a foreground application (else it won't receive keyboard events)
|
|
||||||
ProcessSerialNumber psn = {0, kCurrentProcess};
|
|
||||||
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
[self setupMenu];
|
[self setupMenu];
|
||||||
|
|
||||||
@ -256,6 +232,8 @@
|
|||||||
NSLog(@"No OpenGL Context!");
|
NSLog(@"No OpenGL Context!");
|
||||||
|
|
||||||
[view initialize];
|
[view initialize];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@ -264,14 +242,17 @@
|
|||||||
// Application main() function
|
// Application main() function
|
||||||
//-----------------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
int main(int argc, const char* argv[])
|
int main(int, const char**)
|
||||||
{
|
{
|
||||||
@autoreleasepool
|
@autoreleasepool
|
||||||
{
|
{
|
||||||
NSApp = [NSApplication sharedApplication];
|
[NSApplication sharedApplication];
|
||||||
AppDelegate* delegate = [[AppDelegate alloc] init];
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
[[NSApplication sharedApplication] setDelegate:delegate];
|
|
||||||
|
AppDelegate* appDelegate = [[AppDelegate alloc] init];
|
||||||
|
[NSApp setDelegate:appDelegate];
|
||||||
|
|
||||||
[NSApp run];
|
[NSApp run];
|
||||||
}
|
}
|
||||||
return NSApplicationMain(argc, argv);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
21
examples/example_apple_opengl3/Makefile
Normal file
21
examples/example_apple_opengl3/Makefile
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Makefile for example_apple_opengl3, for macOS only (**not iOS**)
|
||||||
|
CXX = clang++
|
||||||
|
EXE = example_apple_opengl3
|
||||||
|
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_osx.mm $(IMGUI_DIR)/backends/imgui_impl_opengl3.cpp
|
||||||
|
|
||||||
|
CXXFLAGS = -std=c++11 -ObjC++ -fobjc-arc -Wall -Wextra -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||||
|
FRAMEWORKS = -framework Cocoa -framework OpenGL -framework GameController
|
||||||
|
|
||||||
|
all: $(EXE)
|
||||||
|
|
||||||
|
$(EXE): $(SOURCES)
|
||||||
|
$(CXX) $(CXXFLAGS) $(SOURCES) -o $(EXE) $(FRAMEWORKS)
|
||||||
|
|
||||||
|
run: all
|
||||||
|
./$(EXE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(EXE) *.o
|
||||||
@ -0,0 +1,334 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 48;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05E31B57274EF0360083FCB6 /* GameController.framework */; };
|
||||||
|
07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 07A82EDA213941D00078D120 /* imgui_widgets.cpp */; };
|
||||||
|
4080A99820B02D340036BA46 /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A98A20B02CD90036BA46 /* main.mm */; };
|
||||||
|
4080A9A220B034280036BA46 /* imgui_impl_opengl3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */; };
|
||||||
|
4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A620B0343C0036BA46 /* imgui_demo.cpp */; };
|
||||||
|
4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9A720B0343C0036BA46 /* imgui.cpp */; };
|
||||||
|
4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */; };
|
||||||
|
4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4080A99F20B034280036BA46 /* imgui_impl_osx.mm */; };
|
||||||
|
4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B220B034E40036BA46 /* Cocoa.framework */; };
|
||||||
|
4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4080A9B420B034EA0036BA46 /* OpenGL.framework */; };
|
||||||
|
50798230257677FD0038A28D /* imgui_tables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5079822F257677FC0038A28D /* imgui_tables.cpp */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
4080A96920B029B00036BA46 /* CopyFiles */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = /usr/share/man/man1/;
|
||||||
|
dstSubfolderSpec = 0;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 1;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
05E31B57274EF0360083FCB6 /* GameController.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GameController.framework; path = System/Library/Frameworks/GameController.framework; sourceTree = SDKROOT; };
|
||||||
|
07A82EDA213941D00078D120 /* imgui_widgets.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_widgets.cpp; path = ../../imgui_widgets.cpp; sourceTree = "<group>"; };
|
||||||
|
4080A96B20B029B00036BA46 /* example_osx_opengl3 */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = example_osx_opengl3; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
4080A98A20B02CD90036BA46 /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = SOURCE_ROOT; };
|
||||||
|
4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_impl_opengl3.cpp; path = ../../backends/imgui_impl_opengl3.cpp; sourceTree = "<group>"; };
|
||||||
|
4080A99F20B034280036BA46 /* imgui_impl_osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = imgui_impl_osx.mm; path = ../../backends/imgui_impl_osx.mm; sourceTree = "<group>"; };
|
||||||
|
4080A9A020B034280036BA46 /* imgui_impl_opengl3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl3.h; path = ../../backends/imgui_impl_opengl3.h; sourceTree = "<group>"; };
|
||||||
|
4080A9A120B034280036BA46 /* imgui_impl_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_osx.h; path = ../../backends/imgui_impl_osx.h; sourceTree = "<group>"; };
|
||||||
|
4080A9A320B034280036BA46 /* imgui_impl_opengl3_loader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_impl_opengl3_loader.h; path = ../../backends/imgui_impl_opengl3_loader.h; sourceTree = "<group>"; };
|
||||||
|
4080A9A520B0343C0036BA46 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_internal.h; path = ../../imgui_internal.h; sourceTree = "<group>"; };
|
||||||
|
4080A9A620B0343C0036BA46 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_demo.cpp; path = ../../imgui_demo.cpp; sourceTree = "<group>"; };
|
||||||
|
4080A9A720B0343C0036BA46 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui.cpp; path = ../../imgui.cpp; sourceTree = "<group>"; };
|
||||||
|
4080A9A820B0343C0036BA46 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui.h; path = ../../imgui.h; sourceTree = "<group>"; };
|
||||||
|
4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_draw.cpp; path = ../../imgui_draw.cpp; sourceTree = "<group>"; };
|
||||||
|
4080A9AC20B0343C0036BA46 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imconfig.h; path = ../../imconfig.h; sourceTree = "<group>"; };
|
||||||
|
4080A9B220B034E40036BA46 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
|
4080A9B420B034EA0036BA46 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; };
|
||||||
|
5079822F257677FC0038A28D /* imgui_tables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = imgui_tables.cpp; path = ../../imgui_tables.cpp; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
4080A96820B029B00036BA46 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
4080A9B520B034EA0036BA46 /* OpenGL.framework in Frameworks */,
|
||||||
|
4080A9B320B034E40036BA46 /* Cocoa.framework in Frameworks */,
|
||||||
|
05E31B59274EF0700083FCB6 /* GameController.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
4080A96220B029B00036BA46 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
5079822F257677FC0038A28D /* imgui_tables.cpp */,
|
||||||
|
4080A9AC20B0343C0036BA46 /* imconfig.h */,
|
||||||
|
4080A9A720B0343C0036BA46 /* imgui.cpp */,
|
||||||
|
4080A9A820B0343C0036BA46 /* imgui.h */,
|
||||||
|
07A82EDA213941D00078D120 /* imgui_widgets.cpp */,
|
||||||
|
4080A9A620B0343C0036BA46 /* imgui_demo.cpp */,
|
||||||
|
4080A9AA20B0343C0036BA46 /* imgui_draw.cpp */,
|
||||||
|
4080A9A520B0343C0036BA46 /* imgui_internal.h */,
|
||||||
|
4080A99E20B034280036BA46 /* imgui_impl_opengl3.cpp */,
|
||||||
|
4080A9A020B034280036BA46 /* imgui_impl_opengl3.h */,
|
||||||
|
4080A9A320B034280036BA46 /* imgui_impl_opengl3_loader.h */,
|
||||||
|
4080A9A120B034280036BA46 /* imgui_impl_osx.h */,
|
||||||
|
4080A99F20B034280036BA46 /* imgui_impl_osx.mm */,
|
||||||
|
4080A98A20B02CD90036BA46 /* main.mm */,
|
||||||
|
4080A96C20B029B00036BA46 /* Products */,
|
||||||
|
4080A9B120B034E40036BA46 /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
4080A96C20B029B00036BA46 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4080A96B20B029B00036BA46 /* example_osx_opengl3 */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
4080A9B120B034E40036BA46 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
05E31B57274EF0360083FCB6 /* GameController.framework */,
|
||||||
|
4080A9B420B034EA0036BA46 /* OpenGL.framework */,
|
||||||
|
4080A9B220B034E40036BA46 /* Cocoa.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
4080A96A20B029B00036BA46 /* example_osx_opengl3 */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl3" */;
|
||||||
|
buildPhases = (
|
||||||
|
4080A96720B029B00036BA46 /* Sources */,
|
||||||
|
4080A96820B029B00036BA46 /* Frameworks */,
|
||||||
|
4080A96920B029B00036BA46 /* CopyFiles */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = example_osx_opengl3;
|
||||||
|
productName = example_osx_opengl3;
|
||||||
|
productReference = 4080A96B20B029B00036BA46 /* example_osx_opengl3 */;
|
||||||
|
productType = "com.apple.product-type.tool";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
4080A96320B029B00036BA46 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0930;
|
||||||
|
ORGANIZATIONNAME = ImGui;
|
||||||
|
TargetAttributes = {
|
||||||
|
4080A96A20B029B00036BA46 = {
|
||||||
|
CreatedOnToolsVersion = 9.3.1;
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl3" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
);
|
||||||
|
mainGroup = 4080A96220B029B00036BA46;
|
||||||
|
productRefGroup = 4080A96C20B029B00036BA46 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
4080A96A20B029B00036BA46 /* example_osx_opengl3 */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
4080A96720B029B00036BA46 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
4080A99820B02D340036BA46 /* main.mm in Sources */,
|
||||||
|
4080A9AD20B0343C0036BA46 /* imgui_demo.cpp in Sources */,
|
||||||
|
4080A9AF20B0343C0036BA46 /* imgui_draw.cpp in Sources */,
|
||||||
|
4080A9A220B034280036BA46 /* imgui_impl_opengl3.cpp in Sources */,
|
||||||
|
4080A9B020B0347A0036BA46 /* imgui_impl_osx.mm in Sources */,
|
||||||
|
4080A9AE20B0343C0036BA46 /* imgui.cpp in Sources */,
|
||||||
|
50798230257677FD0038A28D /* imgui_tables.cpp in Sources */,
|
||||||
|
07A82EDB213941D00078D120 /* imgui_widgets.cpp in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
4080A97020B029B00036BA46 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
4080A97120B029B00036BA46 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "-";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
4080A97320B029B00036BA46 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
USER_HEADER_SEARCH_PATHS = ../..;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
4080A97420B029B00036BA46 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
USER_HEADER_SEARCH_PATHS = ../..;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
4080A96620B029B00036BA46 /* Build configuration list for PBXProject "example_apple_opengl3" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
4080A97020B029B00036BA46 /* Debug */,
|
||||||
|
4080A97120B029B00036BA46 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
4080A97220B029B00036BA46 /* Build configuration list for PBXNativeTarget "example_osx_opengl3" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
4080A97320B029B00036BA46 /* Debug */,
|
||||||
|
4080A97420B029B00036BA46 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 4080A96320B029B00036BA46 /* Project object */;
|
||||||
|
}
|
||||||
259
examples/example_apple_opengl3/main.mm
Normal file
259
examples/example_apple_opengl3/main.mm
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
// Dear ImGui: standalone example application for OSX + OpenGL3
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#define GL_SILENCE_DEPRECATION
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <OpenGL/gl3.h>
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#include "imgui_impl_opengl3.h"
|
||||||
|
#include "imgui_impl_osx.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
// AppView
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@interface AppView : NSOpenGLView
|
||||||
|
{
|
||||||
|
NSTimer* animationTimer;
|
||||||
|
}
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation AppView
|
||||||
|
|
||||||
|
-(void)prepareOpenGL
|
||||||
|
{
|
||||||
|
[super prepareOpenGL];
|
||||||
|
|
||||||
|
#ifndef DEBUG
|
||||||
|
GLint swapInterval = 1;
|
||||||
|
[[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLContextParameterSwapInterval];
|
||||||
|
if (swapInterval == 0)
|
||||||
|
NSLog(@"Error: Cannot set swap interval.");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)initialize
|
||||||
|
{
|
||||||
|
// Setup Dear ImGui context
|
||||||
|
// FIXME: This example doesn't have proper cleanup...
|
||||||
|
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
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
|
// Setup Platform/Renderer backends
|
||||||
|
[[self openGLContext] makeCurrentContext]; // ImGui_ImplOpenGL3_Init() requires a current GL context.
|
||||||
|
ImGui_ImplOSX_Init(self);
|
||||||
|
ImGui_ImplOpenGL3_Init();
|
||||||
|
|
||||||
|
// Load Fonts
|
||||||
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//io.Fonts->AddFontDefaultVector();
|
||||||
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)updateAndDrawDemoView
|
||||||
|
{
|
||||||
|
// Start the Dear ImGui frame
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
ImGui_ImplOSX_NewFrame(self);
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
// Our state (make them static = more or less global) as a convenience to keep the example terse.
|
||||||
|
static bool show_demo_window = true;
|
||||||
|
static bool show_another_window = false;
|
||||||
|
static ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
|
||||||
|
[[self openGLContext] makeCurrentContext];
|
||||||
|
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||||
|
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(draw_data);
|
||||||
|
|
||||||
|
// Present
|
||||||
|
[[self openGLContext] flushBuffer];
|
||||||
|
|
||||||
|
if (!animationTimer)
|
||||||
|
animationTimer = [NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)reshape { [super reshape]; [[self openGLContext] update]; [self updateAndDrawDemoView]; }
|
||||||
|
-(void)drawRect:(NSRect)bounds { [self updateAndDrawDemoView]; }
|
||||||
|
-(void)animationTimerFired:(NSTimer*)timer { [self setNeedsDisplay:YES]; }
|
||||||
|
-(void)dealloc { animationTimer = nil; }
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
// AppDelegate
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
@property (nonatomic, readonly) NSWindow* window;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation AppDelegate
|
||||||
|
@synthesize window = _window;
|
||||||
|
|
||||||
|
-(BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
|
||||||
|
{
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSWindow*)window
|
||||||
|
{
|
||||||
|
if (_window != nil)
|
||||||
|
return _window;
|
||||||
|
|
||||||
|
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+OpenGL3 Example"];
|
||||||
|
[_window setAcceptsMouseMovedEvents:YES];
|
||||||
|
[_window setOpaque:YES];
|
||||||
|
[_window makeKeyAndOrderFront:NSApp];
|
||||||
|
|
||||||
|
return _window;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setupMenu
|
||||||
|
{
|
||||||
|
NSMenu* mainMenuBar = [[NSMenu alloc] init];
|
||||||
|
NSMenu* appMenu = [[NSMenu alloc] initWithTitle:@"Dear ImGui OSX+OpenGL3 Example"];
|
||||||
|
NSMenuItem* quitMenuItem = [appMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"];
|
||||||
|
[quitMenuItem setTarget:NSApp];
|
||||||
|
[quitMenuItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
|
||||||
|
|
||||||
|
NSMenuItem* appMenuItem = [[NSMenuItem alloc] init];
|
||||||
|
[appMenuItem setSubmenu:appMenu];
|
||||||
|
[mainMenuBar addItem:appMenuItem];
|
||||||
|
[NSApp setMainMenu:mainMenuBar];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)dealloc
|
||||||
|
{
|
||||||
|
_window = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||||
|
{
|
||||||
|
// Menu
|
||||||
|
[self setupMenu];
|
||||||
|
|
||||||
|
NSOpenGLPixelFormatAttribute attrs[] =
|
||||||
|
{
|
||||||
|
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core,
|
||||||
|
NSOpenGLPFADoubleBuffer,
|
||||||
|
NSOpenGLPFADepthSize, 32,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
||||||
|
AppView* view = [[AppView alloc] initWithFrame:self.window.frame pixelFormat:format];
|
||||||
|
format = nil;
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
|
||||||
|
[view setWantsBestResolutionOpenGLSurface:YES];
|
||||||
|
#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||||
|
[self.window setContentView:view];
|
||||||
|
|
||||||
|
if ([view openGLContext] == nil)
|
||||||
|
NSLog(@"No OpenGL Context!");
|
||||||
|
|
||||||
|
[view initialize];
|
||||||
|
|
||||||
|
[NSApp activateIgnoringOtherApps:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
// Application main() function
|
||||||
|
//-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int main(int, const char**)
|
||||||
|
{
|
||||||
|
@autoreleasepool
|
||||||
|
{
|
||||||
|
[NSApplication sharedApplication];
|
||||||
|
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||||
|
|
||||||
|
AppDelegate* appDelegate = [[AppDelegate alloc] init];
|
||||||
|
[NSApp setDelegate:appDelegate];
|
||||||
|
|
||||||
|
[NSApp run];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -44,43 +44,34 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup scaling
|
// 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.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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
style.FontScaleDpi = main_scale; // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
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 <MTLDevice> device = MTLCreateSystemDefaultDevice();
|
||||||
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
|
id <MTLCommandQueue> commandQueue = [device newCommandQueue];
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOther(window, true);
|
||||||
ImGui_ImplMetal_Init(device);
|
ImGui_ImplMetal_Init(device);
|
||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -175,13 +166,6 @@ int main(int, char**)
|
|||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
|
ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
[renderEncoder popDebugGroup];
|
[renderEncoder popDebugGroup];
|
||||||
[renderEncoder endEncoding];
|
[renderEncoder endEncoding];
|
||||||
|
|
||||||
|
|||||||
21
examples/example_glfw_opengl2/build_win.bat
Normal file
21
examples/example_glfw_opengl2/build_win.bat
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@REM Build for Visual Studio compiler. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
|
||||||
|
@REM Detect target architecture (VS 2015 uses Platform, unset for native x86; VS 2017+ uses VSCMD_ARG_TGT_ARCH).
|
||||||
|
@set TARGET_ARCH=%VSCMD_ARG_TGT_ARCH%
|
||||||
|
@if not defined TARGET_ARCH if "%VisualStudioVersion%"=="14.0" (set TARGET_ARCH=x86& if defined Platform set TARGET_ARCH=%Platform%)
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" goto arch_ok
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" goto arch_ok
|
||||||
|
@echo Unsupported or uninitialized compiler environment. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
@exit /b 1
|
||||||
|
|
||||||
|
:arch_ok
|
||||||
|
@set OUT_EXE=example_glfw_opengl2
|
||||||
|
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include
|
||||||
|
@set SOURCES=main.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
|
||||||
|
@set LIBS=glfw3.lib opengl32.lib gdi32.lib shell32.lib
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-32
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-64
|
||||||
|
|
||||||
|
@set OUT_DIR=Debug
|
||||||
|
mkdir %OUT_DIR%
|
||||||
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
@ -1,8 +0,0 @@
|
|||||||
@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_glfw_opengl2
|
|
||||||
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include
|
|
||||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_opengl2.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
|
|
||||||
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.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%
|
|
||||||
@ -92,6 +92,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -107,6 +108,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@ -53,28 +53,18 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad 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
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup scaling
|
// 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.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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
style.FontScaleDpi = main_scale; // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
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
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||||
@ -82,13 +72,12 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -176,17 +165,6 @@ int main(int, char**)
|
|||||||
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData());
|
||||||
//glUseProgram(last_program);
|
//glUseProgram(last_program);
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
|
||||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
glfwMakeContextCurrent(backup_current_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
glfwMakeContextCurrent(window);
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
|
|||||||
21
examples/example_glfw_opengl3/build_win.bat
Normal file
21
examples/example_glfw_opengl3/build_win.bat
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
@REM Build for Visual Studio compiler. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
|
||||||
|
@REM Detect target architecture (VS 2015 uses Platform, unset for native x86; VS 2017+ uses VSCMD_ARG_TGT_ARCH).
|
||||||
|
@set TARGET_ARCH=%VSCMD_ARG_TGT_ARCH%
|
||||||
|
@if not defined TARGET_ARCH if "%VisualStudioVersion%"=="14.0" (set TARGET_ARCH=x86& if defined Platform set TARGET_ARCH=%Platform%)
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" goto arch_ok
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" goto arch_ok
|
||||||
|
@echo Unsupported or uninitialized compiler environment. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
@exit /b 1
|
||||||
|
|
||||||
|
:arch_ok
|
||||||
|
@set OUT_EXE=example_glfw_opengl3
|
||||||
|
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include
|
||||||
|
@set SOURCES=main.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
|
||||||
|
@set LIBS=glfw3.lib opengl32.lib gdi32.lib shell32.lib
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-32
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-64
|
||||||
|
|
||||||
|
@set OUT_DIR=Debug
|
||||||
|
mkdir %OUT_DIR%
|
||||||
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
@ -1,8 +0,0 @@
|
|||||||
@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_glfw_opengl3
|
|
||||||
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include
|
|
||||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\backends\imgui_impl_opengl3.cpp ..\..\imgui*.cpp
|
|
||||||
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 glfw3.lib opengl32.lib gdi32.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%
|
|
||||||
@ -92,6 +92,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -107,6 +108,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@ -81,30 +81,18 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad 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
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup scaling
|
// 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.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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
style.FontScaleDpi = main_scale; // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
#if GLFW_VERSION_MAJOR >= 3 && GLFW_VERSION_MINOR >= 3
|
|
||||||
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.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// 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
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
ImGui_ImplGlfw_InitForOpenGL(window, true);
|
||||||
@ -115,14 +103,13 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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.
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -210,17 +197,6 @@ int main(int, char**)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
|
|
||||||
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
|
||||||
GLFWwindow* backup_current_context = glfwGetCurrentContext();
|
|
||||||
ImGui::UpdatePlatformWindows();
|
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
|
||||||
glfwMakeContextCurrent(backup_current_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwSwapBuffers(window);
|
glfwSwapBuffers(window);
|
||||||
}
|
}
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
|
|||||||
25
examples/example_glfw_vulkan/build_win.bat
Normal file
25
examples/example_glfw_vulkan/build_win.bat
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
@REM Build for Visual Studio compiler. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
|
||||||
|
@REM Detect target architecture (VS 2015 uses Platform, unset for native x86; VS 2017+ uses VSCMD_ARG_TGT_ARCH).
|
||||||
|
@set TARGET_ARCH=%VSCMD_ARG_TGT_ARCH%
|
||||||
|
@if not defined TARGET_ARCH if "%VisualStudioVersion%"=="14.0" (set TARGET_ARCH=x86& if defined Platform set TARGET_ARCH=%Platform%)
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" goto arch_ok
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" goto arch_ok
|
||||||
|
@echo Unsupported or uninitialized compiler environment. First run vcvars32.bat (x86) or vcvars64.bat (x64).
|
||||||
|
@exit /b 1
|
||||||
|
|
||||||
|
:arch_ok
|
||||||
|
@set OUT_EXE=example_glfw_vulkan
|
||||||
|
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
|
||||||
|
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
|
||||||
|
@set LIBS=glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
|
||||||
|
@if /I "%TARGET_ARCH%"=="x86" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32
|
||||||
|
@if /I "%TARGET_ARCH%"=="x64" set LIBS=%LIBS% /LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib
|
||||||
|
|
||||||
|
@set OUT_DIR=Debug
|
||||||
|
mkdir %OUT_DIR%
|
||||||
|
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
|
|
||||||
|
@set OUT_DIR=Release
|
||||||
|
mkdir %OUT_DIR%
|
||||||
|
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
||||||
@ -1,14 +0,0 @@
|
|||||||
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
|
|
||||||
|
|
||||||
@set OUT_EXE=example_glfw_vulkan
|
|
||||||
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
|
|
||||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
|
|
||||||
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-32 /libpath:%VULKAN_SDK%\lib32 glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
|
|
||||||
|
|
||||||
@set OUT_DIR=Debug
|
|
||||||
mkdir %OUT_DIR%
|
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
|
||||||
|
|
||||||
@set OUT_DIR=Release
|
|
||||||
mkdir %OUT_DIR%
|
|
||||||
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
@REM Build for Visual Studio compiler. Run your copy of vcvars64.bat or vcvarsall.bat to setup 64-bit command-line compiler.
|
|
||||||
|
|
||||||
@set OUT_EXE=example_glfw_vulkan
|
|
||||||
@set INCLUDES=/I..\.. /I..\..\backends /I..\libs\glfw\include /I %VULKAN_SDK%\include
|
|
||||||
@set SOURCES=main.cpp ..\..\backends\imgui_impl_vulkan.cpp ..\..\backends\imgui_impl_glfw.cpp ..\..\imgui*.cpp
|
|
||||||
@set LIBS=/LIBPATH:..\libs\glfw\lib-vc2010-64 /libpath:%VULKAN_SDK%\lib glfw3.lib opengl32.lib gdi32.lib shell32.lib vulkan-1.lib
|
|
||||||
|
|
||||||
@set OUT_DIR=Debug
|
|
||||||
mkdir %OUT_DIR%
|
|
||||||
cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
|
||||||
|
|
||||||
@set OUT_DIR=Release
|
|
||||||
mkdir %OUT_DIR%
|
|
||||||
cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS%
|
|
||||||
@ -93,6 +93,7 @@
|
|||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -109,6 +110,7 @@
|
|||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@ -390,28 +390,18 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad 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
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup scaling
|
// 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.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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
style.FontScaleDpi = main_scale; // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
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
|
// Setup Platform/Renderer backends
|
||||||
ImGui_ImplGlfw_InitForVulkan(window, true);
|
ImGui_ImplGlfw_InitForVulkan(window, true);
|
||||||
@ -435,13 +425,12 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
@ -526,25 +515,17 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Rendering
|
// Rendering
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImDrawData* main_draw_data = ImGui::GetDrawData();
|
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||||
const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f);
|
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);
|
||||||
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
if (!is_minimized)
|
||||||
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
|
||||||
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
|
||||||
wd->ClearValue.color.float32[3] = clear_color.w;
|
|
||||||
if (!main_is_minimized)
|
|
||||||
FrameRender(wd, main_draw_data);
|
|
||||||
|
|
||||||
// Update and Render additional Platform Windows
|
|
||||||
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
|
|
||||||
{
|
{
|
||||||
ImGui::UpdatePlatformWindows();
|
wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w;
|
||||||
ImGui::RenderPlatformWindowsDefault();
|
wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w;
|
||||||
}
|
wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w;
|
||||||
|
wd->ClearValue.color.float32[3] = clear_color.w;
|
||||||
// Present Main Platform Window
|
FrameRender(wd, draw_data);
|
||||||
if (!main_is_minimized)
|
|
||||||
FramePresent(wd);
|
FramePresent(wd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
|||||||
@ -1,10 +1,3 @@
|
|||||||
# Building for desktop with Dawn:
|
|
||||||
# 1. git clone https://github.com/google/dawn dawn
|
|
||||||
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
|
||||||
# 3. cmake --build build
|
|
||||||
# The resulting binary will be found at one of the following locations:
|
|
||||||
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
|
||||||
|
|
||||||
# Building for desktop with WGPU-Native:
|
# Building for desktop with WGPU-Native:
|
||||||
# 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases
|
# 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases
|
||||||
# 2. unzip the downloaded file in your_preferred_folder
|
# 2. unzip the downloaded file in your_preferred_folder
|
||||||
@ -13,7 +6,14 @@
|
|||||||
# The resulting binary will be found at one of the following locations:
|
# The resulting binary will be found at one of the following locations:
|
||||||
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
||||||
|
|
||||||
# Building for desktop with WGVK (MUCH EASIER)
|
# Building for desktop with Dawn: (VERY LONG TO BUILD)
|
||||||
|
# 1. git clone https://github.com/google/dawn dawn
|
||||||
|
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
||||||
|
# 3. cmake --build build
|
||||||
|
# The resulting binary will be found at one of the following locations:
|
||||||
|
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
||||||
|
|
||||||
|
# Building for desktop with WGVK:
|
||||||
# 1. git clone https://github.com/manuel5975p/WGVK wgvk
|
# 1. git clone https://github.com/manuel5975p/WGVK wgvk
|
||||||
# 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk
|
# 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk
|
||||||
# 3. cmake --build build
|
# 3. cmake --build build
|
||||||
@ -29,7 +29,7 @@
|
|||||||
# 4. emrun build/index.html
|
# 4. emrun build/index.html
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
|
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
|
||||||
project(imgui_example_glfw_wgpu C CXX)
|
project(example_glfw_wgpu C CXX)
|
||||||
|
|
||||||
set(IMGUI_EXECUTABLE example_glfw_wgpu)
|
set(IMGUI_EXECUTABLE example_glfw_wgpu)
|
||||||
|
|
||||||
|
|||||||
@ -87,14 +87,16 @@ int main(int, char**)
|
|||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup scaling
|
// 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.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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
style.FontScaleDpi = main_scale; // Set initial font scale. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
|
|
||||||
@ -112,14 +114,13 @@ int main(int, char**)
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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.
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
#ifndef IMGUI_DISABLE_FILE_FUNCTIONS
|
||||||
@ -291,6 +292,16 @@ int main(int, char**)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WGPUTextureFormat SelectSurfaceFormat(const WGPUSurfaceCapabilities& capabilities)
|
||||||
|
{
|
||||||
|
const WGPUTextureFormat preferredFormats[] = { WGPUTextureFormat_BGRA8Unorm, WGPUTextureFormat_RGBA8Unorm, WGPUTextureFormat_BGRA8UnormSrgb, WGPUTextureFormat_RGBA8UnormSrgb };
|
||||||
|
for (WGPUTextureFormat preferredFormat : preferredFormats)
|
||||||
|
for (size_t n = 0; n < capabilities.formatCount; n++)
|
||||||
|
if (capabilities.formats[n] == preferredFormat)
|
||||||
|
return preferredFormat;
|
||||||
|
return capabilities.formatCount > 0 ? capabilities.formats[0] : WGPUTextureFormat_Undefined;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||||
static WGPUAdapter RequestAdapter(wgpu::Instance& instance)
|
static WGPUAdapter RequestAdapter(wgpu::Instance& instance)
|
||||||
{
|
{
|
||||||
@ -345,29 +356,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
|||||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||||
{
|
{
|
||||||
IM_UNUSED(userdata2);
|
IM_UNUSED(userdata2);
|
||||||
if (status == WGPURequestAdapterStatus_Success)
|
if (status != WGPURequestAdapterStatus_Success)
|
||||||
{
|
{
|
||||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||||
*extAdapter = adapter;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
|
||||||
}
|
}
|
||||||
|
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||||
|
*extAdapter = adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||||
{
|
{
|
||||||
IM_UNUSED(userdata2);
|
IM_UNUSED(userdata2);
|
||||||
if (status == WGPURequestDeviceStatus_Success)
|
if (status != WGPURequestDeviceStatus_Success)
|
||||||
{
|
{
|
||||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||||
*extDevice = device;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
|
||||||
}
|
}
|
||||||
|
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||||
|
*extDevice = device;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||||
@ -381,8 +388,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
|||||||
adapterCallbackInfo.userdata1 = &local_adapter;
|
adapterCallbackInfo.userdata1 = &local_adapter;
|
||||||
|
|
||||||
WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo);
|
WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo);
|
||||||
|
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||||
|
#endif
|
||||||
IM_ASSERT(local_adapter && "Error on Adapter request");
|
IM_ASSERT(local_adapter && "Error on Adapter request");
|
||||||
return local_adapter;
|
return local_adapter;
|
||||||
}
|
}
|
||||||
@ -394,15 +403,20 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
|||||||
deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly;
|
deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly;
|
||||||
deviceCallbackInfo.callback = handle_request_device;
|
deviceCallbackInfo.callback = handle_request_device;
|
||||||
deviceCallbackInfo.userdata1 = &local_device;
|
deviceCallbackInfo.userdata1 = &local_device;
|
||||||
|
|
||||||
WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo);
|
WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo);
|
||||||
|
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||||
|
#else
|
||||||
|
IM_UNUSED(instance);
|
||||||
|
#endif
|
||||||
IM_ASSERT(local_device && "Error on Device request");
|
IM_ASSERT(local_device && "Error on Device request");
|
||||||
return local_device;
|
return local_device;
|
||||||
}
|
}
|
||||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||||
|
|
||||||
bool InitWGPU(GLFWwindow* window)
|
static bool InitWGPU(GLFWwindow* window)
|
||||||
{
|
{
|
||||||
WGPUTextureFormat preferred_fmt = WGPUTextureFormat_Undefined; // acquired from SurfaceCapabilities
|
WGPUTextureFormat preferred_fmt = WGPUTextureFormat_Undefined; // acquired from SurfaceCapabilities
|
||||||
|
|
||||||
@ -438,8 +452,7 @@ bool InitWGPU(GLFWwindow* window)
|
|||||||
|
|
||||||
WGPUSurfaceCapabilities surface_capabilities = {};
|
WGPUSurfaceCapabilities surface_capabilities = {};
|
||||||
wgpuSurfaceGetCapabilities(wgpu_surface, adapter.Get(), &surface_capabilities);
|
wgpuSurfaceGetCapabilities(wgpu_surface, adapter.Get(), &surface_capabilities);
|
||||||
|
preferred_fmt = SelectSurfaceFormat(surface_capabilities);
|
||||||
preferred_fmt = surface_capabilities.formats[0];
|
|
||||||
|
|
||||||
// WGPU backend: Adapter and Device acquisition, Surface creation
|
// WGPU backend: Adapter and Device acquisition, Surface creation
|
||||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
||||||
@ -451,7 +464,7 @@ bool InitWGPU(GLFWwindow* window)
|
|||||||
|
|
||||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||||
wgpuSetLogCallback(
|
wgpuSetLogCallback(
|
||||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
[](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||||
);
|
);
|
||||||
wgpuSetLogLevel(WGPULogLevel_Warn);
|
wgpuSetLogLevel(WGPULogLevel_Warn);
|
||||||
#endif
|
#endif
|
||||||
@ -468,8 +481,7 @@ bool InitWGPU(GLFWwindow* window)
|
|||||||
|
|
||||||
WGPUSurfaceCapabilities surface_capabilities = {};
|
WGPUSurfaceCapabilities surface_capabilities = {};
|
||||||
wgpuSurfaceGetCapabilities(wgpu_surface, adapter, &surface_capabilities);
|
wgpuSurfaceGetCapabilities(wgpu_surface, adapter, &surface_capabilities);
|
||||||
|
preferred_fmt = SelectSurfaceFormat(surface_capabilities);
|
||||||
preferred_fmt = surface_capabilities.formats[0];
|
|
||||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||||
|
|
||||||
wgpu_surface_configuration.presentMode = WGPUPresentMode_Fifo;
|
wgpu_surface_configuration.presentMode = WGPUPresentMode_Fifo;
|
||||||
@ -549,7 +561,7 @@ WGPUSurface CreateWGPUSurface(const WGPUInstance& instance, GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
create_info.System = "win32";
|
create_info.System = "win32";
|
||||||
create_info.RawWindow = (void*)glfwGetWin32Window(window);
|
create_info.RawWindow = (void*)glfwGetWin32Window(window);
|
||||||
create_info.RawInstance = (void*)::GetModuleHandle(NULL);
|
create_info.RawInstance = (void*)::GetModuleHandle(nullptr);
|
||||||
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
|
return ImGui_ImplWGPU_CreateWGPUSurfaceHelper(&create_info);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|||||||
@ -92,6 +92,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
@ -107,6 +108,7 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
|||||||
@ -61,11 +61,14 @@ int main(int argc, char** argv)
|
|||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
|
|
||||||
|
|
||||||
// Setup Dear ImGui style
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
ImGui::StyleColorsDark();
|
ImGui::StyleColorsDark();
|
||||||
//ImGui::StyleColorsLight();
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
// Setup Platform/Renderer backends
|
// Setup Platform/Renderer backends
|
||||||
// FIXME: Consider reworking this example to install our own GLUT funcs + forward calls ImGui_ImplGLUT_XXX ones, instead of using ImGui_ImplGLUT_InstallFuncs().
|
// FIXME: Consider reworking this example to install our own GLUT funcs + forward calls ImGui_ImplGLUT_XXX ones, instead of using ImGui_ImplGLUT_InstallFuncs().
|
||||||
@ -81,13 +84,12 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
// Load Fonts
|
// Load Fonts
|
||||||
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a small threshold.
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
// - Read 'docs/FONTS.md' for more instructions and details.
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
// - 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->AddFontDefaultVector();
|
//io.Fonts->AddFontDefaultVector();
|
||||||
//io.Fonts->AddFontDefaultBitmap();
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
|
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat, vcvars64.bat, or vcvarsall.bat to setup command-line compiler.
|
||||||
mkdir Debug
|
mkdir Debug
|
||||||
cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib
|
cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib
|
||||||
@ -88,11 +88,13 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -102,11 +104,13 @@
|
|||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -124,8 +128,9 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x86;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
@ -143,8 +148,9 @@
|
|||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<AdditionalDependencies>d3d11.lib;d3dcompiler.lib;dxgi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>
|
||||||
<AdditionalLibraryDirectories>$(DXSDK_DIR)/Lib/x64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
</AdditionalDependencies>
|
||||||
|
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
|||||||
@ -16,6 +16,14 @@ int main(int, char**)
|
|||||||
ImGui::CreateContext();
|
ImGui::CreateContext();
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
ImGui_ImplNullPlatform_Init();
|
ImGui_ImplNullPlatform_Init();
|
||||||
ImGui_ImplNullRender_Init();
|
ImGui_ImplNullRender_Init();
|
||||||
|
|
||||||
|
|||||||
2
examples/example_qnx_opengl3/Makefile
Normal file
2
examples/example_qnx_opengl3/Makefile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
LIST=OS
|
||||||
|
include recurse.mk
|
||||||
29
examples/example_qnx_opengl3/README.md
Normal file
29
examples/example_qnx_opengl3/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Dear ImGui QNX Screen + OpenGL ES 3 example
|
||||||
|
|
||||||
|
This example uses:
|
||||||
|
|
||||||
|
- `imgui_impl_qnx.cpp` as the QNX Screen platform backend
|
||||||
|
- `imgui_impl_opengl3.cpp` as the renderer backend
|
||||||
|
- EGL to create an OpenGL ES 3 context and Screen window surface
|
||||||
|
|
||||||
|
`imgui_impl_opengl3.cpp` supports desktop OpenGL and OpenGL ES. On QNX this
|
||||||
|
example compiles it with `IMGUI_IMPL_OPENGL_ES3` and uses `#version 300 es`.
|
||||||
|
No separate Screen/OpenGL renderer backend is required.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Load the QNX SDP environment, then run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd examples/example_qnx_opengl3
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
The QNX recursive make files build for the CPUs enabled in your SDP
|
||||||
|
configuration and install the program as `example_qnx_opengl3`.
|
||||||
|
|
||||||
|
## Input
|
||||||
|
|
||||||
|
The application polls its `screen_context_t` event queue and forwards every
|
||||||
|
non-`SCREEN_EVENT_NONE` event to `ImGui_ImplQNX_ProcessEvent()`.
|
||||||
|
Escape exits the example.
|
||||||
31
examples/example_qnx_opengl3/common.mk
Normal file
31
examples/example_qnx_opengl3/common.mk
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
ifndef QCONFIG
|
||||||
|
QCONFIG=qconfig.mk
|
||||||
|
endif
|
||||||
|
include $(QCONFIG)
|
||||||
|
|
||||||
|
NAME=example_qnx_opengl3
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
main.cpp \
|
||||||
|
imgui.cpp \
|
||||||
|
imgui_demo.cpp \
|
||||||
|
imgui_draw.cpp \
|
||||||
|
imgui_tables.cpp \
|
||||||
|
imgui_widgets.cpp \
|
||||||
|
imgui_impl_qnx.cpp \
|
||||||
|
imgui_impl_opengl3.cpp
|
||||||
|
|
||||||
|
EXTRA_SRCVPATH += $(PROJECT_ROOT)/../.. $(PROJECT_ROOT)/../../backends
|
||||||
|
EXTRA_INCVPATH += $(PROJECT_ROOT)/../.. $(PROJECT_ROOT)/../../backends
|
||||||
|
|
||||||
|
CXXFLAGS += -std=gnu++11 -DIMGUI_IMPL_OPENGL_ES3
|
||||||
|
LIBS += EGL GLESv2 screen m
|
||||||
|
|
||||||
|
INSTALLDIR=$(firstword $(INSTALLDIR_$(OS)) usr/bin)
|
||||||
|
|
||||||
|
define PINFO
|
||||||
|
PINFO DESCRIPTION=Dear ImGui QNX Screen and OpenGL ES 3 example
|
||||||
|
endef
|
||||||
|
|
||||||
|
include $(MKFILES_ROOT)/qmacros.mk
|
||||||
|
include $(MKFILES_ROOT)/qtargets.mk
|
||||||
309
examples/example_qnx_opengl3/main.cpp
Normal file
309
examples/example_qnx_opengl3/main.cpp
Normal file
@ -0,0 +1,309 @@
|
|||||||
|
// Dear ImGui: standalone example application for QNX Screen + OpenGL ES 3
|
||||||
|
|
||||||
|
// 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_qnx.h"
|
||||||
|
#include "imgui_impl_opengl3.h"
|
||||||
|
#include <stdio.h> // printf, fprintf
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/keycodes.h>
|
||||||
|
#include <screen/screen.h>
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
|
|
||||||
|
#ifndef EGL_OPENGL_ES3_BIT
|
||||||
|
#ifdef EGL_OPENGL_ES3_BIT_KHR
|
||||||
|
#define EGL_OPENGL_ES3_BIT EGL_OPENGL_ES3_BIT_KHR
|
||||||
|
#else
|
||||||
|
#define EGL_OPENGL_ES3_BIT 0x0040
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct QNXWindow
|
||||||
|
{
|
||||||
|
screen_context_t Context = nullptr;
|
||||||
|
screen_window_t Window = nullptr;
|
||||||
|
screen_event_t Event = nullptr;
|
||||||
|
EGLDisplay Display = EGL_NO_DISPLAY;
|
||||||
|
EGLContext GLContext = EGL_NO_CONTEXT;
|
||||||
|
EGLSurface GLSurface = EGL_NO_SURFACE;
|
||||||
|
int Size[2] = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Forward declarations of helper functions
|
||||||
|
bool CreateQNXWindow(QNXWindow* window);
|
||||||
|
void DestroyQNXWindow(QNXWindow* window);
|
||||||
|
bool ProcessQNXEvents(QNXWindow* window);
|
||||||
|
|
||||||
|
// Main code
|
||||||
|
int main(int, char**)
|
||||||
|
{
|
||||||
|
// Setup QNX Screen and EGL
|
||||||
|
QNXWindow window;
|
||||||
|
if (!CreateQNXWindow(&window))
|
||||||
|
{
|
||||||
|
DestroyQNXWindow(&window);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// GL ES 3.0 + GLSL 300 es
|
||||||
|
const char* glsl_version = "#version 300 es";
|
||||||
|
float main_scale = 1.0f;
|
||||||
|
|
||||||
|
// Setup Dear ImGui context
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ImGui::CreateContext();
|
||||||
|
ImGuiIO& io = ImGui::GetIO(); (void)io;
|
||||||
|
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
|
||||||
|
|
||||||
|
// Setup Dear ImGui style
|
||||||
|
ImGuiStyle& style = ImGui::GetStyle();
|
||||||
|
ImGui::StyleColorsDark();
|
||||||
|
//ImGui::StyleColorsLight();
|
||||||
|
//style.FontSizeBase = 16.0f; // Default to 13.0f when unspecified, which allows crisp legacy font for non-4K screens.
|
||||||
|
style.FrameRounding = 3.0f;
|
||||||
|
style.GrabRounding = 3.0f;
|
||||||
|
|
||||||
|
// Setup scaling
|
||||||
|
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. (in docking branch: using io.ConfigDpiScaleFonts=true automatically overrides this for every window depending on the current monitor)
|
||||||
|
|
||||||
|
// Setup Platform/Renderer backends
|
||||||
|
ImGui_ImplQNX_Init(window.Context, window.Window);
|
||||||
|
ImGui_ImplOpenGL3_Init(glsl_version);
|
||||||
|
|
||||||
|
// Load Fonts
|
||||||
|
// - If fonts are not explicitly loaded, Dear ImGui will select an embedded font: either AddFontDefaultVector() or AddFontDefaultBitmap().
|
||||||
|
// This selection is based on (style.FontSizeBase * style.FontScaleMain * style.FontScaleDpi) reaching a threshold.
|
||||||
|
// - You can load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
|
||||||
|
// - If a file cannot be loaded, AddFont functions will return a nullptr. Please handle those errors in your code (e.g. use an assertion, display an error and quit).
|
||||||
|
// - Read 'docs/FONTS.md' for more instructions and details.
|
||||||
|
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use FreeType for higher quality font rendering.
|
||||||
|
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
|
||||||
|
//io.Fonts->AddFontDefaultVector();
|
||||||
|
//io.Fonts->AddFontDefaultBitmap();
|
||||||
|
//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 (!ProcessQNXEvents(&window))
|
||||||
|
done = true;
|
||||||
|
|
||||||
|
// Start the Dear ImGui frame
|
||||||
|
ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
ImGui_ImplQNX_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();
|
||||||
|
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
|
||||||
|
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
|
eglSwapBuffers(window.Display, window.GLSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup
|
||||||
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
|
ImGui_ImplQNX_Shutdown();
|
||||||
|
ImGui::DestroyContext();
|
||||||
|
|
||||||
|
DestroyQNXWindow(&window);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper functions
|
||||||
|
|
||||||
|
bool CreateQNXWindow(QNXWindow* window)
|
||||||
|
{
|
||||||
|
if (screen_create_context(&window->Context, 0) != 0 ||
|
||||||
|
screen_create_window(&window->Window, window->Context) != 0 ||
|
||||||
|
screen_create_event(&window->Event) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "QNX Screen initialization failed: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A newly created QNX Screen window reports the fullscreen dimensions.
|
||||||
|
if (screen_get_window_property_iv(window->Window, SCREEN_PROPERTY_SIZE, window->Size) != 0 || window->Size[0] <= 0 || window->Size[1] <= 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to obtain QNX Screen window size: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_OPENGL_ES3 | SCREEN_USAGE_NATIVE;
|
||||||
|
const int transparency = SCREEN_TRANSPARENCY_NONE;
|
||||||
|
const int swap_interval = 1;
|
||||||
|
if (screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_USAGE, &usage) != 0 ||
|
||||||
|
screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_SIZE, window->Size) != 0 ||
|
||||||
|
screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_TRANSPARENCY, &transparency) != 0 ||
|
||||||
|
screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_SWAP_INTERVAL, &swap_interval) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to configure QNX Screen window: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
window->Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
|
if (window->Display == EGL_NO_DISPLAY || eglInitialize(window->Display, nullptr, nullptr) != EGL_TRUE || eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "EGL initialization failed: 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EGLint config_attributes[] =
|
||||||
|
{
|
||||||
|
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||||
|
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT,
|
||||||
|
EGL_RED_SIZE, 8,
|
||||||
|
EGL_GREEN_SIZE, 8,
|
||||||
|
EGL_BLUE_SIZE, 8,
|
||||||
|
EGL_ALPHA_SIZE, 8,
|
||||||
|
EGL_DEPTH_SIZE, 24,
|
||||||
|
EGL_STENCIL_SIZE, 8,
|
||||||
|
EGL_NONE
|
||||||
|
};
|
||||||
|
EGLConfig config = nullptr;
|
||||||
|
EGLint config_count = 0;
|
||||||
|
if (eglChooseConfig(window->Display, config_attributes, &config, 1, &config_count) != EGL_TRUE || config_count == 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "eglChooseConfig() failed: 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLint native_visual = 0;
|
||||||
|
if (eglGetConfigAttrib(window->Display, config, EGL_NATIVE_VISUAL_ID, &native_visual) != EGL_TRUE ||
|
||||||
|
screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_FORMAT, &native_visual) != 0 ||
|
||||||
|
screen_create_window_buffers(window->Window, 2) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to create QNX Screen buffers: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const EGLint context_attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE };
|
||||||
|
window->GLContext = eglCreateContext(window->Display, config, EGL_NO_CONTEXT, context_attributes);
|
||||||
|
window->GLSurface = eglCreateWindowSurface(window->Display, config, window->Window, nullptr);
|
||||||
|
if (window->GLContext == EGL_NO_CONTEXT || window->GLSurface == EGL_NO_SURFACE ||
|
||||||
|
eglMakeCurrent(window->Display, window->GLSurface, window->GLSurface, window->GLContext) != EGL_TRUE ||
|
||||||
|
eglSwapInterval(window->Display, 1) != EGL_TRUE)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "EGL context creation failed: 0x%04x\n", eglGetError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int visible = 1;
|
||||||
|
if (screen_set_window_property_iv(window->Window, SCREEN_PROPERTY_VISIBLE, &visible) != 0)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Failed to show QNX Screen window: %s\n", strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DestroyQNXWindow(QNXWindow* window)
|
||||||
|
{
|
||||||
|
if (window->Display != EGL_NO_DISPLAY)
|
||||||
|
{
|
||||||
|
eglMakeCurrent(window->Display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
if (window->GLSurface != EGL_NO_SURFACE)
|
||||||
|
eglDestroySurface(window->Display, window->GLSurface);
|
||||||
|
if (window->GLContext != EGL_NO_CONTEXT)
|
||||||
|
eglDestroyContext(window->Display, window->GLContext);
|
||||||
|
eglTerminate(window->Display);
|
||||||
|
}
|
||||||
|
if (window->Event != nullptr)
|
||||||
|
screen_destroy_event(window->Event);
|
||||||
|
if (window->Window != nullptr)
|
||||||
|
screen_destroy_window(window->Window);
|
||||||
|
if (window->Context != nullptr)
|
||||||
|
screen_destroy_context(window->Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessQNXEvents(QNXWindow* window)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (screen_get_event(window->Context, window->Event, 0) != 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int type = SCREEN_EVENT_NONE;
|
||||||
|
if (screen_get_event_property_iv(window->Event, SCREEN_PROPERTY_TYPE, &type) != 0)
|
||||||
|
return false;
|
||||||
|
if (type == SCREEN_EVENT_NONE)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ImGui_ImplQNX_ProcessEvent(window->Event);
|
||||||
|
if (type == SCREEN_EVENT_CLOSE)
|
||||||
|
return false;
|
||||||
|
if (type == SCREEN_EVENT_KEYBOARD)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
int key_cap = 0;
|
||||||
|
if (screen_get_event_property_iv(window->Event, SCREEN_PROPERTY_FLAGS, &flags) == 0 &&
|
||||||
|
screen_get_event_property_iv(window->Event, SCREEN_PROPERTY_KEY_CAP, &key_cap) == 0 &&
|
||||||
|
(flags & SCREEN_FLAG_KEY_DOWN) != 0 && key_cap == KEYCODE_ESCAPE)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
8
examples/example_qnx_opengl3/nto/Makefile
Normal file
8
examples/example_qnx_opengl3/nto/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
LIST=CPU
|
||||||
|
ifndef QRECURSE
|
||||||
|
QRECURSE=recurse.mk
|
||||||
|
ifdef QCONFIG
|
||||||
|
QRDIR=$(dir $(QCONFIG))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
include $(QRDIR)$(QRECURSE)
|
||||||
8
examples/example_qnx_opengl3/nto/aarch64/Makefile
Normal file
8
examples/example_qnx_opengl3/nto/aarch64/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
LIST=VARIANT
|
||||||
|
ifndef QRECURSE
|
||||||
|
QRECURSE=recurse.mk
|
||||||
|
ifdef QCONFIG
|
||||||
|
QRDIR=$(dir $(QCONFIG))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
include $(QRDIR)$(QRECURSE)
|
||||||
1
examples/example_qnx_opengl3/nto/aarch64/o.le/Makefile
Normal file
1
examples/example_qnx_opengl3/nto/aarch64/o.le/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include ../../../common.mk
|
||||||
8
examples/example_qnx_opengl3/nto/x86_64/Makefile
Normal file
8
examples/example_qnx_opengl3/nto/x86_64/Makefile
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
LIST=VARIANT
|
||||||
|
ifndef QRECURSE
|
||||||
|
QRECURSE=recurse.mk
|
||||||
|
ifdef QCONFIG
|
||||||
|
QRDIR=$(dir $(QCONFIG))
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
include $(QRDIR)$(QRECURSE)
|
||||||
1
examples/example_qnx_opengl3/nto/x86_64/o/Makefile
Normal file
1
examples/example_qnx_opengl3/nto/x86_64/o/Makefile
Normal file
@ -0,0 +1 @@
|
|||||||
|
include ../../../common.mk
|
||||||
2
examples/example_qnx_vulkan/Makefile
Normal file
2
examples/example_qnx_vulkan/Makefile
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
LIST=OS
|
||||||
|
include recurse.mk
|
||||||
29
examples/example_qnx_vulkan/README.md
Normal file
29
examples/example_qnx_vulkan/README.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
# Dear ImGui QNX Screen + Vulkan example
|
||||||
|
|
||||||
|
This example uses:
|
||||||
|
|
||||||
|
- `imgui_impl_qnx.cpp` as the QNX Screen platform backend
|
||||||
|
- the unmodified `imgui_impl_vulkan.cpp` renderer backend
|
||||||
|
- `vkCreateScreenSurfaceQNX()` and `VK_QNX_screen_surface`
|
||||||
|
|
||||||
|
No separate Screen/Vulkan renderer backend is required. The QNX-specific work
|
||||||
|
is limited to the Screen platform backend, native window setup, and Vulkan WSI
|
||||||
|
surface creation.
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
Load the QNX SDP environment, then run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd examples/example_qnx_vulkan
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
The build defines `VK_USE_PLATFORM_SCREEN_QNX` and links `libvulkan` and
|
||||||
|
`libscreen`.
|
||||||
|
|
||||||
|
## Input and resize
|
||||||
|
|
||||||
|
The application forwards Screen input events to `ImGui_ImplQNX_ProcessEvent()`.
|
||||||
|
It recreates the Vulkan swapchain when the Screen window size changes or Vulkan
|
||||||
|
reports `VK_ERROR_OUT_OF_DATE_KHR` / `VK_SUBOPTIMAL_KHR`. Escape exits.
|
||||||
31
examples/example_qnx_vulkan/common.mk
Normal file
31
examples/example_qnx_vulkan/common.mk
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
ifndef QCONFIG
|
||||||
|
QCONFIG=qconfig.mk
|
||||||
|
endif
|
||||||
|
include $(QCONFIG)
|
||||||
|
|
||||||
|
NAME=example_qnx_vulkan
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
main.cpp \
|
||||||
|
imgui.cpp \
|
||||||
|
imgui_demo.cpp \
|
||||||
|
imgui_draw.cpp \
|
||||||
|
imgui_tables.cpp \
|
||||||
|
imgui_widgets.cpp \
|
||||||
|
imgui_impl_qnx.cpp \
|
||||||
|
imgui_impl_vulkan.cpp
|
||||||
|
|
||||||
|
EXTRA_SRCVPATH += $(PROJECT_ROOT)/../.. $(PROJECT_ROOT)/../../backends
|
||||||
|
EXTRA_INCVPATH += $(PROJECT_ROOT)/../.. $(PROJECT_ROOT)/../../backends
|
||||||
|
|
||||||
|
CXXFLAGS += -std=gnu++11 -DVK_USE_PLATFORM_SCREEN_QNX=1
|
||||||
|
LIBS += vulkan screen m
|
||||||
|
|
||||||
|
INSTALLDIR=$(firstword $(INSTALLDIR_$(OS)) usr/bin)
|
||||||
|
|
||||||
|
define PINFO
|
||||||
|
PINFO DESCRIPTION=Dear ImGui QNX Screen and Vulkan example
|
||||||
|
endef
|
||||||
|
|
||||||
|
include $(MKFILES_ROOT)/qmacros.mk
|
||||||
|
include $(MKFILES_ROOT)/qtargets.mk
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user